about usb
Markus Brueffer
markus at FreeBSD.org
Sun Feb 17 16:47:34 UTC 2008
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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: This is a digitally signed message part.
Url : http://lists.freebsd.org/pipermail/freebsd-current/attachments/20080217/fd9d36bf/attachment.pgp
More information about the freebsd-current
mailing list