大家好!
本人使用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.
");
g_bConnected = true;
g_eCustomHIDState = CUSTOMHID_STATE_IDLE;
break;
}
//主机已与设备断开.
case USB_EVENT_DISCONNECTED:
{
DEBUG_PRINT("Host disconnected.
");
g_bConnected = false;
g_eCustomHIDState = CUSTOMHID_STATE_UNCONFIGURED;
break;
}
//报告发送到主机. 我们不释放以发送另一个.
case USB_EVENT_TX_COMPLETE:
{
DEBUG_PRINT("TX complete.
");
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);
}
此帖出自
小平头技术问答
一周热门 更多>