Chinaunix首页 | 论坛 | 博客
  • 博客访问: 939059
  • 博文数量: 173
  • 博客积分: 3436
  • 博客等级: 中校
  • 技术积分: 1886
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-07 09:29
文章分类

全部博文(173)

文章存档

2016年(6)

2015年(10)

2014年(14)

2013年(8)

2012年(36)

2011年(63)

2010年(19)

2009年(17)

分类: 嵌入式

2012-02-20 22:11:55

转载自:
 
the keyboard type:

The LK201 was a detachable computer keyboard introduced by of , in 1982. It was first used by Digital's ANSI/ASCII terminal and was subsequently used by the , , and microcomputers and many of Digital's computer workstations such as the and families.

Lk201.jpg

The keyboard layout was new at the time, adding a set of cursor and miscellaneous keys between the main keyboard and the . The cursor keys were arranged in what has now become the standard "Inverted T" arrangement seen on essentially all contemporary full-sized computer keyboards. Ergonomic considerations caused the keyboard to be designed with a very low profile; it was very thin, especially when compared to the keyboard used on the VT100. The keyboard connected using a 4 position over which flowed 12 power and 4800 bit/s data.


It is so good that I could not help to transfer it here.
USnooBie's USB HID Report Descriptor Tutorial 1

I hope you watched my first video on how to build a . In that tutorial, one of the key components was the USB HID report descriptor, where I showed you how to utilize an example descriptor. This may leave you with some questions about how USB HID report descriptors work, I will explain them to you in this tutorial.

First, go to this page http://www.usb.org/developers/hidpage/ and find the document titled "Device Class Definition for HID". What I will be talking about is essentially paraphrasing the important sections of that document.

Second, go get the HID descriptor tool from the same page. You'll want to play with it as you go through this tutorial. It is an absolute headache to write the HID report descriptors manually (converting between binary and hex and looking up the meanings of the numbers) so this tool is essential. What is a USB HID report descriptor?

"The HID protocol makes implementation of devices very simple. Devices define their data packets and then present a "HID descriptor" to the host. The HID descriptor is a hard coded array of bytes that describe the device's data packets. This includes: how many packets the device supports, how large are the packets, and the purpose of each byte and bit in the packet. For example, a keyboard with a calculator program button can tell the host that the button's pressed/released state is stored as the 2nd bit in the 6th byte in data packet number 4 (note: these locations are only illustrative and are device specific). The device typically stores the HID descriptor in ROM and does not need to intrinsically understand or parse the HID descriptor. Some mouse and keyboard hardware in the market today are implemented using only an 8-bit CPU." - Wikipedia on Human Interface Device

I'm going to try teaching you about USB HID report descriptors by walking you through writing a few.

For a simple starting point, let us make a standard mouse. Just three buttons, and movement on the X and Y axis. So we want to send data regarding the buttons and movement. It takes one bit to represent each button, and one byte to represent the movement on one axis as a signed integer. So we can say that we want the data structure to look something like this

  Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
Byte 0 Useless Useless Useless Useless Useless Left Button Middle Button Right Button
Byte 1 X Axis Relative Movement as Signed Integer
Byte 2 Y Axis Relative Movement as Signed Integer

And then we can say our data structure in C looks like

点击(此处)折叠或打开

  1. struct mouse_report_t
  2. {
  3.     uint8_t buttons;
  4.     int8_t x;
  5.     int8_t y;
  6. }
So now in our descriptor, our first item must describe buttons, three of them

点击(此处)折叠或打开

  1. USAGE_PAGE (Button)
  2. USAGE_MINIMUM (Button 1)
  3. USAGE_MAXIMUM (Button 3)


each button status is represented by a bit, 0 or 1

点击(此处)折叠或打开

  1. LOGICAL_MINIMUM (0)
  2. LOGICAL_MAXIMUM (1)


there are three of these bits

点击(此处)折叠或打开

  1. REPORT_COUNT (3)
  2. REPORT_SIZE (1)


