about usb

Chuck Robey chuckr at chuckr.org
Mon Feb 18 01:04:07 UTC 2008


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Markus Brueffer wrote:
> 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).
> 

Boy I am really, really pleased you made this public, and I believe folks
will be googling this for years now.  What a great thing to do!

> 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

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4 (FreeBSD)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFHuNhoz62J6PPcoOkRAiuYAJ4iMn+/EX+lDnmvotxzOPa9JLJ6jQCdHtDN
HGyri1EPkH97rMTojc/x/MQ=
=YWSy
-----END PGP SIGNATURE-----


More information about the freebsd-current mailing list