2016-01-08 05:29 AM
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''. Thehttp://www.st.com/st-web-ui/static/active/jp/resource/technical/document/user_manual/DM00108129.pdf
does not state anything about this.2016-01-08 06:15 AM
It's negotiated using the 9-th byte of the Configuration Descriptor (multiplied by 2).
You can find more informationhttp://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 */
} ;
2016-01-08 07:28 AM
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...
2016-01-09 08:35 PM
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.