12、S3C2440 裸機 — SDRAM

 

12.1 SDRAM 介紹

12.1.1 SDRAM 定義

  • SDRAM(Synchronous Dynamic Random Access Memory):同步動態隨機存儲器-內存條
    • 同步是指內存工做須要同步時鐘,內部的命令的發送與數據的傳輸都以它爲基準;
    • 動態是指存儲陣列須要不斷的刷新來保證數據不丟失;   對比:SRAM(靜態的-觸發器)
    • 隨機是指數據不是線性依次存儲,而是自由指定地址進行數據讀寫  對比:Flash(塊)
  • DDR:DDR就是DDR SDRAM,是SDRAM的升級版。(DDR:double data rate,雙倍速度的SDRAM)
  • SDRAM經歷了幾代:SDR DDR1 DDR2 DDR3 DDR4 - 速度愈來愈快(命名方式採起的讀寫速率)

12.1.2 SDRAM 工做原理

  • 先片選中SDRAM,再選擇Bank,最後在數據讀寫時和表格的檢索原理同樣,先指定一個行(Row),再指定一個列 (Column),就能夠準確地找到所須要的單元格,這就是內存芯片尋址的基本原理,參考SDRAM結構圖(HY57V561620(L)T)
    • 4Mbit*4banks*16---->  32Mbyte ----> 2^5 * 2^20   須要25根地址線(地址線複用)
  • CPU發出片選信號nSCS0(與nGCS6是同一引腳)有效,選中SDRAM芯片
  • SDRAM有4個L-BANK,須要兩個地址信號來選中其中一個,即BA0、BA1。
  • 對被選中的芯片進行同一的行/列(存儲單元)尋址、
  • 找到存儲單元后,被選中的芯片就要進行統一的數據傳輸。

12.2 存儲地址空間

12.2.1 地址空間佈局(Memory MAP)

  • S3C2440做爲32位的CPU,可使用的地址範圍理論上達到4GB。除去用於鏈接外設的1GB地址空間外,還有一部分是CPU內部寄存器的地址,剩下的地址空間沒有使用。
  • BANK0-BANK7 0x00000000-0x40000000
  • S3C2440的內部外設寄存器地址範圍都處於0x48000000-0x5FFFFFFF  (GPIO-0x56000000)
  • SDRAM啓始地址爲:0x30000000
  • BANK是用於擴展總線鏈接外部外設,它的地址和內部外設的地址在一個線性地址空間上。

  

 12.2.2 存儲地址與外設的關係

12.2.2.1 存儲控制器特性

  • 支持小字節序、大字節序(經過軟件選擇);
  • 每一個BANK的地址空間爲128MB,總共1GB(8BANKs);
  • 可編程控制的總線寬度(8/16/32-bit),不過BANK0只能選擇兩種寬度(16/32-bit);
  • 總共8個BANK,BANK0~BANK5能夠支持外接ROM、SRAM等,BANK6~BANK7除能夠支持ROM、SRAM外,還支持SDRAM等;
  • BANK0~BANK6共7個BANK的起始地址是固定的;
  • BANK7的起始地址可編程選擇;
  • BANK六、BANK7的地址空間大小是可編程控制的;
  • 每一個BANK的訪問週期都可編程控制;
  • 能夠經過外部的「wait」信號延長總線的訪問週期;
  • 在外接SDRAM時,支持自刷新(self-refresh)和省電模式(power down mode)

12.2.2.2 S3C2440 與存儲器相關的引腳

  • S3C2440對外引出的27根地址線ADDR0~ADDR26的訪問範圍只有128MB(2^27)
  • CPU對外還引出了8根片選信號nGCS0~nGCS7,對應於BANK0~BANK7,當訪問BANKx的地址空間時,nGCSx引腳輸出低電平用來選中外接的設備。這樣,每一個nGCSx對應128MB地址空間,8個nGCSx信號總共就對應了1GB的地址空間。
  • 數據線有上32根,DATA0-DATA31。控制信號nOE,nWE,nWait,nGCS0-nGCS5  (數據手冊-P49)
  • 開發板中NORFlash DM9000 SDRAM接在了BANK上(總線方式擴展外設)

