cancel
Showing results for 
Search instead for 
Did you mean: 

Multiple USB HID interfaces

smoothmanifolds
Associate III

On an STM32F103CB I'm running the USB Custom HID Device STM32CubeIDE example.

It has 1 USB HID Interface with 2 USB Endpoints (Input and Output, interrupt transfers), and I've added a Report Descriptor with several top-level collections, and it's working well.

I need to add 1 more Interface with a single HID interrupt Endpoint (Input (device-to-host), interrupt transfers).

I've modified the Interface Descriptor inside the Configuration Descriptor `USBD_CUSTOM_HID_CfgFSDesc` in `usbd_customhid.c`, and I've also added an extra Endpoint descriptor (though I'm not sure it's correct):

 

// ---------------------------------------------------------------------- // byte 0 0x09, // bLength: Configuration Descriptor size USB_DESC_TYPE_CONFIGURATION, // bDescriptorType: Configuration Descriptor typee USB_CUSTOM_HID_CONFIG_DESC_SIZ, // wTotalLength: Bytes returned 0x00, 0x01/*0x02 0x03*/, // bNumInterfaces: 1 interface 0x01, // bConfigurationValue: configuration value 0x00, // iConfiguration: index of string descriptor describing the configuration 0xc0, // bmAttributes: bus powered 0x32, // MaxPower 100 mA: this current is used for detecting Vbus // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- 0.0) interface 0 (CUSTOM_HID): Interface Descriptor? // byte 9 0x09, // bLength: Interface Descriptor size USB_DESC_TYPE_INTERFACE, // bDescriptorType: Interface Descriptor type 0x00, // bInterfaceNumber: interface 0x00? 0x00, // bAlternateSetting: alternate setting 0x02, // bNumEndpoints 0x03, // bInterfaceClass: CUSTOM_HID 0x00, // bInterfaceSubClass: 0=no boot, 1=BOOT 0x00, // nInterfaceProtocol: 0=none, 1=keyboard, 2=mouse 0x00, // iInterface: index of string descriptor // ---------------------------------------------------------------------- 0.1) interface 0 (CUSTOM_HID): Report-Descriptor Descriptor? // byte 18 0x09, // bLength: CUSTOM_HID Descriptor size CUSTOM_HID_DESCRIPTOR_TYPE, // bDescriptorType: CUSTOM_HID Descriptor type 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 HIBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), // wItemLength: total length of Report Descriptor // ---------------------------------------------------------------------- 0.2.0) interface 0 (CUSTOM_HID): Endpoint Descriptor?: endpoint 0 // byte 27 0x07, // bLength: Endpoint Descriptor size USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint Descriptor type CUSTOM_HID_EPIN_ADDR, // bEndpointAddress: endpoint address (IN) 0x03, // bmAttributes: interrupt endpoint CUSTOM_HID_EPIN_SIZE, // wMaxPacketSize: 2 byte max 0x00, CUSTOM_HID_FS_BINTERVAL, // bInterval: polling interval // ---------------------------------------------------------------------- 0.2.1) interface 0 (CUSTOM_HID): Endpoint Descriptor?: endpoint 1 // byte 34 0x07, // bLength: Endpoint Descriptor size USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint Descriptor type CUSTOM_HID_EPOUT_ADDR, // bEndpointAddress: endpoint address (OUT) 0x03, // bmAttributes: interrupt endpoint CUSTOM_HID_EPOUT_SIZE, // wMaxPacketSize: 2 bytes max 0x00, CUSTOM_HID_FS_BINTERVAL, // bInterval: polling interval // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- 1.0) interface 1: Interface Descriptor?: for boot keyboard // byte 41 0x09, // bLength USB_DESC_TYPE_INTERFACE, // bDescriptorType 0x01, // bInterfaceNumber: interface 0x01? 0x00, // bAlternateSetting: 0 0x01, // bNumEndpoints 0x03, // bInterfaceClass: CUSTOM_HID 0x00, // bInterfaceSubClass: 0=no boot, 1=BOOT 0x01, // nInterfaceProtocol: 0=none, 1=keyboard, 2=mouse 0x00, // iInterface // ---------------------------------------------------------------------- 1.1) interface 1: Report-Descriptor Descriptor? 0x09, // bLength CUSTOM_HID_DESCRIPTOR_TYPE, // bDescriptorType 0x11, // bCUSTOM_HID version 0x01, 0x00, // bCountryCode 0x01, // bNumDescriptors 0x22, // bDescriptorType: Report LOBYTE(HID_IF1_IRP_DESC_BDIM), // wItemLength HIBYTE(HID_IF1_IRP_DESC_BDIM), // wItemLength // ---------------------------------------------------------------------- 1.2.0) interface 1: Endpoint Descriptor?: endpoint 0 0x07, // bLength USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint Descriptor type CUSTOM_HID_EPIN2_ADDR, // bEndpointAddress 0x03, // bmAttributes: interrupt endpoint CUSTOM_HID_EPIN2_SIZE, // wMaxPacketSize 0x00, CUSTOM_HID_FS_BINTERVAL, // bInterval
View more

 

My question (other than: Is the Configuration Descriptor correct?) is: what other changes do I need to make to the STM32CubeIDE example & USB stack to make it work with 2 (HID) interfaces?

 

2 REPLIES 2
gbm
Principal

You need to modify the class request handler for GET_HID_DESCRIPTOR. It should check the interface number and, based on that, return one or another HID descriptor. Then you need to add the handling for endpoint traffic.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
FBL
ST Employee

Hi @smoothmanifolds 

I suggest you register composite class. Register two instances of HID class. You do not need to update the configuration descriptor to register two instances. See this example for dual CDC interfaces as an example How to implement a dual CDC ACM USB device using t... - STMicroelectronics Community

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.