[STM32F1] 关于USBH_HID_SetReport函数如何使用

[复制链接]
3756|9
 楼主| LZR13179 发表于 2017-8-8 15:49 | 显示全部楼层 |阅读模式
知识背景:对于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 | 显示全部楼层
  1. +/**
  2. +  * [url=home.php?mod=space&uid=247401]@brief[/url]  USBH_HID_Set_Report
  3. +  *         Issues Set Report
  4. +  * @param  phost: Host handle
  5. +  * @param  reportType  : Report type to be sent
  6. +  * @param  reportId    : Targetted report ID for Set Report request
  7. +  * @param  reportBuff  : Report Buffer
  8. +  * @param  reportLen   : Length of data report to be send
  9. +  * @retval USBH Status
  10. +  */
  11. +USBH_StatusTypeDef USBH_HID_SetReport (USBH_HandleTypeDef *phost,
  12. +                                    uint8_t reportType,
  13. +                                    uint8_t reportId,
  14. +                                    uint8_t* reportBuff,
  15. +                                    uint8_t reportLen)
  16. +{
  17. +  
  18. +  phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\
  19. +    USB_REQ_TYPE_CLASS;
  20. +  
  21. +  
  22. +  phost->Control.setup.b.bRequest = USB_HID_SET_REPORT;
  23. +  phost->Control.setup.b.wValue.w = (reportType << 8 ) | reportId;
  24. +  
  25. +  phost->Control.setup.b.wIndex.w = 0;
  26. +  phost->Control.setup.b.wLength.w = reportLen;
  27. +  
  28. +  return USBH_CtlReq(phost, reportBuff , reportLen );
  29. +}

应该是这个函数。
天灵灵地灵灵 发表于 2017-8-8 22:17 | 显示全部楼层
天灵灵地灵灵 发表于 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/
 楼主| LZR13179 发表于 2017-8-9 10:53 | 显示全部楼层
天灵灵地灵灵 发表于 2017-8-8 22:19
例如:
// Set the LEDs on the keyboard.
    //

谢谢,不过你给例子是TI的
下图引自《Stellaris® USB Library USER’S GUIDE 》
QQ图片20170809101107.png
主要困惑是不是只能在在USBH_HID_ClassRequest中调用吗?

  1. /**
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url]  USBH_HID_ClassRequest
  3.   *         The function is responsible for handling Standard requests
  4.   *         for HID class.
  5.   * @param  phost: Host handle
  6.   * @retval USBH Status
  7.   */
  8. static USBH_StatusTypeDef USBH_HID_ClassRequest(USBH_HandleTypeDef *phost)
  9. {   
  10.   
  11.   USBH_StatusTypeDef status         = USBH_BUSY;
  12.   USBH_StatusTypeDef classReqStatus = USBH_BUSY;
  13.   <font color="DarkOrchid"><b>HID_HandleTypeDef *HID_Handle =  (HID_HandleTypeDef *) phost->pActiveClass->pData; </b></font>

  14.   /* Switch HID state machine */
  15.   switch (<font color="DarkOrchid"><b>HID_Handle->ctl_state</b></font>)
  16.   {
  17.   case HID_REQ_INIT:  
  18.   case HID_REQ_GET_HID_DESC:
  19.    
  20.     /* Get HID Desc */
  21.     if (USBH_HID_GetHIDDescriptor (phost, USB_HID_DESC_SIZE)== USBH_OK)
  22.     {
  23.       
  24.       USBH_HID_ParseHIDDesc(&HID_Handle->HID_Desc, phost->device.Data);
  25.       HID_Handle->ctl_state = HID_REQ_GET_REPORT_DESC;
  26.     }
  27.    
  28.     break;     
  29.   case HID_REQ_GET_REPORT_DESC:
  30.    
  31.    
  32.     /* Get Report Desc */
  33.     if (USBH_HID_GetHIDReportDescriptor(phost, HID_Handle->HID_Desc.wItemLength) == USBH_OK)
  34.     {
  35.       /* The descriptor is available in phost->device.Data */
  36. #if 0
  37.         USBH_DbgLog("///////////////////////////");
  38.         USBH_DbgLog("HID REPORT DESC");
  39.         for(uint8_t i = 0; i<HID_Handle->HID_Desc.wItemLength; i++)
  40.         {
  41.             USBH_DbgLog(" %02x",*(uint8_t  *) (phost->device.Data+i));
  42.         }
  43.         USBH_DbgLog("///////////////////////////");
  44. #endif
  45.       HID_Handle->ctl_state = HID_REQ_SET_IDLE;
  46.     }
  47.    
  48.     break;
  49.    
  50.   case HID_REQ_SET_IDLE:
  51.    
  52.     classReqStatus = USBH_HID_SetIdle (phost, 0, 0);
  53.    
  54.     /* set Idle */
  55.     if (classReqStatus == USBH_OK)
  56.     {
  57.       HID_Handle->ctl_state = HID_REQ_SET_PROTOCOL;  
  58.     }
  59.     else if(classReqStatus == USBH_NOT_SUPPORTED)
  60.     {
  61.       HID_Handle->ctl_state = HID_REQ_SET_PROTOCOL;        
  62.     }
  63.     break;
  64.    
  65.   case HID_REQ_SET_PROTOCOL:
  66.     /* set protocol */
  67.     if (USBH_HID_SetProtocol (phost, 0) == USBH_OK)
  68.     {
  69.       HID_Handle->ctl_state = HID_REQ_IDLE;
  70.       
  71.       /* all requests performed*/
  72.       phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
  73.       status = USBH_OK;
  74.     }
  75.     break;
  76.    
  77.   case HID_REQ_IDLE:
  78.   default:
  79.     break;
  80.   }
  81.   
  82.   return status;
  83. }
