从插入USB 键盘开始抓取数据,按笔记本键盘上的按键,测试 Num 从灭到亮,再到灭;测试 Caps 从灭到亮,再到灭。其中的 SET_REPORT 有三个:
- 是刚插入的时候系统用来通知键盘,告知当前三个 LED 状态的;
- 是NUM LED 从灭到亮,再到灭的动作;
- 是CAPS LED 从灭到亮,再到灭的动作;
首先刷上之前的键盘固件,使用逻辑分析仪分析,可以看到,我们之前的设备没有处理SET_REPORT所以会用 STALL 回复:
因此,我们需要响应这个命令。下面是正常情况下,对于一个 SET_REPORT 的通讯:
此外,测试了按USB 键盘 CAPS LOCK按键,让灯从灭到亮再灭的过程。可以看出,USB 键盘通知系统当前有 CAPS LOCK按键,然后系统再通过 HID_REPORT通知当USB键盘前应该的灯状态来实现的。
- 首先在USB1Dev_EDP0_Setup_Deal函数中运行处理 Setup包的代码
// 处理 HID_SET_REPORT
if ((UsbSetupBuf->bRequestType==0x21)&&(SetupReqCode==HID_SET_REPORT))
{
CurrentRequest=HID_SET_REPORT;
printf("SETUP HID_SET_REPORT");
return;
}
- 接下来在USB1Dev_EDP0_OUT_Deal函数中处理 Endpoint0 OUT 数据
if (CurrentRequest==HID_SET_REPORT)
{
printf("EDP0_OUT HID_SET_REPORT:");
for (i=0; i<len; i++)
{
printf("%X ",UsbEp1OUTBuf[i]);
}
printf("\n");
}
- 最后在USB1Dev_EDP0_IN_Deal函数中发送0字节 Package
if (CurrentRequest==HID_SET_REPORT)
{
R16_UEP0_T_LEN1 = 0;
R8_UEP0_TX_CTRL1 = UEP_DATA1 | UEP_T_RES_ACK;
printf("EDP0_IN HID_SET_REPORT\n");
CurrentRequest=0;
return;
}
最终成功的代码:
完整的代码: