[应用相关] STM32 USB驱动

[复制链接]
10850|66
 楼主| chenqiang10 发表于 2018-8-29 22:09 | 显示全部楼层
驱动结构

  目前,独立版USB驱动并不是支持所有的STM3的芯片,且ST已经不再维护独立版的USB库(被Cube系列取代),具体见驱动源码即可。驱动源码的结构还是比较简单的,主要包含驱动库源码、使用示例、其他实用程序、发行说明文档四大部分。
 楼主| chenqiang10 发表于 2018-8-29 22:09 | 显示全部楼层
USB芯片也分为Controller部分和PHY部分。Controller部分主要实现USB的协议和控制。内部逻辑主要有MAC层、CSR层和FIFO控制层,还有其他低功耗管理之类层次。MAC实现按USB协议进行数据包打包和解包,并把数据按照UTMI总线格式发送给PHY(USB3.0为PIPE)。CSR层进行寄存器控制,软件对USB芯片的控制就是通过CSR寄存器,这部分和CPU进行交互访问,主要作为Slave通过AXI或者AHB进行交互。FIFO控制层主要是和DDR进行数据交互,控制USB从DDR搬运数据的通道,主要作为Master通过AXI/AHB进行交互。PHY部分功能主要实现并转串的功能,把UTMI或者PIPE口的并行数据转换成串行数据,再通过差分数据线输出到芯片外部。
  一般来说,如果usb phy封装在芯片内,基本采用UTMI+的接口。不封装到芯片内的一般采用ULPI接口,这样可以降低pin的数量。
  关于STM32芯片内嵌的OTG FS控制器、OTG HS控制器、OTG FS PHY具体见芯片手册。
 楼主| chenqiang10 发表于 2018-8-29 22:10 | 显示全部楼层
USB OTG full speed core

  OTG_FS 是一款双角色设备(DRD) 控制器,同时支持从机功能和主机功能,完全符合USB 2.0 规范的On-The-Go 补充标准。此外,该控制器也可配置为“仅主机”模式或“仅从机”模式,完全符合USB 2.0 规范。在主机模式下,OTG_FS 支持全速(FS,12 Mb/s)和低速(LS,1.5 Mb/s)收发器,而从机模式下则仅支持全速(FS,12 Mb/s)收发器。OTG_FS 同时支持HNP 和SRP。主机模式下需要的唯一外部设备是提供VBUS的电荷泵。
 楼主| chenqiang10 发表于 2018-8-29 22:10 | 显示全部楼层
OTG_FS 接口的通用特性如下:

经USB-IF 认证,符合通用串行总线规范第2.0 版
模块内嵌的PHY 还完全支持定义在标准规范OTG 补充第1.3 版中的OTG 协议
支持A-B 器件识别(ID 线)
支持主机协商协议(HNP) 和会话请求协议(SRP)
允许主机关闭VBUS以在OTG 应用中节省电池电量
支持通过内部比较器对VBUS电平采取监控
支持主机到从机的角色动态切换
可通过软件配置为以下角色:
具有SRP 功能的USB FS 从机(B 器件)
具有SRP 功能的USB FS/LS 主机(A 器件)
USB On-The-Go 全速双角色设备
支持FS SOF 和LS Keep-alive 令牌
SOF 脉冲可通过PAD 输出
SOF 脉冲从内部连接到定时器2 (TIM2)
可配置的帧周期
可配置的帧结束中断
具有省电功能,例如在USB 挂起期间停止系统、关闭数字模块时钟、对PHY 和DFIFO电源加以管理
具有采用高级FIFO 控制的1.25 KB 专用RAM
可将RAM 空间划分为不同FIFO,以便灵活有效地使用RAM
每个FIFO 可存储多个数据包
动态分配存储区
FIFO 大小可配置为非2 的幂次方值,以便连续使用存储单元
一帧之内可以无需要应用程序干预,以达到最大USB 带宽
 楼主| chenqiang10 发表于 2018-8-29 22:10 | 显示全部楼层
OTG_FS 接口在主机模式下具有以下主要特性和要求:

通过外部电荷泵生成VBUS电压。
多达8 个主机通道(管道):每个通道都可以动态实现重新配置,可支持任何类型的USB 传输。
内置硬件调度器可:
在周期性硬件队列中存储多达8 个中断加同步传输请求
在非周期性硬件队列中存储多达8 个控制加批量传输请求
管理一个共享RX FIFO、一个周期性TX FIFO 和一个非周期性TX FIFO,以有效使用USB 数据RAM。
 楼主| chenqiang10 发表于 2018-8-29 22:15 | 显示全部楼层