而在
  1. typedef enum
  2. {
  3.   HID_REQ_INIT = 0,
  4.   HID_REQ_IDLE,
  5.   HID_REQ_GET_REPORT_DESC,
  6.   HID_REQ_GET_HID_DESC,
  7.   HID_REQ_SET_IDLE,
  8.   HID_REQ_SET_PROTOCOL,
  9.   HID_REQ_SET_REPORT,

  10. }
  11. HID_CtlStateTypeDef;
我的猜测和思路
在static USBH_StatusTypeDef USBH_HID_ClassRequest(USBH_HandleTypeDef *phost)中添加红色部分
  1.         case HID_REQ_SET_PROTOCOL:
  2.         /* set protocol */
  3.         if (USBH_HID_SetProtocol (phost, 0) == USBH_OK)
  4.         {
  5.             HID_Handle->ctl_state = HID_REQ_IDLE;

  6.             /* all requests performed*/
  7.             phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
  8.             status = USBH_OK;
  9.         }
  10.   break;
  11. <font color="Red"><b>case HID_REQ_SET_REPORT:
  12.     {
  13.         uint8_t buff[2] = { 0x0, 0x0 };//这测试固定为常量
  14.         USBH_StatusTypeDef ret = USBH_HID_SetReport(phost, 2, 0, buff, 1);

  15.         if ((ret == USBH_OK) || (USBH_NOT_SUPPORTED == ret))
  16.         {
  17.             HID_Handle->ctl_state = HID_REQ_IDLE;
  18.             status = USBH_OK;
  19.             /* all requests performed*/
  20.             phost->pUser(phost, HOST_USER_CLASS_ACTIVE);

  21.         }
  22.     }
  23.     break;</b></font>
  24. case HID_REQ_IDLE:
  25. default:
  26.         break;
USBH_HID_ClassRequest做为phost->pActiveClass->Requests(phost)回调函数
  1. USBH_ClassTypeDef  HID_Class =
  2. {
  3.     "HID",
  4.     USB_HID_CLASS,
  5.     USBH_HID_InterfaceInit,
  6.     USBH_HID_InterfaceDeInit,
  7.     <font color="Red"><b>USBH_HID_ClassRequest</b></font>,
  8.     USBH_HID_Process,
  9.     USBH_HID_SOFProcess,
  10.     NULL,
  11. };
我们可以看到 USBH_Process使用到status = phost->pActiveClass->Requests
  1. USBH_StatusTypeDef  USBH_Process(USBH_HandleTypeDef *phost)
  2. {

  3.   switch (phost->gState)
  4.   {
  5.     ...
  6.   <font color="Blue"><b>case HOST_CLASS_REQUEST</b></font>:  
  7.     /* process class standard control requests state machine */
  8.     if(phost->pActiveClass != NULL)
  9.     {
  10.       <b><font color="Red">status = phost->pActiveClass->Requests(phost);</font></b>
  11.       
  12.       if(status == USBH_OK)
  13.       {
  14.         phost->gState  = HOST_CLASS;        
  15.       }  
  16.     }
  17.     else
  18.     {
  19.       phost->gState  = HOST_ABORT_STATE;
  20.       USBH_ErrLog ("Invalid Class Driver.");
  21.    
  22. #if (USBH_USE_OS == 1)
  23.     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
  24. #endif      
  25.     }
  26.    
  27.     break;   
  28. ...
  29. }



那现在如何触发这个HID_Handle->ctl_state = HID_REQ_SET_REPORT ,即先phost->gState  = HOST_CLASS_REQUEST后调用 phost->pActiveClass->pData。






 楼主| LZR13179 发表于 2017-8-15 08:48 | 显示全部楼层
自己顶一下
 楼主| LZR13179 发表于 2017-8-16 15:21 | 显示全部楼层
天灵灵地灵灵 发表于 2017-8-8 22:19
例如:
// Set the LEDs on the keyboard.
    //

谢谢,后面自己弄一个简单测试demo工程
测试工程
huahuagg 发表于 2018-8-29 18:54 | 显示全部楼层
LZR13179 发表于 2017-8-16 15:21
谢谢,后面自己弄一个简单测试demo工程
测试工程

给力,我转载过来可以吧?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

87

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部