cancel
Showing results for 
Search instead for 
Did you mean: 

How to differentiate USB Mass Storage and Battery charging mode: STM32L476

martinj3456
Associate III
Posted on November 28, 2017 at 01:27

Hello all,

I'm using STM32L476 in a custom PCB board. Using USB OTG libary (from L4 cube examples), our code initialize USB Mass storage by following four lines of code upon USB connectivity (detected by a connected GPIO pin):

USBD_Init(&USBD_Device, &MSC_Desc, 0);                                              // USB MSC initialization

USBD_RegisterClass(&USBD_Device, USBD_MSC_CLASS);                   // USB class registration

USBD_MSC_RegisterStorage(&USBD_Device, &USBD_DISK_fops);        // Storage call backs

USBD_Start(&USBD_Device);                                                                      // Start USB MSC

We want to put the device in low power sleep mode when the USB is connected to the battery charger (not with PC for USB MSC). I request to know, how to differentiate the USB status: USB connected to PC (USB MSC initialized) vs the USB connected to wall Battery charger.

Is there any variable to look? The above functions return USBD_OK in both cases (USB connected to PC or Wall charger).

Thank you in advance for your kind reply.

1 ACCEPTED SOLUTION

Accepted Solutions
Ben K
Senior III
Posted on November 28, 2017 at 22:43

1. A general approach based on the lack of host-device interaction

2. Using the Battery Charger Detection feature

The wall charger doesn't interact with the USB device, therefore by simply observing the 

USBD_Device.dev_state over a couple of milliseconds you should see that instead of going to USBD_STATE_ADDRESSED and later USBD_STATE_CONFIGURED, it goes to USBD_STATE_SUSPENDED (or perhaps stays in USBD_STATE_DEFAULT).

1. A general approach based on the lack of host-device interaction

2. Using the Battery Charger Detection feature

The L4 series is part of the relatively newer product lines, therefore it already has a built-in BCD feature. Unfortunately the HAL API for it is unnecessarily complicated. You should call the HAL_PCDEx_BCD_VBUSDetect() API before calling USBD_Start(). This function - instead of simply returning with the result - calls the HAL_PCDEx_BCD_Callback() callback with the determined upstream port type. Implement this callback with the following operation: call USBD_Start() when the message parameter is PCD_BCD_DISCOVERY_COMPLETED, otherwise enter the low power mode of your choosing.

One thing to keep in mind in both cases: the physical USB connection is designed to establish power connection before the data lines. Therefore depending on the speed of plugging in the device, these detection methods require a variable delay from the time of the power connection, as they are both operational from the time the data lines are connected.

View solution in original post

2 REPLIES 2
Ben K
Senior III
Posted on November 28, 2017 at 22:43

1. A general approach based on the lack of host-device interaction

2. Using the Battery Charger Detection feature

The wall charger doesn't interact with the USB device, therefore by simply observing the 

USBD_Device.dev_state over a couple of milliseconds you should see that instead of going to USBD_STATE_ADDRESSED and later USBD_STATE_CONFIGURED, it goes to USBD_STATE_SUSPENDED (or perhaps stays in USBD_STATE_DEFAULT).

1. A general approach based on the lack of host-device interaction

2. Using the Battery Charger Detection feature

The L4 series is part of the relatively newer product lines, therefore it already has a built-in BCD feature. Unfortunately the HAL API for it is unnecessarily complicated. You should call the HAL_PCDEx_BCD_VBUSDetect() API before calling USBD_Start(). This function - instead of simply returning with the result - calls the HAL_PCDEx_BCD_Callback() callback with the determined upstream port type. Implement this callback with the following operation: call USBD_Start() when the message parameter is PCD_BCD_DISCOVERY_COMPLETED, otherwise enter the low power mode of your choosing.

One thing to keep in mind in both cases: the physical USB connection is designed to establish power connection before the data lines. Therefore depending on the speed of plugging in the device, these detection methods require a variable delay from the time of the power connection, as they are both operational from the time the data lines are connected.

Posted on November 29, 2017 at 05:45

Hi Ben.

Thank you for your direction. Yes, it worked !!! Previously I tried 1st method without the delays. 

This time I've added a one-second delay after 

USBD_Start(&USBD_Device);

 in the 1st method and could differentiate the USB default and configured state. Less than 1 sec did not work in my case.

Thanks once again.

M