I am currently programming a USB device on a STM32F7 microcontroller. This is a simple HID device (basic desktop mouse).
When plugging the device to the host (windows 10 computer), the USB transaction works as expected until the GET HID REPORT DESCRIPTOR request.
- Plugging the device to the computer
- The host resets the device, and asks for the Device Descriptor
- The device replies with the correct device descriptor.
- The host receives the Endpoint 0 MAXPACKETSIZE, and resets the device.
- The host sends a SET_ADDRESS request, the device sets its address accordingly.
- The host asks for the full device descriptor. The device replies by sending it.
- The host asks for the configuration descriptor, the device sends it.
- The host sends a SET_CONFIGURATION request, the device process it.
- The host sends a SET_IDLE request, the device process it.
- The host sends a GET HID REPORT DESCRIPTOR request, but it asks for more data than it was specified in the Configuration Descriptor. My device replies by sending the correct descriptor, but as its length is lower than the size asked by the host, this latter does not accept it.
Here is my full configuration descriptor:
const USB_ConfigurationDescriptorsPackage configuration_0_descriptors = {
.configuration_descriptor = {
.bLength = sizeof(USB_ConfigurationDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION,
.wTotalLength = sizeof(USB_ConfigurationDescriptorsPackage),
.bNumInterfaces = 1, // only one interface (group of endpoints) needed for our application
.bConfigurationValue = 1, // only one configuration, so index 1
.iConfiguration = 0, // index 0 means that there is no string descriptor
.bmAttributes = (0x80), // not(0x20) so no remote wake up, (not 0x40) --> bus powered; 0x80 --> required by the USB specification
.bMaxPower = 25 // our device will draw / require 2mA * 25 = 50 mA
},
.interface_descriptor = {
.bLength = sizeof(USB_InterfaceDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
.bInterfaceNumber = 1,
.bAlternateSetting = 0,
.bNumEndpoints = 1, // only one (IN) endpoint required / activated for our application
/* in the USB Device Descriptor, we told the host that our class will be defined at interface level,
* so we define it here. */
.bInterfaceClass = USB_CLASS_HID,
.bInterfaceSubClass = USB_SUBCLASS_NONE, // no interface subclass here
.bInterfaceProtocol = USB_PROTOCOL_NONE, // no interface specific protocol here
.iInterface = 0 // no string descriptor for our device
},
.endpoint_descriptor = {
.bLength = sizeof(USB_EndpointDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = (0x80 | 0x03), // IN endpoint number 3 (can be chosen arbitrary)
.bmAttributes = USB_ENDPOINT_TYPE_INTERRUPT,
.wMaxPacketSize = 64,
.bInterval = 50
},
/* HID descriptor for a mouse */
.hid_descriptor = {
.bLength = sizeof(USB_HID_Descriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_HID,
.bcdHID = 0x0100, // first version of HID specification
.bCountryCode = USB_HID_COUNTRY_NONE,
.bNumDescriptors = 1, // only 1 HID report descriptor associated with this HID descriptor
.bDescriptorType0 = USB_DESCRIPTOR_TYPE_HID_REPORT,
.wDescriptorLength0 = sizeof(hid_report_descriptor)
},
};
In the HID field, sizeof(hid_report_descriptor) = 48 bytes, which is the correct size of my HID report descriptor.
However, for an unknown reason, when in the GET HID REPORT DESCRIPTOR request, the host asks for a 112 bytes data length packet, instead of 48 bytes i.e. an extra 64 bytes.
I've tracked the USB communication on wireshark, to check that my device was sending the data it is expected to send. So I know that my device is doing what it is intended to.
Here's the trace on wireshark:
The detailed configuration descriptor sends by my device:
The detailed GET HID REPORT DESCRIPTOR request sent by the host:
As you can see, the device sends the correct configuration descriptor and specifies the host that the HID report descriptor is 48 bytes wide. But when the host asks for this descriptor, it asks for 112 bytes instead of 48. I have no idea why ...
Thank you for your help.
EDIT: I've checked with different descriptor sizes,and there is Always an extra 64 bytes, regardless the descriptor size. As this number is 64, it is probably not random. But I don't see to what it may be related.