打印
[STM32F1]

关于香主的““STM32USB延迟HID的GET_REPORT请求”,对“HidD_GetInputReport”无效

[复制链接]
4339|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sxslyy|  楼主 | 2015-6-12 11:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用HidD_GetInputReport函数,发起GET REPORT,包如下:

Device   Phase  Data                                    Description
  24.0   CTL     a1 01 03 01  00 00 14 00       GET REPORT
  24.0   USTS   c0010000                             cancele


根据该文:代码
/*** GET_REPORT ***/
  else if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
        && RequestNo == GET_REPORT)
  {
        if (!isReady)//数据未准备好
        {
                memset(Transceive_Buffer,0,256);
                Transceive_Buffer[0]=0x01;
                Transceive_Buffer[1]=0x01;
                isReady=TRUE;

            return USB_NOT_READY;
        }

    CopyRoutine = CustomHID_GetReport;
  }
虽然,立即准备好数据,但好象只要回应了NAK( USB_NOT_READY),驱动就认为超时了!不自动重请求数据,所以准备好的数据也不能读取!只能等再一次调用HidD_GetInputReport!才能读!

不知道香主及其它高手看看问题出在什么地方!您们有试过延迟HID的GET_REPORT请求的代码么!这种延迟请求在什么情况下试用!
沙发
香水城| | 2015-6-15 17:08 | 只看该作者
通常如果设备不是回复了STALL,主机会在下一个时间间隔自动发出下一次transfer的令牌。

你确定回复的不是STALL,是NAK?

使用特权

评论回复
板凳
sxslyy|  楼主 | 2015-6-16 12:46 | 只看该作者
香主:实测结果是这样的,上位机使用 HidD_GetInputReport 读一次报告!

使用Bushound监测为:
Device   Phase  Data                                    Description
  24.0   CTL     a1 01 03 01  00 00 14 00       GET REPORT

stm32这边:仿真到下面代码。即数据未准备好!返回:return USB_NOT_READY;

if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
        && RequestNo == GET_REPORT)
  {
        if (!isReady)//数据未准备好
        {
                memset(Transceive_Buffer,0,256);
                Transceive_Buffer[0]=0x01;
                Transceive_Buffer[1]=0x01;
                isReady=TRUE;

            return USB_NOT_READY;
        }

这是根据您的**上所写的:return USB_NOT_READY;  就是返回NAK。。

结果只要返回一次NAK,然后 HidD_GetInputReport 这个函数就认为是超时了!它的返回错误值也是超时。时间是5秒。

主要是为什么不明白只返回一次 USB_NOT_READY 驱动就认为是超时!不应该是驱动再试么,试N次后再超时。

使用特权

评论回复
地板
sxslyy|  楼主 | 2015-6-17 10:43 | 只看该作者
现在的情况是当使用“HidD_GetInputReport”这个函数发出GET_REPORT请求时。stm32库使用下面的代码来处理这个请求:

RESULT CustomHID_Data_Setup(u8 RequestNo)
{
  u8 *(*CopyRoutine)(u16);

  CopyRoutine = NULL;
.
.//其它代码
.
if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
        && RequestNo == GET_REPORT)
  {
        if (!isReady)//数据未准备好
        {
            return USB_NOT_READY;
        }

    CopyRoutine = CustomHID_GetReport;
  }

  if (pInformation->USBbmRequestType == CLASS_REQUEST|INTERFACE_RECIPIENT
            && RequestNo == SET_REPORT)
  /**** SET_REPORT ****/
  {
    CopyRoutine = CustomHID_SetReport;
  }

  if (CopyRoutine == NULL)
  {
    return USB_UNSUPPORT;
  }

  pInformation->Ctrl_Info.CopyData = CopyRoutine;
  pInformation->Ctrl_Info.Usb_wOffset = 0;
  (*CopyRoutine)(0);
                                 
  return USB_SUCCESS;
}

这段代码,一定要返回一个USB状态。或着USB_NOT_READY 或着 USB_SUCCESS 但不论返回什么。这段代码都没有一个等待我把数据准备好的过程,其实我的数据是在GET_REPORT请求到达后,需20MS-50MS左右后就可以准备好!现在的情况是如果返回USB_NOT_READY,上位机就认为超时(注意是立即,这个立即指的是,上位机从不等我准备好数据后再读一次,我理解的是发了NAK,上位机隔一段时间会自动重新请求,而这时我的数据准备好了!上位机就把准备好的数据读上去。当然这个过程可能是有一定交互次数或时间限制的,就现在的情况我的感觉是这个过程极短,根本不给我准备好数据的机会)。如果返回 USB_SUCCESS stm32也是立即返回的就是当前缓存区的数据,而缓存区的数据还没准备好!所以返回的全是0000000.

if (数据未准备好)
            return USB_NOT_READY;
这段代码我用的是香水城 版主的**中的方法!以为可以让GET_REPORT请求到达后,stm32可以等我把数据准备好!再去把缓存区的数据发上去。结果没法实现!

应用层的方法,我现在用的是不断读,stm32这边不断上传,未准备好!就返回全0的数据,然后上位机软件抛弃它,返回有用的数据时再处理·!这样可以保证通讯顺畅,实现功能的。

但我觉着不断上传的没用的数据是占USB带宽的,效率差,所以求教兄弟!用什么方法可以使用STM32在GET_REPORT请求到达时,能等我把数据准备好!再去把缓存区的数据发上去。

使用特权

评论回复
5
icecut| | 2015-6-17 21:00 | 只看该作者
你是一直返回 nak,一直返回了5s 吧

使用特权

评论回复
6
icecut| | 2015-6-17 21:02 | 只看该作者
20ms 你设备也太慢了.提前准备和数据.别搞实时生成数据

使用特权

评论回复
7
iamdair| | 2020-3-13 17:55 | 只看该作者
sxslyy 发表于 2015-6-17 10:43
现在的情况是当使用“HidD_GetInputReport”这个函数发出GET_REPORT请求时。stm32库使用下面的代码来处理这 ...

本来我也想发个这样的贴,刚好看到你的贴,return USB_NOT_READY不是返回NAK,返回NAK需要再STATUS_OUT里设置SetEPRxStatus(ENDP0, EP_RX_NAK);  SetEPTxStatus(ENDP0, EP_TX_NAK);才会返回NAK。

使用特权

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

本版积分规则

11

主题

31

帖子

0

粉丝