Question

I am trying to make a USB keyboard which has very minimal keys and i will be using some modifier keys like SHIFT and ALT keys.

Now my question

This is a truncated section of the report descriptor I am using

0x09, 0x06,                    // USAGE (Keyboard)
 0xa1, 0x01,                    // COLLECTION (Application)
 0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
 0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
 0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
 0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
 0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
 0x75, 0x01,                    //   REPORT_SIZE (1)
 0x95, 0x08,                    //   REPORT_COUNT (8)

And this section describes the modifier byte (Byte 0) of the USB message.

As i understand the bits of this byte are set when the following keys are pressed

bit 0 - Left Ctrl
bit 1 - Left Shift
bit 2 - Left Alt
bit 3 - Left GUI or Windows Key
bit 4 - Right Ctrl
bit 5 - Right Shift
bit 6 - Right Alt
bit 7 - Right GUI or Windows Key

Now I am not able to understand why the USAGE_MINIMUM (Keyboard LeftControl) and USAGE_MAXIMUM (Keyboard Right GUI) are limited at these values?

The USB HID specification says

Since only one array element can be reported in each array field, modifier keys should be reported as bitmap data (a group of 1-bit variable fields). For example, keys such as CTRL, SHIFT, ALT, and GUI keys make up the 8 bit modifier byte in a standard keyboard report. Although these usage codes are defined in the Usage Table as E0–E7, the usage is not sent as array data.

Was it helpful?

Solution 2

The USAGE_MINIMUM and USAGE_MAXIMUM are not limited to be any particular value. You could change them in your descriptor. In this case, the values in the descriptor you found are useful because they allow you to put all the modifier key states in one byte, saving you from having to send a larger report to the computer.

OTHER TIPS

The section of the report descriptor that you've posted pertains to the modifier keys that most keyboards have (CTRL, Shift, ALT, etc.).

The USAGE_MINIMUM and USAGE_MAXIMUM are hints to the driver that communicates with the device as to what the bits in this part of the report denote. This descriptor says that we're sending 8 bits to the host, and when a particular bit in that report is set, it should be interpreted as a value from 0xE0 to 0xE7.

If you look up a list of HID keyboard scan codes, you'll see that the scan code for the left CTRL key is 0xE0, left Shift is 0xE1, left ALT is 0xE2, etc.; so if we were to send a packet with 0b10100001, that means we're telling the host that it's receiving scan codes 0xE0, 0xE2, and 0xE7, so the left CTRL, left ALT, and right Meta keys are pressed.

Instead of having to send a whole bunch of byte-long scan codes to the host to communicate the state of each modifier key, we can use a single byte to simultaneously communicate the state of eight of them. The USAGE_MIN and USAGE_MAX are what tells the host to interpret these bytes as the modifier keys.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top