Page 1 of 1

[SOLVED] HIDkeyboard report descriptor problem

Posted: Fri Nov 20, 2009 5:37 pm
by toface
I'm using the HIDkeys (2007.03.29) project as a base to make a MAME keyboard. After reading a lot of documentation I *think* that I know how to make a HIDkeyboard that can have 10 or more simultaneous keys (2 directions + 3 buttons per player) with a report size of 3 bytes. The problem is that the linux kernel does not agree with me =\. I have constructed/parsed the report descriptor itself with the "HID Descriptor Tool(DT)" from usb.org, but I still suspect it is either wrong or somehow too big for vusb.

I have tried replacing the usbdrv with the latest version, but that did not help (nor break) anything.

The hardware is EXACTLY the same as the HIDkeys project. That means mega8 connected with a supply voltage of ~3.5V. If I compile the original HIDkeys program and flash it, it works flawlessly:
[ 9819.345390] usb 2-2.1: new low speed USB device using uhci_hcd and address 15
[ 9819.500539] usb 2-2.1: configuration #1 chosen from 1 choice
[ 9819.525534] input: obdev.at HIDKeys as /devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2.1/2-2.1:1.0/input/input7
[ 9819.525650] generic-usb 0003:4242:E131.0007: input,hidraw1: USB HID v1.01 Keyboard [obdev.at HIDKeys] on usb-0000:00:1d.0-2.1/input0

However as soon as I replace the report descriptor (and change the report size), it just refuses to work and I get this:
[ 9777.097659] usb 2-2.1: new low speed USB device using uhci_hcd and address 14
[ 9777.249654] usb 2-2.1: configuration #1 chosen from 1 choice
[ 9777.264061] generic-usb: probe of 0003:4242:E131.0006 failed with error -22

Here is the diff -urN between the two files:

Code: Select all

--- main.c   2009-11-20 16:13:40.000000000 +0100
+++ minimal_not_working.c   2009-11-20 15:30:49.000000000 +0100
@@ -107,26 +107,110 @@
 static uchar    reportBuffer[2];    /* buffer for HID reports */
 static uchar    idleRate;           /* in 4 ms units */
 
-PROGMEM char usbHidReportDescriptor[35] = { /* USB report descriptor */
-    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
-    0x09, 0x06,                    // USAGE (Keyboard)
-    0xa1, 0x01,                    // COLLECTION (Application)
-    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, 0x01,                    //   REPORT_COUNT (1)
-    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
+PROGMEM char usbHidReportDescriptor[121] = { /* USB report descriptor */
+  0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
+  0x09, 0x06,                    // USAGE (Keyboard)
+  0xa1, 0x01,                    // COLLECTION (Application)
+  0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
+  0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
+  0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
+/*
+   Player 1
+   Right, Left, Down, Up
+   Left Ctrl
+   Left Alt
+   Space
+   1
+*/
+  0x19, 0x4f,                    //   USAGE_MINIMUM (Keyboard Right Arrow)
+  0x29, 0x52,                    //   USAGE_MAXIMUM (Keyboard Up Arrow)
+  0x75, 0x01,                    //   REPORT_SIZE (1) 1-bit value
+  0x95, 0x04,                    //   REPORT_COUNT (4) 4 keys
+  0x81, 0x02,                    //   INPUT (Data,Var,Abs) add report
+  0x95, 0x01,                    //   REPORT_COUNT (1) 1 key
+
+  0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
+  0x29, 0xe0,                    //   USAGE_MAXIMUM (Keyboard LeftControl)
+  0x81, 0x02,                    //   INPUT (Data,Var,Abs) add report
+
+  0x19, 0xe2,                    //   USAGE_MINIMUM (Keyboard LeftAlt)
+  0x29, 0xe2,                    //   USAGE_MAXIMUM (Keyboard LeftAlt)
+  0x81, 0x02,                    //   INPUT (Data,Var,Abs) add report
+
+  0x19, 0x2c,                    //   USAGE_MINIMUM (Keyboard Space)
+  0x29, 0x2c,                    //   USAGE_MAXIMUM (Keyboard Space)
+  0x81, 0x02,                    //   INPUT (Data,Var,Abs) add report
+
+  0x19, 0x1e,                    //   USAGE_MINIMUM (Keyboard LeftAlt)
+  0x29, 0x1e,                    //   USAGE_MAXIMUM (Keyboard LeftAlt)
+  0x81, 0x02,                    //   INPUT (Data,Var,Abs) add report
+
+/*
+   Player 2
+   G, D, F, R
+   A
+   S
+   Q
+   2
+*/
+  0x19, 0x0a,                    //   USAGE_MINIMUM (Keyboard G)
+  0x29, 0x0a,                    //   USAGE_MAXIMUM (Keyboard G)
+  0x81, 0x02,                    //   INPUT (Data,Var,Abs) add report
+
+  0x19, 0x07,                    //   USAGE_MINIMUM (Keyboard D)
+  0x29, 0x07,                    //   USAGE_MAXIMUM (Keyboard D)
+  0x81, 0x02,                    //   INPUT (Data,Var,Abs) add report
+
+  0x19, 0x09,                    //   USAGE_MINIMUM (Keyboard F)
+  0x29, 0x09,                    //   USAGE_MAXIMUM (Keyboard F)
+  0x81, 0x02,                    //   INPUT (Data,Var,Abs) add report
+
+  0x19, 0x15,                    //   USAGE_MINIMUM (Keyboard R)
+  0x29, 0x15,                    //   USAGE_MAXIMUM (Keyboard R)
+  0x81, 0x02,                    //   INPUT (Data,Var,Abs) add report
+
+  0x19, 0x04,                    //   USAGE_MINIMUM (Keyboard A)
+  0x29, 0x04,                    //   USAGE_MAXIMUM (Keyboard A)
+  0x81, 0x02,                    //   INPUT (Data,Var,Abs) add report
+
+  0x19, 0x16,                    //   USAGE_MINIMUM (Keyboard S)
+  0x29, 0x16,                    //   USAGE_MAXIMUM (Keyboard S)
+  0x81, 0x02,                    //   INPUT (Data,Var,Abs) add report
+
+  0x19, 0x14,                    //   usage_minimum (keyboard Q)
+  0x29, 0x14,                    //   usage_maximum (keyboard Q)
+  0x81, 0x02,                    //   input (data,var,abs) add report
+
+  0x19, 0x1f,                    //   usage_minimum (keyboard 2)
+  0x29, 0x1f,                    //   usage_maximum (keyboard 2)
+  0x81, 0x02,                    //   input (data,var,abs) add report
+
+/*
+   Extra
+   5, 6 - Coin in
+   ESC - Quit game
+*/
+
+  0x19, 0x22,                    //   usage_minimum (keyboard 5)
+  0x29, 0x22,                    //   usage_maximum (keyboard 5)
+  0x81, 0x02,                    //   input (data,var,abs) add report
+
+  0x19, 0x23,                    //   usage_minimum (keyboard 6)
+  0x29, 0x23,                    //   usage_maximum (keyboard 6)
+  0x81, 0x02,                    //   input (data,var,abs) add report
+
+  0x19, 0x29,                    //   usage_minimum (keyboard ESC)
+  0x29, 0x29,                    //   usage_maximum (keyboard ESC)
+  0x81, 0x02,                    //   input (data,var,abs) add report
+
+  0x75, 0x05,                    //   REPORT_SIZE (5) 5-bit padding
+  0x81, 0x03,                    //   INPUT (Const,Var,Abs) add report
+  0xc0                           //   END_COLLECTION
 };
+
+
+
+
 /* We use a simplifed keyboard report descriptor which does not support the
  * boot protocol. We don't allow setting status LEDs and we only allow one
  * simultaneous key press (except modifiers). We can therefore use short
@@ -223,7 +307,10 @@
 static void buildReport(uchar key)
 {
 /* This (not so elegant) cast saves us 10 bytes of program memory */
-    *(int *)reportBuffer = pgm_read_word(keyReport[key]);
+    //*(int *)reportBuffer = pgm_read_word(keyReport[key]);
+   reportBuffer[0] = 0;
+   reportBuffer[1] = 0;
+   reportBuffer[2] = 0;
 }
 
 uchar   usbFunctionSetup(uchar data[8])

