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

 

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
Lead III

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.