USB Descriptors Help

Hello everyone!
I found many solution through this forum for my project without starting new topic but now its the time to make one :smiley:

(My project: a joystick with 64 buttons and 4 axis on arduino mega2560 (64 buttons on 52digital pins + 12 analog pins, and 4 axis to 4 analog pins ))

a.

I want to modify descriptors to this http://hunt.net.nz/users/darran/weblog/a3599/Arduino_UNO_Joystick_HID_firmware.html

USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] =
{
	0x05, 0x01,          /* Usage Page (Generic Desktop)                       */
	0x09, 0x04,          /* Usage (Joystick)                                   */
	0xa1, 0x01,          /* Collection (Application)                           */
	0x09, 0x01,          /*   Usage (Pointer)                                  */
	0xa1, 0x00,          /*   Collection (Physical)                            */
	0x05, 0x01,          /*     Usage Page (Generic Desktop)                   */
	0x09, 0x30,          /*     Usage (X)                                      */
	0x09, 0x31,          /*     Usage (Y)                                      */
	0x15, 0x9c,          /*     Logical Minimum (-100)                         */
	0x25, 0x64,          /*     Logical Maximum (100)                          */
	0x75, 0x08,          /*     Report Size (8 )                                */
	0x95, 0x02,          /*     Report Count (2)                               */
	0x81, 0x82,          /*     Input (Data, Variable, Absolute, Volatile)     */
	0xc0,                /*   End Collection                                   */
        0x95, 0x1E,          /*   Report Count (30)                                */
        0x75, 0x01,          /*   Report Size (1)                                  */
        0x05, 0x09,          /*   Usage Page (Button)                              */
        0x19, 0x01,          /*     Usage Minimum (Button 1)                       */
        0x29, 0x1E,          /*     Usage Maximum (Button 30)                      */
        0x15, 0x00,          /*   Logical Minimum (0)                              */
        0x25, 0x01,          /*   Logical Maximum (1)                              */
        0x81, 0x02,          /*   Input (Data, Variable, Absolute)                 */
        0x75, 0x02,          /*   Report Size (2)                                  */
        0x95, 0x01,          /*   Report Count (1)                                 */
        0x81, 0x01,          /*   Input (Constant)                                 */
	0xc0                 /* End Collection                                     */
};

in order to extend my joystick on to 64 buttons!

b.

i also need a small guide about how to extend the joystick report to 64 buttons.

byte0 : Bits 0-7 => x1 axis (int8_t x1;)
byte1 : Bits 0-7 => y1 axis (int8_t y1;)
byte2 : Bits 0-7 => z rotation (int8_t z;)
byte3 : Bits 0-7 => x rotation (int8_t x;)

byte4 : Bits 0-7 => 1-8 buttons (uint8t_t buttons1_8;)
byte5 : Bits 8-15 => 9-16 buttons (uint8t_t buttons9_16;)
byte6 : Bits 16-23 => 17-24 buttons (uint8t_t buttons17_24;)
byte7 : Bits 24-31 => 25-32 buttons (uint8t_t buttons25_32;)
byte8 : Bits 32-39 => 33-40 buttons (uint8t_t buttons33_40;)
byte9 : Bits 40-47 => 41-48 buttons (uint8t_t buttons41_48;)
byte10 : Bits 48-55 => 49-56 buttons (uint8t_t buttons49_56;)
byte11 : Bits 56-64 => 55-64 buttons (uint8t_t buttons57_64;)

the byte4 to byte7 is the same with that (uint32_t buttons1_32;) ??

according this, if its ok, the

typedef struct {
    int8_t  x; /**< Current absolute joystick X position, as a signed 8-bit integer */
    int8_t  y; /**< Current absolute joystick Y position, as a signed 8-bit integer */
    uint32_t button; /**< Bit mask of the currently pressed joystick buttons */
} USB_JoystickReport_Data_t;

will become like this ???

typedef struct {
    int8_t  x1; /**< Current absolute joystick X position, as a signed 8-bit integer */
    int8_t  y1; /**< Current absolute joystick Y position, as a signed 8-bit integer */
    int8_t  z;
    int8_t  x;

    uint32_t buttons1_32; /**< Bit mask of the currently pressed joystick buttons */
    uint32_t buttons33_64;

} USB_JoystickReport_Data_t;

Thanks a lot for your time!!

Please edit your post to put the code in code tags... The # button that says "Insert Code" in its hover-text.

Not even a hint????? something ??? nobody knows nothing?

lostre86:
Not even a hint????? something ??? nobody knows nothing?

