Skip to content

HID 通讯协议(USB 配置通道) ​

BinaryKeyboard 无线版通过 USB HID 配置通道与 Studio(WebHID)通信。本文档以当前固件实现为准,给出逐字节协议定义。

概览 ​

项目说明
配置通道帧长64B
WebHID 模式无 Report ID(reportId=0)
通道方向主机发送命令帧,设备返回响应帧
字节序以字段定义为准(协议中同时存在大端/小端字段)

除异步日志 KBD_CMD_LOG (0x70) 外,响应数据区 DATA[0] 均为状态码(kbd_resp_t)。


配置帧格式(64B) ​

主机 → 设备(命令帧) ​

对应固件 kbd_cmd_frame_t(firmware/CH592F/keyboard/include/kbd_types.h)。

偏移大小字段说明
0x001CMD命令码(kbd_cmd_t)
0x011SUB子命令/序号(层号、槽位号、宏分包序号等)
0x021LENDATA 有效长度(0~61)
0x03~0x3F61DATA请求参数

设备 → 主机(响应帧) ​

当前固件响应帧格式与命令帧一致(CMD 为原命令回显,不携带状态码)。状态码放在 DATA[0]。

偏移大小字段说明
0x001CMD原命令码回显
0x011SUB原 SUB 回显(如层号、槽位号)
0x021LENDATA 有效长度
0x03~0x3F61DATA响应数据(通常 DATA[0] 为状态码)

Studio / WebHID 对接(当前实现) ​

tools/studio/src/services/HidService.ts 使用统一封包方法:

  • sendCommand(cmd, sub, data) 构造 [CMD][SUB][LEN][DATA...]
  • sendReport(0, frame) 发送 64B
  • inputreport 回调读取 event.data.buffer(64B)
  • CMD=0x70 作为异步日志,不进入命令响应等待队列

状态码(kbd_resp_t) ​

值名称含义
0x00KBD_RESP_OK成功
0x01KBD_RESP_ERR_INVALID无效命令
0x02KBD_RESP_ERR_PARAM参数错误
0x03KBD_RESP_ERR_BUSY设备忙
0x04KBD_RESP_ERR_FLASHFlash 操作失败
0x10KBD_RESP_ERR_TOO_LARGE数据过大
0x11KBD_RESP_ERR_NO_SPACE存储空间不足
0x12KBD_RESP_ERR_NOT_FOUND未找到目标

命令码总表(当前固件) ​

分类命令码SUB 含义Studio 当前是否封装
系统SYS_INFO0x010是
系统SYS_STATUS0x020是
配置CFG_SAVE0x100是
配置CFG_LOAD0x110是
配置CFG_RESET0x120是
按键KEYMAP_GET0x20层号是
按键KEYMAP_SET0x21层号是
按键LAYER_GET0x220间接(状态获取可替代)
按键LAYER_SET0x230可扩展使用
RGBRGB_GET0x300是
RGBRGB_SET0x310是
宏MACRO_INFO0x400是
宏MACRO_GET0x410是
宏MACRO_SET0x420=擦除、1=写入是
宏MACRO_DEL0x43有效宏索引是
FNFNKEY_GET0x500是
FNFNKEY_SET0x510是
电源BATTERY0x600是
日志LOG0x70日志类别异步接收
日志LOG_GET0x710是
日志LOG_SET0x720是

字节级协议定义(当前实现) ​

说明:下文 DATA[n] 均指帧内 0x03 起始的数据区偏移。

1. SYS_INFO (0x01) ​

请求

字段值
SUB0x00
LEN0
DATA无

响应(LEN=18)

DATA 偏移大小字段说明
01status状态码
11vid_hiVID 高字节
21vid_loVID 低字节
31pid_hiPID 高字节
41pid_loPID 低字节
51version_major固件主版本
61version_minor固件次版本
71version_patch固件补丁版本
81max_layers最大层数
91max_keys单层最大键位数
101macro_count当前 MeowFS 中的有效宏数
111keyboard_type0=基础款, 1=五键款, 2=旋钮款
121actual_key_count当前键盘类型实际键位数
131fn_key_countFN 键数量
14~174reserved当前为 0

