打印
[STM32F2]

又是一个USB HOST的问题,香水城进来看看

[复制链接]
8992|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
feifan570|  楼主 | 2014-6-20 15:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
USB, os, ST, MSC, TE
CPU是STM32F207VC,软件使用rt-thread,但是USB部分,还是按照裸奔的方法来移植USB代码,专门建一个任务来处理USB;
以下是我做了一下修改:
在 USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev ,void   *phost),修改   
    switch(USBH_MSC_BOTXferParam.MSCState)
    {
    case USBH_MSC_BOT_INIT_STATE:
      USBH_MSC_Init(pdev);
      //USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_RESET;  
    USBH_MSC_BOTXferParam.MSCState = USBH_MSC_GET_MAX_LUN;  
      break;
让它跳过USBH_MSC_BOTReset();
在int USBH_USR_MSC_Application(void)中,进行u盘的挂载;
现在枚举都没有问题,而且也能到达U盘的读操作:下面的读操作的代码:
static rt_size_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
  BYTE status = USBH_MSC_OK;
  if (RT_NULL == dev || !size) return RES_PARERR;
  if (Stat & STA_NOINIT) return RES_NOTRDY;

  if(HCD_IsDeviceConnected(&USB_OTG_Core))
  {  
    do
    {
      status = USBH_MSC_Read10(&USB_OTG_Core, buffer,pos,512 * size);
      USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);
      
      if(!HCD_IsDeviceConnected(&USB_OTG_Core))
      {
        return RES_ERROR;
      }      
    }
    while(status == USBH_MSC_BUSY );
  }
  
  if(status == USBH_MSC_OK)
    return RES_OK;
  return RES_ERROR;
}

单步进void USBH_MSC_HandleBOTXfer (USB_OTG_CORE_HANDLE *pdev ,USBH_HOST *phost),发现红色的代码段返回值不正常;URB_Status 会出现URB_ERROR;而且后面也没有对URB_ERROR进行处理,导致一直在这里死循环;

    case USBH_MSC_BOT_DATAIN_STATE:
      URB_Status =   HCD_GetURB_State(pdev , MSC_Machine.hc_num_in);
      /* BOT DATA IN stage */
      if((URB_Status == URB_DONE) ||(USBH_MSC_BOTXferParam.BOTStateBkp != USBH_MSC_BOT_DATAIN_STATE))
      {
        BOTStallErrorCount = 0;
        USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_BOT_DATAIN_STATE;   
        
        if(remainingDataLength > MSC_Machine.MSBulkInEpSize)
        {
          USBH_BulkReceiveData (pdev,
                            datapointer,
                    MSC_Machine.MSBulkInEpSize ,
                    MSC_Machine.hc_num_in);
         
          remainingDataLength -= MSC_Machine.MSBulkInEpSize;
          datapointer = datapointer + MSC_Machine.MSBulkInEpSize;
        }
        else if ( remainingDataLength == 0)
        {
          /* If value was 0, and successful transfer, then change the state */
          USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE;
        }
        else
        {      
          USBH_BulkReceiveData (pdev,
                            datapointer,
                    remainingDataLength ,
                    MSC_Machine.hc_num_in);
         
          remainingDataLength = 0; /* Reset this value and keep in same state */
        }
      }
      else if(URB_Status == URB_STALL)
      {
        /* This is Data Stage STALL Condition */
        
        error_direction = USBH_MSC_DIR_IN;
        USBH_MSC_BOTXferParam.BOTState  = USBH_MSC_BOT_ERROR_IN;
        
        /* Refer to USB Mass-Storage Class : BOT (www.usb.org)
        6.7.2 Host expects to receive data from the device
        3. On a STALL condition receiving data, then:
        The host shall accept the data received.
        The host shall clear the Bulk-In pipe.
        4. The host shall attempt to receive a CSW.
        
        USBH_MSC_BOTXferParam.BOTStateBkp is used to switch to the Original
        state after the ClearFeature Command is issued.
        */
        USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE;
      }     
      break;   

什么原因导致URB_Status 会出现URB_ERROR,出现URB_ERROR应该怎么处理?
沙发
香水城| | 2014-6-20 17:39 | 只看该作者

从中断代码看到,对于主机的IN通道,

USB_OTG_USBH_handle_hc_n_In_ISR()
  hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT);
  hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCINTMSK);
  hcint.d32 = hcint.d32 & hcintmsk.d32;
  ......

  else if (hcint.b.chhltd)
{
  .....

    else if((pdev->host.HC_Status[num] == HC_XACTERR) ||
            (pdev->host.HC_Status[num] == HC_DATATGLERR))
    {
      pdev->host.ErrCnt[num] = 0;
      pdev->host.URB_State[num] = URB_ERROR;  
      
    }
......

可见当HC_Status是XACTERR或者DATATGLERR时,会把URB_STATE置为URB_ERROR
同样查看XACTERR和DATAEGLERR的置位原因,找到对应的寄存器,即OTG_FS_HCINTx中的【TXERR】和【DTERR】位被硬件置位。
【TXERR】:Transaction error,可能是CRC校验错误、超时、比特填充错误、或者错误的EOP
【DTERR】:Data toggle error,表示收、发双方的数据同步位不再同步,可能是主机处理不当,也有可能是设备处理不当。最直观的方法是使用USB分析仪,看出错前的总线通信来判断是谁没有正确处理数据同步位的翻转。


使用特权

评论回复
板凳
正点原子| | 2014-6-22 00:41 | 只看该作者
DATATGLERR,这个错误我也发现了,不过我是在HID处理鼠标、键盘数据的时候,进入这个错误非常频繁,我现在采取的办法是遇到这个错误,直接整个USB重启,也算是解决这个问题了,但是治标不治本。
比如有的USB鼠标,平均1分钟左右,就会出现一次DATATGLERR错误,这个用官方的USB例程(V2.1.0的库)也是同样存在这个问题的,所以不知道是不是官方库有这个问题?有无长时间测试?
希望官方有个准确的答复。

使用特权

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

本版积分规则

92

主题

195

帖子

1

粉丝