From owner-freebsd-current@FreeBSD.ORG Sun Feb 17 16:47:34 2008 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D6EB316A46C for ; Sun, 17 Feb 2008 16:47:34 +0000 (UTC) (envelope-from markus@FreeBSD.org) Received: from mail-in-05.arcor-online.net (mail-in-05.arcor-online.net [151.189.21.45]) by mx1.freebsd.org (Postfix) with ESMTP id 206C513C4D9 for ; Sun, 17 Feb 2008 16:47:34 +0000 (UTC) (envelope-from markus@FreeBSD.org) Received: from mail-in-19-z2.arcor-online.net (mail-in-19-z2.arcor-online.net [151.189.8.36]) by mail-in-05.arcor-online.net (Postfix) with ESMTP id E601527AC7F; Sun, 17 Feb 2008 16:42:30 +0100 (CET) Received: from mail-in-03.arcor-online.net (mail-in-03.arcor-online.net [151.189.21.43]) by mail-in-19-z2.arcor-online.net (Postfix) with ESMTP id D85D06BD71; Sun, 17 Feb 2008 16:42:30 +0100 (CET) Received: from galaxy.homeunix.org (dslb-084-061-000-159.pools.arcor-ip.net [84.61.0.159]) by mail-in-03.arcor-online.net (Postfix) with ESMTP id 8D81E30AC40; Sun, 17 Feb 2008 16:42:30 +0100 (CET) Received: from cheops.phoenix (cheops.phoenix [192.168.1.3]) by galaxy.homeunix.org (Postfix) with ESMTP id BB64A3F455; Sun, 17 Feb 2008 16:39:45 +0100 (CET) From: Markus Brueffer To: freebsd-current@freebsd.org Date: Sun, 17 Feb 2008 16:41:59 +0100 User-Agent: KMail/1.9.7 References: <47B20739.1050602@chuckr.org> <20080216121241.450ff175@deskjail> <47B79A48.1030406@chuckr.org> In-Reply-To: <47B79A48.1030406@chuckr.org> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="nextPart5572139.TovlfbE5Tt"; protocol="application/pgp-signature"; micalg=pgp-sha1 Content-Transfer-Encoding: 7bit Message-Id: <200802171642.04403.markus@FreeBSD.org> X-Virus-Scanned: ClamAV 0.92.1/5847/Sun Feb 17 12:26:12 2008 on mail-in-03.arcor-online.net X-Virus-Status: Clean Cc: Chuck Robey , Alexander Leidinger Subject: Re: about usb X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 17 Feb 2008 16:47:34 -0000 --nextPart5572139.TovlfbE5Tt Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline 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= =20 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=20 binary representation): bTag=3D0000 bType=3D01 bSize=3D01 =46irst, as bTag is not 1111, we know that this is not a long item (see=20 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 specifie= s=20 the number of following bytes that belong to this item which is 1 in this=20 case. So, looking back at the raw descriptor we know now that the sequence= =20 0x05 0x01 forms one item. We also know that it is a short item and that it = is=20 a global item. What we don't know yet is, what global item this is. For thi= s,=20 we have to look at bTag again. As we know that this is a global item, we ta= ke=20 a look at chapter 6.2.2.7 "Global Items". It tells us that 0000 stands for= =20 Usage Page. Which usage page is meant is encoded in the data part of the=20 item, which is 0x01. From the HID Usage Tables document Chapter 3 we learn= =20 that 0x01 stands for "Generic Desktop Controls". This gives us the followin= g=20 for the first item: 0x05 0x01 USAGE_PAGE (Generic Desktop) Now the second item beginning with 0x09: Binary representation is 00001001.= =20 Splitting this up yields: bTag=3D0000 bType=3D10 bSize=3D01 Again this is a short item as bTag !=3D 1111. bType is a decimal 2 and chap= ter=20 6.2.2.2 tells us that this is a local item. Advancing to chapter=20 6.2.2.7 "Local Items" gives us the meaning for bTag, which is "Usage". As=20 bSize is 1, only the next byte in the report descriptor is considered for t= he=20 data of the item, so the usage is 0x02. Looking at the HID Usage Tables=20 document again, this time chapter 4, as we already learned that this usage= =20 belongs to the usage page Generic Desktop, we see that 0x02 is equivalent=20 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=3D1010 bType=3D00 bSize=3D01 Again this is a short item as bTag !=3D 1111. bType is 0, which stands for = Main=20 Item, according to chapter 6.2.2.2. Looking at chapter 6.2.2.4, we learn th= at=20 the bTag of 1010 actually means "Collection". The data part of 1 byte (see= =20 bSize), which is in this case 0x01 tells us that this is an "Application=20 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=20 local, global and main items relate to each other. Main items are actually= =20 the most important ones, as they directly correlate to physical controls of= =20 your device (apart from the collection items). Global and local items=20 describe the different main items, whereas local items only describe the ne= xt=20 main item. Global items instead keep their state accross main items until=20 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 o= ne 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 contex= t=20 of the items that are within it, so we have: Collection page=3DGeneric_Desktop usage=3DMouse 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=20 controls is specified by the usage page and usage min/max. In this case=20 Button 1 - Button 4. Logical min/max are 0 and 1 and mean that the range of= =20 the data in the data stream, that is submitted by the device, is between 0= =20 and 1, which is actually only 0 and 1 in this case. Report size finally giv= es=20 the size in the data stream for each button state that is submitted by the= =20 device in number of bits. Now we have: Collection page=3DGeneric_Desktop usage=3DMouse Input size=3D1 count=3D1 page=3DButton usage=3DButton_1, logical range 0.= =2E1 Input size=3D1 count=3D1 page=3DButton usage=3DButton_2, logical range 0.= =2E1 Input size=3D1 count=3D1 page=3DButton usage=3DButton_3, logical range 0.= =2E1 Input size=3D1 count=3D1 page=3DButton usage=3DButton_4, logical range 0.= =2E1 The next input item is a const item, which is being used for padding in thi= s=20 case. It can be ignored. In the end we get the following: Collection page=3DGeneric_Desktop usage=3DMouse Input size=3D1 count=3D1 page=3DButton usage=3DButton_1, logical range 0.= =2E1 Input size=3D1 count=3D1 page=3DButton usage=3DButton_2, logical range 0.= =2E1 Input size=3D1 count=3D1 page=3DButton usage=3DButton_3, logical range 0.= =2E1 Input size=3D1 count=3D1 page=3DButton usage=3DButton_4, logical range 0.= =2E1 Input size=3D4 count=3D1 page=3D0x0000 usage=3D0x0000 Const, logical rang= e 0..1 Collection page=3DGeneric_Desktop usage=3DPointer Input size=3D8 count=3D1 page=3DGeneric_Desktop usage=3DX, logical range = =2D127..127 Input size=3D8 count=3D1 page=3DGeneric_Desktop usage=3DY, logical range = =2D127..127 Input size=3D8 count=3D1 page=3DGeneric_Desktop usage=3DZ, logical range = =2D127..127 Input size=3D8 count=3D1 page=3DGeneric_Desktop usage=3DWheel, logical=20 range -127..127 End collection Input size=3D8 count=3D1 page=3D0x00ff usage=3D0x00c0, logical range -127= =2E.127 End collection This actually means, that the mouse reports 6 bytes of data in each=20 transmission. The first 4 bits indicate the button states, the next 4 bits= =20 can be ignored. Byte 2 reports the X axis state, byte 3, 4 and 5 data for Y= ,=20 Z and the wheel. The last byte reports vendor specific data (usage page=20 0x00ff). That's it in short. There is of course much to learn regarding the details,= =20 but it should give you a general overview of how this works. Markus --nextPart5572139.TovlfbE5Tt Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.4 (FreeBSD) iD8DBQBHuFXM1I0Qcnj4qNQRAg9bAKCWK1PRol2EAVAgTUpfU/AhJmKzNwCg/yXZ yW806VV205ScIpHVm/gMAag= =MhWu -----END PGP SIGNATURE----- --nextPart5572139.TovlfbE5Tt--