9 years, 9 months ago.

HID Report ID problem

I am trying yo use the HID Joystick, I have created 2 different HID devices using Report ID, but when I try to send the report, it is not working. This is my code:

#include "stdint.h"
#include "USBJoystick.h"

bool USBJoystick::update(uint8_t button, uint8_t button2)
{
    HID_REPORT report;

    _button = button;
    _button2 = button2;


    // Fill the report according to the Joystick Descriptor

    report.data[0] = _button & 0xff;
    report.data[1] = _button2 & 0xff;
    report.length = 2;


    return send(&report);
}

bool USBJoystick::update()
{
    HID_REPORT report;

    // Fill the report according to the Joystick Descriptor
    report.data[0] = _button & 0xff;
    report.data[1] = _button2 & 0xff;
    report.length = 2;


    return send(&report);
}




bool USBJoystick::button(uint8_t button)
{
    _button = button;

    return update();
}

bool USBJoystick::button2(uint8_t button2)
{

    _button2 = button2;
    return update();
}


void USBJoystick::_init()
{


    _button = 0x00;
    _button2 = 0x00;

}


uint8_t * USBJoystick::reportDesc()
{
    static uint8_t reportDescriptor[] = {

    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x05,                    // USAGE (Game Pad)
    0xa1, 0x01,                    // COLLECTION (Application)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    0x85, 0x01,                    //     REPORT_ID (1)
    0x05, 0x09,                    //     USAGE_PAGE (Button)
    0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
    0x29, 0x06,                    //     USAGE_MAXIMUM (Button 6)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x95, 0x06,                    //     REPORT_COUNT (6)
    0x75, 0x01,                    //     REPORT_SIZE (1)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x75, 0x02,                    //   REPORT_SIZE (2)
    0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)
    0xc0,                          //     END_COLLECTION
    0xc0,                          // END_COLLECTION
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x05,                    // USAGE (Game Pad)
    0xa1, 0x01,                    // COLLECTION (Application)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    0x85, 0x02,                    //     REPORT_ID (2)
    0x05, 0x09,                    //     USAGE_PAGE (Button)
    0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
    0x29, 0x02,                    //     USAGE_MAXIMUM (Button 2)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x95, 0x02,                    //     REPORT_COUNT (2)
    0x75, 0x01,                    //     REPORT_SIZE (1)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x75, 0x06,                    //   REPORT_SIZE (6)
    0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)
    0xc0,                          //     END_COLLECTION
    0xc0                           // END_COLLECTION
        
    };

    reportLength = sizeof(reportDescriptor);
    return reportDescriptor;
}

I think the function update does not work for 2 different Report IDs

1 Answer

9 years, 9 months ago.

Please use <<code>> and <</code>> tags around your posted code to keep it readable.

Not sure that I understand the problem, but note that if you have modified the descriptor that was used when running the example USBJoystick code on your PC this means that you must also use a new Vendor ID and/or Product ID (see Joystick constructor). That is needed because Windows links the VID/PID to a specific descriptor so that it knows which device driver should be loaded. When you change the descriptor and windows detects a difference or a mistake (eg missing or wrong bit padding) it will fail to install the USB HID driver and you probably need to use another Product ID to retry after fixing your code....

Vendor id is not a problem. Descriptor is working perfectly If i use:

    report.data[0] = 0x01;  //Report id 1
    report.data[1] = _button & 0xff;
    report.length = 2;

It works perfectly, but if I try to use:

    report.data[0] = 0x01;  //Report id 1
    report.data[1] = _button & 0xff;
    report.data[2] = 0x02;  //Report id 2
    report.data[3] = _button2 & 0xff;
    report.length = 4;

It doesn't work, btw, if I use button2 alone, like in the first example, it works too

posted by Sergio Fernandez Santos 06 Feb 2015

I dont think I used ever used the report IDs, but you probably need to send two separate updates when you do use report IDs.

report.data[0] = 0x01;  //Report id 1
report.data[1] = _button & 0x3f;
report.length = 2;
send(&report);

report.data[0] = 0x02;  //Report id 2
report.data[1] = _button2 & 0x03;
report.length = 2;
send(&report);

The idea behind the IDs is that you can update only part of the data. In this case with only two sets of buttons it probably does not make much sense and you might as well wrap it all in one package. Also note that according to the descriptor only 6 bits are used in the first message and 2 bits are used in the second. The rest are padding bits.

Some more links are here

posted by Wim Huiskamp 06 Feb 2015