You've proposed some code. Does it compile? Does it run? Does it do what you want? What's the point in us guessing whether it's right, when you haven't taken the trouble to find out for yourself.

b looks correct. As for a, here's another example of a HID descriptor from my own code which has 6 axes and 12 buttons:

USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] =
{
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x04,                    // USAGE (Joystick)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x09, 0x01,                    //   USAGE (Pointer)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
    0x09, 0x30,                    //     USAGE (X)
    0x09, 0x31,                    //     USAGE (Y)
    0x09, 0x32,                    //     USAGE (Z)
    0x09, 0x36,                    //     USAGE (Slider)
    0x09, 0x36,                    //     USAGE (Slider)
    0x09, 0x36,                    //     USAGE (Slider)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x03,              //     LOGICAL_MAXIMUM (1023)
    0x75, 0x10,                    //     REPORT_SIZE (16)
    0x95, 0x06,                    //     REPORT_COUNT (6)
    0x81, 0x82,                    //     INPUT (Data,Var,Abs,Vol)
    0xc0,                          //               END_COLLECTION
    0x05, 0x09,                    //   USAGE_PAGE (Button)
    0x19, 0x02,                    //   USAGE_MINIMUM (Button 2)
    0x29, 0x0d,                    //   USAGE_MAXIMUM (Button 13)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x0c,                    //   REPORT_COUNT (12)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x75, 0x04,                    // REPORT_SIZE (4)
    0x95, 0x01,                    // REPORT_COUNT (1)
    0x81, 0x01,                    //   INPUT (Cnst,Ary,Abs)
    0xc0                           //   END_COLLECTION
};

                typedef struct
                {
                        int16_t  An0;
                        int16_t  An1; 
                        int16_t  An2; 
                        int16_t  An3; 
                        int16_t  An4; 
                        int16_t  An5; 
                        uint16_t Button;
                } USB_JoystickReport_Data_t;

To see how one maps to the other, look closely for "report size" and "report count". In your example, the analog section has report size of 8 and report count of 2, corresponding to the two int8_t variables in the report data. In mine the size is 16 and count is 6, for the six int16_t. For the buttons, your example has a report count of 30 and a report size of 1 for 30 buttons, followed by a report count of 2 and a report size of 1 for the two spare bits, corresponding to the uint32_t in the report data. Mine has count 12 of size 1 for buttons and count 4 of size 1 for spare bits, for a uint16_t. If you have 64 buttons then you won't have any spare bits so you won't need the constant section.

I hope that gives you enough clues to work out what to do for yourself. HID joystick code is very hard to debug because it is almost impossible to get a debug message out to the computer. There is a HID descriptor generator tool on the USB.org website somewhere, but it is rather cryptic and hard to use.

I can't imagine what game you need 4 axes and 64 buttons for - flight simulator chess? :smiley:

Thank you stimmer! u made things more clear!

I modified descriptors for 64 Buttons with success of working

USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] =
{
	0x05, 0x01,          /* Usage Page (Generic Desktop)                       */
	0x09, 0x04,          /* Usage (Joystick)                                   */
	0xa1, 0x01,          /* Collection (Application)                           */
	0x09, 0x01,          /*   Usage (Pointer)                                  */
	0xa1, 0x00,          /*   Collection (Physical)                            */
	0x05, 0x01,          /*     Usage Page (Generic Desktop)                   */
	0x09, 0x30,          /*     Usage (X)                                      */
	0x09, 0x31,          /*     Usage (Y)                                      */
	0x15, 0x9c,          /*     Logical Minimum (-100)                         */
	0x25, 0x64,          /*     Logical Maximum (100)                          */
	0x75, 0x08,          /*     Report Size (8)                                */
	0x95, 0x02,          /*     Report Count (2)                               */
	0x81, 0x82,          /*     Input (Data, Variable, Absolute, Volatile)     */
	0xc0,                /*   End Collection                                   */
 
    0x05, 0x09,          /*   Usage Page (Button)                              */
    0x19, 0x01,          /*   Usage Minimum (Button 1)                         */
    0x29, 0x40,          /*   Usage Maximum (Button 64)                        */
	0x15, 0x00,          /*   Logical Minimum (0)                              */
    0x25, 0x01,          /*   Logical Maximum (1)                              */
	0x95, 0x40,          /*   Report Count (64)                                */
	0x75, 0x01,          /*   Report Size (1)                                  */
	0x81, 0x02,          /*   Input (Data, Variable, Absolute)                 */
	0xc0                 /* End Collection                                     */
};