12.2.3  硬件接線圖分析

12.2.3.1 NOR Flash

JZ2440 選用的是 MX29LV160D T/B 的型號,它爲 2M x 8bit 或 1M x 16bit 的大小,即爲 2M/1M 空間大小。8/16 是位寬。
linux

  • A0-A19:地址線    2^20 = 1M             
  • D0-D15:數據線           16bit
  • BYTE:選擇16/8bit模式,直接接高電平(選擇了16bit模式)
    • 由於S3C2440 的BANK0 只支持(16bit/32bit )的位寬,而 NOR Flash 是接在 BANK0上的,因此只能拉高選擇16 bit 模式
  • CE --  NGCS0 (BANK0)
  • OE WE RESET
  • VCC VSS  
  • CPU_ADDR1 ---  NOR_ADDR0 (忽略了最低位)

12.2.3.2 SDRAM

  • BANK0~BANK5的鏈接方式都是類似的,BANK6鏈接SDRAM時複雜一點,CPU提供了一組用於SDRAM的信號CS --- BANK6,它的首地址爲0x30000000
  • SDRAM時鐘有效信號SCKE;SDRAM時鐘信號SCLK0/SCLK1
  • 數據掩碼信號DQM0/DQM1/DQM2/DQM3(每一個DQM控制8bit,防止寫字節數據覆蓋前面位-32bit操做的)
  • SDRAM片選信號nSCS0(它與nGCS6是同一引腳的兩個功能)
  • SDRAM行地址選通脈衝信號nSRAS 
  • SDRAM列地址選通脈衝信號nSCAS
  • 寫容許信號nWE(它不是專用於SDRAM的),在 JZ2440 中使用的是EM63A165TS ,兩個 32M 的SDRAM
  • HY57V561620(L)T容量:4Banks x 4M x 16Bit   =  32Mbyte,早
    • CPU須要64Mbyte(26根地址線)0x03(0x00)
    • CPU_ADDR2---- SDRAM_ADDR0
  • SDRAM行地址線13根,列地址線9根(Row Address : RA0 ~ RA12, Column Address : CA0 ~ CA8),它們是複用的
  • S3C2440發送一個地址爲0x30001000:
    • 當nSRAS有效時,ADDR2-ADDR14發出的是行地址信號,對應bit[23-11]
    • 當nSCAS有效果時,ADDR2-ADDR10發出的是列地址信號,對應bit[10-2]
  • 硬件接線圖參考數據手冊上給的值,當數據線是32位時,最低兩位是沒有使用的,一個地址對應的是四個字節爲了和字節地址統一,不接bit[1-0]到SDRAM中。
  • 注意:
    • 邏輯上:
      • 採用按字節編址的方式,每個地址對應一個字節單元(與存儲單元字節數無關)-CPU端設置
    • 物理上:
      • 存儲單元:每個地址對應的存儲空間,就是一個存儲單元
      • 存儲器總容量的字節數 = 總的地址數 X 存儲單元字節數
      • 經過擴展地址線/數據線來擴展容量,好比咱們內存模塊是採用 16M*8bit的內存顆粒,那麼咱們使用4個顆粒進行字擴展(數據線),成爲16M*32bit,使用4個顆粒進行容量擴展(地址線)變爲64M*8bit

  

12.3 存儲器控制器

12.3.1 時序圖

  • 時序是表達指令執行中各控制信號在時間上的相互關係,因爲有了時序才能讓 IC 有條不紊的工做。
  • 時序圖讀法:
    • 從上到下,從左到右,高電平在上,低電平在下,高組態在中間。
    • 雙線表示可能高也可能低,視數據而定。
    • 交叉線表示狀態的高低變化點,能夠是高變低,也能夠是低變高,也能夠不變。
  • 時序圖的見解:
    • 按照從上到下,從左到右的順序,每到一個突變點(從0變爲1,或從1變爲0)時,記錄各信號的值,進而分析可知其相應的功能。

