12.4內(nèi)存控制器與SDRAM_SDRAM的設(shè)置
本節(jié)將講解如何設(shè)置SDRAM,如果想對內(nèi)存有更多的了解,可以在網(wǎng)上搜索看下這篇文檔“高手進(jìn)階_終極內(nèi)存技術(shù)指南——完整/進(jìn)階版”。
在JZ2440上接有64M的SDRAM,如果想要使用SDRAM,需要對內(nèi)存控制器做一些設(shè)置。 在前面第一節(jié)講到,CPU將數(shù)據(jù)或地址發(fā)給內(nèi)存控制器,內(nèi)存控制器再去訪問外部的SDRAM,因此設(shè)置內(nèi)存控制器就說本節(jié)的核心。
如圖是SDRAM存儲(chǔ)結(jié)構(gòu)邏輯圖:

SDRAM總共有4個(gè)塊(Banks),可以認(rèn)為每個(gè)塊就是一個(gè)表格,里面的每個(gè)格子表示的是16bit數(shù)據(jù)。
問題1:怎樣訪問里面的某個(gè)格子呢?
1. 首先發(fā)出一個(gè)片選信號,選中整個(gè)芯片;
2. 發(fā)出Bank地址,選擇是哪一個(gè)Bank(塊,即表格);
3. 發(fā)出行地址;
4. 最后發(fā)出列地址,才能選中是個(gè)格子;?
問題2:那么多的信號有誰發(fā)出呢?
由內(nèi)存控制器發(fā)出,所以我們需要設(shè)置內(nèi)存控制器,CPU只是簡單的執(zhí)行讀寫內(nèi)存的命令,其他的都交給內(nèi)存控制起來處理。 例如 :

1. CPU把0x30000000這個(gè)地址發(fā)給內(nèi)存控制器,內(nèi)存控制器根據(jù)這個(gè)地址,判斷屬于哪個(gè)范圍,然后發(fā)出相應(yīng)的片選信號。
2. 根據(jù)類型(比如SDRAM)拆分成三部分:發(fā)出Bank地址、發(fā)出行地址、發(fā)出列地址。
對于上面的三個(gè),怎樣拆分呢?
行地址線有幾條,列地址線有幾條,都要設(shè)置內(nèi)存控制器里面相關(guān)寄存器。
3. 讀數(shù)據(jù)??
綜上所述:對SDRAM的訪問可以分為如下步:
1. CPU發(fā)出的片選信號nSCS6有效,它選中SDRAM芯片。
2. SDRAM中有4個(gè)L-Bank,需要兩根地址信號來選中其中之一,根據(jù)原理圖,可知使用ADDR24,ADDR25作為L-Bank的選擇信號。
3. 對被選中的芯片進(jìn)行統(tǒng)一的行/列(存儲(chǔ)單元)尋址。
根據(jù)SDRAM芯片的列地址線數(shù)目設(shè)置CPU的相關(guān)寄存器后,CPU就會(huì)從32位的地址中自動(dòng)分出L_Bank片選信號,行地址信號,列地址信號,然后先后發(fā)出行地址信號,列地址信號。L_Bank選擇信號在發(fā)出行地址信號的同時(shí)發(fā)出,并維持到列地址信號結(jié)束。?
根據(jù)原理圖可知:
地址、列地址共用地線ADDR2—ADDRI4(BANK6位寬為32,ADDRO/I沒有使用),使用nSRAS、nSCAS兩個(gè)信號來區(qū)分它們。
比如本開發(fā)板中,使用兩根地址線ADDR24、ADDR25作為L-Bank的選擇信號:SDRAM芯片K4s5m632的行地址數(shù)為13,列地址數(shù)為9,所以當(dāng)nSRAS信號有時(shí),ADDR2—ADDR14上發(fā)出是行地址信號,它對應(yīng)32位地址空間的b可23m]:當(dāng)nSCAS信號有效時(shí),ADDR2—ADDR10上發(fā)出的是列地址信號,它對應(yīng)32位地址空間的bit[0:2];由于BANK6以32位的寬度外接DRAM,ADDR0、ADDR1恒為0,不參與譯碼。
4. 找到了存儲(chǔ)單元后,被選中的芯片就要進(jìn)行統(tǒng)一的數(shù)據(jù)傳輸了。
開發(fā)板中使用兩片16位的SDRAM芯片并聯(lián)組成32位的位寬,與CPU的32根數(shù)據(jù)線(DATA0—DATA31)相連。 BANK6的起始地址為0x30000000,所以SDRAM的訪問地址為0x30000000~低0x33FFFFFF,共64MB。?
2440內(nèi)存控制器設(shè)置:
內(nèi)存控制器共有13個(gè)寄存器,
BANK0--BANK5只需要設(shè)置BWSCON和BANKCONx(x為0~5)兩個(gè)寄存器;
BANK6、BANK7外接SDRAM時(shí),除BWSCON和BANKCONx(x為6、7)外,還要設(shè)置REFRESH、BANKSIZE、MRSRB6、MRSRB7等4個(gè)寄存器。
下面分類說明各個(gè)寄存起的設(shè)置。?
1.位寬和等待控制寄存器BWSCON(BUSWIDTH&WAITCONTROLREGISTER)