VID/PID 在该响应中采用高字节在前(大端表示)。

2. SYS_STATUS (0x02) ​

请求:SUB=0x00, LEN=0

响应(LEN=9;旧固件为 LEN=6)

DATA 偏移大小字段说明
01status状态码
11work_mode当前模式(USB/BLE/...)
21conn_state连接状态:0=断开, 1=广播中, 2=已连接, 3=挂起
31current_layer当前层
41battery_level电量(0-100)
51is_charging滤波后的充电状态(0/1)
61adc_raw_lo最近一次 ADC 原始平均值低字节
71adc_raw_hi最近一次 ADC 原始平均值高字节
81charge_pin_rawTP4054 CHRG 瞬时原始电平:0=低,1=高

3. 配置命令 CFG_SAVE / CFG_LOAD / CFG_RESET(0x10/0x11/0x12) ​

请求:SUB=0x00, LEN=0

响应(LEN=1)

DATA 偏移大小字段
01status

4. KEYMAP_GET (0x20) ​

请求

字段值
SUBlayer_index (0~4)
LEN0

响应(成功)(LEN=36)

DATA 偏移大小字段说明
01status0x00
11num_layers当前层数
21current_layer当前激活层
31default_layer默认层
4~3532layer_datakbd_layer_t(8 键 × 4B)

响应(失败)(LEN=1)

DATA[0]含义
KBD_RESP_ERR_PARAM层号超出 num_layers

layer_data(32B)=kbd_layer_t ​

每层固定 8 个按键,每键 4 字节 kbd_action_t:

偏移(层内)大小字段
01type
11modifier
21param1
31param2

第 i 个键偏移 = i * 4。

5. KEYMAP_SET (0x21) ​

请求(LEN=35)

DATA 偏移大小字段说明
01num_layers1~KBD_MAX_LAYERS
11reserved保留(Studio 当前写 0)
21default_layer默认层
3~3432layer_data目标层 kbd_layer_t

SUB = layer_index (0~4)。

响应(LEN=1)

DATA[0]含义
status成功或失败

兼容行为

当前固件对 LEN < 35 不会直接报错,仍可能返回 OK(仅打印日志)。Studio 应始终发送完整 35B。

6. LAYER_GET (0x22) ​

请求:SUB=0x00, LEN=0

响应(LEN=4)

DATA 偏移大小字段
01status
11current_layer
21num_layers
31default_layer

7. LAYER_SET (0x23) ​

请求(LEN>=1)

DATA 偏移大小字段
01target_layer

响应(LEN=2)

DATA 偏移大小字段说明
01statusOK 或 ERR_PARAM
11current_layer实际切换后的层

8. RGB_GET (0x30) ​

请求:SUB=0x00, LEN=0

响应(LEN=13)

DATA 偏移大小字段
01status
11enabled
21mode
31brightness
41speed
51color_r
61color_g
71color_b
81indicator_enabled
91indicator_brightness
101press_effect
111auto_sleep_min
121deep_sleep_min

9. RGB_SET (0x31) ​

请求(LEN=12)

DATA 偏移大小字段说明
01enabledRGB 总开关
11mode灯效模式
21brightness按键灯亮度
31speed动画速度
41color_r静态颜色 R
51color_g静态颜色 G
61color_b静态颜色 B
71indicator_enabled保留;固件始终启用状态指示灯
81indicator_brightness指示灯亮度;低于 13 时按 13 保存
91press_effect0=无、1=亮起渐灭、2=熄灭渐亮;其他值按 0 保存
101auto_sleep_minLIGHT 休眠分钟数;0=禁用
111deep_sleep_min进入 LIGHT 后到 DEEP 的分钟数;0=禁用

