本文轉自公眾號,歡迎關注
基于DWC2的USB驅動開發-DOEP接收相關的DMA寄存器詳解 (qq.com)
前言
前面我們詳細介紹了發送即DIEP相關的一些寄存器,這一篇我們來看看接收即DOEP相關的一些寄存器。形式上DOEP和DIEP寄存器是類似的。不過我們看寄存器列表會發現DOEP會少一個寄存器DTXFSTSi ,
什么會少這個寄存器呢?
因為接收是所有端點共享一個接收緩沖區的,所以這里就沒有DRXFSTSi 這個對應的寄存器來表示每個端點對應的接收緩沖區剩余可用空間了。發送是可以配置為每個端點獨占一個緩沖區的所以有對應的寄存器。
雖然POEP少了一個寄存器,但是寄存器偏移地址上,還是和PIEP保持對應關系的,缺的位置還是預留了空間的,這對軟件來說比較方便,所以一般IP的設計也要考慮軟件的實現是否方便。
這一篇先來介紹DMA相關的寄存器,后面再講剩余的寄存器,為什么DMA寄存器要單獨講,因為其很重要,了解其是如何設置,如何更新,什么階段誰擁有等很重要,可以協助調試分析問題,并且DOEP和DIEP的DMA寄存器的行為有些許差異這點調試時是很重要的,所以這里重點講。
DOEPDMAi
該寄存器的偏移地址是
0xB14 + i*20,雖然端點0的寄存器手冊有單獨描述,但是其偏移地址還是符合該表達式的,實際描述內容也是重復的。
這樣所有的寄存器我們可以使用同樣的宏來尋址
#define DOEP_DMA(n) (OTG_BASE + (0xb14 + (n)*0x20))
這也是IP設計寄存器地址設置要考慮的,方便軟件編程。
我們來看手冊的描述
如果是 Scatter/Gather DMA模式則該寄存器設置為描述符鏈表的地址,否則則設置接收緩沖區的地址,DMA接收到數據自動從RxFIFO搬運到該處。
注意該寄存器必須8字節對齊。
該值在OUT DONE,接收到數據產生中斷后,軟件可以回讀其值,回讀的值為設置的值偏移已經處理的描述符或者已經接收的字節數。
注意該寄存器寫完后并不能立即回讀,此時回讀值為之前的值或者默認值,只有OUT DONE中斷接收到數據之后才能回讀,此時EPena硬件清零,回讀的值已經是按照上述描述更新的值。
在軟件設置該值(注意此時哪怕EPEna沒有置位也是一樣的)到OUT DONE中斷之前該寄存器由控制器所有,此時軟件不能再次寫,回讀也不能回讀出寫入的值。只有OUT DONE中斷之后EPEna硬件自動清零后才能讀會硬件更新的值,注意不是寫入值,時硬件根據處理了多少描述符或者接受了多少數據遞增后的值。
以下是實例
如下使用OUT端點2 設置
0x81012a0到DOEPDMAi ** ,** 0x81012a0是8字節對齊的,時描述符地址
執行完REG_DOEP_DMA(epnum) = (uint32_t)(pep->dma_addr);后回讀DOEPDMAi****的值并沒有更新,此時軟件不能再寫,回讀也不能讀出設置值
CTL寄存器的EPEna置位,SNAK變為了0表示不再NACK了,準備接收數據了
進入OUT DONE中斷再來看
CTL寄存器的EPEna位硬件清零0.表示接收到了數據
此時DOEPDMAi 0x81012a0變為了0x81012a8,因為只有以一個描述符,所以處理完后偏移了8字節。
DOEPDMABi
該寄存器的偏移地址是
0xB1C + i*20
從上面可以看到
0x0000000變為了
0x8100d58
之前是0x0000000是因為設置完后并不能回讀,實際的描述中對應的緩沖區是
0x8100d38,0x8100d58-0x8100d38正好是接收到的數據的長度。
總結
DMA相關的兩個寄存器非常重要,可以幫助調試,但是要注意寫入之后并不能馬上回讀,也不能再寫,需要OUT DONE之后才能回讀和重新寫,寫入該寄存器到OUT DONE中斷之前該寄存器都是控制器所有。
審核編輯:湯梓紅
-
寄存器
+關注
關注
31文章
5343瀏覽量
120348 -
usb
+關注
關注
60文章
7945瀏覽量
264636 -
dma
+關注
關注
3文章
561瀏覽量
100584 -
驅動開發
+關注
關注
0文章
130瀏覽量
12077 -
DWC2
+關注
關注
0文章
35瀏覽量
131
發布評論請先 登錄
相關推薦
評論