谢谢,不过你给例子是TI的
下图引自《Stellaris® USB Library USER’S GUIDE 》
主要困惑是不是只能在在USBH_HID_ClassRequest中调用吗?
在
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] USBH_HID_ClassRequest
* The function is responsible for handling Standard requests
* for HID class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_HID_ClassRequest(USBH_HandleTypeDef *phost)
{
USBH_StatusTypeDef status = USBH_BUSY;
USBH_StatusTypeDef classReqStatus = USBH_BUSY;
<font color="DarkOrchid"><b>HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData; </b></font>
/* Switch HID state machine */
switch (<font color="DarkOrchid"><b>HID_Handle->ctl_state</b></font>)
{
case HID_REQ_INIT:
case HID_REQ_GET_HID_DESC:
/* Get HID Desc */
if (USBH_HID_GetHIDDescriptor (phost, USB_HID_DESC_SIZE)== USBH_OK)
{
USBH_HID_ParseHIDDesc(&HID_Handle->HID_Desc, phost->device.Data);
HID_Handle->ctl_state = HID_REQ_GET_REPORT_DESC;
}
break;
case HID_REQ_GET_REPORT_DESC:
/* Get Report Desc */
if (USBH_HID_GetHIDReportDescriptor(phost, HID_Handle->HID_Desc.wItemLength) == USBH_OK)
{
/* The descriptor is available in phost->device.Data */
#if 0
USBH_DbgLog("///////////////////////////");
USBH_DbgLog("HID REPORT DESC");
for(uint8_t i = 0; i<HID_Handle->HID_Desc.wItemLength; i++)
{
USBH_DbgLog(" %02x",*(uint8_t *) (phost->device.Data+i));
}
USBH_DbgLog("///////////////////////////");
#endif
HID_Handle->ctl_state = HID_REQ_SET_IDLE;
}
break;
case HID_REQ_SET_IDLE:
classReqStatus = USBH_HID_SetIdle (phost, 0, 0);
/* set Idle */
if (classReqStatus == USBH_OK)
{
HID_Handle->ctl_state = HID_REQ_SET_PROTOCOL;
}
else if(classReqStatus == USBH_NOT_SUPPORTED)
{
HID_Handle->ctl_state = HID_REQ_SET_PROTOCOL;
}
break;
case HID_REQ_SET_PROTOCOL:
/* set protocol */
if (USBH_HID_SetProtocol (phost, 0) == USBH_OK)
{
HID_Handle->ctl_state = HID_REQ_IDLE;
/* all requests performed*/
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
status = USBH_OK;
}
break;
case HID_REQ_IDLE:
default:
break;
}
return status;
}
而在
typedef enum
{
HID_REQ_INIT = 0,
HID_REQ_IDLE,
HID_REQ_GET_REPORT_DESC,
HID_REQ_GET_HID_DESC,
HID_REQ_SET_IDLE,
HID_REQ_SET_PROTOCOL,
HID_REQ_SET_REPORT,
}
HID_CtlStateTypeDef;
我的猜测和思路
在static USBH_StatusTypeDef USBH_HID_ClassRequest(USBH_HandleTypeDef *phost)中添加红色部分
case HID_REQ_SET_PROTOCOL:
/* set protocol */
if (USBH_HID_SetProtocol (phost, 0) == USBH_OK)
{
HID_Handle->ctl_state = HID_REQ_IDLE;
/* all requests performed*/
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
status = USBH_OK;
}
break;
<font color="Red"><b>case HID_REQ_SET_REPORT:
{
uint8_t buff[2] = { 0x0, 0x0 };//这测试固定为常量
USBH_StatusTypeDef ret = USBH_HID_SetReport(phost, 2, 0, buff, 1);
if ((ret == USBH_OK) || (USBH_NOT_SUPPORTED == ret))
{
HID_Handle->ctl_state = HID_REQ_IDLE;
status = USBH_OK;
/* all requests performed*/
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
}
}
break;</b></font>
case HID_REQ_IDLE:
default:
break;
而USBH_HID_ClassRequest做为phost->pActiveClass->Requests(phost)回调函数USBH_ClassTypeDef HID_Class =
{
"HID",
USB_HID_CLASS,
USBH_HID_InterfaceInit,
USBH_HID_InterfaceDeInit,
<font color="Red"><b>USBH_HID_ClassRequest</b></font>,
USBH_HID_Process,
USBH_HID_SOFProcess,
NULL,
};
我们可以看到 USBH_Process使用到status = phost->pActiveClass->RequestsUSBH_StatusTypeDef USBH_Process(USBH_HandleTypeDef *phost)
{
switch (phost->gState)
{
...
<font color="Blue"><b>case HOST_CLASS_REQUEST</b></font>:
/* process class standard control requests state machine */
if(phost->pActiveClass != NULL)
{
<b><font color="Red">status = phost->pActiveClass->Requests(phost);</font></b>
if(status == USBH_OK)
{
phost->gState = HOST_CLASS;
}
}
else
{
phost->gState = HOST_ABORT_STATE;
USBH_ErrLog ("Invalid Class Driver.");
#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
#endif
}
break;
...
}
那现在如何触发这个HID_Handle->ctl_state = HID_REQ_SET_REPORT ,即先phost->gState = HOST_CLASS_REQUEST后调用 phost->pActiveClass->pData。
|