分类: LINUX
2011-05-07 10:48:13
前面总结了usb枚举过程,现在总结第一个真正的设备hid,我不总结那么多的理论,记住hid有很多类,比如keyborad,mouse and so on.
28.0 CTL 21 0a 00 00 00 00 00 00 SET IDLE 47.1.0
这个命令是给slave设备的,但是我没在软件上抓住这个包,我想也许它是发给硬件层的吧,或者我这里只有一个hid设备,所以也没什么反应
在这里需要说的是在usb mass storage的set interface则是和set idle一样,在软件上也抓不住,但是也可以在bus hound抓住,可能也是给硬件层
的吧,好了,这个命令只要回复一个0数据段的数据包给host就好了。
28.0 CTL 81 06 00 22 00 00 6d 00 GET DESCRIPTOR 48.1.0
当上面都全部正确了后,host就开始向slave索取report,这个6d在usb 协议里面就规定的是回复report,我们只要把先前我们准备的hid的report
交给host就好了。
在这个时候,我们就可以通过刚才你在set config设置的端点来向host interrupt our data。如果你不想写中断, 那么就写一个循环,不断的向host
发送数据就好了。
好了,基本就总结完了,但是这还有一个问题,怎么写这个report呢,在hid设备里面可是有很多类的,不如键盘、鼠标等等。
有这么一本书《Universal Serial Bus (USB)》Device Class Definition for Human Interface Devices (HID)这就是hid设备的协议,在网上搜USB_HID1_11.pdf就可以找到了。
#define UsagePage(x) 0x05,x
#define Usage(x) 0x09,x
#define Collection(x) 0xA1,x
#define Usage_Minimum(x) 0x19,x
#define Usage_Maximum(x) 0x29,x
#define Logical_Minimum(x) 0x15,x
#define Logical_Maximum(x) 0x25,x
#define ReportSize(x) 0x75,x
#define ReportCount(x) 0x95,x
#define Input(x) 0x81,x
#define Output(x) 0x91,x
#define End_Collection 0xc0
const unsigned char HID_ReportkeyDesc[] = {
UsagePage (0x01 ),
Usage (0x06),
Collection (0x01),
UsagePage (0x07),
Usage_Minimum (224),
Usage_Maximum (231),
Logical_Minimum (0),
Logical_Maximum (1),
ReportSize (1), /*一个按键值*/
ReportCount (8),
Input (0x02), /*这个按键值只有为控制键才用,即时ctrl等键值*/
ReportCount (1), /*一个按键值*/
ReportSize (8),
Input (0x01), /*;Reserved byte*/
ReportCount (6), /*6个按键值*/
ReportSize (8),
Logical_Minimum (0),
Logical_Maximum(101),
UsagePage (0x07),
Usage_Minimum (0),
Usage_Maximum (101),
Input (0x00),
End_Collection,
};
上面就是我的hid keyboard的report,大概意思是说第一个值我们关不了,就为0,第二个值也不是为我们准备的,只有最后6个值,才是我们向host回复的按键值,如果想知道为什么,就看看协议吧,还是很好的。
Byte 0 00000000b
Byte 1 00000000b
Byte 2 04h
Byte 3 3Ah
Byte 4 5Dh
Byte 5 00h
Byte 6 00h
Byte 7 00h
unsigned char key_press_value[8] = {
[0] = 0x00,
[1] = 0x00,
[2] = 0x04, /*这个数据就是a ,至于为什么是a,请查一下键盘转换表*/
[3] = 0x00,
[4] = 0x00,
[5] = 0x00,
[6] = 0x00,
[7] = 0x00,
};
unsigned char key_release_value[8] = {
[0] = 0x00,
[1] = 0x00,
[2] = 0x00,
[3] = 0x00,
[4] = 0x00,
[5] = 0x00,
[6] = 0x00,
[7] = 0x00,
};
void UpdateKeyValue()
{
static int pressed = 1;
int buf[8];
if(pressed)
{
buf = key_press_value;
pressed = 0;
}
else
{
buf = key_release_value;
pressed = 1;
}
Linux_usb_txtr_start (buf, sizeof(buf));
}
好了,就这些了,这里还有网页,http://archive.cnblogs.com/a/1757694/,很好的哦!