Re: about usb

From: Markus Brueffer <markus_at_FreeBSD.org>
Date: Sun, 17 Feb 2008 16:41:59 +0100
Am Sonntag, 17. Februar 2008 03:22:00 schrieb Chuck Robey:
> I am still having a miserable time trying to figure out the HID spec, and
> Kai Wang deserves being nominated for Sainthood, for putting up with my
> horde of stupid questions.  If anyone knows of a HID device which has a
> published [HID report in hex, Parsed output, and comments on how it got
> from one to the other] I would give nearly anything for such a thing
> (anything I happen to have, which doesn't happen to include cash right
> now).

This is the raw report descriptor of a very simple device: an Apple Mighty 
Mouse:

0x05 0x01 0x09 0x02 0xa1 0x01 0x05 0x09
0x19 0x01 0x29 0x04 0x15 0x00 0x25 0x01
0x95 0x04 0x75 0x01 0x81 0x02 0x95 0x01
0x75 0x04 0x81 0x01 0x05 0x01 0x09 0x01
0xa1 0x00 0x09 0x30 0x09 0x31 0x09 0x32
0x09 0x38 0x15 0x81 0x25 0x7f 0x75 0x08
0x95 0x04 0x81 0x06 0xc0 0x05 0xff 0x09
0xc0 0x75 0x08 0x95 0x01 0x81 0x02 0xc0

Decoding it works as follows:

Let's look at the first byte 0x05. The binary representation is 00000101.
Splitting this up as described in chapter 6.2.2.2 gives the following (in 
binary representation):

bTag=0000
bType=01
bSize=01

First, as bTag is not 1111, we know that this is not a long item (see 
6.2.2.3). So this must be a short item.

bType tells us that this is a global item (6.2.2.2). Finally bSize specifies 
the number of following bytes that belong to this item which is 1 in this 
case. So, looking back at the raw descriptor we know now that the sequence 
0x05 0x01 forms one item. We also know that it is a short item and that it is 
a global item. What we don't know yet is, what global item this is. For this, 
we have to look at bTag again. As we know that this is a global item, we take 
a look at chapter 6.2.2.7 "Global Items". It tells us that 0000 stands for 
Usage Page. Which usage page is meant is encoded in the data part of the 
item, which is 0x01. From the HID Usage Tables document Chapter 3 we learn 
that 0x01 stands for "Generic Desktop Controls". This gives us the following 
for the first item:

0x05 0x01	USAGE_PAGE (Generic Desktop)

Now the second item beginning with 0x09: Binary representation is 00001001. 
Splitting this up yields:

bTag=0000
bType=10
bSize=01

Again this is a short item as bTag != 1111. bType is a decimal 2 and chapter 
6.2.2.2 tells us that this is a local item. Advancing to chapter 
6.2.2.7 "Local Items" gives us the meaning for bTag, which is "Usage". As 
bSize is 1, only the next byte in the report descriptor is considered for the 
data of the item, so the usage is 0x02. Looking at the HID Usage Tables 
document again, this time chapter 4, as we already learned that this usage 
belongs to the usage page Generic Desktop, we see that 0x02 is equivalent 
to "Mouse". Now we have:

0x05 0x01       USAGE_PAGE (Generic Desktop)
0x09 0x02       USAGE (Mouse)

Up to the next item which begins with 0xa1, binary 10100001:

bTag=1010
bType=00
bSize=01

Again this is a short item as bTag != 1111. bType is 0, which stands for Main 
Item, according to chapter 6.2.2.2. Looking at chapter 6.2.2.4, we learn that 
the bTag of 1010 actually means "Collection". The data part of 1 byte (see 
bSize), which is in this case 0x01 tells us that this is an "Application 
Collection". So, now we have:

0x05 0x01       USAGE_PAGE (Generic Desktop)
0x09 0x02       USAGE (Mouse)
0xa1 0x01       COLLECTION (Application)

If you continue decoding it this way, you will finally get the following:

