[原创] 当BLE遇上MEMS——HID报告描述符介绍

lb8820265   2020-9-13 19:13 楼主

HID(human interface device)也就是人机接口设备,我们常见的鼠标键盘游戏手柄等都是HID,操作系统自带HID驱动的,有USB接口的,也有蓝牙接口的,都是相似的通信协议。因此这里参考USB接口的HID协议进行介绍。主要参考https://www.usb.org/hid网站中的两篇文档《Device Class Definition for HID 1.11 》《HID Usage Tables 1.2 》,可以直接在官网下载,也可以从本文附件中下载。

1.png

HID有自己协议,叫做报告描述符,用来描述发送的数据代表的含义(并不是发送的数据),包括是什么设备:鼠标、键盘、手柄等,和每一字节的含义。下面以键盘的报告描述符为例具体介绍。

参考例程:

nRF5_SDK_15.3.0_59ac345\examples\ble_peripheral\ble_app_hids_keyboard

main.c函数中的报告描述符如下表。

报告描述符

简介

0x05, 0x01, // Usage Pg (Generic Desktop)

这是一个global类Usage Page作用数据

0x09, 0x06, // Usage (Keyboard)

表示这是一个键盘

0xA1, 0x01, // Collection: (Application)

表示下面所包含的是对键盘的解释

0x05, 0x07, // Usage Pg (Key Codes)

定义的是按键码

0x19, 0xE0, // Usage Min (224)

0x29, 0xE7, // Usage Max (231)

按键码分别是 224~231,共总有 8 个按键码

0x15, 0x00, // Log Min (0)

0x25, 0x01, // Log Max (1)

按键码的值是 0 和 1,分别代表放开和按下

0x75, 0x01, // Report Size (1)

0x95, 0x08, // Report Count (8)

用 8 个 bit 分别表示 8 个按键的状态

0x81, 0x02, // Input: (Data, Variable,Absolute)

将这 8 个 bit 添加到本报告中

0x95, 0x01, // Report Count (1)

0x75, 0x08, // Report Size (8)

0x81, 0x01, // Input: (Constant)

另外再预留 8 个 bit 备用,暂时没用

0x95, 0x05, // Report Count (5)

0x75, 0x01, // Report Size (1)

定义 5 个 1bit

0x05, 0x08, // Usage Pg (LEDs)

这是 LED

0x19, 0x01, // Usage Min (1)

0x29, 0x05, // Usage Max (5)

5 个 bit 分别对应 LED1~LED5

0x91, 0x02, // Output: (Data, Variable,Absolute)

将这 5 个 bit 添加到本报告中,LED 需要作为 OUT

0x95, 0x01, // Report Count (1)

0x75, 0x03, // Report Size (3)

0x91, 0x01, // Output: (Constant)

再增加 3 个 bit,与上面 5 个 bit 组成一个字节

0x95, 0x06, // Report Count (6)

0x75, 0x08, // Report Size (8)

定义 6 个字节

0x15, 0x00, // Log Min (0)

0x25, 0x65, // Log Max (101)

每个字节的取值范围是 0~101

0x05, 0x07, // Usage Pg (Key Codes)

这个也是键盘码

0x19, 0x00, // Usage Min (0)

0x29, 0x65, // Usage Max (101)

分别是键盘码 0~键盘码 101

0x81, 0x00, // Input: (Data, Array)

将这 6 个字节添加到本报告中,表示同时可产生 6 个键值。

0xC0, // End Collection

结束

表中左边每一列由一个或者两个数字组成,第一个数字是前缀,第二个是数据(可无)

例如:0x05, 0x01, // USAGE_PAGE (Generic Desktop)

0x05表示前缀,0x01为数据部分,先看前缀,0x05转换成二进制,就是00000101,按照HID类协议的定义,这个字节被分成3个部分:(参考hid1_11.pdf

2.png bit0~bit1代表的是这个前缀后面跟的数据长度,两位可以表示最大4字节的数据,即bsize

bit2~bit3代表的是这个前缀的类型,总共可以有三种类型:00=main,01=global,10=local,11=reserved;

bit4~bit7代表前缀的tag,这里根据bit2~bit3的不同类型有不同的定义,例如global类型下的定义如下图。(参考hid1_11.pdf

3.png 0000就表示Usage Page。所以前缀0x05代表的含义就是:一个global类型Usage Page作用数据量为1的前缀。

那我们做一个练习题:第二行出现的0x09,二进制就是:00001001,这就是local类型Usage Page作用数据量为1的前缀(local类型具体可以查看hid1_11.pdf的Local Items章节)。

下面来看数据0x01的作用

前缀是global类型Usage Page作用,那么这就要查看Usage Page作用的具体介绍。(参考hut1_2.pdf)

6.png 0x01表示Generic Desktop,表示桌面控制类型的设备,但具体是什么设备就要看第二行。

前面介绍了第二行0x09表示local类型Usage Page作用,参数为0x06,0x06表示键盘,查表如下。

5.png 这里主要就是介绍报告描述符的查阅方法,其他的描述符同样可以按照上述方法进行查阅。

键盘描述符的后定义的是发送数据的类型与格式。如下:

7.png 翻译出来就是,该协议支持一次最多发送6个按钮(键值0~101),支持最多同时按下8个功能按键(键值224~231)。键值表详见附件。

举例

例如我想要发送向上按钮,查表得出向上的键值是0x52(82),所以发送的8Byte数据为。

Byte0

Byte1

Byte2

Byte3

Byte4

Byte5

Byte6

Byte7

0x00

0x00

0x52

0x00

0x00

0x00

0x00

0x00

例如我想发送Ctrl+A,查表得出左Ctrl的键值为0xE0(224),也就是第一字节的第一位为1,A的键值为4。所以发送的8Byte数据为。

Byte0

Byte1

Byte2

Byte3

Byte4

Byte5

Byte6

Byte7

0x80

0x00

0x04

0x00

0x00

0x00

0x00

0x00

本帖最后由 lb8820265 于 2020-9-13 19:13 编辑
QQ:252669569

回复评论 (1)

来学习的,蓝牙+鼠键的应用真的不错

点赞  2020-9-15 09:13
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复