关于LM3S3748应用在custom_usb_dev_hid设备
[复制链接]
大家好!
本人使用ek-lm3s3748的Demo板, 想要实现自定义USBHID设备, 本人根据DEMO板的实例usb_dev_keyboard和usb_dev_mouse为参考代码, 做了一些更改, 主要改动在描述符和一些处理代码, 现在的现象是:
PC机发送IN请求, ek-lm3s3748没有反映, 即当PC发送IN请求时, 无法将数据发送到PC机.
由于是从usb_dev_keyboard和usb_dev_mouse代码上更改的, 如果PC机发送IN请求时, ek-lm3s3748板上有按键按下, 则可以将数据上传到PC, 我不期望使用此功能来实现, 因为可能会造成数据传输不同步的问题.
下面是我的回调函数, 请各位大侠指点一二, 小弟先谢过了:
static unsigned long HIDCustomRxHandler( void *pvCBData, unsigned long ulEvent, unsigned long ulMsgData, void *pvMsgData) { tHIDCustomHIDInstance *psInst; tUSBDHIDCustomDevice *psDevice;
// 入口参数检测. // 确定指针非空. ASSERT(pvCBData);
// 获取实例数据指针. psDevice = (tUSBDHIDCustomDevice *)pvCBData; psInst = psDevice->psPrivateHIDCustomData;
// 发送哪个事件? switch (ulEvent) { // 主机已连接到我们, 并且配置设备. case USB_EVENT_CONNECTED: { psInst->ucUSBConfigured = true;
// 调用回调函数, 将信息传递到客户端. // 调用客户端自己的回调函数, 此处是CustomHIDHandler()回调函数. psDevice->pfnCallback(psDevice->pvCBData, USB_EVENT_CONNECTED, 0, (void *)0);
break; }
// 主机断开了我们. case USB_EVENT_DISCONNECTED: { psInst->ucUSBConfigured = false;
// 调用回调函数, 将信息传递到客户端. // 调用客户端自己的回调函数, 此处是CustomHIDHandler()回调函数. psDevice->pfnCallback(psDevice->pvCBData, USB_EVENT_DISCONNECTED, 0, (void *)0);
break; }
// 主机查询特定的报告描述符, 并且HID驱动程序申请发送最新的版本. case USBD_HID_EVENT_IDLE_TIMEOUT: case USBD_HID_EVENT_GET_REPORT: { // 我们只支持单个输入报告描述符, 所以在此情况下, 我们不需要检查ulMsgValue参数. // 设置pvMsgData中的报告描述符的指针, 并返回报告描述符的字节长度. *(unsigned char **)pvMsgData = psInst->pucReport; //给IN报告描述符 return (CUSTOMHID_IN_REPORT_SIZE); }
// 设备驱动程序类已完成报告描述符发送到主机, 通过响应Get_Report请求. case USBD_HID_EVENT_REPORT_SENT: { // 此处什么也不做. break; }
// 此事件表明主机Set_Report请求已发送到设备,并请求设备提供可以写入报告的缓冲区. // 此事件在主机Set_Report请求的响应中发送. 自定义HID设备有输出报告描述符, 所以我们不返回一个空指针和零长度, 不停止此请求. case USBD_HID_EVENT_GET_REPORT_BUFFER: //SET_REPORT { // 返回OUT报告描述符的长度 if((unsigned long)pvMsgData == CUSTOMHID_OUT_REPORT_SIZE ) { return ((unsigned long)psInst->pucDataBuffer); } else { return (0); } }
// 此事件表明主机发送一个输出或功能报告描述符, 并且该报告描述符存储在之 // 前使用USBD_HID_EVENT_GET_REPORT_BUFFER回调函数提供的缓冲区中. case USBD_HID_EVENT_SET_REPORT: { // 如果键盘指示灯改变, 告知应用程序. // if(psInst->ucLEDStates != psInst->pucDataBuffer[0]) { // 传递信息到客户端. // 调用客户端自己的回调函数, 此处是CustomHIDHandler()回调函数. psDevice->pfnCallback( psDevice->pvCBData, USBD_HID_CUSTOM_EVENT_SET_DATA, psInst->pucDataBuffer[0], (void *)0 ); } break; } // 主机要求我们设置引导或报告协议(并非如此它让你知道此特殊的自定义HID). case USBD_HID_EVENT_SET_PROTOCOL: { psInst->ucProtocol = ulMsgData; break; }
// 主机是要求我们告诉它我们目前使用哪个协议, 引导或请求. case USBD_HID_EVENT_GET_PROTOCOL: { return (psInst->ucProtocol); }
// 传递ERROR, SUSPEND和RESUME到客户端未变. case USB_EVENT_ERROR: case USB_EVENT_SUSPEND: case USB_EVENT_RESUME: { // 调用回调函数, 将信息传递到客户端. // 调用客户端自己的回调函数, 此处是CustomHIDHandler()回调函数. return(psDevice->pfnCallback(psDevice->pvCBData, ulEvent, ulMsgData, pvMsgData)); }
// 忽略其它事件. default: { break; } } return (0); }
unsigned long CustomHIDHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgData, void *pvMsgData) { tHIDCustomHIDInstance *psInst; tUSBDHIDCustomDevice *psDevice;
//入口参数检测. //确定指针非空. ASSERT(pvCBData);
//获取实例数据指针. psDevice = (tUSBDHIDCustomDevice *)pvCBData; psInst = psDevice->psPrivateHIDCustomData;
//确定哪个事件? switch(ulEvent) { //已与主机连接, 并且设备已配置. case USB_EVENT_CONNECTED: { DEBUG_PRINT("Host connected.\n"); g_bConnected = true; g_eCustomHIDState = CUSTOMHID_STATE_IDLE; break; }
//主机已与设备断开. case USB_EVENT_DISCONNECTED: { DEBUG_PRINT("Host disconnected.\n"); g_bConnected = false; g_eCustomHIDState = CUSTOMHID_STATE_UNCONFIGURED; break; }
//报告发送到主机. 我们不释放以发送另一个. case USB_EVENT_TX_COMPLETE: { DEBUG_PRINT("TX complete.\n"); g_eCustomHIDState = CUSTOMHID_STATE_IDLE; break; }
//此事件表明主机送来一个输出或功能报告描述符, 并且, 该报告描述符现在位于我们之前 //由USBD_HID_EVENT_GET_REPORT_BUFFER回调函数提供的缓冲区中主机发送数据 case USBD_HID_CUSTOM_EVENT_SET_DATA: { //设置数据(跑马灯). g_ucLEDStates = ~g_ucLEDStates;
//设置标志以告诉主循环, LED状态改变. g_bLEDStateChanged = true; g_sCustomHIDInstance.bUSBReceived = true;
break; }
//此事件表明主机送来一个输出描述符, 并且, 该报告描述符现在位于我们之前由 //USBD_HID_EVENT_GET_REPORT_BUFFER回调函数提供的缓冲区中主机已发送数据到此设备 case USBD_HID_EVENT_GET_REPORT: { //获取数据. break; }
//我们忽略其它事件. default: { break; } } return(0); }
|