硬汉嵌入式论坛

 找回密码
 立即注册
12
返回列表 发新帖
楼主: eric2013
收起左侧

STM32移植USB库2.2.0版本----USB Host之外挂U盘移植步骤及其注意事项,识别率很高,

  [复制链接]

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
 楼主| 发表于 2022-3-1 09:49:24 | 显示全部楼层
马氏王朝 发表于 2022-3-1 09:15
插入64G  U盘   写着写着会卡一段时间   再写

采用了exFAT格式没。
回复

使用道具 举报

0

主题

12

回帖

12

积分

新手上路

积分
12
发表于 2022-3-1 09:51:45 | 显示全部楼层
为什么8G 16G正常   32G的就不行啊
回复

使用道具 举报

0

主题

12

回帖

12

积分

新手上路

积分
12
发表于 2022-3-1 09:52:08 | 显示全部楼层
为什么8G 16G写正常    32G就无法写正常啊
回复

使用道具 举报

0

主题

12

回帖

12

积分

新手上路

积分
12
发表于 2022-3-1 09:59:08 | 显示全部楼层
64G U盘格式化为exFAT格式了    8G 16G 写正常   64G有时候写着就停止了   过一段时间又再写
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
 楼主| 发表于 2022-3-1 10:03:34 | 显示全部楼层
马氏王朝 发表于 2022-3-1 09:59
64G U盘格式化为exFAT格式了    8G 16G 写正常   64G有时候写着就停止了   过一段时间又再写

fafs使能exfat了没
回复

使用道具 举报

0

主题

12

回帖

12

积分

新手上路

积分
12
发表于 2022-3-1 10:16:13 | 显示全部楼层
请问如何使能      是不是要用R0.12   
回复

使用道具 举报

0

主题

12

回帖

12

积分

新手上路

积分
12
发表于 2022-3-1 10:28:59 | 显示全部楼层
eric2013 发表于 2022-3-1 10:03
fafs使能exfat了没

eric2013  请问如何使能  是不是要用R0.12
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
 楼主| 发表于 2022-3-1 10:44:34 | 显示全部楼层
马氏王朝 发表于 2022-3-1 10:28
eric2013  请问如何使能  是不是要用R0.12

对,从0.12版本开始支持了。
回复

使用道具 举报

0

主题

12

回帖

12

积分

新手上路

积分
12
发表于 2022-5-30 15:42:53 | 显示全部楼层
请问RL-USB库和这个有什么区别啊
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
 楼主| 发表于 2022-5-31 05:04:41 | 显示全部楼层
马氏王朝 发表于 2022-5-30 15:42
请问RL-USB库和这个有什么区别啊

这个是ST的库,RL-USB是ARM家MDK搞的。
回复

使用道具 举报

270

主题

605

回帖

1415

积分

至尊会员

积分
1415
发表于 2024-3-25 21:35:25 | 显示全部楼层
大佬还保存了 V2.2.0 的USB-HOST库没有呀。现在ST官网下载的都是 V2.2.1 的了,没有V2.2.0的可以下载了
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
 楼主| 发表于 2024-3-26 10:50:32 | 显示全部楼层
jplzl10000 发表于 2024-3-25 21:35
大佬还保存了 V2.2.0 的USB-HOST库没有呀。现在ST官网下载的都是 V2.2.1 的了,没有V2.2.0的可以下载了

下载我楼主位的例子,HOST部分的代码,我基本没动。
回复

使用道具 举报

78

主题

278

回帖

512

积分

金牌会员

积分
512
发表于 2024-10-12 07:12:08 | 显示全部楼层
caicaptain2 发表于 2018-8-9 10:11
感谢Eric的细心答复,已经可以正常跑起来了。接的PA口,Full-speed的。 实测,
64G USB3.0的U盘也可以正常 ...

USBH_Process(&USB_OTG_Core, &USB_Host)这个函数的确很敏感
回复

使用道具 举报

1

主题

3

回帖

6

积分

新手上路

