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?

 

1 REPLY 1
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