通信就比较简单了,制定好协议后只要等待指令回复相应的信息即可。
1、接收数据
通信端口在端点0的接口0上,这里由于接收是在中断里执行的,所以把接收信息复制后在main里进行解析,防止中断执行过久;
/// @brief SetReport处理
/// @param index 接口号
void Keyboard_SetReportHandle(u8 index)
{
switch(index)
{
case 0://厂商自定义
{
for(u8 i=0;i<MAX_EP2_SIZE;i++)
{
UsbEp2Buffer[i] = UsbEp0Buffer[i];
}
Task_Comps[Task_UsbProtocol].run = 1;
}
break;
case 1://键盘提示灯
KeyLedReport.State = UsbEp0Buffer[0];
KeyLed_Deal(KeyLedReport.State);
break;
default:break;
}
}
2、解析
主函数里:
void UserProtocol_Deal(void)
{
//超过一定时间未收到数据清除写rom标志
Task_State(Task_UsbProtocol, 0);
if(romRevFlag)
{
Task_TimeSet(Task_UsbProtocolOvertime, 200);
//上位机按字节写
u16 len = (writeLen.U16-writeLenback) > Protocol_MaxSize ? Protocol_MaxSize : (writeLen.U16-writeLenback); //判断本次写入长度
FlashMgr_UnLockEE();
if(FlashMgr_WriteEE(&EpBuffer[Protocol_ValidStart], curEEAddr, len))
{
curEEAddr += len;
writeLenback += len;
if(writeLenback>=writeLen.U16)
{
romRevFlag = InValid;
}
if(cmd==Cmd_WriteLedMap)
LEDApp_SwitchEffect(1);
User_ReturnWriteCmd(WriteCmdSuccess); //返回写入成功
}
else
{
User_ReturnWriteCmd(WriteCmdFail); //返回写入失败
romRevFlag = InValid;
}
return;
}
cmd = EpBuffer[ProtocolMainCmd];
bcmd = EpBuffer[ProtocolBranchCmd];
switch(EpBuffer[ProtocolMainCmd])
{
case Cmd_ReadInfo: //读取版本信息
User_ReadInfo();
break;
case Cmd_ReadUSBInt: //读取USB中断时间
User_ReadUSBIntTime();
break;
case Cmd_ReadButtonInfo: //读取按键信息
{
u16 addr = EpBuffer[ProtocolData];
addr <<= 8;
addr |= EpBuffer[ProtocolData+1];
u16 rlen = EpBuffer[ProtocolData+2];
rlen <<= 8;
rlen |= EpBuffer[ProtocolData+3];
User_ReadButtonInfo(EpBuffer[ProtocolBranchCmd],addr,rlen);
}
break;
case Cmd_ReadLED: //读取灯效信息
User_ReadLED();
break;
case Cmd_ReadLedMap: //读取自定义颜色
{
u16 addr = EpBuffer[ProtocolData];
addr <<= 8;
addr |= EpBuffer[ProtocolData+1];
u16 rlen = EpBuffer[ProtocolData+2];
rlen <<= 8;
rlen |= EpBuffer[ProtocolData+3];
User_ReadLedMap(addr,rlen);
}
break;
case Cmd_ReadMacro: //读取宏定义
{
u16 addr = EpBuffer[ProtocolData];
addr <<= 8;
addr |= EpBuffer[ProtocolData+1];
u16 rlen = EpBuffer[ProtocolData+2];
rlen <<= 8;
rlen |= EpBuffer[ProtocolData+3];
User_ReadKeyMacro(addr,rlen);
}
break;
case Cmd_ReadButtonScanTime: //读取按键响应时间
User_ReadButtonScanTime();
break;
case Cmd_ReadPower: //读取电源信息
User_ReadPower();
break;
case Cmd_ReadLockQuit:
User_ReadLockQuit();
break;
case Cmd_ReadLockGui:
User_ReadLockGui();
break;
case Cmd_ReadShiftWASD:
User_ReadShiftWASD();
break;
case Cmd_Update: //开始更新
if(EpBuffer[ProtocolBranchCmd]==0XFF)
{
Delayms(10); //延时,等待USB数据发送完成
FlashMgr_UnLockCode();
FlashMgr_OverwriteCode(1,0X7FFF);
Reset(); //软复位
}
break;
case Cmd_WriteUSBInt: //写USB中断时间
User_WriteUSBIntTime();
break;
case Cmd_WriteButtonScanTime: //写按键响应时间
User_WriteButtonScanTime();
break;
case Cmd_WriteButtonInfo: //写按键信息
User_WriteButtonInfo(EpBuffer[ProtocolBranchCmd]);
break;
case Cmd_WriteLED: //写灯效信息
User_WriteLED();
break;
case Cmd_WriteLedMap: //写自定义颜色
User_WriteLedMap();
break;
case Cmd_WriteMacro: //写宏定义
User_WriteKeyMacro();
break;
case Cmd_WriteLockQuit:
User_WriteLockQuit();
break;
case Cmd_WriteMusic: //写音乐律动信息
User_WriteMusic();
break;
case Cmd_WriteLockGui:
User_WriteLockGui();
break;
case cmd_WriteShiftWASD:
User_WriteShiftWASD();
break;
case Cmd_WritePower: //写电源
User_WritePower();
break;
default:
User_ReturnUnkown();
break;
}
}
3、主动上传
像切换灯效或者一些操作也会主动发送数据到上位机,同步上位机界面信息