Custom HID device HID report descriptor

后端 未结 5 1847
误落风尘
误落风尘 2020-12-24 04:45

I have a bit of a problem with generating a HID descriptor. I want to use simple reports with ID1 for input and ID2 for output with 64 bytes of data.

I realized that

5条回答
  •  抹茶落季
    2020-12-24 05:16

    As @aja stated above, the official USB documentation is rather obtuse. I created this template (mostly with help from this page) as a simple starting point to communicate with a custom board. The HID code is intended to replace the Virtual COM Port protocol. The big advantage with HID is that no driver is required.

    uint8_t CUSTOM_HID_ReportDesc[REPORT_DESC_SIZE] =
    {
       0x06, 0x00, 0xFF,    // Global  Usage page = 0xFF00 (Vendor-defined pages are in the range 0xFF00 through 0xFFFF)
       0x09, 0x01,          // Local   Usage (vendor usage 1)
       0xA1, 0x01,          // Main    Collection (application) begin
       0x15, 0x00,          // Global  Logical minimum (0) applies to each byte
       0x26, 0xFF, 0x00,    // Global  Logical maximum (255)
       0x75, 0x08,          // Global  Report Size (8 bits)
    
       // 14 bytes | Output message 1 (sent from host to device)
       0x85,  1,            // Global  Report ID (cannot be 0)
       0x98, 64,            // Global  Report Count (number of Report Size fields, in this case 64 bytes)
       0x19, 0x01,          // Local   Usage Minimum (each Report Count must be associated with a Usage)
       0x19, 0x40,          // Local   Usage Maximum
       0x91, 0x02,          // Main    Output (data, array, absolute)
    
       // 24 bytes | Input message 1 (sent from device to host)
       0x85,  1,            // Global  Report ID (cannot be 0)
       0x98, 64,            // Global  Report Count (number of Report Size fields)
       0x19, 0x01,          // Local   Usage Minimum (each Report Count must be associated with a Usage)
       0x19, 0x40,          // Local   Usage Maximum
       0x81, 0x02,          // Main    Input (data, array, absolute)
    
       // 34 bytes | Output message 2 (sent from host to device)
       0x85,  2,            // Global  Report ID (cannot be 0)
       0x98, 12,            // Global  Report Count (number of Report Size fields)
       0x19, 0x01,          // Local   Usage Minimum (each Report Count must be associated with a Usage)
       0x19, 0x40,          // Local   Usage Maximum
       0x91, 0x02,          // Main    Output (data, array, absolute)
    
       // 44 bytes | Input message 2 (sent from device to host)
       0x85,  2,            // Global  Report ID (cannot be 0)
       0x98, 57,            // Global  Report Count (number of Report Size fields)
       0x19, 0x01,          // Local   Usage Minimum (each Report Count must be associated with a Usage)
       0x19, 0x40,          // Local   Usage Maximum
       0x81, 0x02,          // Main    Input (data, array, absolute)
    
       // 54 bytes | End (add one byte)
       0xC0                 // Main    Collection (application) end
    }
    

    A couple of things to note:

    • More input/output pairs can easily be added: just give them another Report ID. Each message definition consists of 10 bytes, so it's simple to add up.
    • We keep track of the number of bytes in the descriptor so that the size of the array can be computed (#define REPORT_DESC_SIZE (55)).

    On the Windows side, I use Mike O'Brien's HIDLibrary. HID reports are typically prepended with the Report ID--in HIDLibrary, use the HidReport.ReportID field to set/get the value. On the board side, remember that the first byte of the report will be the Report ID.

提交回复
热议问题