52964.fb2
This chapter describes the Human Input Device (HID) model, a standard way of interacting with user input devices. A HID device uses various descriptors to define its capabilities. A Report descriptor details the input reports that it can generate and the output reports it can receive. The next chapter describes how to write Windows client device drivers and user mode applications that can talk to HID devices.
The HID specification is an abstract model for most types of input device that people will use to control their computers. An input device can be a plain old keyboard, for example, a vehicle simulation rudder, or the soft on/off button for the computer.
The HID specification was written originally for USB devices and closely follows the USB descriptor model. However, it is sufficiently generic for HID to be used with other types of device.
Naturally, most of the time a HID device provides input data to the computer. However, you can output to a HID device (e.g., to turn on the NumLock LED on a keyboard). You can also control a feature of the device, such as the font used on a display device or an LED color.
In Windows, the system HID class driver provides an abstract view of the input device. The HID device itself can be a USB device, a IEEE 1394 device or even a plain PC-compatible device, provided an appropriate HID minidriver is written to interface to the bus or device.
In this chapter and the next, quite a few of the examples are about getting input from a keyboard. It does not matter whether you are using a USB keyboard or a (hypothetical) IEEE 1394 keyboard. The system still gets keystrokes in exactly the same way, from the HID class driver. As the next chapter shows, Windows does get input from an old PC-compatible keyboard by a different route. Perhaps eventually a minidriver will be written so that HID will provide all the keyboard input.
Figure 22.1 shows how HID devices are used in Windows. A user mode or kernel mode HID client program calls the HID device stack. The stack always contains the system HID class driver, Hidсlass.sys, optionally with HID filter drivers above it. The HID class driver uses HID minidrivers to interface to hardware. In the figure, one of the minidrivers, HidUsb.sys. uses the USB stack to talk to a device.
Figure 22.1 HID drivers and clients
HID provides an abstract model of input devices, so client programs are not concerned with the details of where input comes from. HID models a device as various controls representing the device. A keyboard, therefore, usually has single-bit control representing the state of each modifier key, such as the left Shift key, and it has an array of scan code byte controls representing the other keys that are currently pressed.
Underlying the HID model are compact, but complicated, structures for passing information. HID device engineers and minidriver writers will need to know these structures. However, clients can just use various Windows parsing routines to access the relevant data. There are parsers for HID reports available to both kernel mode, Hidparse.dll, and user mode clients, Hid.dll.
The system HID class driver does most of the hard work. It delegates its hardware interactions to HID minidrivers. Windows includes a HID minidriver HidUsb.sys for the devices on the USB bus, but new minidrivers can be written, if necessary. New USB devices that have the appropriate HID Interface class constants and HID descriptors will not need a new minidriver. The system USB HID minidriver calls the system USB driver USBD.sys, optionally through any lower-level USB filter drivers. The system USB driver then talks to the device, etc.
A HID client, therefore, just talks to the HID class driver. The Windows operating system itself is an example of a kernel client, as it can get its keyboard and mouse input via HID. You can write kernel mode client drivers to use a HID device. However, it is often easier to write a Win32 program that talks directly to the HID class driver.
This section is a summary of the HID Model, particularly as seen by Windows device drivers and clients users. For full details, please read the HID specifications.
The HID specification documents are found on the USB website, www.usb.org/developers/. The "USB: Device Class Definition for HID" document usbhid10.pdf is referred to as the "HID Specification". The USB Compatibility Test software, also available there, includes the HIDView program to inspect and test HID devices. The "Ignore hubs (Memphis only)" box should be checked for Windows 98. The USB website also contains a tool for generating report descriptors, the Descriptor Tool dt. This contains several useful example report descriptors, as well as letting you build your own and check them for errors.
A computer primarily reads input data from a HID device. It can also send output data to it, and send and receive feature data.
Input data might represent a mouse movement or a keyboard keypress. Output data might mean setting the NumLock LED on a keyboard. A feature is something that controls the general operation of a device, such as the display character size. A feature is usually set by a Control Panel type application and not used by ordinary HID clients.
An individual transaction with a device is called a report, which groups several controls together. An input report from a keyboard says which keys are pressed and which modifier keys are pressed (i.e., Shift, etc.).
A control is a value of one or more bits. Control values can be converted from logical to physical form (i.e., scaled and given units). (Windows refers to some controls as buttons, while it calls others values.).
Reports may be grouped together in Collections. An Application top-level collection usually describes all the reports that a device can produce. More than one Application collection can be given. For example, if a keyboard has a built-in pointer (i.e., a mouse), it might well have an Application collection for a keyboard report and an Application collection for a pointer report. Reports and collections may contain other collections.
Figure 22.2 shows an overview of the Report descriptor for a HID keyboard. An input report contains eight control bits for the modifier keys and six byte values for all the keys that are simultaneously pressed. An output report just contains five output control bits for the keyboard LEDs. The full keyboard report descriptor also contains a "reserved" input control byte and a 3-bit control that pads out the output report.
Figure 22.2 Keyboard report descriptor overview
A HID device needs a standard way to tell programmers what their device is: what Input. Output, and Feature reports it can send and receive. Discovering this information is known as getting a device's capabilities.
Each control or collection of controls is assigned a usage that describes its purpose. The HID Specifications list a large number of usages for a range of standard devices. (I have yet to see a device with a "Do Not Disturb" LED. Did you know that a magic carpet has standard controls?)
A usage is, in fact, represented by two bytes: a Usage Page and a Usage. Table 22.1 shows the main usage categories.
Table 22.1 Main Usage categories
Usage Page | Usage |
---|---|
Generic Desktop | pointer |
mouse | |
pen | |
joystick | |
gamepad | |
keyboard | |
keypad | |
Vehicle | rudder |
throttle | |
Virtual Reality | |
Sport | |
Game | |
Consumer | power amp |
video disk | |
Keyboard | all keys |
LED | NumLock |
CapsLock | |
ScrollLock | |
power | |
Button | |
Ordinal | |
Telephony |
Note that usages are used both to specify the general characteristics of a device (i.e., of an Application collection) and the specifics of each control or group of controls.
The Application collection usage defines the overall purpose of a report. For example, a keyboard usually has an Application collection with a Usage Page of "Generic Desktop" and a Usage of "keyboard". The hidusage.h file defines these as byte constants HID_USAGE_PAGE_GENERIC and HID_USAGE_GENERIC_KEYBOARD, respectively. In most Usage Pages, Usage values in the range 1 to 0x1F usually indicate the overall purpose of a device.
The Application collection usage sometimes implies what controls should be in the report. A keyboard usually has eight input single-bit values, eight reserved bits, five output bits, three padding output bits and six input 8-bit values. Although some clients rely on devices having specific controls, most should be able to cope with different devices (e.g., with more controls) or controls in different reports.
Each control also has a usage. The eight single-bit input values in a keyboard report represent the modifier keys (i.e., whether a Shift, Ctrl, or Alt key is pressed at the same time). These modifiers are defined in the "Keyboard" Usage Page (HID_USAGE_PAGE_KEYBOARD). The first single bit value represents the state of the left control key and has a Usage of HID_USAGE_ KEYBOARD_LCTRL.
The HID Specification defines Usage values in the "Keyboard" Usage Page that represent all the common keyboard key scan codes. PC-AT keyboards return usages in the range 0 to 101.
However, the left control key has a usage of 240, HID_USAGE_KEYBOARD_LCTRL As described previously, this is usually returned as a bit value to indicate whether the key is pressed or not.
The HID Specification lets you define several reports in a report descriptor, each with different report IDs. However most Report descriptors do not use report IDs at all. For example, the keyboard Application collection just defines one report with both input and output controls in it. However, a keyboard with a built-in pointing device may have two Application collections with two reports, a keyboard report, and a pointer report.
When first used, a HID device needs to be interrogated to find out what it is. The client gets the device capabilities, the list of reports that the device may generate or accept. The client then decides whether the device is of interest. The capabilities are in a slightly opaque format, so Windows provides a parser to help clients analyze them. The parser functions are described in the next chapter.
You may also want to read a HID device's string descriptors and physical descriptors. Both are not necessary for most HID interactions, so they are only covered briefly here. See the HID specification for more details.
Controls may optionally have a string index. You can ask the device for the corresponding string, identified by the string index and a language ID. The string descriptor for index zero is special; it provides a list of the language IDs that are supported. HID string descriptors are identical to their USB equivalent, described in the previous two chapters.
Physical descriptors describe which parts of the body can be used to activate a device's controls. Each control may optionally have a designator index that can be used to look up the appropriate physical descriptor.
Then…
After this, the device generates input reports whenever appropriate, perhaps regularly. You can send output reports to the device. It may be able to send and receive feature reports.
This section gives explicit details of how the HID model is represented in descriptors and reports. This is useful background for HID client programmers. Minidriver writers and firmware engineers will need to know these details.
HID minidrivers need to return specific data structures to the HID class driver to tell it the device's capabilities. For many new devices, these are provided by the device itself. The crucial data structures are:
• HID descriptor,
• device attributes,
• report descriptor,
• physical descriptors, and
• string descriptors.
The actual data is in little endian format, lowest byte first. A field cannot span more than four bytes in a report.
In a HID USB device, these descriptors will be hard-coded into the device ROM. If you are providing a HID minidriver for a different bus and device, your minidriver may need to synthesize these descriptors internally.
A HID descriptor provides the first information about a device. It mainly confirms that it is a HID device and gives the lengths of its report descriptor and any physical descriptors.
Table 22.2 shows the HID_DESCRIPTOR structure along with typical values. The Descrip-torList field usually just has one element, detailing "report descriptor" and its length. However, it may also specify physical descriptor sets that provide information about the part or parts of the human body used to activate the controls on a device.
Most hardware is not localized, and so should just specify zero for the Country Code.
Table 22.2 HID descriptor
Field | Description | Typical values |
---|---|---|
bLength | length of HID descriptor | 9 |
bDescriptorType | descriptor type | HID_HID_DESCRIPTOR_TYPE, 0x21 |
bcdHID | HID spec release | 0x0100 |
bCountry | country code | 0 == Not Specified |
bNumDescriptors | number of HID class descriptors | 1 |
struct _HID_DESCRIPTOR_DESC_LIST { UCHAR bDescriptorType; USHORT wDescriptorLength; } DescriptorList[1]; | descriptor type; total length of descriptor | HID_REPORT_DESCRIPTOR TYPE, 0x22, sizeof(MyReportDescriptor) |
A Device Attributes HID_DEVICE_ATTRIBUTES structure simply has VendorID, ProductID, and VersionNumber fields, along with a Size.
A Report Descriptor is a somewhat complicated (but compact) structure detailing the device's capabilities. It may describe more than one report. A parser is provided by Windows to make sense of the format.
A Report Descriptor is a variable length structure made up of items that provide information about a device. A group of items might describe a single input, output, feature, or collection.
Overview
A Report descriptor usually has an Application collection defining one or more reports. Each report describes the input, output, or feature controls, and collections that it contains.
Each control has a data size and a usage. Controls can be given units, ranges, and scaling exponents. The data structure allows more than one control to be given usages, units, and exponents easily.
Table 22.3 Keyboard modifier keys example
Item | Item data | Item Type | ActualBytes |
---|---|---|---|
Usage Page | "keyboard" | Global | 05 07 |
Usage Minimum | "left control key" | Local | 19 E0 |
Usage Maximum | "left alt key" | Local | 29 E2 |
Report Size | 1 | Global | 75 01 |
Report Count | 3 | Global | 95 03 |
Input | (Data, Variable, Absolute) | Main | 81 02 |
As an example, Table 22.3 shows how three single-bit input controls are specified, the first three modifier keys on a keyboard. The last item, Input, declares the control(s) and states that they are data values (i.e., not constants). Preceding items give more details of the control(s). The preceding Report Size item says that each control has 1 bit and the Report Count item says that there are 3 controls. The preceding Usage Page item specifies the "keyboard" usage page, while the Usage Minimum and Usage Maximum items say that the first input bit corresponds to the left control key of a keyboard and that the last is the left Alt key.
Note that the Item data is actually a byte (e.g., "keyboard" is the constant 07, HID_USAGE_PAGEKEYBOARD).
Item Parts
An item consists of one or more bytes that define an item type, an item tag, an item size, and possibly item data bytes.
An item may be in Short or Long format. Long format is not used yet, so it is not discussed here.
Figure 22.3 shows that the first byte of an item has a Tag of four bits, a Type of two bits and a Data size of two bits. Table 22.4 shows the interpretation of the size and type fields.
Figure 22.3 Short item format
Table 22.4 Short item values
Data Size | 0 = 0 bytes |
1 = 1 byte | |
2 = 2 bytes | |
3 = 4 bytes | |
Type | 0 = Main |
1 = Global | |
2 = Local | |
3 = Reserved |
Main Item Tags
The Main item type is used for the Input, Output, Feature, Collection, and End Collection tags. A Main item is usually preceded by one or more Global or Local items that provide the rest of the description of the Main item.
Table 22.5 shows the set of possible item tags if the item type is Main (0). The number of data bytes and their definition is also shown. See the HID specification for full details.
Table 22.5 Main item tags
TagBits | Name | Databytes | Data |
---|---|---|---|
1000 | Input | 1-4 | Bit 0: 0=Data 1=Constant |
Bit 1: 0=Array 1=Variable | |||
Bit 2: 0=Absolute 1=Relative | |||
Bit 3: 0=No Wrap 1=Wrap | |||
Bit 4: 0=Linear 1=Non Linear | |||
Bit 5: 0=Preferred State 1=No Preferred | |||
Bit 6: 0=No Null position 1=Null state | |||
Bit 7: Reserved | |||
Bit 8: 0=Bit Field 1=Buffered Bytes | |||
Bit 31-9: Reserved | |||
1001 | Output | 1-4 | same as above, except Bit 7: 0=Non Volatile 1=Volatile |
1011 | Feature | 1-4 | same as Output |
1010 | Collection | 1 | 0x00 Physical group of axes |
0x01 Application mouse, keyboard | |||
0x02 Logical interrelated data | |||
0x03-0x7F Reserved | |||
0x80-0xFF Vendor-defined | |||
1100 | End collection | 0 | |
others |
|
The Input, Output, and Feature tags allow for up to four data bytes. However, if all the data bits in the top bytes are 0, they can be missed out. So, if bits 8-31 are 0 then the item data size can be given as 1 byte. Further, if no data bits are set at all, the data size can be zero.
For example, two bytes A1 01 (1010 0001 0000 0001) represent "Collection, Main, 1 data byte". The data byte is 0x01 (i.e., Application). Therefore, A1 01 is interpreted as "Collection (Application)".
The one byte C0 (1100 0000) is "End collection, Main, 0 data bytes", and so just means "End Collection".
The two bytes 81 02 (1000 0001 0000 0010) represent "Input, Main, 1 data byte". The data byte just has bit 1 set and so means Data, Variable, Absolute, etc. So 81 02 can be written as "Input (Data, Variable, Absolute)".
Input, Output, and Feature Controls
As shown in the earlier example, an Input, an Output, or a Feature item must be preceded by various other items that further describe the controls. The preceding items can be Global if the setting lasts for more than one control. They can be Local if they provide just the setting for one control.
Input, Output, and Feature items must have Report Size and Report Count preceding Global items. Report Count specifies the number of controls, each of Report Size number of bits.
There must be a preceding Usage Page item. Then specify either a Usage for a single control or a Usage Minimum and Usage Maximum pair if more than one control is being defined.
Logical Minimum and Logical Maximum specify the range of values that may be returned. For example, even though a Report Size is eight bits, the actual values returned might be specified as being between Logical Minimum 0 and Logical Maximum 101 inclusive.
"Constant" bit values are often used to pad out a report so that controls are byte-aligned.
When "Array" is specified, it means that the actual report will contain an array of usage values that apply at the time of the report. Report Count sets the maximum number of usages that may be returned. If fewer usages apply then the array is padded with zeroes.
The full example below shows how various types of control are defined.
Collections
A Physical collection is used to group controls that represent related physical data. A mouse movement might consist of X and Y coordinates and various bit fields to indicate which buttons are pressed.
An Application or top-level collection groups together all the reports, controls and collections in a report descriptor. This is preceded by Usage Pace and usage items. The Application collection usage is often used by a client to determine whether the device is of any interest. For example, the Application collection usage might be "keyboard" or "mouse". A keyboard with an integrated pointing device could be defined as two different Application collections.
Collections may be nested.
Global Item Tags
Global item type tags define the attributes of any following Main items. The appropriate Global value remains in force for the rest of the report descriptor unless replaced.
Table 22.6 shows the set of possible item tags if the item type is Global (1). I have already described most of these tags.
Table 22.6 Global item tags
Tag Bits | Name | Data bytes |
---|---|---|
0000 | Usage Page | 1 |
0001 | Logical Minimum | 1-4 |
0010 | Logical Maximum | 1-4 |
0011 | Physical Minimum | 1-4 |
0100 | Physical Maximum | 1-4 |
0101 | Unit Exponent | 1-4 |
0110 | Unit | 1-4 |
0111 | Report Size | 1+ |
1000 | Report ID | 1 |
1001 | Report Count | 1+ |
1010 | Push | 0 |
1011 | Pop | 0 |
others | reserved |
While Logical Minimum and Logical Maximum bound the values returned by a device, Physical Minimum and Physical Maximum give meaning to those bounds. Physical values are logical values with units applied. For example, a thermometer might have logical extents of 0 and 999, but physical extents of 32 and 212 degrees. Logical 0 corresponds to 32 degrees and logical 999 with 212 degrees.
The Unit and Unit Exponent items further define the type and scaling of the subsequent control(s).
Push and Pop items allow the state of the item stack to be saved and restored.
Local Item Tags
Local item type tags define the attributes of the following Main item. The Local value is only in force for the following Main item.
Table 22.7 shows the set of possible item tags if the item type is Local (2).
Table 22.7 Local item tags
Tag Bits | Name | Data bytes | Data |
---|---|---|---|
0000 | Usage | 1 | |
0001 | Usage Minimum | 1 | |
0010 | Usage Maximum | 1 | |
0011 | Designator Index | 1 | |
0100 | Designator Minimum | 1 | |
0101 | Designator Maximum | 1 | |
0111 | String Index | 1 | |
1000 | String Minimum | 1 | |
1001 | String Maximum | 1 | |
1010 | Set Delimiter | 1 | 0 = open set 1 = close set |
others | reserved |
The Usage or Usage Minimum and Usage Maximum give the definition of the following Input, Output, or Feature items.
For example, a keyboard uses eight one-bit values to specify the state of its Ctrl, Shift, Alt, etc., modifier keys. The report descriptor, therefore, has input controls in the HID_USAGE_ PAGE_KEYBOARD Usage Page. Its Usage Minimum is HID_USAGE_KEYBOARD_LCTRL (i.e., 224) and Usage Maximum is HID_USAGE_KEYBOARD_RGUI (i.e., 231). This means that if the first input bit is set, the left Ctrl key is pressed, etc.
The Designator items determine the body part used for each control, and refers to a Physical Descriptor.
Strings can be associated with each control. The String items give the String descriptor index.
A control may have more than one usage, string, or physical descriptor associated with it. One or more alternative sets of local items may be associated with a control by simply bracketing each set with Set Delimiter items.
Example
A 105-key keyboard should report eight modifier keys (i.e., Shift, etc.) and up to six simultaneous key presses. It has five output LEDs (i.e., for NumLock, etc.). The complete report descriptor is shown in Table 22.8.
Table 22.8 A keyboard report descriptor
Item | Data | Data value | Actual bytes | Interpretation |
---|---|---|---|---|
Usage Page | (Generic Desktop) | HID_USAGE_PAGE_GENERIC | 05 01 | |
Usage | (Keyboard) | HID_USAGE_GENERIC_KEYBOARD | 09 06 | |
Collection | (Application) | A1 01 | "Keyboard" | |
Usage Page | (Key Codes) | HID_USAGE_PAGE_KEYBOARD | 05 07 | |
Usage Minimum | left control key | HID_USAGE_KEYBOARD_LCTRL | 19 E0 | |
Usage Maximum | right GUI key | HID_USAGE_KEYBOARD_RGUI | 29 E7 | |
Logical Minimum | 0 | 15 00 | ||
Logical Maximum | 1 | 25 01 | ||
Report Size | 1 | 95 01 | ||
Report Count | 8 | 75 08 | ||
Input | (Data, Variable, Absolute) | 81 02 | Modifier key bits | |
Input | (Constant) | 81 01 | Reserved byte | |
Usage Page | (LEDs) | HID_USAGE_PAGE_LED | 05 08 | |
Report Count | 5 | 95 05 | ||
Usage Minimum | NumLock | HID_USAGE_LED_NUM_LOCK | 19 01 | |
Usage Maximum | kana | HID_USAGE_LED_KANA | 29 05 | |
Output | (Data, Variable, Absolute) | 91 02 | LEDs | |
Report Size | 3 | 75 03 | ||
Report Count | 1 | 95 01 | ||
Output | (Constant) | 91 01 | padding | |
Usage Page | (Key Codes) | HID_USAGE_PAGE_KEYBOARD | 05 07 | |
Usage Minimum | 0 | 19 00 | ||
Usage Maximum | 101 | 29 65 | ||
Report Count | 6 | 95 06 | ||
Report Size | 8 | 75 08 | ||
Logical Minimum | 0 | 15 00 | ||
Logical Maximum | 101 | 25 65 | ||
Input | (Data Array) | 81 00 | Key array (6 bytes) | |
End collection | C0 |
The first three items specify the Application collection as being a keyboard in the generic usage page. A client will therefore know straightaway that this device is a keyboard.
The next items define the modifier input controls. There are eight single-bit inputs, each naturally reporting either 0 or 1. These inputs correspond to eight usage values in the keyboard usage page, the left Shi ft key being pressed, onwards.
The next item defines a reserved constant byte of eight single bits. Note how the Global Report Size and Report Count items persist after the previous Main item.
The next control is for the output LEDs. There are five of them, still bits needing values of 0 or 1. The LED usage page is now in force and the output bits correspond to the NumLock key, etc.
The next control is a 3-bit constant field, padding the output report to make it up to a complete byte.
The actual key presses are defined in a single Input item with its "Array" bit set. Up to 6-key scan codes may be read, each of eight bits. However, the actual values returned are in the range 0 to 101. The keyboard has 102 keys and three modifier keys, returned separately as three bits.
No Report ID items are given, and so the descriptor describes one report that contains the current state of all the input and output items. An actual input report, therefore, always contains the eight modifier bits, a reserved byte of 0x00, and one to six key scan codes padded to six bytes with zeroes. An actual output report just contains one byte with the lower five bits giving the required LED states.
Pressing Ctrl+Alt+Del might result in the six input reports shown in Table 22.9. The reserved byte values are not shown.
Table 22.9 Ctrl+Alt+Del input reports
Transition | Modifier byte | Scan codes (hex) |
---|---|---|
Left Ctrl down | 00000001 | 00, 00, 00, 00, 00, 00 |
Left Alt down | 00000101 | 00, 00, 00, 00, 00, 00 |
Del down | 00000101 | 63, 00, 00, 00, 00, 00 |
Del up | 00000101 | 00, 00, 00, 00, 00, 00 |
Left Ctrl up | 00000100 | 00, 00, 00, 00, 00, 00 |
Left Alt up | 00000000 | 00, 00, 00, 00, 00, 00 |
This chapter has introduced you to the Human Input Device (HID) model. A HID device uses various descriptors to define its functionality. The most important of these, the Report descriptor, defines what input reports it generates and the output reports it can receive. The controls within a report are given "usage" values that define their function exactly. A full example of a Report descriptor was given for a HID keyboard.
The next chapter looks at how to use the HID class drivers in Windows. Both kernel mode drivers and user mode applications can access HID devices.