积分
6
发表于 2025-5-29 18:09:12 | 显示全部楼层
static USBH_Status USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
{
  USBH_Status Status = USBH_BUSY;  
  uint8_t Local_Buffer[64];
  
  switch (phost->EnumState)
  {
  case ENUM_IDLE:  
    /* Get Device Desc for only 1st 8 bytes : To get EP0 MaxPacketSize */
    if ( USBH_Get_DevDesc(pdev , phost, 8) == USBH_OK)
    {
      phost->Control.ep0size = phost->device_prop.Dev_Desc.bMaxPacketSize;
      
      phost->EnumState = ENUM_GET_FULL_DEV_DESC;
      
      /* modify control channels configuration for MaxPacket size */
      USBH_Modify_Channel (pdev,
                           phost->Control.hc_num_out,
                           0,
                           0,
                           0,
                           phost->Control.ep0size);
      
      USBH_Modify_Channel (pdev,
                           phost->Control.hc_num_in,
                           0,
                           0,
                           0,
                           phost->Control.ep0size);      
    }
    break;
   
  case ENUM_GET_FULL_DEV_DESC:  
    /* Get FULL Device Desc  */
    if ( USBH_Get_DevDesc(pdev, phost, USB_DEVICE_DESC_SIZE)\
      == USBH_OK)
    {
      /* user callback for device descriptor available */
      phost->usr_cb->DeviceDescAvailable(&phost->device_prop.Dev_Desc);      
      phost->EnumState = ENUM_SET_ADDR;
    }
    break;
   
  case ENUM_SET_ADDR:
    /* set address */
    if ( USBH_SetAddress(pdev, phost, USBH_DEVICE_ADDRESS) == USBH_OK)
    {
      USB_OTG_BSP_mDelay(2);
      phost->device_prop.address = USBH_DEVICE_ADDRESS;
      
      /* user callback for device address assigned */
      phost->usr_cb->DeviceAddressAssigned();
      phost->EnumState = ENUM_GET_CFG_DESC;
      
      /* modify control channels to update device address */
      USBH_Modify_Channel (pdev,
                           phost->Control.hc_num_in,
                           phost->device_prop.address,
                           0,
                           0,
                           0);
      
      USBH_Modify_Channel (pdev,
                           phost->Control.hc_num_out,
                           phost->device_prop.address,
                           0,
                           0,
                           0);         
    }
    break;
   
  case ENUM_GET_CFG_DESC:  
    /* get standard configuration descriptor */
    if ( USBH_Get_CfgDesc(pdev,
                          phost,
                          USB_CONFIGURATION_DESC_SIZE) == USBH_OK)
    {
      /* before getting full config descriptor, check if it does not exceed
      buffer size allocated to config descriptor USBH_MAX_DATA_BUFFER
      in the usbh_conf.h*/
      if (phost->device_prop.Cfg_Desc.wTotalLength <= USBH_MAX_DATA_BUFFER)
      {
        phost->EnumState = ENUM_GET_FULL_CFG_DESC;
      }
    }
    break;
   
  case ENUM_GET_FULL_CFG_DESC:  
    /* get FULL config descriptor (config, interface, endpoints) */
    if (USBH_Get_CfgDesc(pdev,
                         phost,
                         phost->device_prop.Cfg_Desc.wTotalLength) == USBH_OK)
    {
      /* User callback for configuration descriptors available */
      phost->usr_cb->ConfigurationDescAvailable(&phost->device_prop.Cfg_Desc,
                                                      phost->device_prop.Itf_Desc,
                                                      phost->device_prop.Ep_Desc[0]);
      
      phost->EnumState = ENUM_GET_MFC_STRING_DESC;
    }
    break;
   
  case ENUM_GET_MFC_STRING_DESC:  
    if (phost->device_prop.Dev_Desc.iManufacturer != 0)
    { /* Check that Manufacturer String is available */
      
      if ( USBH_Get_StringDesc(pdev,
                               phost,
                               phost->device_prop.Dev_Desc.iManufacturer,
                               Local_Buffer ,
                               0xff) == USBH_OK)
      {
        /* User callback for Manufacturing string */
        phost->usr_cb->ManufacturerString(Local_Buffer);
        phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
      }
    }
    else
    {
      phost->usr_cb->ManufacturerString("N/A");      
      phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
    }
    break;
   
  case ENUM_GET_PRODUCT_STRING_DESC:   
    if (phost->device_prop.Dev_Desc.iProduct != 0)
    { /* Check that Product string is available */
      if ( USBH_Get_StringDesc(pdev,
                               phost,
                               phost->device_prop.Dev_Desc.iProduct,
                               Local_Buffer,
                               0xff) == USBH_OK)
      {
        /* User callback for Product string */
        phost->usr_cb->ProductString(Local_Buffer);
        phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
      }
    }
    else
    {
      phost->usr_cb->ProductString("N/A");
      phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
    }
    break;
   
  case ENUM_GET_SERIALNUM_STRING_DESC:   
    if (phost->device_prop.Dev_Desc.iSerialNumber != 0)
    { /* Check that Serial number string is available */   
      if ( USBH_Get_StringDesc(pdev,
                               phost,
                               phost->device_prop.Dev_Desc.iSerialNumber,
                               Local_Buffer,
                               0xff) == USBH_OK)
      {
        /* User callback for Serial number string */
        phost->usr_cb->SerialNumString(Local_Buffer);
        phost->EnumState = ENUM_SET_CONFIGURATION;
      }
    }
    else
    {
      phost->usr_cb->SerialNumString("N/A");      
      phost->EnumState = ENUM_SET_CONFIGURATION;
    }  
    break;
      
  case ENUM_SET_CONFIGURATION:
    /* set configuration  (default config) */
    if (USBH_SetCfg(pdev,
                    phost,
                    phost->device_prop.Cfg_Desc.bConfigurationValue) == USBH_OK)
    {
      phost->EnumState = ENUM_DEV_CONFIGURED;
    }
    break;

   
  case ENUM_DEV_CONFIGURED:
    /* user callback for enumeration done */
    Status = USBH_OK;
    break;
   
  default:
    break;
  }  
  return Status;
}