0x05 0x01       USAGE_PAGE (Generic Desktop)
0x09 0x02       USAGE (Mouse)
0xa1 0x01       COLLECTION (Application)
0x05 0x09       USAGE_PAGE (Button)
0x19 0x01       USAGE_MINIMUM (Button 1)
0x29 0x04       USAGE_MAXIMUM (Button 4)
0x15 0x00       LOGICAL_MINIMUM (0)
0x25 0x01       LOGICAL_MAXIMUM (1)
0x95 0x04       REPORT_COUNT (4)
0x75 0x01       REPORT_SIZE (1)
0x81 0x02       INPUT (Data, Var, Abs)
0x95 0x01       REPORT_COUNT (1)
0x75 0x04       REPORT_SIZE (4)
0x81 0x01       INPUT (Const, Var, Abs)
0x05 0x01       USAGE_PAGE (Generic Desktop)
0x09 0x01       USAGE (Pointer)
0xa1 0x00       COLLECTION (Physical)
0x09 0x30       USAGE (X)
0x09 0x31       USAGE (Y)
0x09 0x32       USAGE (Z)
0x09 0x38       USAGE (WHEEL)
0x15 0x81       LOGICAL_MINIMUM (0x81)
0x25 0x7f       LOGICAL_MAXIMUM (0x7f)
0x75 0x08       REPORT_SIZE (8)
0x95 0x04       REPORT_COUNT (4)
0x81 0x06       INPUT (Data, Var, Rel)
0xc0            END COLLECTION
0x05 0xff       USAGE_PAGE (0xff)
0x09 0xc0       USAGE (0xc0)
0x75 0x08       REPORT_SIZE (8)
0x95 0x01       REPORT_COUNT (1)
0x81 0x02       INPUT (Data, Var, Abs)
0xc0

To actually give meaning to the decoded descriptor, you have to learn how 
local, global and main items relate to each other. Main items are actually 
the most important ones, as they directly correlate to physical controls of 
your device (apart from the collection items). Global and local items 
describe the different main items, whereas local items only describe the next 
main item. Global items instead keep their state accross main items until 
they are specified again or are being overrriden by a local item.

In this example we have several main items. Lets have a look at the first one

0x05 0x01       USAGE_PAGE (Generic Desktop)
0x09 0x02       USAGE (Mouse)
0xa1 0x01       COLLECTION (Application)

This is an application collection. Usage page and usage describe the context 
of the items that are within it, so we have:

Collection page=Generic_Desktop usage=Mouse

The next item is a bit more interresting. It's an input item:

0x05 0x09       USAGE_PAGE (Button)
0x19 0x01       USAGE_MINIMUM (Button 1)
0x29 0x04       USAGE_MAXIMUM (Button 4)
0x15 0x00       LOGICAL_MINIMUM (0)
0x25 0x01       LOGICAL_MAXIMUM (1)
0x95 0x04       REPORT_COUNT (4)
0x75 0x01       REPORT_SIZE (1)
0x81 0x02       INPUT (Data, Var, Abs)

It actually describes 4 controls (report count). The meaning of these 4 
controls is specified by the usage page and usage min/max. In this case 
Button 1 - Button 4. Logical min/max are 0 and 1 and mean that the range of 
the data in the data stream, that is submitted by the device, is between 0 
and 1, which is actually only 0 and 1 in this case. Report size finally gives 
the size in the data stream for each button state that is submitted by the 
device in number of bits. Now we have:

Collection page=Generic_Desktop usage=Mouse
Input   size=1 count=1 page=Button usage=Button_1, logical range 0..1
Input   size=1 count=1 page=Button usage=Button_2, logical range 0..1
Input   size=1 count=1 page=Button usage=Button_3, logical range 0..1
Input   size=1 count=1 page=Button usage=Button_4, logical range 0..1

The next input item is a const item, which is being used for padding in this 
case. It can be ignored. In the end we get the following:

Collection page=Generic_Desktop usage=Mouse
Input   size=1 count=1 page=Button usage=Button_1, logical range 0..1
Input   size=1 count=1 page=Button usage=Button_2, logical range 0..1
Input   size=1 count=1 page=Button usage=Button_3, logical range 0..1
Input   size=1 count=1 page=Button usage=Button_4, logical range 0..1
Input   size=4 count=1 page=0x0000 usage=0x0000 Const, logical range 0..1
Collection page=Generic_Desktop usage=Pointer
Input   size=8 count=1 page=Generic_Desktop usage=X, logical range -127..127
Input   size=8 count=1 page=Generic_Desktop usage=Y, logical range -127..127
Input   size=8 count=1 page=Generic_Desktop usage=Z, logical range -127..127
Input   size=8 count=1 page=Generic_Desktop usage=Wheel, logical 
range -127..127
End collection
Input   size=8 count=1 page=0x00ff usage=0x00c0, logical range -127..127
End collection

This actually means, that the mouse reports 6 bytes of data in each 
transmission. The first 4 bits indicate the button states, the next 4 bits 
can be ignored. Byte 2 reports the X axis state, byte 3, 4 and 5 data for Y, 
Z and the wheel. The last byte reports vendor specific data (usage page 
0x00ff).

That's it in short. There is of course much to learn regarding the details, 
but it should give you a general overview of how this works.

Markus

Received on Sun Feb 17 2008 - 15:47:34 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:27 UTC