蓝牙协议真的非常操蛋,好难学啊.
今天直接跳到hids_init来看.终于看到懂得了,这不是USB的描述符吗?
大致看了看,果然是啊.只不过一个有线一个无线,也是有很多设备种类,比如关于HID初始化就有这些东西.
typedef struct { ble_hids_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the HID Service. */ ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ bool is_kb; /**< TRUE if device is operating as a keyboard, FALSE if it is not. */ bool is_mouse; /**< TRUE if device is operating as a mouse, FALSE if it is not. */ uint8_t inp_rep_count; /**< Number of Input Report characteristics. */ ble_hids_inp_rep_init_t * p_inp_rep_array; /**< Information about the Input Report characteristics. */ uint8_t outp_rep_count; /**< Number of Output Report characteristics. */ ble_hids_outp_rep_init_t * p_outp_rep_array; /**< Information about the Output Report characteristics. */ uint8_t feature_rep_count; /**< Number of Feature Report characteristics. */ ble_hids_feature_rep_init_t * p_feature_rep_array; /**< Information about the Feature Report characteristics. */ ble_hids_rep_map_init_t rep_map; /**< Information nedeed for initialization of the Report Map characteristic. */ ble_hids_hid_information_t hid_information; /**< Value of the HID Information characteristic. */ uint8_t included_services_count; /**< Number of services to include in HID service. */ uint16_t * p_included_services_array; /**< Array of services to include in HID service. */ ble_srv_security_mode_t security_mode_protocol; /**< Security settings for HID service protocol attribute */ ble_srv_security_mode_t security_mode_ctrl_point; /**< Security settings for HID service Control Point attribute */ ble_srv_cccd_security_mode_t security_mode_boot_mouse_inp_rep; /**< Security settings for HID service Mouse input report attribute */ ble_srv_cccd_security_mode_t security_mode_boot_kb_inp_rep; /**< Security settings for HID service Keyboard input report attribute */ ble_srv_security_mode_t security_mode_boot_kb_outp_rep; /**< Security settings for HID service Keyboard output report attribute */ } ble_hids_init_t;
而且很好理解,is_kb就是是不是键盘,我们是鼠标所以是is_mouse = true,然后rep_map其实就是描述符的内容,把描述符赋值过去,然后执行初始化,整个过程就完成了,这估计是最简单一部了,如果有USB开发经验,看描述符不是什么难度的问题.
就是把这个hids_init_obj全部赋值好了,就初始化,看情况m_hids函数的输出.
发送函数确实也是很像USB的.
因为这里只发了INPUT_REP_MOVEMENT_INDEX,所以只有方向.跟USB不同的是,数值是0x0FFF最大,USB是0xFF最大.那按键去哪里了呢?其实也是有初始化的.
其中INPUT_REP_MOVEMENT_LEN是3,也就是刚好buffer也是3,但是INPUT_REP_BUTTONS_LEN也是3,也就是按键也要发3个字节的,为什么是3个字节,我有点懵逼.只能看看描述符.
static uint8_t rep_map_data[] = { 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x02, // Usage (Mouse) 0xA1, 0x01, // Collection (Application) // Report ID 1: Mouse buttons + scroll/pan 0x85, 0x01, // Report Id 1 0x09, 0x01, // Usage (Pointer) 0xA1, 0x00, // Collection (Physical) 0x95, 0x05, // Report Count (3) 0x75, 0x01, // Report Size (1) 0x05, 0x09, // Usage Page (Buttons) 0x19, 0x01, // Usage Minimum (01) 0x29, 0x05, // Usage Maximum (05) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x81, 0x02, // Input (Data, Variable, Absolute) 0x95, 0x01, // Report Count (1) 0x75, 0x03, // Report Size (3) 0x81, 0x01, // Input (Constant) for padding 0x75, 0x08, // Report Size (8) 0x95, 0x01, // Report Count (1) 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x38, // Usage (Wheel) 0x15, 0x81, // Logical Minimum (-127) 0x25, 0x7F, // Logical Maximum (127) 0x81, 0x06, // Input (Data, Variable, Relative) 0x05, 0x0C, // Usage Page (Consumer) 0x0A, 0x38, 0x02, // Usage (AC Pan) 0x95, 0x01, // Report Count (1) 0x81, 0x06, // Input (Data,Value,Relative,Bit Field) 0xC0, // End Collection (Physical) // Report ID 2: Mouse motion 0x85, 0x02, // Report Id 2 0x09, 0x01, // Usage (Pointer) 0xA1, 0x00, // Collection (Physical) 0x75, 0x0C, // Report Size (12) 0x95, 0x02, // Report Count (2) 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x30, // Usage (X) 0x09, 0x31, // Usage (Y) 0x16, 0x01, 0xF8, // Logical maximum (2047) 0x26, 0xFF, 0x07, // Logical minimum (-2047) 0x81, 0x06, // Input (Data, Variable, Relative) 0xC0, // End Collection (Physical) 0xC0, // End Collection (Application) // Report ID 3: Advanced buttons 0x05, 0x0C, // Usage Page (Consumer) 0x09, 0x01, // Usage (Consumer Control) 0xA1, 0x01, // Collection (Application) 0x85, 0x03, // Report Id (3) 0x15, 0x00, // Logical minimum (0) 0x25, 0x01, // Logical maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x01, // Report Count (1) 0x09, 0xCD, // Usage (Play/Pause) 0x81, 0x06, // Input (Data,Value,Relative,Bit Field) 0x0A, 0x83, 0x01, // Usage (AL Consumer Control Configuration) 0x81, 0x06, // Input (Data,Value,Relative,Bit Field) 0x09, 0xB5, // Usage (Scan Next Track) 0x81, 0x06, // Input (Data,Value,Relative,Bit Field) 0x09, 0xB6, // Usage (Scan Previous Track) 0x81, 0x06, // Input (Data,Value,Relative,Bit Field) 0x09, 0xEA, // Usage (Volume Down) 0x81, 0x06, // Input (Data,Value,Relative,Bit Field) 0x09, 0xE9, // Usage (Volume Up) 0x81, 0x06, // Input (Data,Value,Relative,Bit Field) 0x0A, 0x25, 0x02, // Usage (AC Forward) 0x81, 0x06, // Input (Data,Value,Relative,Bit Field) 0x0A, 0x24, 0x02, // Usage (AC Back) 0x81, 0x06, // Input (Data,Value,Relative,Bit Field) 0xC0 // End Collection };
鼠标坐标的报告里面,给了X,Y是正负2047啊,难怪要0xFFF,然后按键也给了3个,最主要看Usage,这鼠标有点高级,有Pan(不知道什么),Wheel(滚轮),还有5个按键.没法想象这鼠标样子了.如果结合第三个特性,还有很多多媒体功能,表示震惊了.
这估计是我最看得懂的一节了,先歇会吧.