Now, that seemed to be a problem because as soon as I sent an interesting joystick report descriptor, Windows hated my device (and declared it invalid, etc). If, however, I stuck with keyboard and mouse reports, all seemed well.
At a guess, I tried splitting up the joystick report into two separate reports (figuring that maybe the "send 8 bytes, poll, send more bytes" trick was getting confused with multiple report IDs). The HID report descriptor tool parsed this without difficulty, but Windows says that the device "is not recognized" and refuses to even try. I'm flailing a bit with usage pages and such, but Windows seemed OK with the descriptor when the joystick report was one report rather than split up like this.
So now I have four reports
Joystick report 1 (3 axes at 10 bits, 2 bits constant = 32 bits)
Joystick report 2 (3 axes at 10 bits, 2 bits constant, 16 bits for buttons = 48 bits)
Keyboard report (8 bits modifiers, 40 bits for 5 simultaneous keys = 48 bits)
Mouse report (3 bits buttons, 5 bits const, 3x8 bits axes, 32 bits)
...but I never get that far, as Windows says "unknown device". It worked OK with the two joystick reports as one (6 axes at 10 bits, 16 bits for buttons, 4 bits const = 80 bits).
Any suggestions? Here's the "frankenreport" descriptor (from the hid report descriptor tool; in my V-USB code of course it's PROGMEM with USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH set to 171):
Code: Select all
char ReportDescriptor[171] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x04, // USAGE (Joystick)
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x04, // REPORT_ID (4)
0xa1, 0x00, // COLLECTION (Physical)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x32, // USAGE (Z)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x03, // LOGICAL_MAXIMUM (1023)
0x75, 0x0a, // REPORT_SIZE (10)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x75, 0x02, // REPORT_SIZE (2)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x85, 0x05, // REPORT_ID (5)
0x09, 0x33, // USAGE (Rx)
0x09, 0x34, // USAGE (Ry)
0x09, 0x35, // USAGE (Rz)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x03, // LOGICAL_MAXIMUM (1023)
0x75, 0x0a, // REPORT_SIZE (10)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x75, 0x02, // REPORT_SIZE (2)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0xc0, // END_COLLECTION
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x10, // USAGE_MAXIMUM (Button 16)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x10, // REPORT_COUNT (16)
0x55, 0x00, // UNIT_EXPONENT (0)
0x65, 0x00, // UNIT (None)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x02, // REPORT_ID (2)
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)
0x95, 0x05, // REPORT_COUNT (5)
0x75, 0x08, // REPORT_SIZE (8)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0, // END_COLLECTION
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x03, // REPORT_ID (3)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
};
This is really killing me, because the keyboard/mouse code works a treat and the joystick code used to work, but I can't seem to get a report descriptor that makes windows happy with all 3... there are a few people using this project already and I'm gutted that I've got it at an absolute standstill.