AnsweredAssumed Answered

Firmware-controlled USB connection and HSE activation

Question asked by Brendan McDonnell on Feb 17, 2017

I'm developing firmware for a low power USB 2.0 Full Speed device (12 Mbps) which uses an STM32F070CB microcontroller. The clock source for the USB module is the High Speed External (HSE) oscillator. I'm using STM32CubeMX with version 1.7.0 of STM32CubeF0 to generate the codebase.

To conserve our power budget, we need to turn off the HSE when the USB is not connected. I'm thinking we should make the firmware delay USB detection by the host until the device is ready, so that the events in the firmware would go something like this:

  • Event - Detect physical USB connection
    • Enable HSE
    • Initialize USB
    • Connect Data+ pull-up (DPPU) to trigger USB enumeration by host
  • Event - Detect physical USB disconnection
    • Disconnect DPPU (simulate physical disconnection to host)
    • De-initialize USB
    • Disable HSE (drive PF0-OSC_IN low)

Questions

  1. Is the above the right way to go about this? Are the actions all required? Are they in the right order?

  2. Do I need to call any functions besides USBD_DeInit() to de-init USB?

  3. How can I make the device appear disconnected on the host while physically connected? (i.e. It should disappear from Windows Device Manager.) Why doesn't calling HAL_PCD_DevDisconnect() cause that to happen?

Details

In the following paragraphs, to "physically connect" means to connect the USB cable to the device and the host PC.

I would expect all calls to MX_USB_DEVICE_Init() and MX_USB_DEVICE_DeInit() to take effect immediately, i.e. that I would see the device appear/disappear in Windows Device Manager if the function was called while the device is physically connected. However, I've observed this only on the first call to MX_USB_DEVICE_Init(). All calls to MX_USB_DEVICE_DeInit() and subsequent calls to MX_USB_DEVICE_Init() don't cause the device to appear/disappear from Windows Device Manager until after physical reconnection. (i.e. If it's connected, when the function is called, no change in Device Manager until after disconnect/reconnect.)

Code

As generated by STM32CubeMX:

/* USB Device Core handle declaration */USBD_HandleTypeDef hUsbDeviceFS;/* init function */                     void MX_USB_DEVICE_Init(void){  /* Init Device Library,Add Supported Class and Start the library*/  USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);   USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC);   USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS);   USBD_Start(&hUsbDeviceFS);}

I created:

void MX_USB_DEVICE_DeInit(void){   HAL_PCD_DevDisconnect((PCD_HandleTypeDef *)&hUsbDeviceFS.pData);   USBD_Stop  (&hUsbDeviceFS);   USBD_DeInit(&hUsbDeviceFS);}

It makes no difference whether or when I call HAL_PCD_DevDisconnect(). I have never observed the device disappear from Windows Device Manager while physically connected.

Outcomes