从前面已经说的差不多了,现在开始讲描述符,如果搞过USB,会觉得非常熟悉,因为他们真的就是差不多啊.依然是看hidmouseservice.c,他的描述符如下.
// HID Report Map characteristic value
static CONST uint8 hidReportMap[] =
{
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
};
他其实是分级的,首先USAGE_PAGE (Generic Desktop)标注普通桌面页,USAGE (Mouse)指定是鼠标,比如键盘就是0x09, 0x06,这个在HID用途表都能看到(和USB一样).然后开始COLLECTION -> END_COLLECTION,里面就是其他信息,里面还可以脱掉一层Pointer的COLLECTION,说明是指针设备,物理设备.
首先这不分,按键,最小1,最大3,分别是1左键,2右键,3中键,他们只有逻辑0和1,所以MIN=0,MAX=1,每一个按键占据1bit,大小8bit,他回报的是绝对值.
注意:浪费5bit了,如果不浪费,后面还要补一些dummy bit,凑够8bit.
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
如果上面不想浪费,那么这样填充Dummy.
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
值得注意,描述符没有太多前后顺序,但是你怎么描述,最后就要怎么发送.但是你要把REPORT_SIZE和REPORT_COUNT换个位置,不会改变数据包的位置.同样USAGE_MINIMUM和USAGE_MAXIMUM换个位置,不会改变实际数据意义,一个最小的有意义的块内,顺序无关.
下一个区块,声明用途,通用桌面,然后分别3个用途,X,Y,滚轮,范围是-127~127,刚好8bit,汇报3个,即3个字节,他是相对数值.
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
不过,蓝牙不是所有服务都需要描述符,通用的比如心率计,骑行计数器,跑步计数器等,只要对应UUID发上去,他就已经知道未来这个数据,因为他约定了只有少数几个格式,可以通过Flag约束.那么基础剩余Mesh,我暂时没有2个或者更多的蓝牙开发板,只能暂时这样,我就做点小玩具,暂时还用不上Mesh.
更多蓝牙知识,就以后慢慢补充了,至少,目前最基础的已经够了.