cancel
Showing results for 
Search instead for 
Did you mean: 

After power-up and before using the usb, the STM32L4R9AI processor on our board goes to sleep and the current draw is as expected. But after using usb and removing cable, current consumption does not return to previous level.

dmc
Associate

As some background information, we used STM32CubeMX version 6.5.0 to generate the drivers for a custom hid device that runs on a STM32L4R9AI processor. 

When the usb cable is inserted, MX_USB_DEVICE_Init() is called which is stm’s code in a file called usb_device.c.

When the usb cable is removed, MX_USB_DEVICE_DeInit() is called, also in the same file. I would expect that as a result, the sleep current would be the same as it was before inserting the cable. But instead, the current draw remains roughly double.

I have also noticed that when using the debugger, for both insertion and removal of the usb cable, HAL_PCD_IRQHandler triggers twice first to call a suspend callback and then to call a resume callback. And for both insertion and removal, the order is the same. 

Why does the interrupt trigger twice, and why the same order, suspend then resume?

When measuring the current, I remove the debugger so that it is not the influencing the current draw.

 

3 REPLIES 3
Ghofrane GSOURI
ST Employee

Hello @dmc​ 

First let me thank you for posting.

The STM32L4R9AI processor has a USB peripheral that is used for communication with USB devices, such as the custom HID device you're working with. When the USB cable is inserted, the USB peripheral is initialized and configured for communication with the connected device. When the cable is removed, the USB peripheral is deinitialized to stop communication and put the peripheral into a low-power state.

The reason the current draw remains roughly double even after the cable is removed is likely because something in the USB peripheral or the system is not properly entering a low-power state or is continuing to consume power even when it's not in use. The MX_USB_DEVICE_DeInit() function is responsible for deinitializing the USB peripheral, but there may be other parts of the system that need to be taken into consideration when entering low-power states.

Regarding the HAL_PCD_IRQHandler triggering twice. It is because of USB Suspend and Resume feature, The USB peripheral has a feature called "suspend," which allows it to enter a low-power state when no data is being transferred over the USB cable. This feature is used to conserve power when the device is connected to a USB host but not actively communicating.

When the USB cable is inserted, the USB peripheral is configured and the host sends a "resume" signal to bring the peripheral out of its suspended state and back to its active state. Then when the USB cable is removed, the host sends a "suspend" signal, then the peripheral enters a suspended state and MX_USB_DEVICE_DeInit() is called to stop communication and put the peripheral into a low-power state.

The order of the suspend then resume is because it is the standard procedure as specified in USB 2.0 specification chapter 7.1.7.

Regarding the current measurement, removing the debugger is a good idea, because the debugger can consume additional current and that could have an impact on the measurement.

It will be good idea if you could cross-check the USB driver, clock management and power management in the whole design, that everything is properly configured and optimized for low-power operation.

Thx

Ghofrane

dmc
Associate

Thank you Ghofrane,

I'd like to follow-up to your response with two questions. You suggested that "The MX_USB_DEVICE_DeInit() function is responsible for deinitializing the USB peripheral, but there may be other parts of the system that need to be taken into consideration when entering low-power states."

Yes, I agree. I have spent a considerable amount of time trying to figure out what that might be. I enabled low_power_enable bool in USBD_LL_Init(). We do not need vbus sensing as our design uses the usb-sense input to a gpio pin to wake the processor.

1.) Can you suggest anything specific that I should take into consideration?

Regarding the suspend and resume functions,

2.) Can you think of any reason why resume_callback is called as a result of removing the usb cable?

That is what I have been seeing.

Thank you again.

Ghofrane GSOURI
ST Employee

Hello again @dmc​ 

1.) When entering low-power states with STM32L4R9AI, in addition to deinitializing the USB peripheral with the MX_USB_DEVICE_DeInit() function, you can take the following steps to conserve power:

  • Disable any clocks to unused peripherals and subsystems
  • If the USB peripheral is not in use, you can put it into low-power mode by disabling the USB clock.
  • Use the peripheral control unit to disable power to unused peripherals, such as UART, ADC, etc.
  • If your application doesn't need a high-speed clock, you can switch to a lower frequency clock source.
  • Use the sleep mode feature to put the microcontroller into a low-power mode when it is not performing any tasks.

2.) In the case of STM32L4R9AI, when the USB cable is removed, the USB controller generates a disconnect event, this may cause a call to the resume_callback function if it is not handled properly in the firmware. If the disconnect event is not being handled correctly in the firmware, it could cause the USB controller to believe that it is still connected, and the resume_callback function is called as a result.

It will be helpful to check the USB state machine, the events, and the USB packets that are being sent between the USB device and host to understand the root cause of the resume_callback being called on cable removal.

Thx

Ghofrane