This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Two HID composite device

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.

Parents
  • 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
    };

    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 regards
    Stefan

Reply
  • 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
    };

    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 regards
    Stefan

Children
  • 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