USB 通信协议(键鼠方案)¶
1 设备描述¶
多模键鼠方案自定义了一个 USB 通信协议,当使用此功能时,设备被初始化为多接口设备。
1.1 USB描述符¶
interface0作为标准键盘通信接口,ep1 in作为标准键盘上报通道
interface1作为复合通信接口,通过report ID区分,ep2 in作为通信上报通道,ep2 out作为通信输出通道
ep2最大支持64B, 键盘鼠标vendor对应不同的report ID,vendor消息通信格式如下
设备描述符¶
uint8_t DeviceDscDat[] = {
0x12, /* bLength; */
0x01, /* bDescriptorType; */
0x00, 0x02, /* bcdUSB; */
0x00, /* bDeviceClass; */
0x00, /* bDeviceSubClass; */
0x00, /* bDeviceProtocol; */
0x40, /* bMaxPacketSize0; */
0x6d, 0x04, /* idVendor; */
0x77, 0xc0, /* idProduct; */
0x00, 0x01, /* bcdDevice; */
0x01, /* iManufacturer; */
0x02, /* iProduct; */
0x03, /* iSerialNumber; */
0x01 /* bNumConfigurations; */
};
控制描述符¶
控制描述符只有一个,内容包含了双接口描述符,每个接口描述符子集具有hid描述符,每个hid描述符指定了端点,通过不同的hid report描述符进行对应描述
const uint8_t ConfigDscDat[] = {
/* ============== CONFIGURATION 1 =========== */
/* Configuration 1 descriptor */
0x09, /* CbLength */
0x02, /* CbDescriptorType */
66, /* 66 remove ep3 */
0x00,
0x02, /* CbNumInterfaces remove ep3 */
0x01, /* CbConfigurationValue */
0x00, /* CiConfiguration */
0xA0, /* CbmAttributes Bus powered */
0xF8, /* CMaxPower: 100mA */
/* ============== interface 0 =============== */
/* Interfac Descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID code */
0x01, /* bInterfaceSubclass */
0x02, /* 0: None, 1: keyboad, 2: mouse */
0x00, /* iInterface */
/* HID Descriptor */
0x09, /* bLength */
0x21, /* bDescriptor type - HID Descriptor */
USB_WBVAL(0x111), /* bcdHIDH */
0x00, /* bCountryCode */
0x01, /* bNumDescriptors */
0x22, /* bDescriptorType */
USB_WBVAL(sizeof(standard_keyboard_report)), /* wItemLengthH */
/* Endpoint 1 descriptor */
0x07, /* bLength */
0x05, /* bDescriptorType Endpoint */
0x81, /* bEndpointAddress EP 02 - IN */
0x03, /* bmAttributes INT */
USB_WBVAL(0x40), /* wMaxPacketSize */
0x01, /* bInterval 1 ms */
/* ============== interface 1 =============== */
/* Interface Descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x01, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x02, /* bNumEndpoints remove ep3 */
0x03, /* bInterfaceClass: HID code */
0x01, /* bInterfaceSubclass */
0x01, /* 0: None, 1: keyboad, 2: mouse */
0x00, /* iInterface */
/* HID Descriptor */
0x09, /* bLength */
0x21, /* bDescriptor type - HID Descriptor */
USB_WBVAL(0x111), /* bcdHID */
0x00, /* bCountryCode */
0x01, /* bNumDescriptors */
0x22, /* bDescriptorType */
USB_WBVAL(sizeof(keyboard_report)), /* wItemLengthH */
/* Endpoint descriptor */
0x07, /* bLength */
0x05, /* bDescriptorType Endpoint */
0x82, /* bEndpointAddress EP 02 - IN */
0x03, /* bmAttributes INT */
USB_WBVAL(0x40), /* wMaxPacketSize */
0x01, /* bInterval 1 ms */
/* Endpoint descriptor remove ep3 */
0x07, /* bLength */
0x05, /* bDescriptorType Endpoint */
0x02, /* bEndpointAddress EP 02 - OUT */
0x03, /* bmAttributes INT */
USB_WBVAL(0x40), /* wMaxPacketSize */
0x01, /* bInterval 1 ms */
};
报告描述符¶
标准键盘描述符+自定义键鼠报告描述符(包含键盘,鼠标,自定义 report ID消息)
uint8_t standard_keyboard_report[] = {
0x05, 0x01, /* 0 GLOBAL_USAGE_PAGE(Generic Desktop Controls) */
0x09, 0x06, /* 2 LOCAL_USAGE(Keyboard) */
0xA1, 0x01, /* 4 MAIN_COLLECTION(Applicatior) */
0x05, 0x07, /* 6 GLOBAL_USAGE_PAGE(Keyboard/Keypad) */
0x19, 0xE0, /* 8 LOCAL_USAGE_MINIMUM(224) */
0x29, 0xE7, /* 10 LOCAL_USAGE_MAXIMUM(231) */
0x15, 0x00, /* 12 GLOBAL_LOGICAL_MINIMUM(0) */
0x25, 0x01, /* 14 GLOBAL_LOCAL_MAXIMUM(1) */
0x75, 0x01, /* 16 GLOBAL_REPORT_SIZE(1) */
0x95, 0x08, /* 18 GLOBAL_REPORT_COUNT(8) */
0x81, 0x02, /* 20 MAIN_INPUT(data var absolute NoWrap linear PreferredState NoNullPosition NonVolatile ) Input 1.0 */
0x95, 0x01, /* 22 GLOBAL_REPORT_COUNT(1) */
0x75, 0x08, /* 24 GLOBAL_REPORT_SIZE(8) */
0x81, 0x03, /* 26 MAIN_INPUT(const var absolute NoWrap linear PreferredState NoNullPosition NonVolatile ) Input 2.0 */
0x95, 0x05, /* 28 GLOBAL_REPORT_COUNT(5) */
0x75, 0x01, /* 30 GLOBAL_REPORT_SIZE(1) */
0x05, 0x08, /* 32 GLOBAL_USAGE_PAGE(LEDs) */
0x19, 0x01, /* 34 LOCAL_USAGE_MINIMUM(1) */
0x29, 0x05, /* 36 LOCAL_USAGE_MAXIMUM(5) */
0x91, 0x02, /* 38 MAIN_OUTPUT(data var absolute NoWrap linear PreferredState NoNullPosition NonVolatile ) Output 0.5 */
0x95, 0x01, /* 40 GLOBAL_REPORT_COUNT(1) */
0x75, 0x03, /* 42 GLOBAL_REPORT_SIZE(3) */
0x91, 0x03, /* 44 MAIN_OUTPUT(const var absolute NoWrap linear PreferredState NoNullPosition NonVolatile )Output 1.0 */
0x95, 0x06, /* 46 GLOBAL_REPORT_COUNT(6) */
0x75, 0x08, /* 48 GLOBAL_REPORT_SIZE(8) */
0x15, 0x00, /* 50 GLOBAL_LOGICAL_MINIMUM(0) */
0x25, 0xFF, /* 52 GLOBAL_LOCAL_MAXIMUM(255) */
0x05, 0x07, /* 54 GLOBAL_USAGE_PAGE(Keyboard/Keypad) */
0x19, 0x00, /* 56 LOCAL_USAGE_MINIMUM(0) */
0x29, 0x65, /* 58 LOCAL_USAGE_MAXIMUM(101) */
0x81, 0x00, /* 60 MAIN_INPUT(data array absolute NoWrap linear PreferredState NoNullPosition NonVolatile )Input 8.0 */
0xC0, /* 62 MAIN_COLLECTION_END */
};
uint8_t keyboard_report[] = {
/* bit key */
0x05, 0x01, /* 0 GLOBAL_USAGE_PAGE(Generic Desktop Controls) */
0x09, 0x06, /* 2 LOCAL_USAGE(Keyboard) */
0xA1, 0x01, /* 4 MAIN_COLLECTION(Applicatior) */
0x85, 0x02, /* 6 GLOBAL_REPORT_ID(2) */
0x75, 0x01, /* 8 GLOBAL_REPORT_SIZE(1) */
0x95, 0x08, /* 10 GLOBAL_REPORT_COUNT(8) */
0x05, 0x07, /* 12 GLOBAL_USAGE_PAGE(Keyboard/Keypad) */
0x95, 0x78, /* 14 GLOBAL_REPORT_COUNT(120) */
0x75, 0x01, /* 16 GLOBAL_REPORT_SIZE(1) */
0x15, 0x00, /* 18 GLOBAL_LOGICAL_MINIMUM(0) */
0x25, 0x01, /* 20 GLOBAL_LOCAL_MAXIMUM(1) */
0x05, 0x07, /* 22 GLOBAL_USAGE_PAGE(Keyboard/Keypad) */
0x19, 0x00, /* 24 LOCAL_USAGE_MINIMUM(0) */
0x29, 0x78, /* 26 LOCAL_USAGE_MAXIMUM(120) */
0x81, 0x02, /* 28 MAIN_INPUT(data var absolute NoWrap linear PreferredState NoNullPosition NonVolatile ) Input 15.0 */
0xC0, /* 30 MAIN_COLLECTION_END */
/* media key */
0x05, 0x0C, /* 31 GLOBAL_USAGE_PAGE(Consumer) */
0x09, 0x01, /* 33 LOCAL_USAGE( Consumer Control ) */
0xA1, 0x01, /* 35 MAIN_COLLECTION(Applicatior) */
0x85, 0x03, /* 37 GLOBAL_REPORT_ID(3) */
0x19, 0x00, /* 39 LOCAL_USAGE_MINIMUM(0) */
0x2A, 0x00, 0x04, /* 41 LOCAL_USAGE_MAXIMUM(1024) */
0x15, 0x00, /* 44 GLOBAL_LOGICAL_MINIMUM(0) */
0x26, 0x00, 0x04, /* 46 GLOBAL_LOCAL_MAXIMUM(1024) */
0x95, 0x01, /* 49 GLOBAL_REPORT_COUNT(1) */
0x75, 0x10, /* 51 GLOBAL_REPORT_SIZE(16) */
0x81, 0x00, /* 53 MAIN_INPUT(data array absolute NoWrap linear PreferredState NoNullPosition NonVolatile )Input 17.0 */
0xC0, /* 55 MAIN_COLLECTION_END */
/* power key */
0x05, 0x01, /* 56 GLOBAL_USAGE_PAGE(Generic Desktop Controls) */
0x09, 0x80, /* 58 LOCAL_USAGE() */
0xA1, 0x01, /* 60 MAIN_COLLECTION(Applicatior) */
0x85, 0x04, /* 62 GLOBAL_REPORT_ID(4) */
0x05, 0x01, /* 64 GLOBAL_USAGE_PAGE(Generic Desktop Controls) */
0x19, 0x81, /* 66 LOCAL_USAGE_MINIMUM(129) */
0x29, 0x83, /* 68 LOCAL_USAGE_MAXIMUM(131) */
0x15, 0x00, /* 70 GLOBAL_LOGICAL_MINIMUM(0) */
0x25, 0x01, /* 72 GLOBAL_LOCAL_MAXIMUM(1) */
0x95, 0x03, /* 74 GLOBAL_REPORT_COUNT(3) */
0x75, 0x01, /* 76 GLOBAL_REPORT_SIZE(1) */
0x81, 0x02, /* 78 MAIN_INPUT(data var absolute NoWrap linear PreferredState NoNullPosition NonVolatile )Input 17.3*/
0x95, 0x01, /* 80 GLOBAL_REPORT_COUNT(1) */
0x75, 0x05, /* 82 GLOBAL_REPORT_SIZE(5) */
0x81, 0x01, /* 84 MAIN_INPUT(const array absolute NoWrap linear PreferredState NoNullPosition NonVolatile )Input 18.0*/
0xC0, /* 86 MAIN_COLLECTION_END */
/* mouse */
0x05, 0x01, /* 87 GLOBAL_USAGE_PAGE(Generic Desktop Controls) */
0x09, 0x02, /* 89 LOCAL_USAGE(Mouse) */
0xA1, 0x01, /* 91 MAIN_COLLECTION(Applicatior) */
0x85, 0x05, /* 93 GLOBAL_REPORT_ID(5) */
0x09, 0x01, /* 95 LOCAL_USAGE(Pointer) */
0xA1, 0x00, /* 97 MAIN_COLLECTION(Physical) */
0x05, 0x09, /* 99 GLOBAL_USAGE_PAGE(Button) */
0x15, 0x00, /* 101 GLOBAL_LOGICAL_MINIMUM(0) */
0x25, 0x01, /* 103 GLOBAL_LOCAL_MAXIMUM(1) */
0x19, 0x01, /* 105 LOCAL_USAGE_MINIMUM(1) */
0x29, 0x05, /* 107 LOCAL_USAGE_MAXIMUM(5) */
0x75, 0x01, /* 109 GLOBAL_REPORT_SIZE(1) */
0x95, 0x05, /* 111 GLOBAL_REPORT_COUNT(5) */
0x81, 0x02, /* 113 MAIN_INPUT(data var absolute NoWrap linear PreferredState NoNullPosition NonVolatile )Input 18.5*/
0x95, 0x03, /* 115 GLOBAL_REPORT_COUNT(3) */
0x81, 0x01, /* 117 MAIN_INPUT(const array absolute NoWrap linear PreferredState NoNullPosition NonVolatile )Input 19.0*/
0x05, 0x01, /* 119 GLOBAL_USAGE_PAGE(Generic Desktop Controls) */
0x16, 0x00, 0x80, /* 121 GLOBAL_LOGICAL_MINIMUM(32768) */
0x26, 0xFF, 0x7F, /* 124 GLOBAL_LOCAL_MAXIMUM(32767/32767) */
0x09, 0x30, /* 127 LOCAL_USAGE(X) */
0x09, 0x31, /* 129 LOCAL_USAGE(Y) */
0x75, 0x10, /* 131 GLOBAL_REPORT_SIZE(16) */
0x95, 0x02, /* 133 GLOBAL_REPORT_COUNT(2) */
0x81, 0x06, /* 135 MAIN_INPUT(data var relative NoWrap linear PreferredState NoNullPosition NonVolatile )Input 23.0*/
0x15, 0x81, /* 137 GLOBAL_LOGICAL_MINIMUM(-127) */
0x25, 0x7F, /* 139 GLOBAL_LOCAL_MAXIMUM(127) */
0x09, 0x38, /* 141 LOCAL_USAGE(Wheel) */
0x75, 0x08, /* 143 GLOBAL_REPORT_SIZE(8) */
0x95, 0x01, /* 145 GLOBAL_REPORT_COUNT(1) */
0x81, 0x06, /* 147 MAIN_INPUT(data var relative NoWrap linear PreferredState NoNullPosition NonVolatile )Input 24.0*/
0x05, 0x0C, /* 149 GLOBAL_USAGE_PAGE(Consumer) */
0x0A, 0x38, 0x02, /* 151 LOCAL_USAGE( AC Pan ) */
0x95, 0x01, /* 154 GLOBAL_REPORT_COUNT(1) */
0x81, 0x06, /* 156 MAIN_INPUT(data var relative NoWrap linear PreferredState NoNullPosition NonVolatile )Input 25.0*/
0xC0, /* 158 MAIN_COLLECTION_END */
0xC0, /* 159 MAIN_COLLECTION_END */
/* vendor */
0x06, 0x55, 0xFF, /* 160 GLOBAL_USAGE_PAGE(Reserved or Other) */
0x0A, 0x02, 0x02, /* 163 LOCAL_USAGE() */
0xA1, 0x01, /* 166 MAIN_COLLECTION(Applicatior) */
0x85, 0x06, /* 168 GLOBAL_REPORT_ID(6) */
0x75, 0x08, /* 170 GLOBAL_REPORT_SIZE(8) */
0x95, 0x3F, /* 172 GLOBAL_REPORT_COUNT(63) */
0x15, 0x00, /* 174 GLOBAL_LOGICAL_MINIMUM(0) */
0x26, 0xFF, 0x00, /* 176 GLOBAL_LOCAL_MAXIMUM(255/255) */
0x09, 0x02, /* 179 LOCAL_USAGE() */
0x81, 0x00, /* 181 MAIN_INPUT(NoWrap linear PreferredState NoNullPosition NonVolatile )Input 88.0*/
0x09, 0x02, /* 183 LOCAL_USAGE() */
0x91, 0x00, /* 185 MAIN_OUTPUT(NoWrap linear PreferredState NoNullPosition NonVolatile )Output 63.0*/
0xC0, /* 187 MAIN_COLLECTION_END */
0x06, 0x00, 0xff, /* 188 USAGE_PAGE (Generic Desktop) */
0x09, 0x01, /* 191 USAGE (Vendor Usage 1) */
0xa1, 0x00, /* 193 COLLECTION (Physical) */
0x85, 0x0a, /* 195 GLOBAL_REPORT_ID(a) */
0x15, 0x00, /* 197 LOGICAL_MINIMUM (0) */
0x25, 0xff, /* 199 LOGICAL_MAXIMUM (255) */
0x75, 0x08, /* 201 REPORT_SIZE (8) */
0x95, 0x3F, /* 203 REPORT_COUNT (63) */
0x09, 0x01, /* 205 USAGE (Vendor Usage 1) */
0x81, 0x02, /* 207 INPUT (Data,Var,Abs) */
0x09, 0x01, /* 209 USAGE (Vendor Usage 1) */
0x91, 0x02, /* 211 OUTPUT (Data,Var,Abs) */
0xc0 /* 213 END_COLLECTION */
};
2 通信协议(0x0a)¶
2.1 USB DFU Control(0x0x)¶
DFU Control包括升级流程中,控制流程的实现,但不包括数据传输的cmd
DFU Control cmd最高4bit位为0x0
2.1.1 00 Get Version¶
查询当前运行固件信息,主机ep发送
report id(1B) |
dfu control cmd(1B) |
version area(1B) |
---|---|---|
0x0a |
0x00 |
0x00 controller |
上报当前运行固件信息,从机上报 len 11
report id(1B) |
dfu control cmd(1B) |
version area(1B) |
version Major(1B) |
version Minor(1B) |
version Revision(2B) |
version Build Num(4B) |
---|---|---|---|---|---|---|
0x0a |
0x00 |
0x00 controller 0x01 app |
扩展读取透传HS USB设备固件信息
查询当前运行固件信息,主机ep发送
report id(1B) |
dfu control cmd(1B) |
version area(1B) |
---|---|---|
0x0a |
0x00 |
0x02 HS USB Device |
上报当前运行固件信息,从机上报 len 11
report id(1B) |
dfu control cmd(1B) |
version area(1B) |
reserved(8B) |
---|---|---|---|
0x0a |
0x00 |
0x02 HS USB Device |
后续自定义解析信息格式 |
2.1.2 01 Check Version¶
发送确认待升级固件信息,从机ep发送
report id(1B) |
dfu control cmd(1B) |
start addr(4B) |
version Major(1B) |
version Minor(1B) |
version Revision(2B) |
version Build Num(4B) |
image size(4B) |
crc(4B) |
---|---|---|---|---|---|---|---|---|
0x0a |
0x01 |
固件img解析出的下载地址 |
image size hex |
上位机运算整个image的crc32信息 |
从机收取待升级固件信息,检查版本兼容性(待升级固件是否可以在程序中升级),检查固件大小,存储crc信息
确认后通过ep2上报确认信息 len 4
report id(1B) |
dfu control cmd(1B) |
status(1B) |
version area(1B) |
---|---|---|---|
0x0a |
0x01 |
0x00: success else: fail reason |
0x00 controller 0x01 app |
PS: image 头部信息存储格式如下,对应bin文件首地址开始ih_img_size
ih_ver
VERSION_PATCH 对应 iv_revision低位
VERSION_APP 对应 iv_build_num 低位
image size(4B) 对应 固件bin整体大小
struct image_version {
uint8_t iv_major;
uint8_t iv_minor;
uint16_t iv_revision;
uint32_t iv_build_num;
};
/** Image header. All fields are in little endian byte order. */
struct image_header {
uint32_t ih_magic;
uint32_t ih_load_addr;
uint16_t ih_hdr_size; /* Size of image header (bytes). */
uint16_t ih_protect_tlv_size; /* Size of protected TLV area (bytes). */
uint32_t ih_img_size; /* Does not include header. */
uint32_t ih_flags; /* IMAGE_F_[...]. */
struct image_version ih_ver;
uint32_t _pad1;
};
扩展检查透传HS USB设备固件信息
发送确认待升级固件信息,从机ep发送
report id(1B) |
dfu control cmd(1B) |
start addr(4B) |
version reserved(8B) |
image size(4B) |
crc(4B) |
---|---|---|---|---|---|
0x0a |
0x01 |
固件img解析出的下载地址 |
预留,HS USB 暂时不需要传输版本信息 |
image size hex |
上位机运算整个image的crc32信息 |
从机收取待升级固件信息,预留检查版本兼容性(待升级固件是否可以在程序中升级),检查固件大小,存储crc信息
确认后通过ep2上报确认信息 len 4
report id(1B) |
dfu control cmd(1B) |
status(1B) |
version area(1B) |
---|---|---|---|
0x0a |
0x01 |
0x00: success else: fail reason |
0x02 HS USB Device |
2.1.3 02 DFU Start¶
Check Version成功后,主机ep发送DFU开始命令
report id(1B) |
dfu control cmd(1B) |
---|---|
0x0a |
0x02 |
从机收到 DFU start后,首先ep2回复进行消息收到确认
report id(1B) |
dfu control cmd(1B) |
---|---|
0x0a |
0x02 |
从机收到 DFU start后,开始擦除指定区域和大小的flash,擦除成功后,停止ep1的通信端点上报,ep2上报回复信息
fail reason 包含擦除失败,固件未确认等(可以扩展) len 3
report id(1B) |
dfu control cmd(1B) |
status(1B) |
---|---|---|
0x0a |
0x02 |
0x00: success else: fail reason |
2.1.4 03 DFU Finish¶
发送完所有数据后,主机ep发送传输完成命令
report id(1B) |
dfu control cmd(1B) |
---|---|
0x0a |
0x03 |
从机收到完成命令后,首先进行消息收到确认
report id(1B) |
dfu control cmd(1B) |
---|---|
0x0a |
0x03 |
之后对收到数据进行crc校验,与Check Version获取到的CRC信息进行核对,通过ep2进行上报 len 7
report id(1B) |
dfu control cmd(1B) |
status(1B) |
crc check value(4B) |
---|---|---|---|
0x0a |
0x03 |
0x00: success else: fail reason |
若主机收到失败消息,可以选择重新升级(重新点击开始升级)或者发送DFU END退出升级
2.1.5 04 DFU End¶
升级成功结束后,主机ep发送结束命令,指定是否重启进行固件搬运升级,升级失败时reboot flag置为0x01
report id(1B) |
dfu control cmd(1B) |
reboot flag(1B) |
---|---|---|
0x0a |
0x04 |
0x00: reboot 0x01: not reboot |
从机收到升级结束命令,开启鼠标正常ep1上报功能,若不需要重启,通过ep2上报回复消息 len 2
report id(1B) |
dfu control cmd(1B) |
---|---|
0x0a |
0x04 |
2.1.6 06 DFU Force Upgrade¶
主机ep发送强制升级命令
report id(1B) |
dfu control cmd(1B) |
force flag(1B) |
---|---|---|
0x0a |
0x06 |
0x00: force enable 0x01: force disable |
从机收到命令,并回复对应cmd
report id(1B) |
dfu control cmd(1B) |
---|---|
0x0a |
0x06 |
2.1.7 07 DFU Force Upgrade HS USB Device *¶
主机ep发送强制升级命令,CH32端写入flash flag并跳转到IAP区域
report id(1B) |
dfu control cmd(1B) |
force flag(1B) |
---|---|---|
0x0a |
0x07 |
0x00: force enable 0x01: force disable |
从机收到命令,并回复对应cmd
report id(1B) |
dfu control cmd(1B) |
force flag(1B) |
---|---|---|
0x0a |
0x07 |
0x00: force enable 0x01: force disable |
2.2 USB DFU Transfer(0x10)¶
DFU Transfer为数据传输的cmd
DFU Transfer cmd最高4bit位为0x1
DFU Transfer预定义一条消息,主机通过ep连续传输待升级固件
report id(1B) |
dfu transfer cmd(1B) |
data(62B) |
---|---|---|
0x0a |
0x10 |
升级数据 |
*从机收到传输消息后,暂定不回复,如果需要回复可以回复相同数据进行确认(参考客户方案)
report id(1B) |
dfu control cmd(1B) |
data(62B) |
---|---|---|
0x0a |
0x10 |
回复收到的数据 |
实际参考panlink升级,指定从机flash write单元256B,当收到的数据超过flash write单元后,ep2上报一条写成功消息通知主机继续发送
report id(1B) |
dfu control cmd(1B) |
block num(2B) |
---|---|---|
0x0a |
0x10 |
数据长度/256 |
2.3 扩展 EP1 操作消息(0x2x)¶
ep1 test cmd最高4bit位为0x2
需要手动关闭开启ep1上报功能时(暂时不确认升级过程中是否需要关闭ep1),主机通过ep发送控制消息
report id(1B) |
ep1 control cmd(1B) |
ep1 status |
---|---|---|
0x0a |
0x20 |
0x00: off 0x01: on |
从机收到消息成功控制后,通过ep2回复确认消息
report id(1B) |
ep1 control cmd(1B) |
ep1 status |
---|---|---|
0x0a |
0x20 |
0x00: off 0x01: on |
2.4 扩展 EMI 命令(0x3x)¶
emi命令为rf test时的cmd
emi cmd最高4bit位为0x3
30 蓝牙测试命令¶
report id(1B) |
dfu transfer cmd(1B) |
data(xB) |
---|---|---|
0x0a |
0x30(蓝牙测试模式) |
蓝牙测试命令 |
蓝牙测试命令细化如下
Reset Command¶
Command |
OCF |
Command Parameters |
Return Parameters |
---|---|---|---|
HCI_Reset |
0x0003 |
Status |
Sample Data:
Data Send (005) : 01 03 0C 00
Value
Description
0x01
HCI Packet: Command
0x0C03
Command_Opcode: Reset
0x00
Length of command parameters
Data Recv (007) : 04 0E 04 01 03 0C 00
Value
Description
0x04
HCI Packet: Event
0x0E
Event_Code: HCI_Command_Complete
0x04
Length of event parameters
0x01
Num_HCI_Command_Packets
0x0C03
Command_Opcode: Reset
0x00
Status: Success
LE Receiver Test Command¶
Command |
OCF |
Command Parameters |
Return Parameters |
---|---|---|---|
HCI_LE_Receiver_Test [v2] |
0x0033 |
RX_Channel, |
Status |
Description:
This command is used to start a test where the DUT receives test reference packets at a fixed interval. The tester generates the test reference packets.
Command parameters:
RX_Channel: (Size: 1 octet)
Value |
Parameter Description |
---|---|
N = 0xXX |
N = (F-2402) / 2 |
PHY: (Size: 1 octet)
Value |
Parameter Description |
---|---|
0x01 |
Receiver set to use the LE 1M PHY. |
0x02 |
Receiver set to use the LE 2M PHY. |
0x03 |
Receiver set to use the LE Coded PHY. |
Others |
Reserved for future use. |
Modulation_Index: (Size: 1 octet)
Value |
Parameter Description |
---|---|
0x00 |
Assume transmitter will have a standard modulation index. |
0x01 |
Assume transmitter will have a stable modulation index. |
Others |
Reserved for future use. |
Return parameters:
Status: (Size: 1 octet)
Value |
Parameter Description |
---|---|
0x00 |
Command succeeded. |
0x01 to 0xFF |
Command failed. |
Event(s) generated (unless masked away):
设置完成后, 将会回复一个 HCI_Command_Complete event.
Sample Data:
LE_Receiver_Test_v2:
Data Send (007) : 01 33 20 03 00 02 00
Value
Description
0x01
HCI Packet: Command
0x2033
Command_Opcode: LE_Receiver_Test_v2
0x03
Length of command parameters
0x00
RX_Channel: 2402MHz
0x02
PHY: LE 2M PHY
0x00
Modulation Index: Standard
Data Recv (007) : 04 0E 04 01 33 20 00
Value
Description
0x04
HCI Packet: Event
0x0E
Event_Code: HCI_Command_Complete
0x04
Length of event parameters
0x01
Num_HCI_Command_Packets
0x2033
Command_Opcode: LE_Receiver_Test_v2
0x00
Status: Success
LE Transmitter Test command¶
Command |
OCF |
Command Parameters |
Return Parameters |
---|---|---|---|
HCI_LE_Transmitter_Test [v2] |
0x0034 |
TX_Channel, |
Status |
Description:
This command is used to start a test where the DUT generates test reference packets at a fixed interval.
Command parameters:
TX_Channel: (Size: 1 octet)
Value |
Parameter Description |
---|---|
N = 0xXX |
N = (F-2402) / 2 |
Test_Data_Length: (Size: 1 octet)
Value |
Parameter Description |
---|---|
0x00 to 0xFF |
Length in bytes of payload data in each packet. |
Packet_Payload: (Size: 1 octet)
Value |
Parameter Description |
---|---|
0x00 |
PRBS9 sequence ‘11111111100000111101…’(in transmission order). |
0x01 |
Repeated ‘11110000’ (in transmission order) sequence. |
0x02 |
Repeated ‘10101010’ (in transmission order) sequence. |
0x03 |
PRBS15 sequence. |
0x04 |
Repeated ‘11111111’ (in transmission order) sequence. |
0x05 |
Repeated ‘00000000’ (in transmission order) sequence. |
0x06 |
Repeated ‘00001111’ (in transmission order) sequence. |
0x07 |
Repeated ‘01010101’ (in transmission order) sequence. |
Others |
Reserved for future use. |
PHY: (Size: 1 octet)
Value |
Parameter Description |
---|---|
0x01 |
Transmitter set to use the LE 1M PHY. |
0x02 |
Transmitter set to use the LE 2M PHY. |
0x03 |
Transmitter set to use the LE Coded PHY with S=8 data coding. |
0x04 |
Transmitter set to use the LE Coded PHY with S=2 data coding |
Others |
Reserved for future use. |
Return parameters:
Status: (Size: 1 octet)
Value |
Parameter Description |
---|---|
0x00 |
Command succeeded. |
0x01 to 0xFF |
Command failed. |
Event(s) generated (unless masked away):
设置完成后, 将会回复一个 HCI_Command_Complete event.
LE_Transmitter_Test_v2:
Data Send (008) : 01 34 20 04 00 FF 01 02
Value
Description
0x01
HCI Packet: Command
0x2034
Command_Opcode: LE_Transmitter_Test_v2
0x04
Length of command parameters
0x00
TX_Channel: 2402MHz
0xFF
Length_Of_Test_Data: 255 octets
0x01
Packet_Payload: Repeated ‘11110000’
0x02
PHY: LE 2M PHY
Data Recv (007) : 04 0E 04 01 34 20 00
Value
Description
0x04
HCI Packet: Event
0x0E
Event_Code: HCI_Command_Complete
0x04
Length of event parameters
0x01
Num_HCI_Command_Packets
0x2034
Command_Opcode: LE_Transmitter_Test_v2
0x00
Status: Success
LE Test End command¶
Command |
OCF |
Command Parameters |
Return Parameters |
---|---|---|---|
HCI_LE_Test_End |
0x001F |
Status, |
Description:
This command is used to stop any test which is in progress. The Num_Packets for a transmitter test shall be reported as 0x0000. The Num_Packets is an unsigned number and contains the number of received packets.
Command parameters:
None.
Return parameters:
Status: (Size: 1 octet)
Value |
Parameter Description |
---|---|
0x00 |
Command succeeded. |
0x01 to 0xFF |
Command failed. |
Num_Packets: (Size: 2 octets)
Value |
Parameter Description |
---|---|
0xXXXX |
Number of packets received. |
Event(s) generated (unless masked away):
设置完成后, 将会回复一个 HCI_Command_Complete event.
Sample Data:
Data Send (004) : 01 1F 20 00
Value
Description
0x01
HCI Packet: Command
0x201F
Command_Opcode: LE_Test_End
0x00
Length of command parameters
Data Recv (009) : 04 0E 06 01 1F 20 00 40 06
Value
Description
0x04
HCI Packet: Event
0x0E
Event_Code: HCI_Command_Complete
0x06
Length of event parameters
0x01
Num_HCI_Command_Packets
0x201F
Command_Opcode: LE_Test_End
0x00
Status: Success
0x0640
Number_Of_Packets: 1600
HCI Vendor Debug Write Tx Power Command¶
Command |
HCI_OCF_EXT |
Command Parameters |
Return Parameters |
---|---|---|---|
HCI_Vendor_Debug_Write_Tx_Power |
0x03 |
Tx_Power |
Status |
Description:
Command parameters:
Tx_Power:
Value |
Parameter Description |
---|---|
0xXX |
Range: -24 to +7 |
Return parameters:
Status:
Value |
Parameter Description |
---|---|
0x00 |
Command succeeded. |
0x01 to 0xFF |
Command failed. |
Event(s) generated (unless masked away):
设置完成后, 将会回复一个 HCI_Command_Complete event.
HCI Vendor Constant Tone Test Command¶
Command |
HCI_OCF_EXT |
Command Parameters |
Return Parameters |
---|---|---|---|
HCI_Vendor_Constant_Tone_Test [V1] |
0x0B |
TX_Channel, |
Status |
Description:
启动单音测试模式,用于debug. 两组接口支持配置频点的方式不同.
HCI_Vendor_Constant_Tone_Test [v1]: Tx_Channel 与 HCI_LE_Transmitter_Test 中的 Tx_Channel 一致, 只支持切换 BLE 支持的 Channel.
Command parameters:
TX_Channel: (Size: 1 octet)
Value |
Parameter Description |
---|---|
N = 0xXX |
N = (F-2402) / 2 |
Tx_Power: (Size: 1 octet)
Value |
Parameter Description |
---|---|
0x01 |
0dBm |
0x03 |
6dBm |
0x04 |
7dBm |
Others |
Reserved for future use. |
Return parameters:
Status: (Size: 1 octet)
Value |
Parameter Description |
---|---|
0x00 |
Command succeeded. |
0x01 to 0xFF |
Command failed. |
Event(s) generated (unless masked away):
设置完成后, 将会回复一个 HCI_Command_Complete event.
Sample Data:
HCI_Vendor_Constant_Tone_Test_v1
Data Send (006) : 01 CB FF 02 00 01
Value
Description
0x01
HCI Packet: Command
0xFFCB
Command_Opcode: HCI_VENDOR_CMD_OCF_DEBUG_CONSTANT_TONE_V1
0x02
Length of command parameters
0x00
TX_Channel: 2402MHz
0x01
Tx Power: 0 dBm
Data Recv (007) : 04 0E 04 01 CB FF 00
Value
Description
0x04
HCI Packet: Event
0x0E
Event_Code: HCI_Command_Complete
0x04
Length of event parameters
0x01
Num_HCI_Command_Packets
0xFFCB
Command_Opcode: HCI_VENDOR_CMD_OCF_DEBUG_CONSTANT_TONE_V1
0x00
Status: Success
HCI Vendor Debug LE Transmitter Parameters Command¶
Command |
HCI_OCF_EXT |
Command Parameters |
Return Parameters |
---|---|---|---|
HCI_Vendor_Debug_LE_Transmitter_Parameters |
0x11 |
Tx_Interval Packet_Count |
Status |
Description:
Command parameters:
Tx_Interval: (Size: 2 octet)
Value |
Parameter Description |
---|---|
0x0000 |
Use the default value. |
Others |
Tx interval time in us. If the value is less than the default value, it does not take effect. |
Packet_Count: (Size: 2 octet)
Value |
Parameter Description |
---|---|
0x0000 |
Transmitter will keep sending until the |
Others |
Tx packet count |
Return parameters:
Status:
Value |
Parameter Description |
---|---|
0x00 |
Command succeeded. |
0x01 to 0xFF |
Command failed. |
Event(s) generated (unless masked away):
设置完成后, 将会回复一个 HCI_Command_Complete event.
Sample Data:
Data Send (004) : 01 D1 FF 04 E8 03 E8 03
Value
Description
0x01
HCI Packet: Command
0xFFD1
Command_Opcode: HCI_VENDOR_CMD_OCF_DEBUG_LE_TRANSMITTER_PARAMS
0x04
Length of command parameters
0x03E8
Tx_Interval, 1000us
0x03E8
Packet_Count, 1000
Data Recv (007) : 04 0E 04 01 D1 FF 00
Value
Description
0x04
HCI Packet: Event
0x0E
Event_Code: HCI_Command_Complete
0x04
Length of event parameters
0x01
Num_HCI_Command_Packets
0xFFD1
Command_Opcode: HCI_VENDOR_CMD_OCF_DEBUG_LE_TRANSMITTER_PARAMS
0x00
Status: Success
31 2.4G 测试命令¶
report id(1B) |
dfu transfer cmd(1B) |
data(xB) |
---|---|---|
0x0a |
0x31(2.4g测试模式) |
2.4g测试命令(见如下命令格式) |
1、test start
上位机发送
cmd |
data |
status |
---|---|---|
0x1a |
0x01(test start) |
0x01 |
下位机回复
cmd |
data |
status |
---|---|---|
0x1a |
0x01(test start) |
0x00 |
2、tx carrier cmd
上位机发送
cmd |
freq |
tx power |
status |
---|---|---|---|
0x1b |
2byte(2402~2480)LSB |
1byte(-45~7) |
0x01 |
下位机回复
cmd |
freq |
tx power |
status |
---|---|---|---|
0x1b |
2byte(2402~2480)LSB |
1byte(-45~7) |
0x00 |
3、tx cmd
上位机发送
cmd |
freq max |
freq min |
tx power |
phy |
hop time |
tx count |
status |
---|---|---|---|---|---|---|---|
0x1c |
2byte(2402~2480)LSB |
2byte(2402~2480)LSB |
1byte(-45~7) |
1byte(1M/2M) |
1byte(0~10s)跳频间隔 |
2byte(0:一直发)LSB |
0x01(send);0x00(recv) |
下位机回复
cmd |
freq max |
freq min |
tx power |
phy |
hop time |
tx count |
status |
---|---|---|---|---|---|---|---|
0x1c |
2byte(2402~2480)LSB |
2byte(2402~2480)LSB |
1byte(-45~7) |
1byte(1M/2M) |
1byte(0~10s)跳频间隔 |
2byte(0:一直发)LSB |
0x00 |
4、rx cmd
上位机发送
cmd |
freq |
phy |
status |
---|---|---|---|
0x1d |
2byte(2402~2480)LSB |
1byte(1M/2M) |
0x01(send);0x00(recv) |
下位机回复
cmd |
freq |
phy |
status |
---|---|---|---|
0x1d |
2byte(2402~2480)LSB |
1byte(1M/2M) |
0x01(send);0x00(recv) |
5、test end
上位机发送
cmd |
data |
status |
---|---|---|
0x1a |
0x00(test end) |
0x01 |
下位机回复
cmd |
data |
status |
count |
---|---|---|---|
0x1a |
0x00(test end) |
0x00 |
2byte(rx模式才有该字段)LSB |
获取mac地址命令¶
35 GET OWN ADDR¶
report id(1B) |
dfu transfer cmd(1B) |
---|---|
0x0a |
0x35 |
REPLY OWN ADDR
report id(1B) |
dfu transfer cmd(1B) |
own mac(6B) |
---|---|---|
0x0a |
0x35 |
本设备的mac地址 |
36 GET PAIR ADDR¶
report id(1B) |
dfu transfer cmd(1B) |
---|---|
0x0a |
0x36 |
REPLY PAIR ADDR
report id(1B) |
dfu transfer cmd(1B) |
pair mac(6B) |
---|---|---|
0x0a |
0x36 |
配对设备的mac地址 |
2.5 RF回传配置命令(0x4x)¶
CONFIG命令为配置鼠标参数时的cmd,需要注意通过dongle回传的命令也是以以下cmd为导向
config cmd最高4bit位为0x4
40 RF Vendor¶
用于客户自定义拓展
report id(1B) |
cmd(1B) |
vendor data(xB)max 62B |
---|---|---|
0x0a |
0x40 |
连接成功,从机ep2上报
report id(1B) |
cmd(1B) |
vendor data(xB)max 7B |
---|---|---|
0x0a |
0x40 |
41 RF Set¶
用于属性设置
report id(1B) |
cmd(1B) |
attr(1B) |
vendor data(xB)max 61B |
---|---|---|---|
0x0a |
0x41 |
连接成功,从机ep2上报
report id(1B) |
cmd(1B) |
attr(1B) |
err code(1B) |
---|---|---|---|
0x0a |
0x41 |
success: 0x00;fail:other |
42 RF Get¶
用于属性查询
report id(1B) |
cmd(1B) |
attr(1B) |
---|---|---|
0x0a |
0x42 |
连接成功,从机ep2上报
report id(1B) |
cmd(1B) |
attr(1B) |
attr data(xB)max6B |
---|---|---|---|
0x0a |
0x42 |
43 RF Control¶
用于dongle通知主机连续进入/退出发送模式,PC连接dongle后每300ms发送一次,用来0a 43 01查询鼠标在线状态,,收到回复后不再发送,退出上位机时,发送0a 43 00 退出鼠标配置模式,鼠标关机时,dongle也会上报0a 43 00消息
report id(1B) |
cmd(1B) |
status(1B) |
---|---|---|
0x0a |
0x43 |
0x00 for disable/0x01for enable |
连接成功,从机ep2上报
report id(1B) |
cmd(1B) |
status(1B) |
---|---|---|
0x0a |
0x43 |
0x00 for disable/0x01for enable |
44 RF Report¶
用于RF模式下,RF主动上报至上位机的消息,当有些配置信息发生变化后主动上报更新
report id(1B) |
cmd(1B) |
attr(1B) |
vendor data(xB)max 13B |
---|---|---|---|
0x0a |
0x44 |
2.6 USB模式配置命令(0x5x)¶
用户需要通过Endpoint2实现类似pid,vid更新的操作时,可以参考以上DFU/EMI的消息模式,自定义消息进行通信
config cmd最高4bit位为0x4
50 CONFIG Vendor¶
用于客户自定义拓展
report id(1B) |
cmd(1B) |
vendor data(xB)max 62B |
---|---|---|
0x0a |
0x50 |
连接成功,从机ep2上报
report id(1B) |
cmd(1B) |
vendor data(xB)max 62B |
---|---|---|
0x0a |
0x50 |
51 USB Set¶
用于属性设置
report id(1B) |
cmd(1B) |
attr(1B) |
vendor data(xB)max 61B |
---|---|---|---|
0x0a |
0x51 |
连接成功,从机ep2上报
report id(1B) |
cmd(1B) |
attr(1B) |
err code(1B) |
---|---|---|---|
0x0a |
0x51 |
success: 0x00;fail:other |
根据attr的值有以下参数
00 USB SET VID¶
set vid(1B) |
data(2B) |
---|---|
0x00 |
0x04,0x6D |
01 USB SET PID¶
set vid(1B) |
data(2B) |
---|---|
0x01 |
0xC0,0x77 |
02 USB SET String Desc1¶
set String Desc1(1B) |
data(xB) max 32B String max 15 char |
---|---|
0x02 |
String Desc1 |
03 USB SET String Desc2¶
set String Desc2(1B) |
data(xB) max 32B String max 15 char |
---|---|
0x03 |
String Desc2 |
52 USB Get¶
用于属性查询
report id(1B) |
cmd(1B) |
attr(1B) |
---|---|---|
0x0a |
0x52 |
连接成功,从机ep2上报
report id(1B) |
cmd(1B) |
attr(1B) |
attr data(xB)max6B |
---|---|---|---|
0x0a |
0x52 |
53 USB Control¶
用于USB控制
report id(1B) |
cmd(1B) |
cmd(1B) |
---|---|---|
0x0a |
0x53 |
0x00:reboot |
连接成功,从机ep2上报
report id(1B) |
cmd(1B) |
cmd(1B) |
err code(1B) |
---|---|---|---|
0x0a |
0x53 |
0x00:reboot |
success: 0x00;fail:other |
54 USB PAN Vendor¶
用于主机控制
report id(1B) |
cmd(1B) |
status(1B) |
---|---|---|
0x0a |
0x54 |
0x00 for disable/0x01for enable |
连接成功,从机ep2上报
report id(1B) |
cmd(1B) |
status(1B) |
---|---|---|
0x0a |
0x54 |
0x00 for disable/0x01for enable |
55 USB Connect¶
连接命令,主机发送,确认设备已连接
report id(1B) |
cmd(1B) |
---|---|
0x0a |
0x55 |
连接成功,从机ep2上报
report id(1B) |
cmd(1B) |
reserved(4B) |
---|---|---|
0x0a |
0x55 |
for 2628 |
56 USB Device Info¶
获取设备信息命令,主机发送,获取连接设备类型
report id(1B) |
cmd(1B) |
---|---|
0x0a |
0x56 |
连接成功,从机ep2上报
report id(1B) |
cmd(1B) |
dev(1B) |
---|---|---|
0x0a |
0x56 |
1k MS:0x00;4k MS:0x01;8k USB MS:0x02;1k KB:0x03 |
57 USB Report¶
用于USB模式下,USB主动上报至上位机的消息,当有些配置信息发生变化后主动上报更新
report id(1B) |
cmd(1B) |
attr(1B) |
vendor data(xB)max 13B |
---|---|---|---|
0x0a |
0x57 |
3 应用流程简介¶
3.1 DFU¶
panchip dfu
通过工具量产烧录工具\Panchip DFU Tool
,基于上述协议,经过中断端点应用方式,进行交互升级
3.1.1 108 DFU¶
读取设备版本信息流程
发送
USB Connect
尝试找寻到可以回复的设备发送
USB Device Info
获取设备类型(ZDK1.1.0之后支持)发送
2.3 EP1 Control
消息预留备用,用于可能设置的鼠标状态发送
Get Version
获取app + controller 版本信息发送
2.3 EP1 Control
消息预留备用,用于可能设置的鼠标状态
升级流程
强制升级代表进入boot内一步升级,1.1.0之后版本有条件扩充了部分消息,部分消息可以选择裁剪
发送
USB Connect
尝试找寻到可以回复的设备发送
USB Connect
尝试找寻到可以回复的设备(兼容2628检测进入boot状态)需要进入boot内进行强制升级,如果勾选了强制升级或者加载了imaged.bin 发送
DFU Force Upgrade
进入boot(通过flash flag使芯片reboot后留在boot区域)发送
USB Connect
等待进入强制升级完成发送
check Version
,通信芯片端下载地址,版本信息,固件大小,crc信息;等待下位机回复确认发送
USB DFU Transfer
,每发送4~5包组成到256B后等待芯片端写入后回复发送
DFU Finish
收取2条消息:发送消息被收到;芯片主动上报校验确认结果发送
DFU End
,可以控制芯片是否重启,默认重启(可选)发送
USB Connect
;发送Get Version
;检查升级后版本信息更新发送
DFU Force Upgrade
擦除flash flag使芯片之后reboot不会留在boot区域
3.1.2 HS USB Device DFU¶
ZDK 1.1.0及之前版本 支持 HS USB Device DFU
芯片工具流程升级
ZDK 1.2.0及之后版本 支持 本文档定义的panchip升级HS USB Device
流程
进入透传设备升级(ZDK 1.1.0及之前版本)
发送 DFU Force Upgrade HS USB Device
使 HS USB Device
跳转进入IAP程序区,并打开配合上位机软件(非Panchip软件)完成升级流程
读取设备版本信息流程(ZDK 1.2.0 及之后版本)
根据USB Device Info
回复信息,设备类型为8k USB MS:0x02/4k MS DG:0x11
时
在Get Version
获取108 app controller版本后继续获取 HS USB Device
信息
升级流程(ZDK 1.2.0 及之后版本)
发送
USB Connect
尝试找寻到可以回复的设备发送
DFU Force Upgrade HS USB Device
,通知HS USB Device
进入兼容此协议升级的状态发送
check Version
,通信芯片端下载地址,版本信息(reserved),固件大小,crc信息;等待下位机回复确认发送
USB DFU Transfer
,每发送4~5包组成到256B后等待芯片端写入后回复发送
DFU Finish
收取2条消息:发送消息被收到;芯片主动上报校验确认结果发送
DFU End
,可以控制HS USB Device
芯片是否重启,默认重启(暂时不需要做)发送
DFU Force Upgrade HS USB Device(disabled)
,通知HS USB Device
退出兼容此协议升级的状态