当前文档版本为 v1.2.0,您可以访问当前页面的 开发中 版本以获取最近可能的更新。

USB 通信协议(键鼠方案)

1 设备描述

多模键鼠方案自定义了一个 USB 通信协议,当使用此功能时,设备被初始化为多接口设备。

1.1 USB描述符

device_des

  • interface0作为标准键盘通信接口,ep1 in作为标准键盘上报通道

  • interface1作为复合通信接口,通过report ID区分,ep2 in作为通信上报通道,ep2 out作为通信输出通道

    • ep2最大支持64B, 键盘鼠标vendor对应不同的report ID,vendor消息通信格式如下

      ana_inout

设备描述符

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
0x01 app

上报当前运行固件信息,从机上报 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
ex:首包block num0x0000,在收到5包后进行上报

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,
PHY,
Modulation_Index

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
Range: 0x00 to 0x27.
Frequency Range: 2402 MHz to 2480 MHz.

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,
Test_Data_Length,
Packet_Payload,
PHY

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
Range: 0x00 to 0x27.
Frequency Range: 2402 MHz to 2480 MHz.

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,
Num_Packets

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
Units: dBm

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,
Tx_Power

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
Range: 0x00 to 0x27.
Frequency Range: 2402 MHz to 2480 MHz.

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 le_test_end or reset command received.

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地址

emi确认版本命令

37 EMI CHECK VERSION

report id(1B)

dfu transfer cmd(1B)

version Major(1B)

version Minor(1B)

version Revision(2B)

version Build Num(4B)

0x0a

0x37

EMI CHECK VERSION REPLY

report id(1B)

dfu transfer cmd(1B)

status(1B)

0x0a

0x37

0x00: success 0x01: fail

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
0x01:usb reset
0x02:usb revert

连接成功,从机ep2上报

report id(1B)

cmd(1B)

cmd(1B)

err code(1B)

0x0a

0x53

0x00:reboot
0x01:usb reset
0x02:usb revert

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
1k MS DG:0x10;4k MS DG:0x11;1k KB DG:0x12;
1k MS DG 2(2628):0x20;1k KB DG2(2628):0x21;

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

读取设备版本信息流程

  1. 发送USB Connect尝试找寻到可以回复的设备

  2. 发送USB Device Info获取设备类型(ZDK1.1.0之后支持)

  3. 发送2.3 EP1 Control消息预留备用,用于可能设置的鼠标状态

  4. 发送Get Version获取app + controller 版本信息

  5. 发送2.3 EP1 Control消息预留备用,用于可能设置的鼠标状态

升级流程

强制升级代表进入boot内一步升级,1.1.0之后版本有条件扩充了部分消息,部分消息可以选择裁剪

  1. 发送USB Connect尝试找寻到可以回复的设备

  2. 发送USB Connect尝试找寻到可以回复的设备(兼容2628检测进入boot状态)

  3. 需要进入boot内进行强制升级,如果勾选了强制升级或者加载了imaged.bin 发送DFU Force Upgrade进入boot(通过flash flag使芯片reboot后留在boot区域)

  4. 发送USB Connect等待进入强制升级完成

  5. 发送check Version,通信芯片端下载地址,版本信息,固件大小,crc信息;等待下位机回复确认

  6. 发送USB DFU Transfer ,每发送4~5包组成到256B后等待芯片端写入后回复

  7. 发送DFU Finish收取2条消息:发送消息被收到;芯片主动上报校验确认结果

  8. 发送DFU End,可以控制芯片是否重启,默认重启

  9. (可选)发送USB Connect;发送Get Version;检查升级后版本信息更新

  10. 发送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 及之后版本)

  1. 发送USB Connect尝试找寻到可以回复的设备

  2. 发送DFU Force Upgrade HS USB Device,通知HS USB Device进入兼容此协议升级的状态

  3. 发送check Version,通信芯片端下载地址,版本信息(reserved),固件大小,crc信息;等待下位机回复确认

  4. 发送USB DFU Transfer ,每发送4~5包组成到256B后等待芯片端写入后回复

  5. 发送DFU Finish收取2条消息:发送消息被收到;芯片主动上报校验确认结果

  6. 发送DFU End,可以控制HS USB Device芯片是否重启,默认重启

  7. (暂时不需要做)发送DFU Force Upgrade HS USB Device(disabled),通知HS USB Device退出兼容此协议升级的状态