12.3.2 寄存器設置

  • 存儲控制器共有13各寄存器,BANK0-BANK5 只須要設置 BWSCON 和 BANKCONx(x 爲 0~5)兩個寄存器;
  • BANK六、BANK7 外接 SDRAM 時,除 BWSCON 和 BANKCONx(x 爲六、7)外,還須要設置 REFRESH、BANKSIZE、MRSRB六、MRSRB7 等 4 各寄存器:
    • BWSCON:
      • STx 用於設置啓用 UB/LB(0)
      • WSx 是否使用存儲器的 WAIT 信號(0)
      • DWx 用於設置 BANK 位寬
    • BANKCONx(x 爲 0 - 5):用於控制外接設備的訪問時序,使用默認的 0x700 便可知足要求
    • BANKCONx(x 爲 六、7):
      • MT[16 - 15] 設置接的是 ROM/SRAM[00] 仍是 SDRAM[11],若是是 00 的話,其餘設備和 BANKCONx(x 爲 0 - 5) 同樣;當 MT 設置成 SDRAM 還須要設置 Trcd[3:2],RAStoCAS(delay 設置推薦爲 01),Scan[1:0](SDRAM 列地址位數)

12.4 SDRAM 初始化

 Makefileshell

 1 # 獲取當前工做目錄
 2 CURRDIR = $(shell pwd)
 3 
 4 # 頭文件所在目錄
 5 INCDIR = $(CURRDIR)
 6 
 7 # 交叉編譯工具鏈的絕對路徑
 8 CROSS_COMPILE = ~/work/s3c2440/tools/gcc-3.4.5-glibc-2.3.6/bin/arm-linux-
 9 
10 # 編譯器工具
11 AS            = $(CROSS_COMPILE)as
12 LD            = $(CROSS_COMPILE)ld
13 CC            = $(CROSS_COMPILE)gcc
14 CPP            = $(CC) -E
15 AR            = $(CROSS_COMPILE)ar
16 NM            = $(CROSS_COMPILE)nm
17 STRIP        = $(CROSS_COMPILE)strip
18 OBJCOPY        = $(CROSS_COMPILE)objcopy
19 OBJDUMP        = $(CROSS_COMPILE)objdump
20 
21 # 編譯器標識位設置
22 CFLAGS :=
23 AFLAGS :=
24 LDFLAGS :=
25 CFLAGS    :=
26 AFLAGSL    :=
27 
28 # 目標文件設置
29 objs := startup.o sdram.o
30 
31 all: clean s3c2440.bin
32 
33 
34 # 執行編譯的過程
35 s3c2440.bin: $(objs)
36     $(LD) -Ttext 0x00000000 -o s3c2440_elf $^
37     $(OBJCOPY) -O binary -S s3c2440_elf $@
38     $(OBJDUMP) -D -m arm s3c2440_elf > s3c2440.dis
39 
40 
41 %.o:%.c
42     $(CC)  -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding -c -o $@ $<
43 
44 %.o:%.S
45     $(CC)  -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding -c -o $@ $<
46 
47 clean:
48     rm -f *.bin *_elf *.dis *.o