send this variable data to the computer

点击(此处)折叠或打开

  1. INPUT (Data,Var,Abs)


点击(此处)折叠或打开

  1. USAGE_PAGE (Button)
  2. USAGE_MINIMUM (Button 1)
  3. USAGE_MAXIMUM (Button 3)
  4. LOGICAL_MINIMUM (0)
  5. LOGICAL_MAXIMUM (1)
  6. REPORT_COUNT (3)
  7. REPORT_SIZE (1)
  8. INPUT (Data,Var,Abs)


?

that will represent the buttons

but what about the five useless padding bits?

点击(此处)折叠或打开

  1. REPORT_COUNT (1)
  2. REPORT_SIZE (5)
  3. INPUT (Cnst,Var,Abs)


now we make the X axis movement

点击(此处)折叠或打开

  1. USAGE_PAGE (Generic Desktop)
  2. USAGE (X)


we want it to be a signed integer that takes one byte, so it has a value between -127 and +127

点击(此处)折叠或打开

  1. LOGICAL_MINIMUM (-127)
  2. LOGICAL_MAXIMUM (127)


we want it to take an entire byte which is 8 bits

点击(此处)折叠或打开

  1. REPORT_SIZE (8)
  2. REPORT_COUNT (1)
and send it to the computer as a variable relative coordinate

点击(此处)折叠或打开

  1. INPUT (Data,Var,Rel)


you end up with something like this to represent the X axis movement

点击(此处)折叠或打开

  1. USAGE_PAGE (Generic Desktop)
  2. USAGE (X)
  3. LOGICAL_MINIMUM (-127)
  4. LOGICAL_MAXIMUM (127)
  5. REPORT_SIZE (8)
  6. REPORT_COUNT (1)
  7. INPUT (Data,Var,Rel)
How about Y axis? You can try

点击(此处)折叠或打开

  1. USAGE_PAGE (Generic Desktop)
  2. USAGE (X)
  3. LOGICAL_MINIMUM (-127)
  4. LOGICAL_MAXIMUM (127)
  5. REPORT_SIZE (8)
  6. REPORT_COUNT (1)
  7. INPUT (Data,Var,Rel)
  8. USAGE_PAGE (Generic Desktop)
  9. USAGE (Y)
  10. LOGICAL_MINIMUM (-127)
  11. LOGICAL_MAXIMUM (127)
  12. REPORT_SIZE (8)
  13. REPORT_COUNT (1)
  14. INPUT (Data,Var,Rel)


\Which will work, but to save memory, we can do this instead

点击(此处)折叠或打开

  1. USAGE_PAGE (Generic Desktop)
  2. USAGE (X)
  3. USAGE (Y)
  4. LOGICAL_MINIMUM (-127)
  5. LOGICAL_MAXIMUM (127)
  6. REPORT_SIZE (8)
  7. REPORT_COUNT (2)
  8. INPUT (Data,Var,Rel)

So all your data will end up looking like

点击(此处)折叠或打开

  1. USAGE_PAGE (Button)
  2. USAGE_MINIMUM (Button 1)
  3. USAGE_MAXIMUM (Button 3)
  4. LOGICAL_MINIMUM (0)
  5. LOGICAL_MAXIMUM (1)
  6. REPORT_COUNT (3)
  7. REPORT_SIZE (1)
  8. INPUT (Data,Var,Abs)
  9. REPORT_COUNT (1)
  10. REPORT_SIZE (5)
  11. INPUT (Cnst,Var,Abs)
  12. USAGE_PAGE (Generic Desktop)
  13. USAGE (X)
  14. USAGE (Y)
  15. LOGICAL_MINIMUM (-127)
  16. LOGICAL_MAXIMUM (127)
  17. REPORT_SIZE (8)
  18. REPORT_COUNT (2)
  19. INPUT (Data,Var,Rel)
Ah but we are not done, in order to make the computer know that this is a mouse, we do

