USB學習筆記(4)STM32關於USB庫的解讀

2020-08-11 23:35:41

USB學習筆記(4)STM32關於USB庫的解讀

爲了方便在STM32上實現USB功能,本文對USB庫的檔案進行解讀。

USB-FS_Device peripheral interface(外圍介面)

1. usb_regs(.h/.c)

此模組實現硬體抽象層,提供存取USB外圍暫存器的基本功能。

  • 通用暫存器函數
暫存器 偏移量 功能 說明
CNTR 0x40 void SetCNTR(uint16_t wValue) 設定USB控制暫存器
uint16_t GetCNTR(void) 獲取USB控制暫存器值
ISTR 0x44 void SetISTR(uint16_t wValue) 設定USB中斷狀態暫存器
uint16_t GetISTR(void) 獲取USB中斷狀態暫存器
FNR 0x48 uint16_t GetFNR(void) 獲取USB幀編號暫存器
DADDR 0x4C void SetDADDR(uint16_t wValue) 設定USB裝置地址暫存器
uint16_t GetDADDR(void) 獲取USB裝置地址暫存器值
BTABLE 0x50 void 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_TYPE EP_KIND意義
BULK DBL_BUF,雙緩衝端點
CONTROL STATUS_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) 喚醒

我的個人部落格網址:一個點的頻率 希望大家關注一下,謝謝!!!