USB学习笔记(4)STM32关于USB库的解读

USB学习笔记(4)STM32关于USB库的解读

为了方便在STM32上实现USB功能,本文对USB库的文件进行解读。

USB-FS_Device peripheral interface(外围接口)

1. usb_regs(.h/.c)

此模块实现硬件抽象层,提供访问USB外围寄存器的基本功能。

  • 通用寄存器函数
寄存器偏移量功能说明
CNTR0x40void SetCNTR(uint16_t wValue)设置USB控制寄存器
uint16_t GetCNTR(void)获取USB控制寄存器值
ISTR0x44void SetISTR(uint16_t wValue)设置USB中断状态寄存器
uint16_t GetISTR(void)获取USB中断状态寄存器
FNR0x48uint16_t GetFNR(void)获取USB帧编号寄存器
DADDR0x4Cvoid SetDADDR(uint16_t wValue)设置USB设备地址寄存器
uint16_t GetDADDR(void)获取USB设备地址寄存器值
BTABLE0x50void SetBTABLE(uint16_t wValue)设置USB分组缓冲区描述表地址寄存器
uint16_t GetBTABLE(void)获取USB分组缓冲区描述表地址寄存器值
  • 端点寄存器函数

Endpoint set/get value:获取或者设置端点寄存器的值

void SetENDPOINT(uint8_t bEpNum,uint16_t wRegValue) 
uint16_t GetENDPOINT(uint8_t bEpNum) 

Endpoint TYPE field:获取或者设置端点类型

#define EP_BULK         (0x0000) // 批量端点
#define EP_CONTROL      (0x0200) // 控制端点
#define EP_ISOCHRNOUS   (0x0400) // 同步端点
#define EP_INTERRUPT    (0x0600) // 中断端点

void SetEPType (uint8_t bEpNum, uint16_t wtype) 
uint16_t GetEPType (uint8_t bEpNum) 

Endpoint STATUS field:获取或者设置端点发送或者接受状态

#define EP_TX_DIS       (0x0000) // 端点忽略所有的发送请求
#define EP_TX_STALL     (0x0010) // 端点以STALL分组响应所有的发送请求
#define EP_TX_NAK       (0x0020) // 端点以NAK分组响应所有发送请求
#define EP_TX_VALID     (0x0030) // 端点可以用于发送
#define EP_RX_DIS       (0x0000) // 端点忽略所有的接受请求
#define EP_RX_STALL     (0x1000) // 端点以STALL分组响应所有的接受请求
#define EP_RX_NAK       (0x2000) // 端点以NAK分组响应所有接受请求
#define EP_RX_VALID     (0x3000) // 端点可以用于接受

void SetEPTxStatus(uint8_t bEpNum,uint16_t wState) 
void SetEPRxStatus(uint8_t bEpNum,uint16_t wState) 

uint16_t GetEPTxStatus(uint8_t bEpNum)
uint16_t GetEPRxStatus(uint8_t bEpNum)

Endpoint KIND field:设置端点特殊类型位,需要和TYPE位搭配使用

EP_TYPEEP_KIND意义
BULKDBL_BUF,双缓冲端点
CONTROLSTATUS_OUT
IOS未使用
INTERRUPT未使用
void SetEP_KIND(uint8_t bEpNum)
void ClearEP_KIND(uint8_t bEpNum)

void Set_Status_Out(uint8_t bEpNum)
void Clear_Status_Out(uint8_t bEpNum)

void SetEPDoubleBuff(uint8_t bEpNum)
void ClearEPDoubleBuff(uint8_t bEpNum)

//正确接受/发送标志位
void ClearEP_CTR_RX(uint8_t bEpNum)
void ClearEP_CTR_TX(uint8_t bEpNum)

Data Toggle Rx/Tx fields:数据包类型翻转

void ToggleDTOG_RX(uint8_t bEpNum)
void ToggleDTOG_TX(uint8_t bEpNum)

Address field:设置/获取端点地址,在使能端点前,需要给端点设置地址

void SetEPAddress(uint8_t bEpNum,uint8_t bAddr)
uint8_t GetEPAddress(uint8_t bEpNum)
  • 缓冲区描述表函数:这些函数用于设置或获取端点的接收和发送缓冲区地址和大小。