OTG_FS 接口在从机模式下具有以下特性:

1 个双向控制端点0
3 个IN 端点(EP),可配置为支持批量传输、中断传输或同步传输
3 个OUT 端点,可配置为支持批量传输、中断传输或同步传输
管理一个共享Rx FIFO 和一个Tx-OUT FIFO,以高效使用USB 数据RAM
管理多达4 个专用Tx-IN FIFO(分别用于每个使能的IN EP),降低应用程序负荷
支持软断开功能。
 楼主| chenqiang10 发表于 2018-8-29 23:17 | 显示全部楼层
模块内嵌DMA,并可软件配置AHB 的突发传输类型
具备省电功能,例如在USB 挂起期间停止系统时钟,关闭数字模块内部时钟域、PHY 和DFIFO 电源管理
具有包含高级FIFO 管理的专用4K 字节数据RAM:
可以将存储区配置为不同FIFO,以便灵活高效地使用RAM
每个FIFO 可包含多个数据包
动态地进行存储器分配
FIFO 大小可配置为2 的幂以外的值,以便连续使用存储区
一帧之内可以无需要应用程序干预,以达到最大USB 带宽
 楼主| chenqiang10 发表于 2018-8-29 23:18 | 显示全部楼层
主机模式下的OTG_HS 接口特征如下:

需要外部电荷泵来生成VBUS
具有多达12 个主机通道(管道),每个通道可动态地进行重新配置,可支持任何类型的USB 传输
内置硬件调度器:
在周期性硬件队列中存储多达8 个中断加同步传输请求
在非周期性硬件队列中存储多达8 个控制加批量传输请求
管理一个共享RX FIFO、一个周期性TX FIFO 和一个非周期性TX FIFO,以有效使用USB 数据RAM
在主机模式下具备对SOF 帧周期进行动态调校的功能
 楼主| chenqiang10 发表于 2018-8-29 23:19 | 显示全部楼层
OTG_HS 接口在从机模式下具有以下特性:

具有1 个双向控制端点0
具有5 个IN 端点(EP),可配置为支持批量、中断或同步传输
具有5 个OUT 端点,可配置为支持批量、中断或同步传输
管理一个共享Rx FIFO 和一个Tx-OUT FIFO,可高效使用USB 数据RAM
管理多达6 个专用Tx-IN FIFO(每个IN 配置的EP 使用一个)以降低应用程序负载
具备软断开功能
 楼主| chenqiang10 发表于 2018-8-30 12:21 | 显示全部楼层
Low level driver structures

该部分使用一个结构体USB_OTG_CORE_HANDLE来定义需要使用的变量、状态和缓冲区等。这个结构体也是用户在使用时需要重点关注的第一个结构体。具体如下:

  1. typedef struct USB_OTG_handle
  2. {
  3.   USB_OTG_CORE_CFGS    cfg;
  4.   USB_OTG_CORE_REGS    regs;
  5. #ifdef USE_DEVICE_MODE
  6.   DCD_DEV     dev;
  7. #endif
  8. #ifdef USE_HOST_MODE
  9.   HCD_DEV     host;
  10. #endif
  11. #ifdef USE_OTG_MODE
  12.   OTG_DEV     otg;
  13. #endif
  14. }
  15. USB_OTG_CORE_HANDLE , *PUSB_OTG_CORE_HANDLE;


 楼主| chenqiang10 发表于 2018-8-30 12:21 | 显示全部楼层

同时在使用DMA时,需要注意:

  • 目前,DMA仅在高速模式下使用。
  • 在使用DMA时,必须要保证所有需要处理DMA 收发Buf的结构体必须是四字节对齐的。所以,USB_OTG_handle(其封装了所有内部Buffer和变量)必须要四字节对齐。具体可使用如下代码:
    1. #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
    2.   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    3.     #pragma data_alignment=4   
    4.   #endif
    5. #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
    6. __ALIGN_BEGIN USB_OTG_CORE_HANDLE USB_OTG_Core __ALIGN_END;


 楼主| chenqiang10 发表于 2018-8-30 12:22 | 显示全部楼层
