【沁恒 CH58x 应用】利用CH582M将有线键盘改为无线键盘
兼容芯片:CH582、CH583
代码以及固件 gitee 仓库:https://gitee.com/wenlilili/ch582m-bluetoothkbd
固件在其中 obj 文件夹中的 USBhidtoBLE.hex。
代码具体思路:
1. 阅读CH582M官方例程---HID-Keyboard
【沁恒RISC-V内核 CH582】蓝牙HID键盘代码解读:http://bbs.eeworld.com.cn/thread-1198402-1-1.html
关键部分在hidkbd.c中:
uint16_t HidEmu_ProcessEvent(uint8_t task_id, uint16_t events)
{
static uint8_t send_char = 4;
/*省略其余无关部分*/
if(events & START_REPORT_EVT)
{
hidEmuSendKbdReport(send_char);//发送字符
send_char++;
if(send_char >= 29)
send_char = 4;
hidEmuSendKbdReport(0x00);
tmos_start_task(hidEmuTaskId, START_REPORT_EVT, 2000);
return (events ^ START_REPORT_EVT);
}
}
其中 send_char 是HID字符代码,如下所示:可见send_char=4 的时候,对应的字符为a
图1 HID键盘键值对应码
2. 阅读CH582M官方例程---USB_U2Host
【沁恒RISC-V内核 CH582】CH582 USB HOST 代码解读 http://bbs.eeworld.com.cn/thread-1198831-1-1.html
关键部分在 main() 函数中usb枚举和读取 usb设备数据的部分。
/* 如果设备是键盘 */
loc = U2SearchTypeDevice(DEV_TYPE_KEYBOARD); // 在ROOT-HUB以及外部HUB各端口上搜索指定类型的设备所在的端口号
if(loc != 0xFFFF)
{ // 找到了,如果有两个KeyBoard如何处理?
i = (uint8_t)(loc >> 8);
len = (uint8_t)loc;
SelectU2HubPort(len); // 选择操作指定的ROOT-HUB端口,设置当前USB速度以及被操作设备的USB地址
endp = len ? DevOnU2HubPort[len - 1].GpVar[0] : ThisUsb2Dev.GpVar[0]; // 中断端点的地址,位7用于同步标志位
if(endp & USB_ENDP_ADDR_MASK)
{ // 端点有效
s = USB2HostTransact(USB_PID_IN << 4 | endp & 0x7F, endp & 0x80 ? RB_UH_R_TOG | RB_UH_T_TOG : 0, 0); // 传输事务,获取数据,NAK不重试
if(s == ERR_SUCCESS)
{
endp ^= 0x80; // 同步标志翻转
if(len)
DevOnU2HubPort[len - 1].GpVar[0] = endp; // 保存同步标志位
else
ThisUsb2Dev.GpVar[0] = endp;
len = R8_USB2_RX_LEN; // 接收到的数据长度
if(len)
{
U2SETorOFFNumLock(RxBuffer);
PRINT("keyboard data: ");
for(i = 0; i < len; i++)//此处打印出所有接收到的 USB 键盘发送来的数据
{
PRINT("x%02X ", (uint16_t)(RxBuffer));
}
PRINT("\n");
}
}
else if(s != (USB_PID_NAK | ERR_USB_TRANSFER))
{
PRINT("keyboard error %02x\n", (uint16_t)s); // 可能是断开了
}
}
else
{
PRINT("keyboard no interrupt endpoint\n");
}
3-蓝牙HID和USB_HOST的例程结合在一起
具体思路就是:
- 键盘通过USB,向CH582M发送数据,CH582通过一个缓存(RxBuffer)接收数据;(CH582M 此时为USB主机,键盘为USB设备)
- CH582接收到键盘的数据后,通过自身的蓝牙,发送给电脑数据。
- 电脑接收到数据之后,打印出相应的字符。
实现代码可以看文章:
【沁恒RISC-V内核 CH582】CH582 有线键盘转蓝牙键盘 http://bbs.eeworld.com.cn/thread-1199038-1-1.html
关键部分是按照上面的具体思路,将缓存接收到的数据,在HID-Keyboard中调用HID设备发送报文函数:HidDev_Report(HID_RPT_ID_KEY_IN, HID_REPORT_TYPE_INPUT, HID_KEYBOARD_IN_RPT_LEN, RxBuffer);
if(events & START_REPORT_EVT)
{
if (need_send) {
HidDev_Report(HID_RPT_ID_KEY_IN, HID_REPORT_TYPE_INPUT, HID_KEYBOARD_IN_RPT_LEN, RxBuffer);//这行代码是关键
need_send = 0;
}
tmos_start_task(hidEmuTaskId, START_REPORT_EVT, 1);//提高发送频率,设置为1ms执行一次
return (events ^ START_REPORT_EVT);
}
附录:
1. 《键盘按键名称及HID扫描码及VK虚拟键码对照表》:https://blog.csdn.net/kKmaro/article/details/130256738
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
2018-12-21 learn the python the hard way习题11~17总结
2018-12-21 JavaScript 第三章总结