Tx/Rx buffer address fields

void SetEPTxAddr(uint8_t bEpNum,uint16_t wAddr);
void SetEPRxAddr(uint8_t bEpNum,uint16_t wAddr);

uint16_t GetEPTxAddr(uint8_t bEpNum);
uint16_t GetEPRxAddr(uint8_t bEpNum);

Tx/Rx buffer counter fields

void SetEPTxCount(uint8_t bEpNum,uint16_t wCount);
void SetEPRxCount(uint8_t bEpNum,uint16_t wCount);

uint16_t GetEPTxCount(uint8_t bEpNum);
uint16_t GetEPRxCount(uint8_t bEpNum);
  • 双缓冲区端点函数:为了获得大量或等时模式下的高数据传输吞吐量,必须对双缓冲模式进行编程。在这种操作模式下,端点寄存器和缓冲区描述的某些字段有不同的含义。

通过设置EP-KIND位,可以将编程为在批量模式下工作的端点设置为双缓冲。

void SetEPDoubleBuff(uint8_t bEpNum);

在双缓冲模式下,端点变为单向,并应用未使用方向的缓冲区作为第二个缓冲区来处理。

从应用程序中释放正在使用的缓冲区,

void FreeUserBuffer(uint8_t bEpNum, uint8_t bDir);

地址和计数器必须以不同的方式处理。Rx和TX地址和计数器单元变成Buffer0和Buffer1单元。

Double buffer addresses

void SetEPDblBuffAddr(uint8_t bEpNum,uint16_t wBuf0Addr,uint16_t wBuf1Addr);
void SetEPDblBuf0Addr(uint8_t bEpNum,uint16_t wBuf0Addr);
void SetEPDblBuf1Addr(uint8_t bEpNum,uint16_t wBuf1Addr);

uint16_t GetEPDblBuf0Addr(uint8_t bEpNum);
uint16_t GetEPDblBuf1Addr(uint8_t bEpNum);

Double buffer counters

void SetEPDblBuffCount(uint8_t bEpNum, uint8_t bDir, uint16_t wCount);
void SetEPDblBuf0Count(uint8_t bEpNum, uint8_t bDir, uint16_t wCount); 
void SetEPDblBuf1Count(uint8_t bEpNum, uint8_t bDir, uint16_t wCount);

uint16_t GetEPDblBuf0Count(uint8_t bEpNum);
uint16_t GetEPDblBuf1Count(uint8_t bEpNum);

Double buffer STATUS

STALL状态由下面的函数控制,其他状态用之前单模式下的函数控制。

void SetDouBleBuffEPStall(uint8_t bEpNum,uint8_t bDir)

2. usb_int(.h/.c)

此模块处理正确的传输中断服务例程;它提供USB设备协议事件和库之间的链接。

  1. CTR_LP(): 低优先级中断:由函数CTR_LP()管理,用于控制,中断和批量(在简单的缓冲模式下)。
  2. CTR_HP(): 高优先级中断:由函数CTR_HP()管理,用于像等时和批量(双缓冲模式)这样更快的传输模式)。

3. usb_mem(.h/.c)

此模块将用户缓冲区数据复制到PMA缓冲区(USB设备与主机通讯使用的数据缓冲区),反之亦然

void UserToPMABufferCopy(uint8_t *pbUsrBuf,uint16_t wPMABufAddr, uint16_t 
wNBytes);	
void PMAToUserBufferCopy(uint8_t *pbUsrBuf,uint16_t wPMABufAddr, uint16_t 
wNBytes);

USB-FS-Device_Driver medium layer(中间层模块)

1. usb_init(.h/.c)

此模块设置将在库中使用的初始化例程和全局变量

2. usb_core(.h/.c)

此模块是库的"内核"。它实现了USB2.0规范第9章中描述的所有功能。

可用的子程序包括与控制端点(ENDP0)相关的USB标准请求的处理,提供了完成枚举阶段序列所需的代码。

实现状态机是为了处理设置事务的不同阶段。