USB OTG low level driver中的Host层

  该部分主要是指usb_hcd.c/h和usb_hcd_int.c/h两个文件。在初始化主机驱动程序(HCD)之后,低级驱动程序为数据和URB状态监视保存多个结构和缓冲区。 主机通道结构保存在主机驱动程序中,并通过主机号索引从上层访问。USB Host 的定义结构:

  1. typedef struct _HCD
  2. {
  3.   uint8_t                  Rx_Buffer [MAX_DATA_LENGTH];  /* 此缓冲区保存IN数据包,并可以从全局主机核心结构直接访问,如下所示:pdev-> host.Rx_Buffer。*/
  4.   __IO uint32_t            ConnSts; /* 连接状态。 它可以直接或通过使用HCD_IsDeviceConnected()函数进行访问。 */
  5.   __IO uint32_t            PortEnabled;  /* */
  6.   __IO uint32_t            ErrCnt[USB_OTG_MAX_TX_FIFOS];  /* 在一次传输过程中保存通道上的错误数量。 */
  7.   __IO uint32_t            XferCnt[USB_OTG_MAX_TX_FIFOS]; /* 保存已在Rx_Buffer中接收和可用的IN数据的数量。 它可以直接访问或使用GetXferCnt()函数访问。*/
  8.   __IO HC_STATUS           HC_Status[USB_OTG_MAX_TX_FIFOS];  /* 由驱动程序内部使用。 可被上层访问。它保存一个通道上的当前传输的状态 */
  9.   __IO URB_STATE           URB_State[USB_OTG_MAX_TX_FIFOS]; /* 该变量保持主机通道上的传输状态。*/
  10.   USB_OTG_HC               hc [USB_OTG_MAX_TX_FIFOS];
  11.   uint16_t                 channel [USB_OTG_MAX_TX_FIFOS]; /* 这个变量管理主机通道状态(使用或空闲)。 */
  12. }
  13. HCD_DEV , *USB_OTG_USBH_PDEV;


 楼主| chenqiang10 发表于 2018-8-30 13:25 | 显示全部楼层
usb_hcd_int.c/h文件中使用如下结构来处理USB中断
  1. typedef struct _USBH_HCD_INT
  2. {
  3.   uint8_t (* SOF) (USB_OTG_CORE_HANDLE *pdev);
  4.   uint8_t (* DevConnected) (USB_OTG_CORE_HANDLE *pdev);
  5.   uint8_t (* DevDisconnected) (USB_OTG_CORE_HANDLE *pdev);
  6.   uint8_t (* DevPortEnabled) (USB_OTG_CORE_HANDLE *pdev);  
  7.   uint8_t (* DevPortDisabled) (USB_OTG_CORE_HANDLE *pdev);
  8. }USBH_HCD_INT_cb_TypeDef;

  9. extern USBH_HCD_INT_cb_TypeDef *USBH_HCD_INT_fops;


 楼主| chenqiang10 发表于 2018-8-30 13:25 | 显示全部楼层
在库层中,一旦定义了USBH_HCD_INT_cb_TypeDef结构,就应该将其分配给USBH_DCD_INT_fops指针。因为库内部实际使用变量USBD_HCD_INT_fops。
必须在中断中引用函数uint32_t USBH_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
 楼主| chenqiang10 发表于 2018-8-30 13:27 | 显示全部楼层
USB OTG low level driver中的Device层

  该部分主要是指usb_dcd.c/h和usb_dcd_int.c/h两个文件。这两个文件主要是定义实现USB作为Device时的每个断点的收发缓冲器、起始地址等。USB Device的定义结构:

  1. /* DCD_DEV结构包含用于实时保存与设备有关的所有信息,控制传输状态机以及端点信息和状态的所有变量和结构。
  2. 在此结构中,device_config保存当前的USB设备配置,device_state控制具有以下状态的状态机:
  3. // EP0 State
  4. #define USB_OTG_EP0_IDLE        0
  5. #define USB_OTG_EP0_SETUP       1
  6. #define USB_OTG_EP0_DATA_IN     2
  7. #define USB_OTG_EP0_DATA_OUT    3
  8. #define USB_OTG_EP0_STATUS_IN   4
  9. #define USB_OTG_EP0_STATUS_OUT  5
  10. #define USB_OTG_EP0_STALL       6
  11. 在这个结构中,device_status定义了连接,配置和电源状态:
  12. // Device Status
  13. #define USB_OTG_DEFAULT        0
  14. #define USB_OTG_ADDRESSED      1
  15. #define USB_OTG_CONFIGURED     2
  16. */
  17. typedef struct _DCD
  18. {
  19.   uint8_t        device_config;
  20.   uint8_t        device_state;
  21.   uint8_t        device_status;
  22.   uint8_t        device_old_status;
  23.   uint8_t        device_address;
  24.   uint8_t        connection_status;  
  25.   uint8_t        test_mode;
  26.   uint32_t       DevRemoteWakeup;
  27.   USB_OTG_EP     in_ep   [USB_OTG_MAX_TX_FIFOS];
  28.   USB_OTG_EP     out_ep  [USB_OTG_MAX_TX_FIFOS];
  29.   uint8_t        setup_packet [8*3];
  30.   USBD_Class_cb_TypeDef         *class_cb;
  31.   USBD_Usr_cb_TypeDef           *usr_cb;
  32.   USBD_DEVICE                   *usr_device;  
  33.   uint8_t        *pConfig_descriptor;
  34. }
  35. DCD_DEV , *DCD_PDEV;


 楼主| chenqiang10 发表于 2018-8-30 13:27 | 显示全部楼层
