Introduction
The HID Tool comes with several example descriptors which you can use as the basis for your own custom HID descriptors. This article will demonstrate how to modify the descriptors to suit your specifications.
Many thanks to Glen Alexis for explaining this to me!
Basic Principles
When modifying the HID descriptors, there is one important rule that must be followed in order for the modifications to be accepted: the total number of data bits specified in the descriptor must be a multiple of 8 bits. For example, let’s have a look at the default joystick descriptor:
USAGE_PAGE (Generic Desktop) LOGICAL_MINIMUM (0) USAGE (Joystick) COLLECTION (Application) USAGE_PAGE (Simulation Controls) USAGE (Throttle) LOGICAL_MINIMUM (-127) LOGICAL_MAXIMUM (127) REPORT_SIZE (8) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Pointer) COLLECTION (Physical) USAGE (X) USAGE (Y) REPORT_COUNT (2) INPUT (Data,Var,Abs) END_COLLECTION USAGE (Hat switch) LOGICAL_MINIMUM (0) LOGICAL_MAXIMUM (3) PHYSICAL_MINIMUM (0) PHYSICAL_MAXIMUM (270) UNIT (Eng Rot:Angular Pos) REPORT_SIZE (4) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Button) USAGE_MINIMUM (Button 1) USAGE_MAXIMUM (Button 4) LOGICAL_MINIMUM (0) LOGICAL_MAXIMUM (1) REPORT_SIZE (1) REPORT_COUNT (4) UNIT_EXPONENT (0) UNIT (None) 65 00 INPUT (Data,Var,Abs) END_COLLECTION
From the descriptor, we can see that the data is defined as follows:
Value | Size (bits) |
Throttle | 8 |
X axis | 8 |
Y axis | 8 |
POV Hat | 4 |
Buttons | 4 |
Total | 32 bits = 4 bytes |
The data bits form a whole number of bytes and so is accepted by the host PC. Let’s say, however, that we didn’t want the POV Hat in our joystick and we removed it’s section from the descriptor. We would end up with the following descriptor:
USAGE_PAGE (Generic Desktop) LOGICAL_MINIMUM (0) USAGE (Joystick) COLLECTION (Application) USAGE_PAGE (Simulation Controls) USAGE (Throttle) LOGICAL_MINIMUM (-127) LOGICAL_MAXIMUM (127) REPORT_SIZE (8) REPORT_COUNT (1) INPUT (Data,Var,Abs) USAGE_PAGE (Generic Desktop) USAGE (Pointer) COLLECTION (Physical) USAGE (X) USAGE (Y) REPORT_COUNT (2) INPUT (Data,Var,Abs) END_COLLECTION USAGE_PAGE (Button) USAGE_MINIMUM (Button 1) USAGE_MAXIMUM (Button 4) LOGICAL_MINIMUM (0) LOGICAL_MAXIMUM (1) REPORT_SIZE (1) REPORT_COUNT (4) UNIT_EXPONENT (0) UNIT (None) 65 00 INPUT (Data,Var,Abs) END_COLLECTION
Our data would look like this:
Value | Size (bits) |
Throttle | 8 |
X axis | 8 |
Y axis | 8 |
Buttons | 4 |
Total | 28 bits = 3.5 bytes |
What’s immediately noticeable is that the total number of data bits does not come to a whole number of bytes and this is why the above descriptor would fail. In order to fix this problem, some padding needs to be added at the end of the descriptor to fill up the extra 4 bits. The necessary modification is highlighted below:
USAGE_PAGE (Generic Desktop)
LOGICAL_MINIMUM (0)
USAGE (Joystick)
COLLECTION (Application)
USAGE_PAGE (Simulation Controls)
USAGE (Throttle)
LOGICAL_MINIMUM (-127)
LOGICAL_MAXIMUM (127)
REPORT_SIZE (8)
REPORT_COUNT (1)
INPUT (Data,Var,Abs)
USAGE_PAGE (Generic Desktop)
USAGE (Pointer)
COLLECTION (Physical)
USAGE (X)
USAGE (Y)
REPORT_COUNT (2)
INPUT (Data,Var,Abs)
END_COLLECTION
USAGE_PAGE (Button)
USAGE_MINIMUM (Button 1)
USAGE_MAXIMUM (Button 4)
LOGICAL_MINIMUM (0)
LOGICAL_MAXIMUM (1)
REPORT_SIZE (1)
REPORT_COUNT (4)
UNIT_EXPONENT (0)
UNIT (None) 65 00
INPUT (Data,Var,Abs)
REPORT_COUNT (4) <-Adds 4 extra padding bits to the descriptor INPUT (Constant,Var,Abs)
END_COLLECTION
The two lines above the END_COLLECTION statement declares a constant that is 4 bits in size. This brings the total data bits to 32 bits which forms 4 complete bytes.
Conclusion
That’s pretty much the key to any modifications you make to the HID descriptors – as long as you make sure that you add the correct amount of padding to your descriptor, you should be able to modify to your heart’s content.
How i can set descriptor only for X-axis,Y-axis and 8 buttons, without Throttle and POV Hat
i dont understand your xplanations
That solved my issue, thank you!