usbhidusb-hid

I've read through the USB documentation, but i still don't understand where the prefixes for USB report descriptor usage pages and usages come from


I've read through the documentation for the USB HID class and the USB usages tables, and looked at examples provided.

Here:

https://www.usb.org/sites/default/files/hut1_6.pdf

https://www.usb.org/sites/default/files/hid1_11.pdf

enter image description here

But I still don't understand where some of these codes come from. I understand the 0x01 portion of the Usage Page(Generic Desktop) tag, but I don't understand why 0x05 byte is used. If i had to guess, 0x05 is the code for a "usage switch", but where does 0x09 and 0xA1 come from? In the context of usage tags, there is no mention of these codes in either document.

I've read through other stack overflow posts, but there is no clear explanation on specifically the codes code that signify a usage page, usage, and collection tags.


Solution

  • The format of Report Descriptor items is documented (not very clearly IMHO) in https://www.usb.org/sites/default/files/hid1_11.pdf in section 5.3 "Generic Item Format".

    That doco does not explicitly list all the possible item codes in hexadecimal format, but the HIDRDD Report Descriptor Decoder freeware does:

    Table of item codes in hexadecimal. The item code varies depending on the
    length of the subsequent item data field as follows:
    
                                  Item code for 
                                  Data Field Length
    Item                           0    1    2    4   Comment
    ---------------------------   --   --   --   --   -----------------------------
    (MAIN)   INPUT                80   81   82   83   Defines input to the host device
    (MAIN)   OUTPUT               90   91   92   93   Defines output from the host device
    (MAIN)   COLLECTION           A0   A1   A2   A3   See collection types below
    (MAIN)   FEATURE              B0   B1   B2   B3   Defines data to or from the host device
    (MAIN)   END_COLLECTION       C0                  Item data field is not supported
    (GLOBAL) USAGE_PAGE                05   06   07   USAGE_PAGE 00 is invalid
    (GLOBAL) LOGICAL_MINIMUM      14   15   16   17
    (GLOBAL) LOGICAL_MAXIMUM      24   25   26   27
    (GLOBAL) PHYSICAL_MINIMUM     34   35   36   37
    (GLOBAL) PHYSICAL_MAXIMUM     44   45   46   47
    (GLOBAL) UNIT_EXPONENT        54   55   56   57
    (GLOBAL) UNIT                 64   65   66   67
    (GLOBAL) REPORT_ID                 85   86   87   REPORT_ID=0 is reserved
    (GLOBAL) REPORT_SIZE               75   76   77   REPORT_SIZE=0 is invalid
    (GLOBAL) REPORT_COUNT         94   95   96   97   REPORT_COUNT=0 is not useful
    (GLOBAL) PUSH                 A4                  Item data field is not supported
    (GLOBAL) POP                  B4                  Item data field is not supported
    (LOCAL)  USAGE                08   09   0A   0B
    (LOCAL)  USAGE_MINIMUM        18   19   1A   1B
    (LOCAL)  USAGE_MAXIMUM        28   29   2A   2B
    (LOCAL)  DESIGNATOR_INDEX     38   39   3A   3B
    (LOCAL)  DESIGNATOR_MINIMUM   48   49   4A   4B
    (LOCAL)  DESIGNATOR_MAXIMUM   58   59   5A   5B
    (LOCAL)  STRING_INDEX         78   79   7A   7B
    (LOCAL)  STRING_MINIMUM       88   89   8A   8B
    (LOCAL)  STRING_MAXIMUM       98   99   9A   9B
    (LOCAL)  DELIMITER            A8   A9   AA   AB
    

    Basically, the item code changes depending on the length of the following data - so in your example,

    05 01

    ...means item code 05 (USAGE_PAGE) followed by 1 byte of data, and that data is 01 meaning usage page 1 (Generic Desktop Page).

    The item code is a bit-encoded field that contains the length of the following data - which is why the code changes depending on the length of the data. In other words, the following sequences mean exactly the same thing (USAGE PAGE 1):

    05 01             // USAGE PAGE 1 (1-byte data length)
    06 01 00          // USAGE PAGE 1 (2-byte data length)
    07 01 00 00 00    // USAGE PAGE 1 (4-byte data length)
    
    

    People usually code the shortest sequence (to save memory in microcontroller-based USB devices, for example).