Composite Joy/Key/Mouse report descriptor failing....

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
Post Reply
vputz
Posts: 4
Joined: Mon May 25, 2009 11:34 am

Composite Joy/Key/Mouse report descriptor failing....

Post by vputz » Mon Jul 13, 2009 9:01 pm

I'm working on a device which acts as a composite joystick/mouse/keyboard-- and actually made it quite far using three different report IDs. Unfortunately, the joystick report was quite long (6 axes at 10 bits apiece plus 16 buttons, plus a byte for the report ID meant I needed to do the "send 8 bytes, poll, send more bytes" trick).

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.

vputz
Posts: 4
Joined: Mon May 25, 2009 11:34 am

Re: Composite Joy/Key/Mouse report descriptor failing....

Post by vputz » Tue Jul 14, 2009 10:01 pm

Looks like I fixed it; not sure what the problem was but I broke the joystick report into a four-axis 16-button report and a separate two-axis report (for the lesser-used axes). Now it seems to work OK; haven't tried it with full device operation yet (ie joystick+mouse+kbd) but that is coming.

Post Reply