usb_dcd_int.c/h文件中使用如下结构来处理USB中断
  1. typedef struct _USBD_DCD_INT
  2. {
  3.   uint8_t (* DataOutStage) (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
  4.   uint8_t (* DataInStage)  (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
  5.   uint8_t (* SetupStage) (USB_OTG_CORE_HANDLE *pdev);
  6.   uint8_t (* SOF) (USB_OTG_CORE_HANDLE *pdev);
  7.   uint8_t (* Reset) (USB_OTG_CORE_HANDLE *pdev);
  8.   uint8_t (* Suspend) (USB_OTG_CORE_HANDLE *pdev);
  9.   uint8_t (* Resume) (USB_OTG_CORE_HANDLE *pdev);
  10.   uint8_t (* IsoINIncomplete) (USB_OTG_CORE_HANDLE *pdev);
  11.   uint8_t (* IsoOUTIncomplete) (USB_OTG_CORE_HANDLE *pdev);  

  12.   uint8_t (* DevConnected) (USB_OTG_CORE_HANDLE *pdev);
  13.   uint8_t (* DevDisconnected) (USB_OTG_CORE_HANDLE *pdev);   

  14. }USBD_DCD_INT_cb_TypeDef;


 楼主| chenqiang10 发表于 2018-8-30 13:29 | 显示全部楼层
在库层中,一旦定义了USBD_DCD_INT_cb_TypeDef结构,就应该将其分配给USBD_DCD_INT_fops指针。因为库内部实际使用变量USBD_DCD_INT_fops。
必须在中断中引用函数uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
 楼主| chenqiang10 发表于 2018-8-30 13:29 | 显示全部楼层
对于全速模式,会使用芯片内嵌的全速的PHY。只能工作在全速模式
对于高速模式,用户可以选择两种PHY:
ULPI接口的外部高速PHY:此时,USB HS Core将以高速模式运行。 此时用户可以通过修改usb_core.c文件中OTG_HS_GUSBCFG寄存器的ULPIFSLS比特位来修改为全速模式。
芯片内嵌的全速PHY:USB HS Core将以全速模式运行。尽管选择了高速。
 楼主| chenqiang10 发表于 2018-8-30 13:29 | 显示全部楼层
SB Host库是基于支持Host模式、Device模式和OTG模式的通用USB OTG低级驱动程序的,其适用于高速,全速和低速(主机模式)。
  USBHost的移植配置部分见另一篇博文。

支持多数据包传输功能,可传输大量数据; 而不必将其分成最大数据包大小的传输。
使用配置文件更改核心和库配置,而不更改库代码(只读)。
32位对齐的数据结构在高速模式下处理基于DMA的传输。
从用户级别支持多个USB OTG核心实例。
围绕全局状态机构建。
完全兼容实时操作系统(RTOS)。
 楼主| chenqiang10 发表于 2018-8-30 13:38 | 显示全部楼层
usbh_core (.c, .h):该文件包含处理所有USB通信和状态机的功能。
usbh_stdreq(.c, .h) :该文件实现设备枚举的标准请求。
USBH_Get_CfgDesc:获取配置描述符请求。
USBH_Get_DevDesc:获取设备描述符请求。
USBH_Get_StringDesc:获取字符串描述符请求。
USBH_GetDescriptor:通用获取描述符请求
USBH_SetCfg:设置配置请求。选择默认配置(配置0)
USBH_SetAddress:设置地址请求。将地址设置为1
USBH_ClrFeature:清除特征的请求
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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