Page 1 of 1

Report descriptor for joystick gives weird results in MAME

Posted: Tue Mar 04, 2008 4:05 pm
by mojo
I have made a USB joystick controller that works perfectly. All buttons are detected properly in Windows. See http://joystick.world3.net for more info.

I have found a slight issue with the HID descriptor though. Although it works, MAME sees the buttons not as "Joy 1 Button X" but as "Joy 1 Joystick", "Joy 1 Pointer", "Joy 1 Keyboad" etc. until we get to "Joy 1 Button 10". It works fine, it just looks weird.

Here is my current report descriptor:

Code: Select all

ReportDescriptor:
      .db 0x05,0x01      ;Usage_Page (Generic Desktop)
      .db 0x09,0x05      ;Usage (Game Pad)
      .db 0xA1,0x01      ;Collection (Application)
      .db 0x09,0x01         ;Usage (Pointer)
      .db 0xA1,0x00         ;Collection (Physical)      
      .db 0x09,0x30            ;Usage (X)
      .db 0x09,0x31            ;Usage (Y)
      .db 0x15,0x81            ;Logical_Minimum (-127)
      .db 0x25,0x7F            ;Logical Maximum (127)
      .db 0x75,0x08            ;Report_Size (8)
      .db 0x95,0x02            ;Report_Count (2)
      .db 0x81,0x02            ;Input (Data, Var, Abs)      
      .db 0xC0,0x16         ;End_Collection, dummy

      .db 0x05,0x09         ;Usage_Page (Button)
      .db 0x19,0x01            ;Usage_Minimum (Button 1)
      .db 0x29,0x0a            ;Usage_Maximum (Button 10)
      .db 0x15,0x00            ;Logical_Minimum (0)
      .db 0x25,0x01            ;Logical_Maximum (1)
      .db 0x75,0x01            ;Report_Size (1)
      .db 0x95,0x0a            ;Report_Count (10)
      .db 0x55,0x00            ;Unit_Exponent (0)
      .db 0x65,0x00            ;Unit (None)
      .db 0x81,0x02            ;Input (Data, Var, Abs)

;round it out to whole byte for Windows
      .db 0x09,0x00            ;Usage (undefined)
      .db 0x15,0x01            ;Logical_Minimum (1)
      .db 0x25,0x06            ;Logical_Maximum (6)
      .db 0x75,0x06            ;Report_Size (6)
      .db 0x95,0x01            ;Report_Count (1)
      .db 0x81,0x02            ;Input (Data, Var, Abs)

      .db 0xC0,0x00         ;End_Collection , dummy padding
ReportDescriptorEnd:


I can't see anything obviously wrong with it. I checked MAME with various other USB controllers and it detects the buttons correctly.

Is there any software available that can read a report descriptor from a USB device? I couldn't find any, but it would be useful to read the descriptor from a working USB gamepad for comparison.

Posted: Tue Mar 04, 2008 9:10 pm
by STB
You can find a tool for recording Reports here:

http://sourceforge.net/projects/usbsnoop/

Regards,

STB

Posted: Wed Mar 05, 2008 12:23 am
by Grendel
Report looks ok to me. Try to move the buttons that are on the handle into the pointer collection.

On my stick that looks like:

Code: Select all

...
 0x05,0x09,              //     USAGE_PAGE (Button)
 0x19,0x01,              //     USAGE_MINIMUM (Button 1)
 0x29,0x04,              //     USAGE_MAXIMUM (Button 4)
 0x81,0x02,              //     INPUT (Data,Var,Abs)
 0xC0,                   //   END_COLLECTION
 0x19,0x05,              //   USAGE_MINIMUM (Button 5)
 0x29,0x08,              //   USAGE_MAXIMUM (Button 8)
 0x81,0x02,              //   INPUT (Data,Var,Abs)
...

Posted: Wed Mar 05, 2008 12:50 am
by mojo
Thanks, but it does not seem to be logging the report descriptor as far as I can see.

I did find this descriptor from an XBOX controller:

Code: Select all

0501   Usage Page (Generic Desktop)
0905   Usage (Game Pad)
A101   Collection (Application)
   
0501      Usage Page (Generic Desktop)
093A      Usage (Counted Buffer)      ;XXX
A102      Collection (Logical)
      
         ; padding
7508         Report Size (8)
9501         Report Count (1)
8101         Input (Constant)
   
         ; byte count
7508         Report Size (8)
9501         Report Count (1)
0501         Usage Page (Generic Desktop)
093B         Usage (Byte Count)      ;XXX
8101         Input (Constant)
      
         ; D-pad
0501         Usage Page (Generic Desktop)
0901         Usage (Pointer)
A100         Collection (Physical)
7501            Report Size (1)
1500            Logical Minimum (0)
2501            Logical Maximum (1)
3500            Physical Minimum (0)
4501            Physical Maximum (1)
9504            Report Count (4)
0501            Usage Page (Generic Desktop)
0990            Usage (D-pad Up)
0991            Usage (D-pad Down)
0993            Usage (D-pad Left)
0992            Usage (D-pad Right)
8102            Input (Data,Variable,Absolute)
C0         End Collection
      
         ; start, back, stick press
7501         Report Size (1)
1500         Logical Minimum (0)
2501         Logical Maximum (1)
3500         Physical Minimum (0)
4501         Physical Maximum (1)
9504         Report Count (4)
0509         Usage Page (Button)
1907         Usage Minimum (Button 7)
290A         Usage Maximum (Button 10)
8102         Input (Data,Variable,Absolute)
      
         ; reserved
7501         Report Size (1)
9508         Report Count (8)
8101         Input (Constant)
      
         ; analog buttons