响应(LEN=1):DATA[0] = status

10. FNKEY_GET (0x50) ​

请求:SUB=0x00, LEN=0

响应(LEN=33)

DATA 偏移大小字段
01status
1~3232kbd_fnkey_config_t

kbd_fnkey_config_t(32B)字节布局 ​

由 4 个 kbd_fnkey_entry_t 组成,每项 8B。

单项(8B)布局:

偏移(项内)大小字段
01click_action
11click_param
21long_action
31long_param
41long_press_ms_lo
51long_press_ms_hi
61reserved0
71reserved1

第 i 个 FN 项偏移 = i * 8。

11. FNKEY_SET (0x51) ​

请求(LEN=32)

DATA 偏移大小字段
0~3132kbd_fnkey_config_t

响应(LEN=1):DATA[0] = status

12. BATTERY (0x60) ​

请求:SUB=0x00, LEN=0

响应(LEN=8;旧固件为 LEN=5)

DATA 偏移大小字段说明
01status状态码
11level电量百分比 0~100
21charging滤波后的状态:0=未充电, 1=充电中
31voltage_lo电压毫伏低字节
41voltage_hi电压毫伏高字节
51adc_raw_lo最近一次 ADC 原始平均值低字节(未应用校准偏移)
61adc_raw_hi最近一次 ADC 原始平均值高字节(未应用校准偏移)
71charge_pin_rawTP4054 CHRG 引脚瞬时原始电平:0=低,1=高

字节序

voltage_mV 和 adc_raw 在 BATTERY 响应中使用 小端序(LE)。Studio 按 LEN 判断诊断字段是否存在,仍兼容只返回前 5 字节的旧固件。

电压与电量算法

CH592 按 WCH 外部分压参考方式使用 0dB 单端 ADC:丢弃首次转换,连续采样去掉一个最大值和一个最小值,再应用 ADC 粗校准、1.05V 参考值和 100kΩ/100kΩ 分压比。周期结果使用低通滤波;超过 250mV 的突变必须由第二组采样确认。

电量由单节 LiPo 电压曲线估算。充电时先补偿 TP4054 造成的端电压抬升,普通曲线结果最高限制为 99%;只有高压区连续确认满足满电锁存条件后才显示 100%。由于硬件没有电流检测或库仑计,该百分比不是精确 SOC。CHRG=1 也只能表示 TP4054 当前没有拉低引脚,无法区分“未接入 VBUS”和“已经充电结束”。

为适配样板约 4.17~4.18V 的实测满充平台,高压区另有满电锁存:4.16V 以上连续 3 次有效采样后显示 100%,降到 4.10V 以下连续 2 次后解除。阈值之间的回差用于避免满电百分比随采样误差反复变化。

满电锁存后,CHRG 高电平稳定约 1s 即将稳定充电状态切换为“未充电”。随后 TP4054 因板载负载产生的短低电平补充充电脉冲只保留在 charge_pin_raw 中,不会重新改变稳定状态或 RGB;满电锁存解除后恢复普通的 300ms 进入、10s 退出判定。

充电末段 TP4054 可能因终止和板载负载进入短周期补充充电,CHRG 原始电平会在 0/1 间切换。固件每 100ms 采样 CHRG:连续低电平约 300ms 后进入“充电中”,连续高电平约 10s 后退出“充电中”。charging 使用该稳定状态,RGB 也以它为准;charge_pin_raw 保留瞬时电平用于诊断,因此两者在退出延迟期间可以暂时不同。

13. LOG_GET (0x71) ​

请求:SUB=0x00, LEN=0

响应(LEN=2)

DATA 偏移大小字段
01status
11enabled

14. LOG_SET (0x72) ​

请求(LEN=1)

DATA 偏移大小字段说明
01enabled0=关, 非0=开

响应(LEN=1):DATA[0] = status

15. 异步日志 LOG (0x70) ​

