Skip to main content
Visitor II
July 20, 2020
Solved

Remote Wakeup signalling on STM32F7xx. My full-speed CDC device doesn't appear to generate the remote wakeup signal.

  • July 20, 2020
  • 6 replies
  • 3124 views

Environment:

STM32F756

IAR Embedded Workbench IDE - Arm 8.40.1

USB CDC device, Full Speed

FreeRTOS

Problem:

Remote wakeup function does not work. I've set the remote wake-up attribute in the config descriptor. The host enters suspend. My device doesn't wake the host. (I also have a mouse connected, and it can successfully wake the host, so host config is not the problem).

void product_remote_wake(void)
{
// PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)usb_device.pData;
// HAL_PCD_ActivateRemoteWakeup( hpcd );
 
// as you can see, I've tried multiple approaches, all appear to 
 // end up pointing to the USB_BASE address at 0x50000000 to do the work
 
 USB_ActivateRemoteWakeup( USB_OTG_FS ); //usb_device ); // USB_OTG_GlobalTypeDef *USBx) 
 
 vTaskDelay(pdMS_TO_TICKS(10));
 
// HAL_PCD_DeActivateRemoteWakeup( hpcd );
 
 USB_DeActivateRemoteWakeup( USB_OTG_FS ); //usb_device ); // USB_OTG_GlobalTypeDef *USBx) 
 
// USB_ActivateRemoteWakeup( hpcd->Instance ); //usb_device ); // USB_OTG_GlobalTypeDef *USBx) 
// HAL_PCD_ActivateRemoteWakeup( usb_device.pData );
}

    This topic has been closed for replies.
    Best answer by MFOGA.1

    Looked at some other example code and noticed that they are using this macro to unlock the USB PHY clock prior to hitting the RWUSIG bit. That fixed it.

     /* Ungate PHY clock */

     __HAL_PCD_UNGATE_PHYCLOCK((&hpcd));

          

     /* Activate Remote wakeup */

     HAL_PCD_ActivateRemoteWakeup((&hpcd));

    6 replies

    Super User
    July 20, 2020

    Cube is open source, so you can debug it as your own program.

    Make sure it sets USB_OTG_DCTL_RWUSIG, by reading out and checking the DCTL register.

    JW

    MFOGA.1Author
    Visitor II
    July 20, 2020

    Well sure, I can single step through it even, and inspect the memory. It looks like the bit is getting set correctly.

    Let me know if you see anything wrong:

    The code that performs the action at the lowest level is

      USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;

    The USB base address, is 0x50000000, DCTL is 0x804, RWUSIG is the bottom bit. The code appears to correctly set and clear the bottom bit at 0x50000804.

    These are the defines, snippets pulled from the code that describe how the line above is being decoded.

    #define USB_OTG_FS_PERIPH_BASE        0x50000000UL

    typedef struct

    {

     __IO uint32_t DCFG;      /*!< dev Configuration Register  800h */

     __IO uint32_t DCTL;      /*!< dev Control Register     804h */

    ..<snip>

    #define USB_OTG_DCTL_RWUSIG_Pos         (0U)              

    #define USB_OTG_DCTL_RWUSIG_Msk         (0x1UL << USB_OTG_DCTL_RWUSIG_Pos) /*!< 0x00000001 */

    #define USB_OTG_DCTL_RWUSIG           USB_OTG_DCTL_RWUSIG_Msk    /*!< Remote wakeup signaling */

    MFOGA.1Author
    Visitor II
    July 22, 2020

    I just noticed these bits in DCTL:

    Bits 6:4 TCTL[2:0]: Test control

    000: Test mode disabled

    001: Test_J mode

    010: Test_K mode

    011: Test_SE0_NAK mode

    100: Test_Packet mode

    101: Test_Force_Enable

    Others: Reserved

    They don't appear to have an effect either.

    Super User
    July 20, 2020

    So, if the RWUSIG bit actually changed, so should the respective signal on the bus - at that moment the bus is essentially DC, look it up in the USB spec.

    If it does and the host won't respond, well then it's something host related (still can be e.g. incorrect descriptors). Btw how many hours did you try and how diverse were they?

    If it does not... well, dunno.

    JW

    MFOGA.1Author
    Visitor II
    July 21, 2020

    From the Universal Serial Bus Specification Revision 2.0, Table 7-2. Low-/full-speed Signaling Levels:

    Resume signalling for full speed is Data K state, aka Differential "0", which is D- high & D+ low

    I'm seeing that the pins are in the Data J state (D- low, D+ high) before RWUSIG gets set and after RWUSIG gets set. So RWUSIG has no effect. So I guess it isn't a host problem. I'm still looking for a STM32-related problem.

    The descriptors related to remote wake up amount to a single bit in the config descriptor. Also, the device is supposed to correctly handle the USB_FEATURE_REMOTE_WAKEUP set and clear. I'm not seeing the host trying to set that on using protocol analyzer.

    Either way, that shouldn't have an effect on the ST's ability to signal RWU if I force it. I'm thinking there's something wrong with the memory area I'm trying to init. Or maybe the USB register region has to be enabled somehow? Ideas?

    Super User
    July 22, 2020

    No idea here, sorry. I don't use the Cube USB stack, I wrote mine, and simply setting the wake-up bit works for me as expected. I also don't use the F7 but F4, but that shouldn't matter that much.

    You may want to try to pester ST directly, through web support firm or through FAE.

    JW

    MFOGA.1AuthorAnswer
    Visitor II
    July 25, 2020

    Looked at some other example code and noticed that they are using this macro to unlock the USB PHY clock prior to hitting the RWUSIG bit. That fixed it.

     /* Ungate PHY clock */

     __HAL_PCD_UNGATE_PHYCLOCK((&hpcd));

          

     /* Activate Remote wakeup */

     HAL_PCD_ActivateRemoteWakeup((&hpcd));

    Super User
    July 25, 2020

    Thank you for coming back with the solution.

    This makes sense. Devices I am working at are never very consumption-restricted, so I never felt the pressure to spare a few mA by switching off the PHY...

    JW