startup.S編程

  1 .equ        MEM_CTL_BASE,       0x48000000
  2 .equ        SDRAM_BASE,         0x30000000
  3 
  4 .text
  5 .global _start
  6 _start:
  7     bl  disable_watch_dog               @ 關閉WATCHDOG,不然CPU會不斷重啓
  8     bl  memsetup                        @ 設置存儲控制器
  9     bl  copy_steppingstone_to_sdram     @ 複製代碼到SDRAM中
 10     ldr pc, =on_sdram                   @ 跳到SDRAM中繼續執行
 11 
 12 @ 棧是先入後出,SDRAM 的地址爲 0x30000000,64M 大小的結束地址爲 0x34000000
 13 on_sdram:
 14     ldr sp, =0x34000000                 @ 設置堆棧, 此時 pc 指向了棧頂
 15     bl  main
 16 
 17 halt_loop:
 18     b   halt_loop
 19 
 20 @ WTCON 寄存器容許用戶使能或禁止看門狗定時器、從 4 個不一樣源選擇時鐘信號、使能或禁止中斷和使能或禁止看門狗定時器輸出。
 21 @ 看門狗定時器是用於恢復 S3C2440A 上電後如有故障重時新啓動;若是不但願控制器從新啓動,則應該禁止看門狗定時器。
 22 @ 若是用戶但願使用看門狗定時器做爲普通定時器,則應使能中斷而且禁止看門狗定時器。
 23 @ STR{條件}  源寄存器,<存儲器地址>
 24 @ STR指令用於從源寄存器中將一個 32 位的字數據傳送到存儲器中。
 25 disable_watch_dog:
 26     @ 往 WATCHDOG 寄存器寫 0 便可,操做 WTCON 寄存器
 27     mov r1,     #0x53000000
 28     mov r2,     #0x0
 29     str r2,     [r1]
 30     mov pc,     lr      @ 返回
 31 
 32 @ S3C2440A 引導代碼能夠在外部 NAND Flash 存儲器上執行。
 33 @ 爲了支持 NAND Flash 的 BootLoader,S3C2440A 配備了一個內置的 SRAM 緩衝器,叫作「Steppingstone」。
 34 @ 引導啓動時,NAND Flash 存儲器的開始 4K 字節將被加載到 Steppingstone 中而且執行加載到 Steppingstone 的引導代碼。
 35 copy_steppingstone_to_sdram:
 36     @ 將Steppingstone 的 4K 數據所有複製到 SDRAM 中去
 37     @ Steppingstone 起始地址爲 0x00000000,SDRAM 中起始地址爲 0x30000000
 38 
 39     mov r1, #0
 40     ldr r2, =SDRAM_BASE
 41     mov r3, #4*1024
 42 1:
 43     ldr r4, [r1],#4     @ 從Steppingstone讀取4字節的數據,並讓源地址加4
 44     str r4, [r2],#4     @ 將此4字節的數據複製到SDRAM中,並讓目地地址加4
 45     cmp r1, r3          @ 判斷是否完成:源地址等於Steppingstone的未地址?
 46     bne 1b              @ 若沒有複製完,繼續
 47     mov pc,     lr      @ 返回
 48 
 49 @ 存儲控制器設置
 50 memsetup:
 51     @ 設置存儲控制器以便使用SDRAM等外設
 52 
 53     mov r1,     #MEM_CTL_BASE       @ 存儲控制器的13個寄存器的開始地址
 54     adrl    r2, mem_cfg_val         @ 這13個值的起始存儲地址
 55     add r3,     r1, #52             @ 13*4 = 54
 56 1:
 57     ldr r4,     [r2], #4            @ 讀取設置值,並讓r2加4
 58     str r4,     [r1], #4            @ 將此值寫入寄存器,並讓r1加4
 59     cmp r1,     r3                  @ 判斷是否設置完全部13個寄存器
 60     bne 1b                          @ 若沒有寫成,繼續
 61     mov pc,     lr                  @ 返回
 62 
 63 .align 4
 64 mem_cfg_val:
 65     @ 存儲控制器13個寄存器的設置值
 66     @ BWSCON 總線寬度和等待控制寄存器
 67     @ ‭0010 0010 0000 0001 0001 0001 0001 0000‬
 68     .long   0x22011110      @ BWSCON
 69     @ BANKCON0 Bank0 控制寄存器
 70     @ ‭0000 0000 0000 0000 0000 0111 0000 0000‬
 71     @ 設置了訪問週期爲 14 各時鐘
 72     .long   0x00000700      @ BANKCON0
 73     @ BANKCON1 Bank· 控制寄存器
 74     .long   0x00000700      @ BANKCON1
 75     @ BANKCON2 Bank2 控制寄存器
 76     .long   0x00000700      @ BANKCON2
 77     @ BANKCON3 Bank3 控制寄存器
 78     .long   0x00000700      @ BANKCON3
 79     @ BANKCON4 Bank4 控制寄存器
 80     .long   0x00000700      @ BANKCON4
 81     @ BANKCON5 Bank5 控制寄存器
 82     .long   0x00000700      @ BANKCON5
 83     @ BANKCON6 Bank6 控制寄存器
 84     @ 0000 0000 00000001 1000 0000 0000 0101‬
 85     @ 0 - 16 bit 有效:
 86     @ [16:15] 11:即 MT 設置爲同步 DRAM 即 SDRAM
 87     @ 存儲器類型 = ROM 或 SRAM [MT=00](15 位),下面的數據設置爲0,只有[3:0]有效
 88     @ [14:13] 
 89     @ [12:11]
 90     @ [10:8]
 91     @ [7:6]
 92     @ [5:4]
 93     @ 存儲器類型 = SDRAM [MT=11](4 位)時候:
 94     @ [3:2] 01:Trcd RAS 到 CAS 的延遲,設置爲 3 各時鐘(根據 SDRAM 的芯片手冊設置)
 95     @ [1:0] 01:SCAN 列地址數,設置爲 9 列,一樣根據 SDRAM 手冊設置
 96     .long   0x00018005      @ BANKCON6
 97     @ BANKCON7 Bank7 控制寄存器
 98     .long   0x00018005      @ BANKCON7
 99     @ REFRESH SDRAM 刷新控制寄存器 [24: 0] 有效
