ARM9與FPGA並口通訊的實現
並口通訊是最常用基礎功能,實現ARM9與FPGA的並口通訊有兩種方式,一種頗為巧妙,利用SMC(Static Memory Controllor),其中的使能點都通過暫存器可以輕鬆控制;另一種方式就是通過GPIO來完成。
由於我拿到板子硬體的DRAM_CSN0、DRAM_WEN和DRAM_RDN在前期PCB設計時沒有充分考慮過SMC可能被使用,故使用接外掛上其他引腳進行代替,使用了圖1中畫圈的三根引腳SPI0_MOSI、SPI0_SCK、SPI0_CS。因為這三根引腳可以複用為GPIO,所以在並口除錯中將這三根引腳當作GPIO來使用。
圖1
圖2
圖3
表1
原 |
GPIO |
FPGA引腳 |
功能 |
SPI0_MOSI |
PA1 |
W21 |
寫使能 |
SPI0_SCK |
PA2 |
W22 |
讀使能 |
SPI0_CS |
PA3 |
W20 |
片選 |
硬體連線對應情況如圖2、圖3和表1所示。到此,你應該已經瞭解了實現通訊需要關注的引腳了吧。
工程步驟:
1重設Pin Planner
根據當前硬體的實際連線情況,對Quartus中的Pin
Planner進行更新,將訊號i_rd_cpu、i_wr_cpu、i_select對應的location
圖4
2對PIOA的暫存器組重新初始化
在最初的驅動程式中包括了對GPIO的初始化,經過試驗觀察PIO可讀暫存器的內容發現暫存器的配置不能滿足本任務的完成,使用已有的初始化會干擾到使能訊號的操作,於是要對GPIO進行重新初始化,對暫存器進行配置。
2.1PIO_PER暫存器
圖5
該暫存器是用來啟用PIOA各個引腳的GPIO模式,如圖5所示,每一位都對應控制著一根GPIO管腳,通過給P1、P2、P3置1激活了PA1、PA2、PA3的GPIO模式,同時也等於關閉了複用外圍A、B的模式。
2.2 PIO_OER暫存器
圖6
該暫存器有預設的設定,觀察發現最低4位預設為1100。本專案需要用到GPIO的輸出模式,所以需要對該暫存器進行重新配置,給P1,P2,P3置1,開啟引腳的輸出功能。
2.3PIO_PUDR暫存器
圖7
通過觀察PIO_PUSR暫存器可以發現預設的上拉暫存器是全部開啟的,上拉暫存器的啟用會影響GPIO的正常輸出,所以通過PIO_PUDR暫存器將上拉暫存器關閉,為之後正常操控GPIO提供基礎。
資料的寫入:
1概況
PIO_SODR和PIO_CODR這兩個暫存器可以將指定位的GPIO電平置1置0。由於這裡設計的讀寫使能為低電平有效,在程式中首先將涉及的訊號均拉高,相當於對訊號進行一個復位。之後就可以進行資料的傳送工作。
圖8
圖9
圖8為連續傳送0x1122,0x3344,0x5566等多個數據時的情況,在寫使能的上升沿對資料匯流排和地址總線上的資訊進行取樣;圖9中顯示當寫使能訊號上升沿的時刻,資料匯流排上的資訊為0x5566,地址總線上的資訊為0x0005,即將0x5566儲存到RAM的0x0005地址中。(上圖SignalTap取樣時鐘為125MHz)
在一個傳送週期中,經歷以下過程:
0:地址總線上出現地址資訊;
1:片選訊號拉低;
2:寫使能訊號拉低;
3:資料放到資料匯流排上;
4:寫使能拉高,同時在上升沿時刻對資料取樣;
5:片選訊號拉高。
在DATASHEET的SMC一章中有對並口的傳送時序進行描述,當前實驗結果也符合資料手冊中通過SMC實現並口通訊的說明,如圖10、圖11所示。可見,其實兩種方式大同小異,實現的結果相同。
圖10
圖11
2ARM中資料的傳送
通過FPGA_WriteData函式完成資料的傳送工作,其中使用了PIO暫存器中的PIO_CODR,PIO_SODR,PIO_ODSR三個暫存器,分別實現使能拉低,使能拉高,和標誌位判斷的功能。
語句中,(volatileunsigned short *)(x)將x定義為了一個地址指標,再通過*取內容,這樣就可以將資料寫到這個地址上,在之後的程式中只要直接呼叫WREG()就可以方便的向地址寫資料。
3FPGA中資料的儲存
reg uprise_wr_dly;
always @(posedgei_clk,negedge i_rst_n)
begin
if(!i_rst_n)
uprise_wr_dly <= 1'b0;
else
uprise_wr_dly <= i_wr_cpu_pre;
end
reg wr;
always @(posedgei_clk,negedge i_rst_n)
begin
if(!i_rst_n)
wr <= 1'b0;
else if((i_wr_cpu_pre == 1'b1) && (uprise_wr_dly ==1'b0))
wr <= 1'b1;
else
wr <= wr;
end
以上程式製作了一個比寫使能訊號延後一個clock的訊號,再通過兩個訊號的組合判斷實現了寫使能上升沿訊號的處理。這在FPGA的程式中是很常見的處理方式。
最後通過RAM程式中的介面程式,將已經處理好的資料匯流排訊號、地址匯流排訊號和使能訊號、時鐘訊號新增進介面當中,功能便實現了。
資料的讀取:
資料讀取時的使能訊號同樣使用了PIO_CODR和PIO_SODR這兩個關鍵的暫存器,按照時序控制這兩個暫存器的值即可。
資料讀取的情況如圖12所示:
圖12
通過對FPGA程式設計將資料0x3456放到資料匯流排上,在ARM的程式中對資料匯流排所在的地址進行讀取,就可以將資料讀出。這裡將讀出的資料儲存到了PIOC暫存器中,你也可以把它放到變數中來觀察,驗證對錯。在IAR裡檢視PIOC的只讀暫存器PIOC_ODSR就可以看到資料已經被存放到了暫存器當中。
關於涉及到的暫存器、暫存器的控制方式、使能訊號的時序以及相關軟體的使用和程式設計思路,讀取與寫入是大致一樣的,這裡不再重複描述。