/**
  * @brief  USBH_HandleControl
  *         Handles the USB control transfer state machine
  * @param  pdev: Selected device
  * @retval Status
  */
USBH_Status USBH_HandleControl (USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
{
  uint8_t direction;  
  static uint16_t timeout = 0;
  USBH_Status status = USBH_OK;
  URB_STATE URB_Status = URB_IDLE;
  
  phost->Control.status = CTRL_START;

  
  switch (phost->Control.state)
  {
  case CTRL_SETUP:
    /* send a SETUP packet */
    USBH_CtlSendSetup     (pdev,
                           phost->Control.setup.d8 ,
                           phost->Control.hc_num_out);  
    phost->Control.state = CTRL_SETUP_WAIT;  
    break;
   
  case CTRL_SETUP_WAIT:
   
    URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);
    /* case SETUP packet sent successfully */
    if(URB_Status == URB_DONE)
    {
      direction = (phost->Control.setup.b.bmRequestType & USB_REQ_DIR_MASK);
      
      /* check if there is a data stage */
      if (phost->Control.setup.b.wLength.w != 0 )
      {        
        timeout = DATA_STAGE_TIMEOUT;
        if (direction == USB_D2H)
        {
          /* Data Direction is IN */
          phost->Control.state = CTRL_DATA_IN;
        }
        else
        {
          /* Data Direction is OUT */
          phost->Control.state = CTRL_DATA_OUT;
        }
      }
      /* No DATA stage */
      else
      {
        timeout = NODATA_STAGE_TIMEOUT;
        
        /* If there is No Data Transfer Stage */
        if (direction == USB_D2H)
        {
          /* Data Direction is IN */
          phost->Control.state = CTRL_STATUS_OUT;
        }
        else
        {
          /* Data Direction is OUT */
          phost->Control.state = CTRL_STATUS_IN;
        }
      }         
      /* Set the delay timer to enable timeout for data stage completion */
      phost->Control.timer = HCD_GetCurrentFrame(pdev);
    }
    else if(URB_Status == URB_ERROR)
    {
      phost->Control.state = CTRL_ERROR;     
      phost->Control.status = CTRL_XACTERR;
    }   
    break;
   
  case CTRL_DATA_IN:  
    /* Issue an IN token */
    USBH_CtlReceiveData(pdev,
                        phost->Control.buff,
                        phost->Control.length,
                        phost->Control.hc_num_in);

    phost->Control.state = CTRL_DATA_IN_WAIT;
    break;   
   
  case CTRL_DATA_IN_WAIT:
   
    URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in);
   
    /* check is DATA packet transferred successfully */
    if  (URB_Status == URB_DONE)
    {
      phost->Control.state = CTRL_STATUS_OUT;
    }
   
    /* manage error cases*/
    if  (URB_Status == URB_STALL)
    {
      /* In stall case, return to previous machine state*/
      phost->gState =   phost->gStateBkp;
      phost->Control.state = CTRL_STALLED;  
    }   
    else if (URB_Status == URB_ERROR)
    {
      /* Device error */
      phost->Control.state = CTRL_ERROR;   
    }
    else if ((HCD_GetCurrentFrame(pdev)- phost->Control.timer) > timeout)
    {
      /* timeout for IN transfer */
      phost->Control.state = CTRL_ERROR;
    }   
    break;
   
  case CTRL_DATA_OUT:
    /* Start DATA out transfer (only one DATA packet)*/
    pdev->host.hc[phost->Control.hc_num_out].toggle_out = 1;
        
    USBH_CtlSendData (pdev,
                      phost->Control.buff,
                      phost->Control.length ,
                      phost->Control.hc_num_out);
   
    phost->Control.state = CTRL_DATA_OUT_WAIT;
    break;
   
  case CTRL_DATA_OUT_WAIT:
   
    URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);     
    if  (URB_Status == URB_DONE)
    { /* If the Setup Pkt is sent successful, then change the state */
      phost->Control.state = CTRL_STATUS_IN;
    }
   
    /* handle error cases */
    else if  (URB_Status == URB_STALL)
    {
      /* In stall case, return to previous machine state*/
      phost->gState =   phost->gStateBkp;
      phost->Control.state = CTRL_STALLED;  
    }
    else if  (URB_Status == URB_NOTREADY)
    {
      /* Nack received from device */
      phost->Control.state = CTRL_DATA_OUT;
    }   
    else if (URB_Status == URB_ERROR)
    {
      /* device error */
      phost->Control.state = CTRL_ERROR;      
    }
    break;
   
   
  case CTRL_STATUS_IN:
    /* Send 0 bytes out packet */
    USBH_CtlReceiveData (pdev,
                         0,
                         0,
                         phost->Control.hc_num_in);
   
    phost->Control.state = CTRL_STATUS_IN_WAIT;
   
    break;
   
  case CTRL_STATUS_IN_WAIT:
   
    URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in);
   
    if  ( URB_Status == URB_DONE)
    { /* Control transfers completed, Exit the State Machine */
      phost->gState =   phost->gStateBkp;
      phost->Control.state = CTRL_COMPLETE;
    }
   
    else if (URB_Status == URB_ERROR)
    {
      phost->Control.state = CTRL_ERROR;  
    }
   
    else if((HCD_GetCurrentFrame(pdev)\
      - phost->Control.timer) > timeout)
    {
      phost->Control.state = CTRL_ERROR;
    }
     else if(URB_Status == URB_STALL)
    {
      /* Control transfers completed, Exit the State Machine */
      phost->gState =   phost->gStateBkp;
      phost->Control.state = CTRL_STALLED;
      status = USBH_NOT_SUPPORTED;
    }
    break;
   
  case CTRL_STATUS_OUT:
    pdev->host.hc[phost->Control.hc_num_out].toggle_out ^= 1;
    USBH_CtlSendData (pdev,
                      0,
                      0,
                      phost->Control.hc_num_out);
   
    phost->Control.state = CTRL_STATUS_OUT_WAIT;
    break;
   
  case CTRL_STATUS_OUT_WAIT:
   
    URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);  
    if  (URB_Status == URB_DONE)
    {
      phost->gState =   phost->gStateBkp;
      phost->Control.state = CTRL_COMPLETE;
    }
    else if  (URB_Status == URB_NOTREADY)
    {
      phost->Control.state = CTRL_STATUS_OUT;
    }      
    else if (URB_Status == URB_ERROR)
    {
      phost->Control.state = CTRL_ERROR;      
    }
    break;
   
  case CTRL_ERROR:
    /*
    After a halt condition is encountered or an error is detected by the
    host, a control endpoint is allowed to recover by accepting the next Setup
    PID; i.e., recovery actions via some other pipe are not required for control
    endpoints. For the Default Control Pipe, a device reset will ultimately be
    required to clear the halt or error condition if the next Setup PID is not
    accepted.
    */
    if (++ phost->Control.errorcount <= USBH_MAX_ERROR_COUNT)
    {
      /* Do the transmission again, starting from SETUP Packet */
      phost->Control.state = CTRL_SETUP;
    }
    else
    {
      phost->Control.status = CTRL_FAIL;
      phost->gState =   phost->gStateBkp;
      
      status = USBH_FAIL;
    }
    break;
   
  default:
    break;
  }
  return status;
}
/*******************************/
请教个问题,这是ST USB的驱动库,版本是V2.2.0,相对于之前的版本,解决了这个问题“在获取完整的配置描述符之前添加对分配给配置描述符的缓冲区大小的检查,USBH_MAX_DATA_BUFFER定义添加到 usbh_conf.h 中
”,但是我看的代码,这个宏定义和数组大小并没有关联起来,他是如何解决的?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 03:09 , Processed in 0.048050 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表