Modifying the Joystick USB HID Descriptor

Published on 28 November, 2010

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.

2 Responses to Modifying the Joystick USB HID Descriptor

  1. MarMar says:

    How i can set descriptor only for X-axis,Y-axis and 8 buttons, without Throttle and POV Hat

  2. flex says:

    i dont understand your xplanations

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This blog is kept spam free by WP-SpamFree.