But in the joystick's calibration, shows only 32..

According this "..compared to DirectInput's support for 8 axes, 128 buttons, and full-range POV"
in this DirectInput - Wikipedia,
should show 64 Buttons.

What do i miss ??

Unfortunately I don't use windows so can't be of much further help. I tried your descriptor on a Uno connected to Linux and ran jstest, which showed 64 buttons as required :slight_smile:

Thanks again stimmer!!

after that u said,i modified descriptors once again with 2 report IDs an now i have 2 joysticks with 32 buttons each! :smiley:

here is the code if anyone might need it

USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] =
{
	0x05, 0x01,          /* Usage Page (Generic Desktop)                       */
	0x09, 0x04,          /* Usage (Joystick)                                   */
	0xa1, 0x01,          /* Collection (Application)                           */
	0x85, 0x01,				//reportid1
	0x09, 0x01,          /*   Usage (Pointer)                                  */
	0xa1, 0x00,          /*   Collection (Physical)                            */
	0x05, 0x01,          /*     Usage Page (Generic Desktop)                   */
	0x09, 0x30,          /*     Usage (X)                                      */
	0x09, 0x31,          /*     Usage (Y)                                      */
	0x15, 0x9c,          /*     Logical Minimum (-100)                         */
	0x25, 0x64,          /*     Logical Maximum (100)                          */
	0x75, 0x08,          /*     Report Size (8)                                */
	0x95, 0x04,          /*     Report Count (4)                               */
	0x81, 0x82,          /*     Input (Data, Variable, Absolute, Volatile)     */
	0xc0,                /*   End Collection                                   */
    0x05, 0x09,          /*   Usage Page (Button)                              */
    0x19, 0x01,          /*   Usage Minimum (Button 1)                         */
    0x29, 0x20,          /*   Usage Maximum (Button 32)                        */
	0x15, 0x00,          /*   Logical Minimum (0)                              */
    0x25, 0x01,          /*   Logical Maximum (1)                              */
	0x95, 0x20,          /*   Report Count (32)                                */
	0x75, 0x01,          /*   Report Size (1)                                  */
	0x81, 0x02,          /*   Input (Data, Variable, Absolute)                 */
	0xc0,                 /* End Collection                                     */

	0x05, 0x01,          /* Usage Page (Generic Desktop)                       */
	0x09, 0x04,          /* Usage (Joystick)                                   */
	0xa1, 0x01,          /* Collection (Application)                           */
	0x85, 0x02,				//reportid2
	0x09, 0x01,          /*   Usage (Pointer)                                  */
	0xa1, 0x00,          /*   Collection (Physical)                            */
	0x05, 0x01,          /*     Usage Page (Generic Desktop)                   */
	0x09, 0x30,          /*     Usage (X)                                      */
	0x09, 0x31,          /*     Usage (Y)                                      */
	0x15, 0x9c,          /*     Logical Minimum (-100)                         */
	0x25, 0x64,          /*     Logical Maximum (100)                          */
	0x75, 0x08,          /*     Report Size (8)                                */
	0x95, 0x04,          /*     Report Count (4)                               */
	0x81, 0x82,          /*     Input (Data, Variable, Absolute, Volatile)     */
	0xc0,                /*   End Collection                                   */
    0x05, 0x09,          /*   Usage Page (Button)                              */
    0x19, 0x01,          /*   Usage Minimum (Button 1)                         */
    0x29, 0x20,          /*   Usage Maximum (Button 32)                        */
	0x15, 0x00,          /*   Logical Minimum (0)                              */
    0x25, 0x01,          /*   Logical Maximum (1)                              */
	0x95, 0x20,          /*   Report Count (32)                                */
	0x75, 0x01,          /*   Report Size (1)                                  */
	0x81, 0x02,          /*   Input (Data, Variable, Absolute)                 */
	0xc0                 /* End Collection                                     */
};

Now i must figure out how to play with variables for those buttons, how to assign pins and then... maybe a successfull project!

Attached is my modification of the code to work as 2 joysticks of 2 axes and 32 buttons each.

Arduino-joystick.c (8.96 KB)

Arduino-joystick.h (3.5 KB)

Descriptors.c (12 KB)

doublejoy.ino (1.07 KB)

And here is the hex file:

Arduino-joystick.hex (11.3 KB)

My friend,I love you ...... :smiley: :smiley: :smiley: :smiley:

Update to help with sticking buttons problem.

Arduino-joystick.c (8.96 KB)

Arduino-joystick.hex (11.3 KB)