本文轉自公眾號系列文章,歡迎關注
基于DWC2的USB驅動開發-USB包詳解 (qq.com)
一.前言
本篇講解Scatter/Gather DMA模式下控制傳輸相關的寄存器??刂苽鬏斒?a target="_blank">USB驅動的核心部分,控制傳輸調通了驅動就完成了一大半,而驅動的核心又是中斷的處理。
二.控制傳輸相關的DMA描述符
Scatter/Gather DMA模式的優點是可以提供一個描述符鏈表,一次處理更多的數據,控制器自動去索引描述符鏈表,進行相應的DMA處理。而Buffer DMA模式一次只能處理一個DMA操作。
來簡單回顧下控制傳輸,控制傳輸包括
Setup,Data,Status三個階段,不是所有情況都需要包括三種階段,存在無數據階段的控制傳輸。
存在三種可能
控制寫
控制讀
無數據的控制傳輸,2階段控制傳輸。
控制傳輸需要準備以下幾種描述符
2.1.SETUP
為了接收最多可能存在的3個連續的SETUP包,所以需要準備一個描述符鏈表包括3個描述符。該描述符也可以用于接收控制讀傳輸主機發送的狀態包(0長包)。
該描述符鏈表的前面兩個還可以作為ping-pong提高接收效率。
第三個描述符,初始化為空,最終設置為以接收在數據和狀態階段主機又異常發了SETUP。
2.2IN
2.3OUT
三.控制傳輸相關的中斷處理
3.1相關寄存器
首先我們來看和中斷相關的一些寄存器,控制傳輸對應的就是端點0所以和其他端點其實是一樣的,只不過其多了一些比如SETUP等狀態而已。
首先我們來看相關的寄存器
首先全局的:GAHBCFG寄存器的bit0 GlblIntrMsk作為全局中斷的總開關,置位使能總中斷。
然后寄存器GINTMSK/2的bit19,bit18,OEPIntMsk和IEPIntMsk作為所有的OUT和IN端點的中斷使能,對應的狀態寄存器是GINTSTS/2。
然后DIEPMSK和DOEPMSK控制所有的OUT和IN端點的中斷類型,哪些使能。
對應的狀態寄存器是DIEPINTi 和DOEPINTi。
最后DAINTMSK控制某一個端點是否使能中斷。對應的狀態寄存器是DAINT。
注意
DIEPMSK和DOEPMSK是對所有端點的配置,不能對某一個端點使能某些類型中斷,對另外一個端點使能其他類型的中斷。
以上形成了金字塔式的總分式,層層控制的中斷開關控制。
而中斷的處理順序是層層解析的方式,先通過
DAINT查看是哪個端點產生的中斷,然后通過DIEPINTi 和DOEPINTi確認對應端點具體的中斷類型。
DAINT的標志的置位和清除是跟著DIEPINTi 和DOEPINTi變化的,該寄存器軟件只讀。對應DIEPINTi 和DOEPINTi寄存器有標志置位則該寄存器對應位置位,DIEPINTi 和DOEPINTi寄存器所有標志位清除則該寄存器對應位清除。
而GINTSTS.OEPInt和GINTSTS.IEPInt是跟著DAINT的狀態走的,軟件也是只讀的,DAINT對應位有置為則該位置位,DAINT中對應所有寄存器都清零,則該位也清零。
DIEPINTi 和DOEPINTi寄存器的標志都是寫1清零。所以對于IN和OUT中斷的標志清除,只需要對這兩個寄存器對應位寫1清零即可。DAINT和GINTSTS.OEPInt和GINTSTS.IEPInt是根據上述寄存器狀態硬件清除無需軟件手動清。
對比DIEPMSK和DIEPINTi可知,DIEP的NYET,Bble,PktDrp,TxFEmp是不受MASK控制的。
對比DOEPMSK和DOEPINTi可知,DOEP的StupPktRcvd,PktDrpSts是不受MASK控制的。
對比如IN和OUT中斷類型有一些相同的,有一些不一樣的,比如OUT多了Setup等。
拓撲結構如下
3.2中斷處理
前面提到控制傳輸對應端點0,和其他端點沒什么本質區別。其中斷狀態主要關注
DIEPINTn和DOEPINTn兩個寄存器以確定具體的中斷類型。
前面回顧了控制傳輸有3個階段,所以對于驅動編寫來說重點要知道當前處于什么階段以決定下一步軟件要怎么做,所以軟件一般使用狀態機記錄當前狀態然后根據中斷標志確定下一個階段。從上面可以看到DIEPINTn和DOEPINTn兩個寄存器有很多的中斷類型,并不是所有的都和控制傳輸的階段有關的,控制器設計時就考慮到了這一點,盡量精簡標志的邏輯,通過盡可能少的標志組合可以確定當前階段。
手冊《10.3.1 Interrupt Handling》中做了一個總結,
軟件只需要關心以下標志即可
DIEPINTn.XferCompl 如果描述符中IOC設置,表示IN端點對應的描述符處理完
DIEPINTn.InTknTxfEmp TxFIFO空時收到了主機發的IN令牌,此時設備沒有數據可回
DOEPINTn.XferCompl 如果描述符中IOC設置,表示OUT端點對應的描述符處理完
DOEPINTn.SetUp 表示控制器在Setup包后收到了IN和OUT令牌。
DOEPINTn.StsPhseRcvd 控制寫傳輸主機切換到了狀態階段,此時設備需要發狀態包(0長包)
當控制器看到需要為OUT端點設置多個中斷位時,控制器會對這些中斷設置進行一些優化,減少中斷的有效組合的數量,以簡化應用程序處理。
控制器對中斷處理的優先級如下
DOEPINTn.XferCompl>DOEPINTn.StsPhseRcvd(SI)>DOEPINTon.SetUp.
基于此,應用程序只需要解碼下表中所示的OUT端點的中斷組合:
場景 | StsPhseRcvd (SI) | SetUp (SPD) | XferCompl (IOC) | 說明 |
---|---|---|---|---|
A | 0 | 0 | 1 | 控制器更新了描述符,軟件需要查詢描述符的SR位以確定數據是SETUP包還是OUT傳輸的數據。 |
B | 0 | 1 | 0 | 前面收到了SETUP包且Setup階段完成,即收到了Setup包的內容。 |
C | 0 | 1 | 1 | 控制器更新了描述符,對應Setup包。且Setup階段完成。 |
D | 1 | 0 | 0 | 控制OUT傳輸,主機切換到了狀態階段。 |
E | 1 | 0 | 1 | 在A的基礎上且主機切換到了控制寫的狀態階段,即D+A. |
總結一下就是B和C確定當前處于Setup完成階段,根據Setup包內容軟件決定后面是發數據還是讀數據,還是回狀態包(無數據)。
D和E確定當前處于控制寫的狀態階段,設備需要回0長包。
A需要根據描述符的SR位以確定當前是收到的SETUP包還是OUT數據包。
四.總結
本篇重點介紹了中斷相關寄存器,以及OUT端點相關中斷的組合以確定當前處于控制傳輸的什么階段。兩者都是驅動編寫的重點需要理解的內容。下一篇我們繼續介紹控制傳輸,軟件的編寫。
審核編輯:湯梓紅
-
寄存器
+關注
關注
31文章
5325瀏覽量
120052 -
usb
+關注
關注
60文章
7903瀏覽量
264046 -
編程
+關注
關注
88文章
3596瀏覽量
93609 -
中斷
+關注
關注
5文章
895瀏覽量
41401 -
開發板
+關注
關注
25文章
4959瀏覽量
97214 -
代碼
+關注
關注
30文章
4753瀏覽量
68368 -
單板計算機
+關注
關注
0文章
74瀏覽量
15615 -
編譯
+關注
關注
0文章
654瀏覽量
32813 -
驅動開發
+關注
關注
0文章
130瀏覽量
12065 -
DWC2
+關注
關注
0文章
35瀏覽量
120
發布評論請先 登錄
相關推薦
評論