STMicroelectronics / STM32CubeL4

STM32Cube MCU Full Package for the STM32L4 series - (HAL + LL Drivers, CMSIS Core, CMSIS Device, MW libraries plus a set of Projects running on all boards provided by ST (Nucleo, Evaluation and Discovery Kits))
Other
259 stars 151 forks source link

USB HID Report Descriptor length greater than 255 bytes not supported #56

Closed fronders closed 2 years ago

fronders commented 2 years ago

USB HID Descriptor uses only lowest byte of 16-bit USB HID Report Descriptor length (defined by standard), while higher byte is always set to 0. This results in maximum length of HID Report Descriptor to only 255 bytes instead of 65535. This issue is related to USB_Device middleware and is present across all STM32 families. Same issue appears when using HID or Custom HID classes in USB Device middleware.

Describe the set-up

Describe the bug The following code gets generated for Device Configuration descriptor in usbd_customhid.c when using USB Custom HID Class:

  /******************** Descriptor of CUSTOM_HID *************************/
  /* 18 */
  0x09,                                               /* bLength: CUSTOM_HID Descriptor size */
  CUSTOM_HID_DESCRIPTOR_TYPE,                         /* bDescriptorType: CUSTOM_HID */
  0x11,                                               /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
  0x01,
  0x00,                                               /* bCountryCode: Hardware target country */
  0x01,                                               /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
  0x22,                                               /* bDescriptorType */
  USBD_CUSTOM_HID_REPORT_DESC_SIZE,                   /* wItemLength: Total length of Report descriptor */
  0x00,

Here the field wItemLength is at offset 7 and has length of 1 byte, second byte is explicitly set to 0x00, while the HID Class Definition states wDescriptorLength is at offset 7 and length of 2 bytes (see screenshot below). This prevents the HID Descriptor being larger than 255 bytes.

image

In order to fix the issue I suggest changing the uppermentioned descriptor to following:

  /******************** Descriptor of CUSTOM_HID *************************/
  /* 18 */
  0x09,                                               /* bLength: CUSTOM_HID Descriptor size */
  CUSTOM_HID_DESCRIPTOR_TYPE,                         /* bDescriptorType: CUSTOM_HID */
  0x11,                                               /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
  0x01,
  0x00,                                               /* bCountryCode: Hardware target country */
  0x01,                                               /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
  0x22,                                               /* bDescriptorType */
  LOBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE),           /* wItemLength: Total length of Report descriptor (lower byte) */
  HIBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE),           /* wItemLength: Total length of Report descriptor (higher byte) */

I have verified the fix to work correctly in multiple projects with HID Report Descriptor being 300+ bytes length. This needs to be patched in multiple locations throughout usbd_customhid.c as it is present in multiple config descriptor arrays:

fronders commented 2 years ago

Found USB Middleware repo, moved the issue there https://github.com/STMicroelectronics/stm32_mw_usb_device/issues/4