cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 as bus-powered USB device: how to negotiate more power?

caco3
Associate II
Posted on January 08, 2016 at 14:29

According to

http://www.beyondlogic.org/usbnutshell/usb2.shtml#PowerVbus

, a vbus powered USB device (slave) can only pull more than 100 mA after it negotiated with the host (e.g. PC):

''High power bus powered functions will draw all its power from the bus and cannot draw more than one unit load until it has been configured, after which it can then drain 5 unit loads (500mA Max) provided it asked for this in its descriptor.''

How does the STM32Cube USB device library do this? I can not find any parameter in the Configuration descriptor.

Above page states this:

''A USB device specifies its power consumption expressed in 2mA units in the configuration descriptor''.

The

http://www.st.com/st-web-ui/static/active/jp/resource/technical/document/user_manual/DM00108129.pdf

does not state anything about this.

3 REPLIES 3
qwer.asdf
Senior
Posted on January 08, 2016 at 15:15

It's negotiated using the 9-th byte of the Configuration Descriptor (multiplied by 2).

You can find more information

http://www.beyondlogic.org/usbnutshell/usb5.shtml

, under the ''Configuration Descriptors'' section. Here is an example of the CDC device requesting 500mA from the usbd_cdc_core.c file (older USB library, not from STM32Cube):

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
/* USB CDC device Configuration Descriptor */
__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
{
/*Configuration Descriptor*/
0x09, 
/* bLength: Configuration Descriptor size */
USB_CONFIGURATION_DESCRIPTOR_TYPE, 
/* bDescriptorType: Configuration */
USB_CDC_CONFIG_DESC_SIZ, 
/* wTotalLength:no of returned bytes */
0x00,
0x02, 
/* bNumInterfaces: 2 interface */
0x01, 
/* bConfigurationValue: Configuration value */
0x00, 
/* iConfiguration: Index of string descriptor describing the configuration */
0x80, 
/* bmAttributes: default was 0xC0 */
0xFA, 
/* MaxPower 500 mA */
/*---------------------------------------------------------------------------*/
/*Interface Descriptor */
0x09, 
/* bLength: Interface Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, 
/* bDescriptorType: Interface */
/* Interface descriptor type */
0x00, 
/* bInterfaceNumber: Number of Interface */
0x00, 
/* bAlternateSetting: Alternate setting */
0x01, 
/* bNumEndpoints: One endpoints used */
0x02, 
/* bInterfaceClass: Communication Interface Class */
0x02, 
/* bInterfaceSubClass: Abstract Control Model */
0x01, 
/* bInterfaceProtocol: Common AT commands */
0x00, 
/* iInterface: */
/*Header Functional Descriptor*/
0x05, 
/* bLength: Endpoint Descriptor size */
0x24, 
/* bDescriptorType: CS_INTERFACE */
0x00, 
/* bDescriptorSubtype: Header Func Desc */
0x10, 
/* bcdCDC: spec release number */
0x01,
/*Call Management Functional Descriptor*/
0x05, 
/* bFunctionLength */
0x24, 
/* bDescriptorType: CS_INTERFACE */
0x01, 
/* bDescriptorSubtype: Call Management Func Desc */
0x00, 
/* bmCapabilities: D0+D1 */
0x01, 
/* bDataInterface: 1 */
/*ACM Functional Descriptor*/
0x04, 
/* bFunctionLength */
0x24, 
/* bDescriptorType: CS_INTERFACE */
0x02, 
/* bDescriptorSubtype: Abstract Control Management desc */
0x02, 
/* bmCapabilities */
/*Union Functional Descriptor*/
0x05, 
/* bFunctionLength */
0x24, 
/* bDescriptorType: CS_INTERFACE */
0x06, 
/* bDescriptorSubtype: Union func desc */
0x00, 
/* bMasterInterface: Communication class interface */
0x01, 
/* bSlaveInterface0: Data Class Interface */
/*Endpoint 2 Descriptor*/
0x07, 
/* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, 
/* bDescriptorType: Endpoint */
CDC_CMD_EP, 
/* bEndpointAddress */
0x03, 
/* bmAttributes: Interrupt */
LOBYTE(CDC_CMD_PACKET_SZE), 
/* wMaxPacketSize: */
HIBYTE(CDC_CMD_PACKET_SZE),
#ifndef USE_EMBEDDED_PHY // fixed by me, it was #ifdef USE_USB_OTG_HS
0x10, 
/* bInterval: */
#else
0xFF, 
/* bInterval: */
#endif /* USE_USB_OTG_HS */
/*---------------------------------------------------------------------------*/
/*Data class interface descriptor*/
0x09, 
/* bLength: Endpoint Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, 
/* bDescriptorType: */
0x01, 
/* bInterfaceNumber: Number of Interface */
0x00, 
/* bAlternateSetting: Alternate setting */
0x02, 
/* bNumEndpoints: Two endpoints used */
0x0A, 
/* bInterfaceClass: CDC */
0x00, 
/* bInterfaceSubClass: */
0x00, 
/* bInterfaceProtocol: */
0x00, 
/* iInterface: */
/*Endpoint OUT Descriptor*/
0x07, 
/* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, 
/* bDescriptorType: Endpoint */
CDC_OUT_EP, 
/* bEndpointAddress */
0x02, 
/* bmAttributes: Bulk */
LOBYTE(CDC_DATA_MAX_PACKET_SIZE), 
/* wMaxPacketSize: */
HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
0x00, 
/* bInterval: ignore for Bulk transfer */
/*Endpoint IN Descriptor*/
0x07, 
/* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, 
/* bDescriptorType: Endpoint */
CDC_IN_EP, 
/* bEndpointAddress */
0x02, 
/* bmAttributes: Bulk */
LOBYTE(CDC_DATA_MAX_PACKET_SIZE), 
/* wMaxPacketSize: */
HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
0x00 
/* bInterval: ignore for Bulk transfer */
} ;

caco3
Associate II
Posted on January 08, 2016 at 16:28

Thank you very much for your explanations!

With your hint, I found the file Middlewares\ST\STM32_USB_Device_Library\Class\CDC\Src\usbd_cdc.c which contains the following section:

/* USB CDC device Configuration Descriptor */
__ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
{
/*Configuration Descriptor*/
0x09, 
/* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, 
/* bDescriptorType: Configuration */
USB_CDC_CONFIG_DESC_SIZ, 
/* wTotalLength:no of returned bytes */
0x00,
0x02, 
/* bNumInterfaces: 2 interface */
0x01, 
/* bConfigurationValue: Configuration value */
0x00, 
/* iConfiguration: Index of string descriptor describing the configuration */
0xC0, 
/* bmAttributes: self powered */

0x32, 
/* MaxPower 0 mA */

...

For some reason, they set it statically in the library to 100 mA (0x32 = 50 => 100 mA). Also, the comment (0 mA) is wrong. In usbd_msc.c (Mass Storage Class) they commented it how ever correctly. Now, I wonder why they set it statically. It is not very professional when I have to go and modify this parameter inside the library...
mark239955_stm1
Associate II
Posted on January 10, 2016 at 05:35

I may be talking through my hat here, because I'm still using a pre-Cube and personally hacked up version of ST's USB CDC device driver, but based on the existence of that device configuration descriptor (much the same as in my driver version) I'm going to say that near the start of the user CDC files you will probably find a function call that references a pointer to the default device configuration descriptor; you can change it to point to your own configuration descriptor instead.  I've done exactly that to change the device instance ID so that I can map each of my flock of MCU's to it's own Windows VCP.