hanseltime
hanseltime

Reputation: 13

What are the bare requirements for HID usages in a report descriptor?

I'm currently planning out the code for a Bluetooth low energy (BLE) device that will operate on the HID over GATT profile from the bluetooth specification. I've read through the HID specification 1.11 and the Usage Tables 1.12, but I can't find anything about the minimum required use of Usage_pages and Usages.

Since we're implementing both the host and device, the plan is to use a vendor defined usage page for our report descriptor, but since our goal is to have fast connections and low power consumption, I don't want to send more bytes than I have to in the report definition phase of HID over GATT. Because of this, I'm considering removing all usages that would normally tag an input/output since they only seem semantic.

Here's a sample of what I'm considering:

    Usage_Page( Vendor Defined)
    Usage( Vendor 1)
    Collection(Application)
         Collection(Logical)               ; First Collection and Report
         Report_ID(1)
         Usage_Page(Button)                ; This is what the specification seems to encourage
         Usage_Minimum(Button 1)
         Usage_Maximum(Button 3)
         Logical_Minimum(0)                ; Logical limits
         Logical_Maximum(1)
         Report_Size(3)                    ; Three bits corresponding to the buttons
         Report_Count(1)                   ; One of the three bit sets
         Input( Data, Variable, Absolute)  ; Make it an input
         Report_Size(5)
         Report_Count(1)
         Input(Constant)                   ; Pad the transmitted byte
         Collection End
    Collection End

When I look at the this, I see a lot of extra bytes that do nothing since I'm not using a native parser. These range from Usages to even logical minimums/maximums. What consequences would there be if I just defined my report descriptor with only the top-level usage and no use of things like logical maximums?

Upvotes: 1

Views: 1179

Answers (1)

Nipo
Nipo

Reputation: 2927

A compliant parser should accept the following optimized descriptor:

 0x85, 0x01,                    // ReportID (1)
 0x05, 0xff,                    // UsagePage (255)
 0x09, 0x01,                    // Usage (1)
 0xa1, 0x01,                    // Collection (Application)
 0x25, 0x01,                    //     LogicalMaximum (1)
 0x75, 0x01,                    //     ReportSize (1)
 0x05, 0x09,                    //     UsagePage (Button)
 0x19, 0x01,                    //     UsageMinimum (Button(1))
 0x29, 0x03,                    //     UsageMaximum (Button(3))
 0x95, 0x03,                    //     ReportCount (3)
 0x81, 0x02,                    //     Input (Variable)
 0xc0,                          // EndCollection
  • logical minimum defaults to 0,
  • padding at the end of last byte comes for free.

Also note all Central-side implementations (Win, Bluez, CoreBluetooth, and Bluedroid) of HoG actually cache the report descriptor when pairing occurs in order to minimize the reconnection time. So, the actual size of the report descriptor is not that important: it will only take time once upon pairing, and probably never again (until device is paired again of course).

Also consider the report descriptor reading represents a few packets exchanged between central and peripheral (one every 20 bytes with a default MTU), each round-trip costs two intervals (if both stack implementations are not too bad), which will be around 60 ms (most centrals connect with a default interval to ~30 ms). So the actual discovery latency will be less than 200 ms longer when your report descriptor is 60 bytes longer... It is not a big deal for something that happens only once in the life of the device.

Lastly, a side note: You should probably not use a vendor-specific collection type, but try to stick to standard ones. It will allow driverless operation of your device in most cases.

Don’t forget that even if you only foresee an application-specific usage of your hardware, some people may actually be happy to reuse it for something else. If so, driverless is better, unless you want to forbid third part usage at all, but there is no point using HID in the first place. (HID was designed for driverless operation, and I'm still puzzled to see drivers for mice and gamepads, remote controls and push buttons just because of the maker's laziness.)

Upvotes: 1

Related Questions