该USB内核模块还使用结构User_Standard_Requests实现标准请求和用户实现之间的动态接口。

USB内核就会向用户程序发送特定类的请求和一些总线事件。用户处理程序在Device_Property结构中给出。

  • Device table structure:DEVICE

      typedef struct _DEVICE { 
       uint8_t Total_Endpoint;         //USB应用程序使用的端点数
       uint8_t Total_Configuration;    //USB应用程序的配置数量
      } DEVICE;
    
  • Device information structure:DEVICE_INFO

由于该结构在库中的任何地方都使用,因此定义了一个全局变量pInformation,以便于访问Device_Info表,它是指向DEVICE_INFO结构的指针。pInformation = &Device_Info.

	typedef struct _DEVICE_INFO
	{
	  uint8_t USBbmRequestType;             /* bmRequestType */
	  uint8_t USBbRequest;                  /* bRequest */
	  uint16_t_uint8_t USBwValues;          /* wValue */
	  uint16_t_uint8_t USBwIndexs;          /* wIndex */
	  uint16_t_uint8_t USBwLengths;         /* wLength */
	
	  uint8_t ControlState;                 //控制过程所处的状态:CONTROL_STATE
	  uint8_t Current_Feature;              //当前设备特性。它受到SET_FEATURE和CLEAR_FEATURE请求的影响并由GET_STATUS请求检索。用户代码不使用此字段。
	  uint8_t Current_Configuration;        //当前配置状态。它分别由SET_CONFIGURATION和GET_CONFIGURATION请求设置和检索
	  uint8_t Current_Interface;            //当前接口
	  uint8_t Current_AlternateSetting;     //当前工作配置和接口选择的替代设置。它由SET_INTERFACE和GET_INTERFACE请求设置和检索
	  ENDPOINT_INFO Ctrl_Info;              //端点等待发送的字符串信息
	}DEVICE_INFO;


	typedef struct _ENDPOINT_INFO
	{
	  uint16_t  Usb_wLength;						//字符串长度
	  uint16_t  Usb_wOffset;						//字符串发送的偏移量
	  uint16_t  PacketSize;							//包的大小
	  uint8_t   *(*CopyData)(uint16_t Length);
	}ENDPOINT_INFO;									/*端点等待发送的字符串信息*/
  • Device property structure:DEVICE_PROP

      typedef struct _DEVICE_PROP { 
      	void (*Init)(void); 
      	void (*Reset)(void); 
      	void (*Process_Status_IN)(void); 
      	void (*Process_Status_OUT)(void); 
      	RESULT (*Class_Data_Setup)(uint8_t RequestNo); 
      	RESULT (*Class_NoData_Setup)(uint8_t RequestNo); 
      	RESULT (*Class_Get_Interface_Setting)(uint8_t Interface,uint8_t 
      	AlternateSetting);
      	uint8_t* (*GetDeviceDescriptor)(uint16_t Length); 
      	uint8_t* (*GetConfigDescriptor)(uint16_t Length); 
      	uint8_t* (*GetStringDescriptor)(uint16_t Length); 
      	void* RxEP_buffer; /* This field is not used in current library version. 
      	It is kept only for compatibility with previous versions */
      	uint8_t MaxPacketSize; 
      } DEVICE_PROP;
    
  • User standard request structure:
    USER_STANDARD_REQUESTS 标准请求中的用户代码

      typedef struct _USER_STANDARD_REQUESTS {
      	void(*User_GetConfiguration)(void);
      	void(*User_SetConfiguration)(void);
      	void(*User_GetInterface)(void);
      	void(*User_SetInterface)(void);
      	void(*User_GetStatus)(void);
      	void(*User_ClearFeature)(void);
      	void(*User_SetEndPointFeature)(void);
      	void(*User_SetDeviceFeature)(void);
      	void(*User_SetDeviceAddress)(void);
      } USER_STANDARD_REQUESTS;
    

3. usb_sil(.h/.c)

此模块为USB_FS_Device外围设备实现了额外的抽象层。它提供了访问读写操作端点的简单函数

void USB_SIL_Write(uint32_t EPNum, uint8_t* pBufferPointer, uint32_t 
wBufferSize);