100     @ ‭0000 0000 1000 1100 0000 0111 1010 0011‬
101     @ 具體看芯片手冊
102     .long   0x008C07A3      @ REFRESH
103     .long   0x000000B1      @ BANKSIZE 可變 Bank 大小寄存器
104     @ 當代碼在 SDRAM 中運行時必定不要改變 MRSR 寄存器
105     @ 睡眠模式中,SDRAM 必須使能 SDRAM 自刷新模式
106     .long   0x00000030      @ MRSRB6 模式寄存器組寄存器 Bank6
107     .long   0x00000030      @ MRSRB7

sdram.c多線程

 1 /**
 2  * 將0x56000050 強轉爲 unsigned long 型指針,並取這個地址的值
 3  * volatile 關鍵字:防止編譯器優化,在應用層上多線程變量,在嵌入式中外設寄存器
 4  */
 5 #define GPFCON      (*(volatile unsigned long *)0x56000050)
 6 #define GPFDAT      (*(volatile unsigned long *)0x56000054)
 7 #define GPFUP       (*(volatile unsigned long *)0x56000058)
 8 
 9 /** 設置 GPFCON 的 4 5 6 引腳爲輸出 */
10 #define GPF4_OUT    (1 << (4 * 2))
11 #define GPF5_OUT    (1 << (5 * 2))
12 #define GPF6_OUT    (1 << (6 * 2))
13 
14 static void delay_ms(unsigned long ms);
15 
16 int main(void)
17 {
18     /** 將LED1-3對應的GPF4/5/6三個引腳設爲輸出 */
19     GPFCON = GPF4_OUT | GPF5_OUT | GPF6_OUT;
20 
21     unsigned long i = 0;
22     while(1){
23         delay_ms(500);
24         GPFDAT = (~(i<<4));         // 根據i的值,點亮LED1,2,4
25         if(++i == 8)
26             i = 0;
27     }
28 }
29 
30 static void delay_ms(unsigned long ms)
31 {
32     unsigned int i;
33 
34     while(ms--) {
35         for(i = 0; i < 1200; i++);
36     }
37 }
相關文章
相關標籤/搜索