设备主动推送,不走命令应答队列。

帧格式

帧字段含义
CMD0x70
SUB日志类别 kbd_log_category_t
LEN日志数据长度(0~8)
DATA日志负载(无状态码前缀)

日志类别与 DATA 字节定义 ​

SUB类别DATA 字节定义
0x01KEY_EVENT[0]=key_index, [1]=pressed, [2]=action_type, [3]=param
0x02FN_EVENT[0]=fn_id, [1]=is_long, [2]=action, [3]=param
0x03LAYER_EVENT[0]=old_layer, [1]=new_layer
0x04MODE_EVENT[0]=old_mode, [1]=new_mode
0x05BLE_EVENT[0]=state
0x06RGB_EVENT[0]=mode, [1]=brightness
0x07SYSTEM_EVENT[0]=event(BOOT/SLEEP/WAKEUP)

16. MACRO_INFO (0x40) ​

请求:SUB=0x00, LEN=0

响应(LEN=8)

DATA 偏移大小字段说明
01status状态码
1~22total_sizeMeowFS 总容量,大端
3~42page_size擦除页大小,大端
51used_count有效宏数
6~72free_bytes剩余字节数,大端

17. MACRO_GET (0x41) ​

请求(SUB=0x00, LEN=3)

DATA 偏移大小字段说明
01offset_hi读取偏移高字节
11offset_lo读取偏移低字节
21req_len请求长度;固件最多读取 59 字节

响应(成功)(LEN = 2 + read_len)

DATA 偏移大小字段说明
01statusOK
11read_len实际读取长度
2..read_lenchunkMeowFS 原始数据

偏移使用高字节在前(大端表示)。读取到末尾时,固件返回的 read_len 会小于请求长度;协议没有 is_last 字段。

18. MACRO_SET (0x42) ​

固件将 Flash 操作延后到 TMOS 主循环执行,完成后再发送响应。

SUB请求用途
0DATA[0]=page擦除指定页;page=0xFF 擦除整个宏区
1offset_hi, offset_lo, len, data...从指定偏移写入原始 MeowFS 数据;每包最多 58 字节数据

offset 为大端。擦除或写入成功时响应 LEN=1,DATA[0]=OK;参数错误或 Flash 操作失败时返回相应错误码。

19. MACRO_DEL (0x43) ​

请求:SUB=有效宏索引, LEN=0

响应(LEN=1)

DATA[0]含义
status(OK 或 ERR_PARAM)删除结果

索引按 MeowFS 中的有效宏顺序编号。删除操作仅写入删除标记,不会立即回收空间;Studio 保存宏时会重建整个宏区。


Studio 当前命令调用映射(HidService) ​

Studio 方法命令请求字节响应字节(DATA)
getSysInfo()SYS_INFO无status + 17B 信息
getSysStatus()SYS_STATUS无status + 5B 状态
getKeymap(layer)KEYMAP_GETSUB=layerstatus + 3B 层头 + 32B层数据
setKeymap(...)KEYMAP_SET35Bstatus
getRgbConfig()RGB_GET无status + 12B
setRgbConfig()RGB_SET12Bstatus
getFnKeyConfig()FNKEY_GET无status + 32B
setFnKeyConfig()FNKEY_SET32Bstatus
getMacroOverview()MACRO_INFO无status + 7B MeowFS 信息
getMacroData()MACRO_INFO、MACRO_GET由 Studio 分段读取MeowFS 条目
setMacroData()MACRO_SET擦除全区后分段写入status
deleteMacro()MACRO_DELSUB=宏索引status
saveConfig()CFG_SAVE无status
loadConfig()CFG_LOAD无status
resetConfig()CFG_RESET无status
getBattery()BATTERY无status + 4B 电池信息 + 3B 原始诊断值
getLogConfig()LOG_GET无status + enabled
setLogConfig()LOG_SETenabled(1B)status

相关文档 ​