点击(此处)折叠或打开

  1. USAGE_PAGE (Generic Desktop)
  2. USAGE (Mouse)
  3. COLLECTION (Application)
  4.     USAGE (Pointer)
  5.     COLLECTION (Physical)
  6.       
  7.     ... What we wrote already goes here
  8.       
  9.     END COLLECTION
  10. END COLLECTION
So in the end, this is the USB HID report descriptor for a standard mouse

点击(此处)折叠或打开

  1. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  2. 0x09, 0x02, // USAGE (Mouse)
  3. 0xa1, 0x01, // COLLECTION (Application)
  4. 0x09, 0x01, // USAGE (Pointer)
  5. 0xa1, 0x00, // COLLECTION (Physical)
  6. 0x05, 0x09, // USAGE_PAGE (Button)
  7. 0x19, 0x01, // USAGE_MINIMUM (Button 1)
  8. 0x29, 0x03, // USAGE_MAXIMUM (Button 3)
  9. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  10. 0x25, 0x01, // LOGICAL_MAXIMUM (1)
  11. 0x95, 0x03, // REPORT_COUNT (3)
  12. 0x75, 0x01, // REPORT_SIZE (1)
  13. 0x81, 0x02, // INPUT (Data,Var,Abs)
  14. 0x95, 0x01, // REPORT_COUNT (1)
  15. 0x75, 0x05, // REPORT_SIZE (5)
  16. 0x81, 0x03, // INPUT (Cnst,Var,Abs)
  17. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  18. 0x09, 0x30, // USAGE (X)
  19. 0x09, 0x31, // USAGE (Y)
  20. 0x15, 0x81, // LOGICAL_MINIMUM (-127)
  21. 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
  22. 0x75, 0x08, // REPORT_SIZE (8)
  23. 0x95, 0x02, // REPORT_COUNT (2)
  24. 0x81, 0x06, // INPUT (Data,Var,Rel)
  25. 0xc0, // END_COLLECTION
  26. 0xc0 // END_COLLECTION


This is actually the example descriptor provided with the USB HID documentation, and you can also find this as an example provided with the HID tool.

Cool, at this point, you will have encountered some concepts that you may have questions about, you should research the following: Usage Pages

There's one thing that I think isn't explained well in the documentation, USAGE, USAGE_PAGE, USAGE_MINIMUM and USAGE_MAXIMUM. In a descriptor, you first set a USAGE_PAGE, and certain USAGEs are available. In the mouse example, USAGE_PAGE (Generic Desktop) allowed you to use USAGE (Mouse), and when the usage page was changed to USAGE_PAGE (Button), then the USAGE_MINIMUM and USAGE_MAXIMUM allowed you to specify the buttons, and before you can use USAGE (X) and USAGE (Y), the usage page was changed back to USAGE_PAGE (Generic Desktop). The usage page is like a namespace, changing the usage page affects what "usages" are available. Read the documentation called " HID Usage Tables" for more info. Collections

Read the documentation about the official proper use of collections. In my own words, collections can be used to organize your data, for example, a keyboard may have a built-in touchpad, then the data for the keyboard should be kept in one application collection while the touchpad data is kept in another. We can assign an "Report ID" to each collection, which I will show you later.

Hey here's something you can do, by turning "USAGE (Mouse)" into "USAGE (Gamepad)", you make the computer think that it's a game pad with one joystick and 3 buttons.

TODO screenshot

Or... How about converting a Playstation 2 controller into a USB gamepad? The controller has 16 buttons and two thumb sticks, so we want the data to look like

  Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
Byte 0 Button Button Button Button Button Button Button Button
Byte 1 Button Button Button Button Button Button Button Button
Byte 2 Left X Axis as Signed Integer
Byte 3 Left Y Axis as Signed Integer
Byte 4 Right X Axis as Signed Integer
Byte 5 Right Y Axis as Signed Integer

So our data structure looks like


阅读(3322) | 评论(0) | 转发(0) |
0

上一篇:BSD compile

下一篇:vSphereClient使用

给主人留下些什么吧!~~