Introduction
wikipedia 上的一段话:
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.
HID Class是USB 协议族中的一类,从字面上理解是Human interface Devices,比如常见的键盘,鼠标,通过usb 接口进行通信,其中HID 起到了描述设备按键操作的作用。
其实,HID 很多情况下也可以作为一个USB复合设备与HOST通信的补充,实现自定义的控制功能,比如在UAC 设备中,通过插入HID class,实现音频设备的与host主机的主动控制通信,弥补UAC 设备单向通信的不足。
Class Requirement
- All HID devices must have a control endpoint (Endpoint 0) and an interrupt IN endpoint. Many devices also use an interrupt OUT endpoint.
- In most cases, HID devices are not allowed to have more than one OUT and one IN endpoint.
- All data transferred must be formatted as reports whose structure is defined in the report descriptor.
HID 设备必须要支持一个Interrupt IN endpoint和一个控制节点,并且,大多数情况下不支持多于一个IN 和一个OUT节点,所有的数据以report descriptor的形式组织上报给Host
Report config Descriptor
Report config Descriptor 的组织方式:
一个典型的mouse HID report descriptor 例子,包含3个button,格式如下:
USAGE_PAGE (Button)
USAGE_MINIMUM (Button 1)
USAGE_MAXIMUM (Button 3)
LOGICAL_MINIMUM (0)
LOGICAL_MAXIMUM (1)
REPORT_COUNT (3)
REPORT_SIZE (1)
INPUT (Data,Var,Abs)
REPORT_COUNT (1)
REPORT_SIZE (5)
INPUT (Cnst,Var,Abs)
USAGE_PAGE (Generic Desktop)
USAGE (X)
USAGE (Y)
LOGICAL_MINIMUM (-127)
LOGICAL_MAXIMUM (127)
REPORT_SIZE (8)
REPORT_COUNT (2)
INPUT (Data,Var,Rel)
一个自定义HID report class的例子:
const uint8_t CustomHID_ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =
{
0x06, 0xFF, 0x00, /* USAGE_PAGE (Vendor Page: 0xFF00) */
0x09, 0x01, /* USAGE (Demo Kit) */
0xa1, 0x01, /* COLLECTION (Application) */
/* 6 */
/* Led 1 */
0x85, 0x01, /* REPORT_ID (1) */
0x09, 0x01, /* USAGE (LED 1) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01