I have a keyboard emulator device that I need to send data to "in the background". I have lots of endpoints to play with if I need them: currently I'm using EP1 IN for standard key data report and EP2 IN for consumer control key report. The device also receives the LED status from the host on EP0. I'm need help choosing a technique for the data-back-to-the-device part.
Previously I have used Feature Reports on EP0 to send data to the device. Please see below for my HID report descriptors. My problem with the existing technique is that I cannot get it to work on Win8 consistently. It's fine all the way back to XP... I've been using it for years, but this Win8 thing is defeating me. Anyway, Jan recommended making the Feature Report (the part commented out) a Top Level Collection, but I have not been able to come up with an HID report that doesn't fail on enumeration ("Your device did not install correctly"). An example of a device with two top level collections sharing an endpoint would be awesome.
So failing that, what ELSE can I do? Can I use another endpoint as vendor defined HID? I'm thinking that anything I create using WriteFile from the PC end is going to fail because Windows controls the HID keyboard device. On the PC-side I'm using application level Win32 API.
// Standard keys report and LED status.
code char HidReport_DescriptorKB1[] =
{
0x05, 0x01, // usage page (generic desktop)
0x09, 0x06, // usage (keyboard)
0xA1, 0x01, // collection (application)
0x05, 0x07, // usage page( key codes) - Modifier Keys
0x19, 0xE0, // usage minimum (224)
0x29, 0xE7, // usage maximum (231)
0x15, 0x00, // logical minimum (0)
0x25, 0x01, // logical maximum (1)
0x75, 0x01, // report size (1 bit)
0x95, 0x08, // report count (8 bytes)
0x81, 0x02, // input report (data, variable, absolute) - Modifier bytes
0x95, 0x01, // report count (1 byte) - A zero byte
0x75, 0x08, // report size (8 bits)
0x81, 0x01, // input report (constant) - Input Report padding.
0x95, 0x06, // report count (6) - 6 bytes of key data
0x75, 0x08, // report size (8)
0x15, 0x00, // logical minimum (0)
0x26, 0x93, 0x00, // logical maximum (147). Added F14-F24
0x05, 0x07, // usage page (key codes)
0x19, 0x00, // usage minimum (0)
0x2A, 0x93, 0x00, // usage maximum (147) Added F1-F24 LANG4
0x81, 0x00, // input report (data, array) - Keyboard report
0x95, 0x05, // report count (5) - The LED status
0x75, 0x01, // report size (1)
0x05, 0x08, // usage page (LEDs)
0x19, 0x01, // usage minimum (1)
0x29, 0x05, // usage maximum (5)
0x91, 0x02, // output report (data, variable, absolute) - LED report
0x95, 0x01, // report count (1)
0x75, 0x03, // report size (3)
0x91, 0x01, // output report (constant) - LED padding
// 0x09, 0x03, // Usage (vendor defined) - Feature report that is killing me on Win8.
// 0x75, 0x08, // Report size (8 bits)
// 0x95, 0x05, // Report count (5 fields)
// 0xB1, 0x02, // NEW Feature Report (Data, Variable, Absolute)
0xC0 // end collection
};
// "Multimedia" keys.
code char HidReport_DescriptorKB2[] =
{
0x05, 0x0C, // usage page (Consumer Page)
0x09, 0x01, // usage (Consumer Control)
0xA1, 0x01, // collection (application)
0x85, 0x01, // REPORT_ID (1)
0x19, 0x00, // USAGE_MINIMUM (Unassigned)
0x2A, 0x3C, 0x02, // USAGE_MAXIMUM (AC Format)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0x3C, 0x02, // LOGICAL_MAXIMUM (572)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x10, // REPORT_SIZE (16)
0x81, 0x00, // NEW INPUT REPORT (Data,Array,Absolute)
0xC0 // end collection
};