打印
[STM32F1]

关于USBH_HID_SetReport函数如何使用

[复制链接]
2921|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
知识背景:对于HID类,OUT端点并不是必须的.
根据USB HID协议,当没有专用的OUT端点时,set report使用control端点实现,具体就是通过HID类的请求,然后通过Data stage携带set report数据.

现在遇到一个项目需要进行双向通讯的HID。使用STM32F105作为usb host,
1、目前在在en.stm32cubef1\STM32Cube_FW_F1_V1.4.0\Projects\STM3210C_EVAL\Applications\USB_Host\HID_Standalone基础上修改能够正常的读取input端点发送的数据。
2、《UM1720【用户手册】STM32Cube™ USB 主机库》中提到USBH_HID_SetReport[通过控制通道发送报告数据 ],不知道如何使用这个USBH_HID_SetReport函数。


沙发
mmuuss586| | 2017-8-8 21:13 | 只看该作者
谢谢分享

使用特权

评论回复
板凳
天灵灵地灵灵| | 2017-8-8 22:09 | 只看该作者

人家提问呢,你也谢谢分享,真搞笑。。

使用特权

评论回复
地板
天灵灵地灵灵| | 2017-8-8 22:12 | 只看该作者
+/**
+  * [url=home.php?mod=space&uid=247401]@brief[/url]  USBH_HID_Set_Report
+  *         Issues Set Report
+  * @param  phost: Host handle
+  * @param  reportType  : Report type to be sent
+  * @param  reportId    : Targetted report ID for Set Report request
+  * @param  reportBuff  : Report Buffer
+  * @param  reportLen   : Length of data report to be send
+  * @retval USBH Status
+  */
+USBH_StatusTypeDef USBH_HID_SetReport (USBH_HandleTypeDef *phost,
+                                    uint8_t reportType,
+                                    uint8_t reportId,
+                                    uint8_t* reportBuff,
+                                    uint8_t reportLen)
+{
+  
+  phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\
+    USB_REQ_TYPE_CLASS;
+  
+  
+  phost->Control.setup.b.bRequest = USB_HID_SET_REPORT;
+  phost->Control.setup.b.wValue.w = (reportType << 8 ) | reportId;
+  
+  phost->Control.setup.b.wIndex.w = 0;
+  phost->Control.setup.b.wLength.w = reportLen;
+  
+  return USBH_CtlReq(phost, reportBuff , reportLen );
+}

应该是这个函数。

使用特权

评论回复
5
天灵灵地灵灵| | 2017-8-8 22:17 | 只看该作者

使用特权

评论回复
6
天灵灵地灵灵| | 2017-8-8 22:19 | 只看该作者
例如:
// Set the LEDs on the keyboard.
    //
    USBHHIDSetReport(pUSBHKeyboard->ulHIDInstance, 0,   (unsigned char *)&ulModifiers, 1);
参考
https://searchcode.com/codesearch/view/47035242/

使用特权

评论回复
7
LZR13179|  楼主 | 2017-8-9 10:53 | 只看该作者
天灵灵地灵灵 发表于 2017-8-8 22:19
例如:
// Set the LEDs on the keyboard.
    //

谢谢,不过你给例子是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->Requests
USBH_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。






使用特权

评论回复
8
LZR13179|  楼主 | 2017-8-15 08:48 | 只看该作者
自己顶一下

使用特权

评论回复
9
LZR13179|  楼主 | 2017-8-16 15:21 | 只看该作者
天灵灵地灵灵 发表于 2017-8-8 22:19
例如:
// Set the LEDs on the keyboard.
    //

谢谢,后面自己弄一个简单测试demo工程
测试工程

使用特权

评论回复
10
huahuagg| | 2018-8-29 18:54 | 只看该作者
LZR13179 发表于 2017-8-16 15:21
谢谢,后面自己弄一个简单测试demo工程
测试工程

给力,我转载过来可以吧?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

87

帖子

1

粉丝