【ARM學習筆記】實驗三:S3C2440A與記憶體SDRAM連線實驗
阿新 • • 發佈:2019-02-01
前文講到了儲存控制器對外引出了8根片選訊號線,分別對應8個BANK,每個BANK的地址空間大小為128MB,共計1GB的物理定址空間
在8個BANK中,BANK0佔用匯流排地址0x00000000~0x07FFFFFF,而CPU在上電後會從匯流排地址0x00000000讀取指令執行,只能通過硬體引腳OM1和OM0配置成16bit或32bit的位寬,一般情況下,BANK0都是用來連線Nor Flash作為啟動裝置用的
BANK1~BANK5可以隨意連線具備類記憶體介面的ROM和SRAM,支援8bit,16bit和32bit這3種位寬
BANK6和BANK7則除了連線具備類記憶體介面的ROM和SRAM,還可以用來連線SDRAM,因為BANK6和BANK7多出了幾個特殊介面用來支援SDRAM,同時BANK6和BANK7還支援2塊SDRAM並聯
實際上,由於Nor Flash和SRAM價格較貴,而且容量較小,所以大多數開發板都採用Nand Flash啟動,使用2塊SDRAM並聯作為記憶體
以百問網的JZ2440v2開發板為例:
JZ2440v2採用2顆三星K4S561632N SDRAM晶片作為記憶體,單片容量32MB,位寬16bit,兩片組成32bit,不要需要注意的是,並聯以後儲存管理器會把2片記憶體當成獨立的64MB、32bit的一片記憶體對待。
JZ2440v2同時擁有Nor Flash和Nand Flash
以下為JZ2440的SDRAM接線圖:
如上圖,LDATA[31:0]是32根資料線,LADDR[26:0]是27根地址線
由於這種型號的SDRAM的行地址的寬度是13,列地址的寬度是9,所以只用到13根地址線,另外LADDR0、LADDR1按照32bit晶片接法是不用接的
另外,除了“高/低位元組資料掩碼訊號”LnWBE0、LnWBE1、LnWBE2、LnWBE3以及輸入時鐘LSCLK0、LSCLK1不相同外
其他引腳,如:片選引腳LnGCS6,行地址列地址使能LnSRAS、LnSCAS,讀寫控制LnWE,輸入時鐘有效訊號LSCKE,都是共用的
另外LADDR[25:24]用於SDRAM內部的BANK選擇
使用SDRAM涉及到的暫存器
1.匯流排寬度和等待控制暫存器(BWSCON)
其暫存器匯流排地址為0x48000000,用來設定裝置位寬、WAIT狀態和UB/LB狀態,每4位對應一個BANK
由於JZ2440使用2塊SDRAM佔用BANK6和BANK7,BANK7對應的bit[31:28]=0b0010,BANK6對應的bit[27:24]=0b0010
第一個0(即bit[31]和bit[27])表示不使用UB/LB狀態,第二個0(即bit[30]和bit[26])表示不使用WAIT狀態,之後的10(即bit[29:28]和bit[26:2])表示位寬32bit,其它位不用設定
故此暫存器的32位的十六進位制值為0x22000000
2.BANK控制暫存器(BANKCON6和BANKCON7 )
BANKCON6的匯流排地址為0x4800001C,BANKCON7的匯流排地址為0x48000020,2個BANK只要設定相同的數值即可
本例使用三星K4S561632N只需設定bit[16:15]=0x11和bit[3:0]=0b0101
其中bit[16:15]用來設定儲存器型別為SDRAM,bit[3:0]用來設定RAS到CAS的延遲為3個時鐘週期(bit[3:2])以及列地址數為9位(bit[1:0])
所以BANKCON6和BANKCON7兩個暫存器的32位的十六進位制值都設定為0x00018005
3.重新整理控制暫存器(REFRESH)
REFRESH的匯流排地址為0x48000024
本例使用三星K4S561632N只需設定bit[23]=0x1和bit[19:18]=0b11
另外bit[10:0]用來設定重新整理計數器Refresh Counter,這個需要根據Datasheet中的重新整理週期來計算
Refresh Counter的計算公式為:2^11 + 1 - SDRAM時鐘頻率(MHz)* SDRAM重新整理週期
本例使用三星K4S561632N的關鍵特性中註明了“64ms refresh period (8K Cycle)”,意思是64毫秒重新整理8K次(8192次),算得重新整理週期=64ms/8192=7.8125μm
而此時SDRAM的時鐘頻率等於晶振的12MHz(CPU還未設定時鐘頻率,此時使用晶振)
所以Refresh Counter的值=2^11 + 1 - 12 * 7.8125 = 1955.25 = 0x7A3
加上之前的bit[23]和bit[19:18],所以重新整理控制暫存器的32位的十六進位制值為0x008C07A3
4.BANK大小暫存器(BANKSIZE )
BANKSIZE的匯流排地址為0x48000028
本例使用三星K4S561632N只需設定bit[7]=0x1、bit[5]=0b1、bit[4]=0b1、bit[2:0]=0b001
其中bit[7]用來設定允許ARM突發操作,bit[5]用來設定SDRAM在掉電模式能使能SCKE 控制,bit[4]用來設定只在SDRAM 訪問週期期間SCLK 使能,以降低功耗。bit[2:0]用來設定Bank 6/7 儲存器對映64MB/64MB
所以BANKSIZE暫存器的32位的十六進位制值都設定為0x000000B1
5.SDRAM模式暫存器組暫存器(MRSRB6 和MRSRB7)
MRSRB6的匯流排地址為0x4800002C,MRSRB7的匯流排地址為0x48000030,2個BANK只要設定相同的數值即可
本例使用三星K4S561632N只需設定bit[6:4]=0x011
查詢Datasheet可知,此值可設為0b010(十進位制2)或0b011(十進位制3)和
本開發板建議使用0b011
所以MRSRB6 和MRSRB7兩個暫存器的32位的十六進位制值都設定為0x00000030
#################################################################################################################
【程式碼實現】
僅用C語言實現,比較簡單方便
#################################################################################################################
sdram.bin : head.S sdram.c led4.c arm-linux-gcc -c -o head.o head.S arm-linux-gcc -c -o sdram.o sdram.c arm-linux-gcc -c -o led4.o led4.c arm-linux-ld -Tsdram.lds head.o sdram.o led4.o -o sdram_elf arm-linux-objcopy -O binary -S sdram_elf sdram.bin arm-linux-objdump -D -m arm sdram_elf > sdram.dis clean: rm -f *.bin *elf *.o *bak *.dis *~
SECTIONS { first 0x00000000 : { head.o sdram.o } second 0x30000000 : AT(0x00000800) { led4.o } }
.text .global _start _start: ldr sp, =0x00001000 bl disable_watch_dog bl memsetup bl copy_2th_to_sdram ldr sp, =0x34000000 ldr pc, =0x30000000 halt_loop: b halt_loop
void disable_watch_dog(void) { * (unsigned long *)0x53000000 = 0x00000000; } void memsetup(void) { * (unsigned long *)0x48000000 = 0x22000000; * (unsigned long *)0x4800001C = 0x00018005; * (unsigned long *)0x48000020 = 0x00018005; * (unsigned long *)0x48000024 = 0x008C07A3; * (unsigned long *)0x48000028 = 0x000000B1; * (unsigned long *)0x4800002C = 0x00000030; * (unsigned long *)0x48000030 = 0x00000030; } void copy_2th_to_sdram(void) { unsigned long * pdwSrc = (unsigned long *)0x00000800; unsigned long * pdwDest = (unsigned long *)0x30000000; while (pdwSrc < (unsigned long *)0x00001000) { * pdwDest = * pdwSrc; pdwSrc++; pdwDest++; } }
int main(void) { * (unsigned long *)0x56000050 = 0x00000100; unsigned long i = 0x00000000; unsigned long x = 0x00000000; while(1) { * (unsigned long *)0x56000054 = i; for(x=0x0007530; x>0; x--); i = ~i; } return 0; }
sdram_elf: file format elf32-littlearm Disassembly of section first: 00000000 <_start>: 0: e3a0da01 mov sp, #4096 ; 0x1000 4: eb000004 bl 1c 8: eb00000a bl 38 c: eb00002c bl c4 10: e3a0d30d mov sp, #872415232 ; 0x34000000 14: e3a0f203 mov pc, #805306368 ; 0x30000000 00000018 : 18: eafffffe b 18 0000001c : 1c: e1a0c00d mov ip, sp 20: e92dd800 stmdb sp!, {fp, ip, lr, pc} 24: e24cb004 sub fp, ip, #4 ; 0x4 28: e3a02453 mov r2, #1392508928 ; 0x53000000 2c: e3a03000 mov r3, #0 ; 0x0 30: e5823000 str r3, [r2] 34: e89da800 ldmia sp, {fp, sp, pc} 00000038 : 38: e1a0c00d mov ip, sp 3c: e92dd800 stmdb sp!, {fp, ip, lr, pc} 40: e24cb004 sub fp, ip, #4 ; 0x4 44: e3a02312 mov r2, #1207959552 ; 0x48000000 48: e3a03422 mov r3, #570425344 ; 0x22000000 4c: e5823000 str r3, [r2] 50: e3a02312 mov r2, #1207959552 ; 0x48000000 54: e282201c add r2, r2, #28 ; 0x1c 58: e3a03906 mov r3, #98304 ; 0x18000 5c: e2833005 add r3, r3, #5 ; 0x5 60: e5823000 str r3, [r2] 64: e3a02312 mov r2, #1207959552 ; 0x48000000 68: e2822020 add r2, r2, #32 ; 0x20 6c: e3a03906 mov r3, #98304 ; 0x18000 70: e2833005 add r3, r3, #5 ; 0x5 74: e5823000 str r3, [r2] 78: e3a02312 mov r2, #1207959552 ; 0x48000000 7c: e2822024 add r2, r2, #36 ; 0x24 80: e3a03723 mov r3, #9175040 ; 0x8c0000 84: e2833e7a add r3, r3, #1952 ; 0x7a0 88: e2833003 add r3, r3, #3 ; 0x3 8c: e5823000 str r3, [r2] 90: e3a03312 mov r3, #1207959552 ; 0x48000000 94: e2833028 add r3, r3, #40 ; 0x28 98: e3a020b1 mov r2, #177 ; 0xb1 9c: e5832000 str r2, [r3] a0: e3a03312 mov r3, #1207959552 ; 0x48000000 a4: e283302c add r3, r3, #44 ; 0x2c a8: e3a02030 mov r2, #48 ; 0x30 ac: e5832000 str r2, [r3] b0: e3a03312 mov r3, #1207959552 ; 0x48000000 b4: e2833030 add r3, r3, #48 ; 0x30 b8: e3a02030 mov r2, #48 ; 0x30 bc: e5832000 str r2, [r3] c0: e89da800 ldmia sp, {fp, sp, pc} 000000c4 : c4: e1a0c00d mov ip, sp c8: e92dd800 stmdb sp!, {fp, ip, lr, pc} cc: e24cb004 sub fp, ip, #4 ; 0x4 d0: e24dd008 sub sp, sp, #8 ; 0x8 d4: e3a03b02 mov r3, #2048 ; 0x800 d8: e50b3010 str r3, [fp, #-16] dc: e3a03203 mov r3, #805306368 ; 0x30000000 e0: e50b3014 str r3, [fp, #-20] e4: e51b2010 ldr r2, [fp, #-16] e8: e3a03eff mov r3, #4080 ; 0xff0 ec: e283300f add r3, r3, #15 ; 0xf f0: e1520003 cmp r2, r3 f4: 8a00000a bhi 124 f8: e51b2014 ldr r2, [fp, #-20] fc: e51b3010 ldr r3, [fp, #-16] 100: e5933000 ldr r3, [r3] 104: e5823000 str r3, [r2] 108: e51b3010 ldr r3, [fp, #-16] 10c: e2833004 add r3, r3, #4 ; 0x4 110: e50b3010 str r3, [fp, #-16] 114: e51b3014 ldr r3, [fp, #-20] 118: e2833004 add r3, r3, #4 ; 0x4 11c: e50b3014 str r3, [fp, #-20] 120: eaffffef b e4 124: e24bd00c sub sp, fp, #12 ; 0xc 128: e89da800 ldmia sp, {fp, sp, pc} 12c: 43434700 cmpmi r3, #0 ; 0x0 130: 4728203a undefined 134: 2029554e eorcs r5, r9, lr, asr #10 138: 2e342e33 mrccs 14, 1, r2, cr4, cr3, {1} 13c: 00000035 andeq r0, r0, r5, lsr r0 Disassembly of section second: 30000000 : 30000000: e1a0c00d mov ip, sp 30000004: e92dd800 stmdb sp!, {fp, ip, lr, pc} 30000008: e24cb004 sub fp, ip, #4 ; 0x4 3000000c: e24dd008 sub sp, sp, #8 ; 0x8 30000010: e3a03456 mov r3, #1442840576 ; 0x56000000 30000014: e2833050 add r3, r3, #80 ; 0x50 30000018: e3a02c01 mov r2, #256 ; 0x100 3000001c: e5832000 str r2, [r3] 30000020: e3a03000 mov r3, #0 ; 0x0 30000024: e50b3010 str r3, [fp, #-16] 30000028: e3a03000 mov r3, #0 ; 0x0 3000002c: e50b3014 str r3, [fp, #-20] 30000030: e3a03456 mov r3, #1442840576 ; 0x56000000 30000034: e2833054 add r3, r3, #84 ; 0x54 30000038: e51b2010 ldr r2, [fp, #-16] 3000003c: e5832000 str r2, [r3] 30000040: e3a03c75 mov r3, #29952 ; 0x7500 30000044: e2833030 add r3, r3, #48 ; 0x30 30000048: e50b3014 str r3, [fp, #-20] 3000004c: e51b3014 ldr r3, [fp, #-20] 30000050: e3530000 cmp r3, #0 ; 0x0 30000054: 0a000003 beq 30000068 30000058: e51b3014 ldr r3, [fp, #-20] 3000005c: e2433001 sub r3, r3, #1 ; 0x1 30000060: e50b3014 str r3, [fp, #-20] 30000064: eafffff8 b 3000004c 30000068: e51b3010 ldr r3, [fp, #-16] 3000006c: e1e03003 mvn r3, r3 30000070: e50b3010 str r3, [fp, #-16] 30000074: eaffffed b 30000030 30000078: 43434700 cmpmi r3, #0 ; 0x0 3000007c: 4728203a undefined 30000080: 2029554e eorcs r5, r9, lr, asr #10 30000084: 2e342e33 mrccs 14, 1, r2, cr4, cr3, {1} 30000088: 00000035 andeq r0, r0, r5, lsr r0
<完結>