一.HID设备识别
前面有提到关于SCSI协议的USB设备实现。现在来谈谈USBHID设备。HID全称Human Interface Device。HID协议里增加了HID描述符和报告描述符,以及特定的关于HID的类请求。HID设备的通信是通过报表来进行的。据说,报告描述符是USB设备中最难的描述符了。关于HID描述符可以参考HID协议。接下来我们谈谈报告描述符。
二.报告描述符
每一个HID设备都有自己的报告描述符。报告描述符有三种类项目:Main类项目,Global类项目,Local类项目。具体看下表
Global作用域是遇到下一个同名Global,Local作用域是遇到下一个Main(Input,Output,Feature)。Usage Min-Max表示有几种功能,Logical Min-Max表示有几种状态。每个报告描述符都有报告ID,报告ID是用来区别复合设备的。在报告描述符里没有写报告ID,默认报告ID是0。USB的控制端点可以进行Input,Output,Feature项目的传输,
中断端点可以进行Input,Output传输。
三.鼠标和键盘的报告描述符
(1)键盘的报告描述符
0x05,0x01,// Global Generic Desktop
0x09,0x06,// Local KeyBoard
0xA1,0x01,// Main app collection
0x05,0x07,// Global KeyBoard
//第1字节
0x19,0xe0,// Local Usage Min (KeyBoard LeftControl)
0x29,0xe7,// Local Usage Max (KeyBoard Right GUI)
0x15,0x00,// Global Logical Min
0x25,0x01,// Global Logical Max
0x95,0x08,// Global ReportCount
0x75,0x01,// Global ReportSize
0x81,0x02,// Main Input(Data,Var,Abs)
//第2字节
0x95,0x01,// Global ReportCount
0x75,0x08,// Global ReportSize
0x81,0x03,// Main Input(Cnst,Var,Abs)
//第3-8字节
0x95,0x06,// Global ReportCount
0x75,0x08,// Global ReportSize
0x15,0x00,// Global Logical Min
0x26,0xff,0x00,//Global Logical Max
0x19,0x00,// Local Usage Min
0x29,0x65,// Local Usage Max
0x81,0x00,// Main Output(Data,Ary,Abs)
1字节输出报告
0x15,0x00,// Global Logical Min
0x25,0x01,// Global Logical Max
0x95,0x05,// Global ReportCount
0x75,0x01,// Global ReportSize
0x05,0x08,// Global LED
0x19,0x01,// Local Usage Min
0x29,0x05,// Local Usage Max
0x91,0x02,// Main Output(Data,Var,Abs)
补足上面变成1个字节
0x95,0x01,// Global ReportCount
0x75,0x03,// Global ReportSize
0x91,0x03,// Main Output(Cnst,Var,Abs)
0xc0 // Main End collection
键盘的描述符共有8字节的输入报告和1字节的输出报告。
8字节输入报告:第1字节特殊按键,第2字节保留常量,第3-8字节普通按键。键值可以参考USB HID to PS/2 Scan Code Translation Table.
1字节输出报告:这1个字节总共用了5bits使用3bits常量来补足成1个字节。5bits用来点亮特殊键盘上的Led灯,比如键盘的大小写,数字键,小键盘的LED灯。
如果不给键盘配置OUT端点,那么键盘的1字节输出报告将由控制端点的SetReport进行传输。
(2)鼠标描述符
0x05,0x01, // Global Generic Desktop
0x09,0x02, // Local Mouse
0xa1,0x01, // Main app collection
0x09,0x01, // Local Pointer
0xa1,0x00, // Main phy collection
0x95,0x03, // Global ReportCount
0x75,0x01, // Global ReportSize
0x05,0x09, // Global Button
0x19,0x01, // Local Usage Min
0x29,0x03, // Local Usage Max
0x15,0x00, // Global Logical Min
0x25,0x01, // Global Logical Max
0x81,0x02, // Main Input(Data,Var,Abs)
0x95,0x01, // Global ReportCount
0x75,0x05, // Global ReportSize
0x81,0x03, // Main Input(Cnsr,Var,Abs)
0x95,0x03,0x75,0x08, // Global ReportCount Global ReportSize
0x05,0x01, // Global Generic Desktip
0x09,0x30, // Local X
0x09,0x31, // Local Y
0x09,0x38, // Locak Wheel
0x15,0x81, // Global Logical Min
0x25,0x7f, // Global Logical Max
0x81,0x06, // Main Input(Data,Var,Rel)
0xc0, // Main End collection
0xc0 // Main End collection
鼠标描述符有4字节输入报告。第1个字节前3位表示左右中三键,后面3个字节分别表示X轴,Y轴,滑轮。