7508         Report Size (8)
1500         Logical Minimum (0)
26FF00         Logical Maximum (255)
3500         Physical Minimum (0)
46FF00         Physical Maximum (255)
9506         Report Count (6)
0509         Usage Page (Button)
1901         Usage Minimum (Button 1)
2906         Usage Minimum (Button 6)
8102         Input (Data,Variable,Absolute)
      
         ; triggers
7508         Report Size (8)
1500         Logical Minimum (0)
26FF00         Logical Maximum (255)
3500         Physical Minimum (0)
46FF00         Physical Maximum (255)
9502         Report Count (2)
0501         Usage Page (Generic Desktop)
0932         Usage (Z)
0935         Usage (Rz)
8102         Input (Data,Variable,Absolute)
      
         ; sticks
7510         Report Size (16)
160080         Logical Minimum (-32768)
26FF7F         Logical Maximum (32767)
360080         Physical Minimum (-32768)
46FF7F         Physical Maximum (32767)
   
0501         Usage Page (Generic Desktop)
0901         Usage (Pointer)
A100         Collection (Physical)
9502            Report Count (2)
0501            Usage Page (Generic Desktop)
0930            Usage (X)
0931            Usage (Y)         ;north positive
8102            Input (Data,Variable,Absolute)
C0         End Collection
   
0501         Usage Page (Generic Desktop)
0901         Usage (Pointer)
A100         Collection (Physical)
9502            Report Count (2)
0501            Usage Page (Generic Desktop)
0933            Usage (Rx)
0934            Usage (Ry)         ;north positive
8102            Input (Data,Variable,Absolute)
C0         End Collection
   
C0      End Collection
      
0501      Usage Page (Generic Desktop)
093A      Usage (Counted Buffer)      ;XXX
A102      Collection (Logical)
      
         ; padding
7508         Report Size (8)
9501         Report Count (1)
9101         Output (Constant)
   
         ; byte count
7508         Report Size (8)
9501         Report Count (1)
0501         Usage Page (Generic Desktop)
093B         Usage (Byte Count)      ;XXX
9101         Output (Constant)
   
         ; padding
7508         Report Size (8)
9501         Report Count (1)
9101         Output (Constant)
      
         ; left actuator
7508         Report Size (8)
1500         Logical Minimum (0)
26FF00         Logical Maximum (255)
3500         Physical Minimum (0)
46FF00         Physical Maximum (255)
9501         Report Count (1)
0600FF         Usage Page (vendor-defined)
0901         Usage (1)
9102         Output (Data,Variable,Absolute)
      
         ; padding
7508         Report Size (8)
9501         Report Count (1)
9101         Output (Constant)
         
         ; right actuator
7508         Report Size (8)
1500         Logical Minimum (0)
26FF00         Logical Maximum (255)
3500         Physical Minimum (0)
46FF00         Physical Maximum (255)
9501         Report Count (1)
0600FF         Usage Page (vendor-defined)
0902         Usage (2)
9102         Output (Data,Variable,Absolute)
         
C0      End Collection
   
C0   End Collection


I can't see how it is fundamentally different. I can't figure out why MAME is picking up these strange names either. As I said, it works fine and looks okay in the control panel applet.

Posted: Wed Mar 05, 2008 1:20 am
by mojo
Thanks Grendel, you put me on to a solution. On further inspection there is an error in my descriptor. The buttons are in the same collection as the pointer. I moved them to their own collection and that sorted out the naming issues:

Code: Select all

ReportDescriptor:
      .db 0x05,0x01      ;Usage_Page (Generic Desktop)
      .db 0x09,0x05      ;Usage (Game Pad)
      .db 0xA1,0x01      ;Collection (Application)
      .db 0x09,0x01         ;Usage (Pointer)
      .db 0xA1,0x00         ;Collection (Physical)      
      .db 0x09,0x30            ;Usage (X)
      .db 0x09,0x31            ;Usage (Y)
      .db 0x15,0x81            ;Logical_Minimum (-127)
      .db 0x25,0x7F            ;Logical Maximum (127)
      .db 0x75,0x08            ;Report_Size (8)
      .db 0x95,0x02            ;Report_Count (2)
      .db 0x81,0x02            ;Input (Data, Var, Abs)      
      .db 0xC0,0x16         ;End_Collection, dummy

      .db 0xA1,0x00         ;Collection (Physical)
      .db 0x05,0x09            ;Usage_Page (Button)
      .db 0x19,0x01            ;Usage_Minimum (Button 1)
      .db 0x29,0x0a            ;Usage_Maximum (Button 10)
      .db 0x15,0x00            ;Logical_Minimum (0)
      .db 0x25,0x01            ;Logical_Maximum (1)
      .db 0x75,0x01            ;Report_Size (1)
      .db 0x95,0x0a            ;Report_Count (2)
      .db 0x55,0x00            ;Unit_Exponent (0)
      .db 0x65,0x00            ;Unit (None)
      .db 0x81,0x02            ;Input (Data, Var, Abs)

;round it out
      .db 0x05,0x01            ;Usage_Page (Generic Desktop)
      .db 0x09,0x00            ;Usage (Undefined)
      .db 0x15,0x01            ;Logical_Minimum (0)
      .db 0x25,0x06            ;Logical_Maximum (5)
      .db 0x75,0x06            ;Report_Size (6)
      .db 0x95,0x01            ;Report_Count (1)
      .db 0x81,0x02            ;Input (Data, Var, Abs)
      .db 0xC0,0x00         ;End_Collection , dummy padding

ReportDescriptorEnd:


Another issue was that the usage_page was still set to "button" for the padding bits, which caused an 11th button to be seen in Windows. Changing the page back to "generic desktop" fixed things.

Thanks for the push in the right direction :D

MAME now sees the buttons correctly.