I am working on a STM32L496 and I try to get 2 HID devices running on one USB port / device.
The first one is a keyboard HID (USBD_Config_HID_0), the second one is a custom HID Interface (USBD_Config_HID_1).
I set both HID descriptors to 'User Provided HID Report Descriptor' with no report IDs.
I can send keyboard codes on the USBD_Config_HID_0 by using USBD_HID_GetReportTrigger(0, 0, buf, len).
But what do I have to use to send data via the custom HID interface (USBD_Config_HID_1) ?
'USBD_HID_GetReportTrigger(1, 0, buf, len)' or 'USBD_HID_GetReportTrigger(0, 1, buf, len)'?
As far as I understand is the first entry the USB instance, with is in both cases '0', because I only have 'USB_Config_0'.
And because I haven't set any report IDs the second value can't be 1?
I appreciate any help.
Stefan
P.S. I found this discussion '2-hids-in-one-composite-usb-code' but it doesn't lead to a conclusion.
That was taken with Total Phase Beagle USB 480 Protocol Analyzer and screenshot was taken form Total Phase's software called Total Phase Data Center.
Thank you. I actually have one of those but end up using the Ellisys all the time.
Hey guys, I have one of the Beagles too, but use it quiet rarely.But back to my last question. I think I didn't describe it properly.
I had problems by creating a compsite device, with one describtor including 2 diffrent devices. My question was aimed at how i designed the descritor.
I wrote two keyboard describtors with diffrent report IDs. The first one will be a keyboard and the second one will be either a self-defined one or a descriptor for a special device.
I had problems addressing the seperate parts of the describtor by its report IDs. It should be:'USBD_HID_GetReportTrigger(0, 1, buf, len)' for the first keyboard and 'USBD_HID_GetReportTrigger(0, 2, buf, len)' for the second.
I talked to a quy and he mentioned that I have to design the descriptor as a 2 dimensional array.Probably something like this:
const uint8_t usbd_hid0_report_descriptor[][] = { { // KEYBOARD STRUCT 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x06, // USAGE (Keyboard) 0xa1, 0x01, // COLLECTION (Application) 0x85, 0x01, // REPORT_ID (1) // modifier 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x08, // REPORT_COUNT (8) 0x81, 0x02, // INPUT (Data,Var,Abs) //reserved 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,Var,Abs) // keycodes[6] 0x95, 0x06, // REPORT_COUNT (6) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x65, // LOGICAL_MAXIMUM (101) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 0x81, 0x00, // INPUT (Data,Ary,Abs) 0xc0, // END_COLLECTION }, { // KEYBOARD STRUCT 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x06, // USAGE (Keyboard) 0xa1, 0x01, // COLLECTION (Application) 0x85, 0x02, // REPORT_ID (2) // modifier 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x08, // REPORT_COUNT (8) 0x81, 0x02, // INPUT (Data,Var,Abs) //reserved 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,Var,Abs) // keycodes[6] 0x95, 0x06, // REPORT_COUNT (6) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x65, // LOGICAL_MAXIMUM (101) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 0x81, 0x00, // INPUT (Data,Ary,Abs) 0xc0, // END_COLLECTION } };
But the most common format I saw in all documentation was:
const uint8_t usbd_hid0_report_descriptor[] = // KEYBOARD STRUCT 1 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x06, // USAGE (Keyboard) 0xa1, 0x01, // COLLECTION (Application) 0x85, 0x01, // REPORT_ID (1) // modifier 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x08, // REPORT_COUNT (8) 0x81, 0x02, // INPUT (Data,Var,Abs) //reserved 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,Var,Abs) // keycodes[6] 0x95, 0x06, // REPORT_COUNT (6) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x65, // LOGICAL_MAXIMUM (101) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 0x81, 0x00, // INPUT (Data,Ary,Abs) 0xc0, // END_COLLECTION // KEYBOARD STRUCT 2 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x06, // USAGE (Keyboard) 0xa1, 0x01, // COLLECTION (Application) 0x85, 0x02, // REPORT_ID (2) // modifier 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x08, // REPORT_COUNT (8) 0x81, 0x02, // INPUT (Data,Var,Abs) //reserved 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,Var,Abs) // keycodes[6] 0x95, 0x06, // REPORT_COUNT (6) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x65, // LOGICAL_MAXIMUM (101) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 0x81, 0x00, // INPUT (Data,Ary,Abs) 0xc0, // END_COLLECTION };
Milorad Cvjetkovic said:Also, instead of hardcoded numbers you can use macros for the values in the Report Descriptor, like HID_UsagePage(x), HID_Collection(x), HID_UsageMin(x).
I saw that in the examples, but I also try to create the same descriptor(s) for a bluetooth modul (Silabs BT121/122), so the hardcoded one is closer to the same starting point.
Has anyone ever come in to contact with one of the bluetooth modules?Kind regardsStefan
Hi Stefan.
The const uint8_t usbd_hid0_report_descriptor should not be 2-dimensional array, because library expects a 1-dimensional array with the declaration of the descriptor being:
extern const uint8_t usbd_hid0_report_descriptor[];
I do not have any experience with bluetooth modules.
Best regards, Milorad