BWSCON中每4位控制一個(gè)BANK,最高4位對應(yīng)BANK7(沒有使用)、接下來4位對應(yīng)BANK6。
(1)ST6[27]: 啟動(dòng)/禁止SDRAM的數(shù)據(jù)掩碼引腳,對于SDRAM,此位為0:對于SRAM此位為1。
(2)WS6[26]:是否使用存儲(chǔ)器的WAIT信號,通常設(shè)為0。
(3)DW6[25:24]:使用兩位來設(shè)置相應(yīng)BANK的位寬,0b00對應(yīng)8位,0b01對應(yīng)16位,0b10對應(yīng)32位(開發(fā)板用的就是32位的),0b11表示保留。
因此BWSCON寄存器的值為:0x22000000。?
2. BANK控制寄存器BANKCON6(BANKCONTROLREGISTER)
在8個(gè)BANK中,只有BANK6和BANK7可以外接SRAM或SDRAM。

(1)MT[16:15]:用于設(shè)置本BANK外接的是ROM/SRAM還是SDRAM,SRAM:0b00,SDRAM:0b11(開發(fā)板使用的是SDRAM)。
當(dāng)MT[16:15]設(shè)置為00時(shí),此寄存器與BANKC0N0、BANKCON5類似,不再贅述。
當(dāng)MT[16:15]設(shè)置為11時(shí),此寄存器其他值如下設(shè)置。

(2)Trcd[3:2]:行地址和列地址間隔多長時(shí)間,看芯片手冊時(shí)間間隔是20ns,本來開發(fā)板的HCLK是100MHZ,clocks為10ns,所以設(shè)置為推薦值0b00(2clocks)。
(3)SCAN[1:0]:SDRAM的列地址位數(shù),對于本開發(fā)板使用的SDRAMK4S561632。列地址位數(shù)為9,所以SCAN=0b010如果使用其他型號的SDRAM,需要查看其數(shù)據(jù)手冊。來決定SCAN的取值。0b00表示8位,0b01表示9位,0b10表示10位。
綜上所述,本開發(fā)板中BANKCON6設(shè)為0x018001。?
3. 刷新控制寄存器REFRESH(REFRESHCONTROLREGISTER)

(1)REFEN[23]:0=禁止SDRAM的刷新功能,1:開啟SDRAM的刷新功能(設(shè)置開啟SDRAM的刷新功能)。
(2)TREFMD[22]:SDRAM的刷新模式,0=CBR/AutoRefresh,1=SelfRefresh(一般在系統(tǒng)休眠時(shí)使用),我們設(shè)置默認(rèn)值。
(3)Trp[21:20):根據(jù)芯片手冊設(shè)為0即可。
(4)Tsrc[19:18]:根據(jù)芯片手冊設(shè)為默認(rèn)值0b01即可。
(5)RefreshCounter[10:0]:即R_CNT
R_CNT可如下汁算(SDRAM時(shí)鐘頻率就是HCLK):?
R_CNT=2^11+1-SDRAM時(shí)鐘頻率(MZ)*SDRAM刷新周期(us)
SDRAM的刷新周期在SDRAM的數(shù)據(jù)手冊上有標(biāo)明,在本開發(fā)板使用的SDRAM:K4S561632的數(shù)據(jù)手冊上,可看見這么一行“64msrefreshpenod(8KCycle)所以,刷新周期=64ms/8192=7.8125us。
Refreshcount=2^11+1-100x7.8=1269=0x4F5
因此,本開發(fā)板中REFRESH設(shè)為0x8404F5。?
4. BANKSIZE寄存器REFRESH(BANKSIZEREG ISTER)

(1)BURST_EN[7]:0=ARM核禁上突發(fā)傳輸,1=ARM核支持突發(fā)傳輸(推薦);
(2)SCKEEN[5]:0=不使用SCKE信號令SDRAM進(jìn)入省電模式,1=使用SCKE信號令SDRAM進(jìn)入省電模式(推薦);
(3)SCLK-EN[4]:0=時(shí)刻發(fā)出SCLK信號,1=僅在訪問SDRAM期間發(fā)出SCLK信號(推薦);
(4)BK76MAP[2:0]:設(shè)置BANK6的大小。本開發(fā)板BANK6外接64MB的SDRAM,令[2:0]=b001(64M/64M),表示BANK6/7的容量都是64MB,雖然BANK7沒有使用。
因此,本開發(fā)板中BANKSIZE設(shè)為0xB1。?
5. SDRAM模式設(shè)置寄存器MRSRBx6(SDRAM MODE REGISTER SET REGISTER)

能修改的只有位CL[6:4],這是SDRAM時(shí)序的一個(gè)時(shí)間參數(shù),表示發(fā)出行、列地址后,等多久才返回收到數(shù)據(jù), CL可以取值為0b0l0(2 clocks)或0b011(3 clocks)。
本開發(fā)板取最保守的值0b010,所以MRSRB6的值為0x20。?
下面開始寫程序:
在init.c里面進(jìn)行對內(nèi)存控制器的寄存器依次進(jìn)行設(shè)置:?

再寫一個(gè)測試函數(shù),向SDRAM里面連續(xù)寫1000個(gè)數(shù),再讀出數(shù)據(jù)對比是否是設(shè)置的數(shù),返回對比結(jié)果:

在主函數(shù)里調(diào)用sdram_test()測試函數(shù),如果測試成功,LED閃爍:?

實(shí)驗(yàn)結(jié)果:
LED按預(yù)期閃爍,屏蔽掉sdram_init()后,LED不閃爍。?