uint32_t USB_SIL_Read(uint32_t EPNum, uint8_t* pBufferPointer);

4. usb_type.h/usb_def.h

此模块提供了库中使用的主要类型和USB定义。

5. platform_config.h

此模块负责为每个eval板提供特定的配置。 此文件应复制到应用程序文件夹,然后由用户在该文件夹中配置。

Application interface(应用程序接口)

应用程序接口的模块作为模板提供,它们必须由应用程序开发人员为每个应用程序量身定做

1. usb_conf.h/usb_endp.c

此模块自定义USB端点,以及端点回调函数等信息

2. usb_desc(.h/.c)

此模块应该包含与应用程序相关的所有USB描述符。用户必须根据应用程序、程序和类设置这些描述符

3. usb_prop(.h/.c)

此模块用于实现USB核心使用的Device_PropertyDevice_TableUSER_STANDARD_REQUEST结构。

Device_Property

  • void Init(void):USB外设的初始化程序。在应用程序开始时调用一次来管理初始化过程

  • void Reset(void):USB外设的复位程序。当设备从总线接收到重置信号时,就会调用它。用户程序应在此过程中设置端点功能。

  • void Process_Status_IN(void):回调过程,它是在阶段中的状态完成时调用的。用户程序可以通过这个回调来控制执行与类和应用程序相关的进程。

  • void Process_Status_OUT(void):回调过程,当状态退出阶段完成时调用它。与Process_Status_IN一样,用户程序可以在状态退出阶段之后执行操作

  • RESULT (see note below) *(Class_Data_Setup)(uint8_t RequestNo):回调过程,当一个类请求被识别并且这个请求需要一个数据阶段时调用它。

  • RESULT (*Class_NoData_Setup)(uint8_t RequestNo):回调过程,它是在识别非标准设备请求时调用的,不需要数据阶段。

  • RESULT (*Class_GET_Interface_Setting)(uint8_t Interface, uint8_t AlternateSetting):此例程用于测试接收到的集合接口标准请求。

  • uint8_t* GetDeviceDescriptor(uint16_t Length):获取设备描述符。

  • uint8_t* GetConfigDescriptor(uint16_t Length):获取配置描述符。

  • uint8_t* GetStringDescriptor(uint16_t Length):获取字符串描述符。

  • uint16_t MaxPacketSize:设备默认控制端点的最大数据包大小。

RESULT 返回结果:

typedef enum _RESULT {
	USB_SUCCESS = 0,    /* 请求过程成功 */
	USB_ERROR,          /* 请求过程错误 */
	USB_UNSUPPORT,      /* 请求不支持 */
	USB_NOT_READY       /* 请求过程还没结束,端点将以NAK满足进一步的请求 */
} RESULT;

USER_STANDARD_REQUEST

  • void (*User_GetConfiguration)(void): 获取配置描述符的标准请求
  • void (*User_SetConfiguration)(void): 设置配置描述符的标准请求
  • void (*User_GetInterface)(void): 获取接口描述符的标准请求
  • void (*User_SetInterface)(void): 设置接口描述符的标准请求
  • void (*User_GetStatus)(void): 获取接口描述符的标准请求
  • void (*User_ClearFeature)(void): 在收到Clear Feature Standard请求后调用。
  • void (*User_SetEndPointFeature)(void): 在收到设置的Feature Standard请求后调用(仅针对端点接收方)。
    Standard request (only for endpoint recipient).
  • void (*User_SetDeviceFeature)(void): 在收到设置的特性标准请求后调用(仅用于设备接收方)。
  • void (*User_SetDeviceAddress)(void): 在收到设置的地址标准请求后调用。

4. usb_istr.c

此模块提供了一个名为USB_Istr()的函数,它处理所有USB中断

5. usb_pwr(.h/.c)

此模块管理USB设备的电源管理

函数说明
RESULT Power_on(void)关闭
RESULT Power_off(void)打开
void Suspend(void)挂起
void Resume(RESUME_STATE eResumeSetVal)唤醒

我的个人博客网址:一个点的频率 希望大家关注一下,谢谢!!!


版权声明:本文为weixin_49467863原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。