Re: HIDkeyboard report descriptor problem

Posted: Sat Nov 21, 2009 5:11 pm
by toface
Ok, for some reason it seems not all of the HID descriptor is sent. I turned on debugging, and hooked it up to an ftdi chip:

Code: Select all

00:

ff:
ff:
ff:
ff:
ff:
ff:
ff:
ff:
1d: 80 06 00 01 00 00
 40 00 dd 94
20: 4b 12 01 10 01 00 00 00 08 11 77
20: c3 42 42 31 e1 00 01 01 02 31 bf
20: 4b 00 01 3f 8f
ff:
ff:
ff:
ff:
ff:
1d: 00 05 0d 00 00 00 00 00 eb e9
20: 4b 00 00
1d: 80 06 00 01 00 00 12 00 e0 f4
20: 4b 12 01 10 01 00 00 00 08 11 77
20: c3 42 42 31 e1 00 01 01 02 31 bf
20: 4b 00 01 3f 8f
1d: 80 06 00 02 00 00 09 00 ae 04
20: 4b 09 02 22 00 01 01 00 80 0b 40
20: c3 32 c1 6a
1d: 80 06 00 02 00 00 22 00 b0 f4
20: 4b 09 02 22 00 01 01 00 80 0b 40
20: c3 32 09 04 00 00 01 03 00 f4 8d
20: 4b 00 00 09 21 01 01 00 01 92 96
20: c3 22 23 00 07 05 81 03 08 ca e5
20: 4b 00 0a 7e 48
1d: 80 06 00 03 00 00 ff 00 d4 64
20: 4b 04 03 09 04
09 78
1d: 80 06 02 03 09 04 ff 00 97 db
20: 4b 10 03 48 00 49 00 44 00 a7 2c
20: c3 4b 00 65 00 79 00 73 00 cf ee
20: 4b 00 00
1d: 80 06 01 03 09 04 ff 00 97 e8
20: 4b 12 03 6f 00 62 00 64 00 30 06
20: c3 65 00 76 00 2e 00 61 00 52 0d
20: 4b 74 00 d9 4f
1d: 00 09 01 00 00 00 00 00 27 25
20: 4b 00 00
1d: 21 0a 00 00 00 00 00 00 d6 20
20: 4b 00 00
1d: 81 06 00 22 00 00 23 00 f1 6f
20: 4b 05 01 09 06 a1 01 05 07 d7 3c
20: c3 15 00 25 01 19 4f 29 52 ec d4
20: 4b 75 01 95 04 81 02 95 01 a3 86
20: c3 19 e0 29 e0 81 02 19 e2 1b 56
20: 4b 29 e2 81 d7 37



As can be seen, the whole descriptor isn't sent.. Looking around in the .h files I found the error.. I didn't change the USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH :oops: