S3C2440 SDRAM

http://blog.csdn.net/mr_raptor/article/details/6555786

++++++++++++++++++++++++++++++++++++++++++

 

SDRAMSynchronous Dynamic Random Access Memory,同步動態隨機存儲器)也就是通常所說的內存。內存的工作原理、控制時序、及相關控制器的配置方法一直是嵌入式系統學習、開發過程中的一個難點。我們從其硬件的角度來分析其原理,然後再引出SDRAM的驅動編寫過程。

內存是代碼的執行空間,以PC機爲例,程序是以文件的形式保存在硬盤裏面的,程序在運行之前先由操作系統裝載入內存中,由於內存是RAM(隨機訪問存儲器),可以通過地址去定位一個字節的數據,CPU在執行程序時將PC的值設置爲程序在內存中的開始地址, CPU會依次的從內存裏取址,譯碼,執行,在內存沒有被初始化之前,內存好比是未建好的房子,是不能讀取和存儲數據的,因此我們要想讓MTOS運行在內存裏必須進行內存的初始化。

通用存儲設備:

在介紹內存工作原理之前有必要了解下存儲設備的存儲方式:ROMRAM

l  ROM(Read-Only Memory)只讀存儲器,是一種只能讀出事先所存數據的固態半導體存儲器。其特性是一旦儲存資料就無法再將之改變或刪除。通常用在不需經常變更資料的電子或電腦系統中,資料並且不會因爲電源關閉而消失。如PC裏面的BIOS

l  RAM(Random Access Memory) 隨機訪問存儲器,存儲單元的內容可按需隨意取出或存入,且存取的速度與存儲單元的位置無關的存儲器。可以理解爲,當你給定一個隨機有效的訪問地址,RAM會返回其存儲內容(隨機尋址),它訪問速度與地址的無關。這種存儲器在斷電時將丟失其存儲內容,故主要用於存儲短時間內隨機訪問使用的程序。計算機系統裏內存地址是一個四字節對齊的地址(32位機),CPU的取指,執行,存儲都是通過地址進行的,因此它可以用來做內存。

RAM按照硬件設計的不同,隨機存儲器又分爲DRAMDynamic RAM)動態隨機存儲器和SRAMStatic RAM) 靜態隨機存儲器。

l  DRAM它的基本原件是小電容,電容可以在兩個極板上短時間內保留電荷,可以通過兩極之間有無電壓差代表計算機裏的01,由於電容的物理特性,要定期的爲其充電,否則數據會丟失。對電容的充電過程叫做刷新,但是製作工藝較簡單,體積小,便於集成化,經常做爲計算機裏內存製作原件。比如:PC的內存,SDRAM, DDR, DDR2, DDR3等,缺點:由於要定期刷新存儲介質,存取速度較慢。

l  SRAM它是一種具有靜止存取功能的內存,不需要刷新電路即能保存它內部存儲的數據。因此其存取速度快,但是體積較大,功耗大,成本高,常用作存儲容量不高,但存取速度快的場合,比如CPUL1 cacheL2cache(一級,二級緩存) ,寄存器。

 

爲了滿足開發的需要MINI2440在出廠時搭載了三種存儲介質:

1NOR FLASH2M):ROM存儲器,通常用來保存BootLoader,引導系統啓動

2NAND FLASH256M,型號不一樣,Nandflash大小不一樣):保存操作系統映像文件和文件系統

3SDRAM64M):內存,執行程序

l  NOR FLASH它的特點是支持XIP芯片內執行(eXecute In Place),這樣應用程序可以直接在Flash閃存內運行,不必再把代碼讀到系統RAM中,也就是說可以隨機尋址。NOR FLASH的成本較高。

l  NAND FLASH:它能提供極高的單元密度,可以達到高存儲密度,並且寫入和擦除的速度也很快。其成本較低,不支持XIP。可做嵌入式裏的數據存儲介質。如:手機存儲卡,SD卡等。

1.1.1   S3C2440存儲器地址段(Bank

S3C2440對外引出了27根地址線ADDR0~ADDR26,它最多能夠尋址128MB,而S3C2440的尋址空間可以達到1GB,這是由於S3C24401GB的地址空間分成了8BANKSBank0~Bank7),其中每一個BANK對應一根片選信號線nGCS0~nGCS7,當訪問BANKx的時候,nGCSx管腳電平拉低,用來選中外接設備, S3C2440通過8根選信號線和27根地址線,就可以訪問1GB。如圖2-48所示。

 

2-48 S3C2440存儲器BANK

如圖所示,左側圖對應不使用Nandflash啓動時(通過跳線設置),存儲器Bank分佈圖,通常在這種啓動方式裏選擇Norflash啓動,將Norflash焊接在Bank0 系統上電後,CPUBank0的開始地址0x00000000開始取指運行。

上圖右側是選擇從Nandflash引導啓動(通過跳線設置),系統上電後,CPU會自動將Nandflash裏前4K的數據複製到S3C2440內部一個4K大小 SRAM類型存儲器裏(叫做Steppingstone),然後從Steppingstone取指啓動。

其中Bank0~Bank5可以焊接ROMSRAM類型存儲器,Bank6~Bank7可以焊接ROMSRAMSDRAM類型存儲器,也就是說,S3C2440SDRAM內存應該焊接在Bank6~Bank7上,最大支持內存256MBank0~Bank5通常焊接一些用於引導系統啓動小容量ROM,具體焊接什麼樣存儲器,多大容量,根據每個開發板生產商不同而不同,比如MINI2440開發板將2MNorflash焊接在了Bank0上,用於存放系統引導程序Bootloader,將兩片32M16Bit位寬SDRAM內存焊接在Bank6Bank7上,並聯形成64M32位內存。

由於S3C244032位芯片,理論上講可以達到4GB的尋址範圍,除去上述8BANK用於連接外部設備,還有一部分的地址空間是用於設備特殊功能寄存器,其餘地址沒有被使用。

2-14 S3C2440設備寄存器地址空間

外接設備

起始地址

結束地址

存儲控制器

0x48000000

0x48000030

USB Host控制器

0x49000000

0x49000058

中斷控制器

0x4A000000

0x4A00001C

DMA

0x4B000000

0x4B0000E0

時鐘和電源管理

0x4C000000

0x4C000014

LCD控制器

0x4D000000

0x4D000060

NAND FLASH控制器

0x4E000000

0x4E000014

攝像頭接口

0x4F000000

0x4F0000A0

UART

0x50000000

0x50008028

脈寬調製計時器

0x51000000

0x51000040

USB設備

0x52000140

0x5200026F

WATCHDOG計時器

0x53000000

0x53000008

IIC控制器

0x54000000

0x5400000C

IIS控制器

0x55000000

0x55000012

I/O端口

0x56000000

0x560000B0

實時時鐘RTC

0x57000040

0x5700008B

A/D轉換器

0x58000000

0x58000010

SPI

0x59000000

0x59000034

SD接口

0x5A000000

0x5A000040

AC97音頻編碼接口

0x5B000000

0x5B00001C

1.1.2   SDRAM內存工作原理

SDRAM的內部是一個存儲陣列。陣列就如同表格一樣,將數據“填”進去。在數據讀寫時和表格的檢索原理一樣,先指定一個行(Row),再指定一個列 Column),我們就可以準確地找到所需要的單元格,這就是內存芯片尋址的基本原理,如圖2-49所示。

 

2-49內存行,列地址尋址示意圖

這個單元格(存儲陣列)就叫邏輯 BankLogical Bank,下文簡稱 L-Bank)。 由於技術、成本等原因,不可能只做一個全容量的 L-Bank,而且最重要的是,由於 SDRAM的工作原理限制,單一的 L-Ban k將會造成非常嚴重的尋址衝突,大幅降低內存效率。所以人們在 SDRAM內部分割成多個 L-Bank,目前基本都是 4個(這也是SDRAM規範中的最高L-Bank數量),由此可見,在進行尋址時就要先確定是哪個 L-Bank,然後在這個選定的 L-Bank中選擇相應的行與列進行尋址。因此對內存的訪問,一次只能是一個 L-Bank工作。如圖2-50

 

2-50內存存儲單元

當對內存進行操作時(見下圖),先要確定操作L-Bank,因此要對L-Bank進行選擇。在內存芯片的外部管腳上多出了兩個管腳BA0, BA1,用來片選4L-Bank。如前所述, 32位的地址長度由於其存儲結構特點,分成了行地址和列地址。通過下面的內存結構圖可知,內存外接管腳地址線只有13根地址線A0~A12,它最多隻能尋址8M內存空間,到底使用什麼機制來實現對64M內存空間進行尋址的呢?SDRAM的行地址線和列地址線是分時複用的,即地址要分兩次送出,先送出行地址(nSRAS行有效操作),再送出列地址(nSCAS列有效操作)。這樣,可以大幅度減少地址線的數目,提高器件的性能和製作工藝複雜度。但尋址過程也會因此而變得複雜。實際上,現在的SDRAM一般都以L-Bank爲基本尋址對象的。由L-Bank地址線BAn控制L-Bank間的選擇,行地址線和列地址線貫穿連接所有的L-Bank,每個L-Bank的數據的寬度和整個存儲器的寬度相同,這樣,可以加快數據的存儲速度。同時,BAn還可以使未被選中的L-Bank工作於低功耗的模式下,從而降低器件的功耗。

 

 

2-51 HY57561620內部結構圖

 

開發板內存控制器管腳接線(以MINI2440開發板爲例):

1)確定BA0BA1的接線

2-15 BA0BA1接線

 

 

Bank Size: 外接內存容量大小(HY575616204Mbit*16bit*4Bank*2Chips/8=64MB

Bus Width: 總線寬度 (兩片16HY57561620,並聯成32位)
Base Component
:單個芯片容量(bit)256Mb
Memory Configration
:內存配置 (4M*16*4banks*2Chips )

由硬件手冊Bank Address管腳連接配置表可知,使用A[25:24]兩根地址線作爲Bank片選信號,正好兩根接線可以片選每個存儲單元的4BANKS

2)確定其它接線

SDRAM內存是焊接在BANK6~BANK7上的,其焊接管腳,如圖2-52

 

2-52 S3C2440 16位寬內存芯片

上圖是S3C2440提供的兩片16位芯片並聯連接示意圖,AnCPU地址總線,其中A2~A14爲內存芯片尋址總線,之所以地址尋址總線從A2開始是因爲內存地址都是按字節對齊的,,A24A25L-Bank片選信號,DnCPU數據總線,其它爲對應控制信號線。

2-16 內存芯片各管腳說明

外接管腳名

內接管腳名

全稱

描述

A2~A14

A0~A12

Address

地址線

D0 ~D31

DQ0~DQ31

Data Input/Output

數據線

A24,A25

BA0,BA1

Bank Address

L-BANK片選信號

DQM0~DQM3

LDQM, UDQM

Data Input/Output Mask

高,低字節數據掩碼信號

SCKE

SCKE

Clock Enable

輸入時鐘有效信號

SCLK

SCLK

Clock

輸入時鐘

nSCS0

nSCS

General Chip Select

片選信號(它與nGCS6是同一管腳的兩個功能)

nSRAS

nSRAS

Row Address Strobe

行地址選通信號

nSCAS

nSCAS

Column Address Strobe

列地址選通信號

nWE

newnWE

Write Enable

寫入有效信號

我們通過S3C2440 16位寬內存芯片接線圖可以看出,兩片內存芯片只有兩個地方不一樣,LDQM, UDQM和數據總線DQn接線方式不一樣。

由於存儲芯片位寬爲16位,一次可以進行兩個字節的讀取。但是,通常操作系統裏最小尋址單位是1字節,因此內存控制器必須要保證可以訪問內存裏每一個字節。UDQM LDQM分別代表16位數據的高,低字節讀取信號,當讀取數據時,LDQM /UDQM分別用來控制16位數據中高低字節能否被讀取,當LDQM /UDQM爲低電平時,對應的高/低字節就可以被讀取,如果LDQM /UDQM爲高電平時,對應的高/低字節就不能被讀取。當向內存裏寫入數據時,LDQM /UDQM控制數據能否被寫入,當LDQM /UDQM爲低電平時,對應的高/低字節就可以被寫入,如果LDQM /UDQM爲高電平時,對應的高/低字節就不能被寫入。通過對LDQM /UDQM信號的控制可以控制對兩個存儲芯片存儲數據,由於兩個存儲單元的地址線是通用的,他們都能接收到CPU發出的地址信號,但是,發給兩個存儲單元的LDQM /UDQM信號是不同的,以此來區分一個字的高低字節。

S3C2440A32CPU,也就是說其數據總線和地址總線寬度都是32位(可以理解爲32根線一端連接CPU內部,另外一端連接向內存控制器),那麼內存數據的輸入/輸出端也要保證是32位總線,MINI2440上採用兩片16位寬總線內存芯片並聯構成32位總線。其中一個芯片連接到CPU數據總線的低16位,另外一個芯片連接到數據總線上的高16位,並聯成32位總線,因此兩個芯片的輸入/輸出總線連接到CPU總線上的不同管腳上。

1.1.3   SDRAM的讀操作

SDRAM進行讀操作時,先向地址線上送上要讀取數據的地址,通過前面的知識瞭解到,地址被分成3部分,行地址,列地址,L-Bank片選信號。片選(L-Bank的定址)操作和行有效操作可以同時進行。

CSL-Bank定址的同時,RASnSRAS行地址選通信號)也處於有效狀態。此時 An地址線則發送具體的行地址。A0~A12,共有13根地址線(可表示8192行),A0~A12的不同數值就確定了具體的行地址。由於行有效的同時也是相應 L-Bank有效,所以行有效也可稱爲L-Bank有效。

行地址確定之後,就要對列地址進行尋址了。但是,地址線仍然是行地址所用的 A0~A12。沒錯,在SDRAM中,行地址與列地址線是複用的。列地址複用了A0~A8,共9根(可表示512列)。那麼,讀/寫的命令是怎麼發出的呢?其實沒有一個信號是發送讀或寫的明確命令的,而是通過芯片的可寫狀態的控制來達到讀/寫的目的。顯然WE信號(nWE)就是一個關鍵。WE無效時,當然就是讀取命令。有效時,就是寫命令。

SDRAM基本操作命令, 通過各種控制/地址信號的組合來完成(H代表高電平,L代表低電平,X表示高,低電平均沒有影響)。此表中,除了自刷新命令外,所有命令都是默認CKESCKEl輸入時鐘頻率有效)有效。列尋址信號與讀寫命令是同時發出的。雖然地址線與行尋址共用,但CASnSCAS列地址選通信號)信號則可以區分開行與列尋址的不同,配合A0~A8A9~A11來確定具體的列地址。

讀取命令與列地址一塊發出(當WE爲低電平是即爲寫命令)然而,在發送列讀寫命令時必須要與行有效命令有一個間隔,這個間隔被定義爲 tRCD,即RAS to CAS DelayRAS CAS延遲),這個很好理解,在地址線上送完行地址之後,要等到行地址穩定定位後再送出列地址,tRCDSDRAM的一個重要時序參數,相關數值參看對應芯片硬件手冊。通常tRCD以時鐘週期(tCKClock Time)數爲單位,比如筆者MINI2440所用內存芯片裏面寫到tRCD20nst,如果將來內存工作在100MHz,那麼RCD至少要爲2個時鐘週期, RCD=2

 

2-53 SDRAM讀操作時序圖

在選定列地址後,就已經確定了具體的存儲單元,剩下就是等待數據通過數據 I/O通道(DQ)輸出到內存數據總線上了。但是在列地址選通信號CAS 發出之後,仍要經過一定的時間纔能有數據輸出,從CAS與讀取命令發出到第一筆數據輸出的這段時間,被定義爲 CLCAS LatencyCAS潛伏期)。由於CL只在讀取時出現,所以CL又被稱爲讀取潛伏期(RLRead Latency)。CL的單位與tRCD一樣,也是時鐘週期數,具體耗時由時鐘頻率決定(筆者官方手冊CL=3)。不過,CAS並不是在經過CL週期之後才送達存儲單元。實際上CASRAS一樣是瞬間到達的。由於芯片體積的原因,存儲單元中的電容容量很小,所以信號要經過放大來保證其有效的識別性,這個放大/驅動工作由S-AMP負責。但它要有一個準備時間才能保證信號的發送強度,這段時間我們稱之爲tACAccess Time from CLK,時鐘觸發後的訪問時間)。

1.1.4    SDRAM預充電操作

從存儲體的結構圖上可以看出,原本邏輯狀態爲1的電容在讀取操作後,會因放電而變爲邏輯0。由於SDRAM的尋址具有獨佔性,所以在進行完讀寫操作後,如果要對同一L-Bank的另一行進行尋址,就要將原先操作行關閉,重新發送行/列地址。在對原先操作行進行關閉時,DRAM爲了在關閉當前行時保持數據,要對存儲體中原有的信息進行重寫,這個充電重寫和關閉操作行過程叫做預充電,發送預充電信號時,意味着先執行存儲體充電,然後關閉當前L-Bank操作行。預充電中重寫的操作與刷新操作(後面詳細介紹)一樣,只不過預充電不是定期的,而只是在讀操作以後執行的。

1.1.5    SDRAM突發操作

突發(Burst)是指在同一行中相鄰的存儲單元連續進行數據傳輸的方式,連續傳輸所涉及到存儲單元(列)數量就是突發長度(Burst Length,簡稱BL)。

在目前,由於內存控制器一次讀/P-Bank位寬的數據,也就是8個字節,但是在現實中小於8個字節的數據很少見,所以一般都要經過多個週期進行數據的傳輸,上文寫到的讀/寫操作,都是一次對一個存儲單元進行尋址,如果要連續讀/寫,還要對當前存儲單元的下一單元進行尋址,也就是要不斷的發送列地址與讀/寫命令(行地址不變,所以不用再對地尋址)。雖然由於讀/寫延遲相同可以讓數據傳輸在I/O端是連續的,但是它佔用了大量的內存控制資源,在數據進行連續傳輸時無法輸入新的命令效率很低。爲此,引入了突發傳輸機制,只要指定起始列地址與突發長度,內存就會依次自動對後面相應長度數據的數據存儲單元進行讀/寫操作而不再需要控制器連續地提供列地址,這樣,除了第一筆數據的傳輸需要若干個週期(主要是之間的延遲,一般的是tRCD + CL)外,其後每個數據只需一個週期即可。

總結下:

SDRAM的基本讀操作需要控制線和地址線相配合地發出一系列命令來完成。先發出芯片有效命令(ACTIVE),並鎖定相應的L-BANK地址(BA0BA1給出)和行地址(A0A12給出)。芯片激活命令後必須等待大於tRCD(SDRAMRASCAS的延遲指標)時間後,發出讀命令。CLCAS延遲值)個時鐘週期後,讀出數據依次出現在數據總線上。在讀操作的最後,要向SDRAM發出預充電(PRECHARGE)命令,以關閉已經激活的L-BANK。等待tRP時間(PRECHAREG命令後,相隔tRP時間,纔可再次訪問該行)後,可以開始下一次的讀、寫操作。SDRAM的讀操作支持突發模式(Burst Mode),突發長度爲1248可選。

1.1.6    SDRAM寫操作

SDRAM的基本寫操作也需要控制線和地址線相配合地發出一系列命令來完成。先發出芯片有效命令,並鎖定相應的L-BANK地址(BA0BA1給出)和行地址(A0A12給出)。芯片有效命令發出後必須等待大於tRCD的時間後,發出寫命令數據,待寫入數據依次送到DQ(數據線)上。在最後一個數據寫入後,延遲tWR時間。發出預充電命令,關閉已經激活的頁。等待tRP時間後,可以展開下一次操作。寫操作可以有突發寫和非突發寫兩種。突發長度同讀操作。

 

2-54 SDRAM寫操作時序圖

1.1.7    SDRAM的刷新

SDRAM之所以成爲DRAM就是因爲它要不斷進行刷新(Refresh)才能保留住數據,因此它是SDRAM最重要的操作。

刷新操作與預充電中重寫的操作一樣,都是用S-AMP先讀再寫。但爲什麼有預充電操作還要進行刷新呢?因爲預充電是對一個或所有 L-Bank中的工作行操作,並且是不定期的,而刷新則是有固定的週期,依次對所有行進行操作,以保留那些很長時間沒經歷重寫的存儲體中的數據。但與所有L-Bank預充電不同的是,這裏的行是指所有L-Bank中地址相同的行,而預充電中各L-Bank中的工作行地址並不是一定是相同的。那麼要隔多長時間重複一次刷新呢?目前公認的標準是,存儲體中電容的數據有效保存期上限是64ms(毫秒,1/1000秒),也就是說每一行刷新的循環週期是64ms。這樣刷新時間間隔就是: 64m/行數s。我們在看內存規格時,經常會看到4096 Refresh Cycles/64ms8192 Refresh Cycles/64ms的標識,這裏的40968192就代表這個芯片中每個L-Bank的行數。刷新命令一次對一行有效,刷新間隔也是隨總行數而變化,4096行時爲 15.625μs(微秒,1/1000毫秒),8192行時就爲 7.8125μs。刷新操作分爲兩種:Auto Refresh,簡稱ARSelf Refresh,簡稱SR。不論是何種刷新方式,都不需要外部提供行地址信息,因爲這是一個內部的自動操作。對於 ARSDRAM內部有一個行地址生成器(也稱刷新計數器)用來自動的依次生成行地址。由於刷新是針對一行中的所有存儲體進行,所以無需列尋址,或者說CAS RAS之前有效。所以,AR又稱CBRCAS Before RAS,列提前於行定位)式刷新。由於刷新涉及到所有L-Bank,因此在刷新過程中,所有 L-Bank都停止工作,而每次刷新所佔用的時間爲9個時鐘週期(PC133標準),之後就可進入正常的工作狀態,也就是說在這9個時鐘期間內,所有工作指令只能等待而無法執行。64ms之後則再次對同一行進行刷新,如此週而復始進行循環刷新。顯然,刷新操作肯定會對SDRAM的性能造成影響,但這是沒辦法的事情,也是DRAM相對於 SRAM(靜態內存,無需刷新仍能保留數據)取得成本優勢的同時所付出的代價。SR則主要用於休眠模式低功耗狀態下的數據保存,這方面最著名的應用就是 STRSuspend to RAM,休眠掛起於內存)。在發出AR命令時,將CKE置於無效狀態,就進入了SR模式,此時不再依靠系統時鐘工作,而是根據內部的時鐘進行刷新操作。在SR期間除了CKE之外的所有外部信號都是無效的(無需外部提供刷新指令),只有重新使CKE有效才能退出自刷新模式並進入正常操作狀態。

SDRAM相關寄存器:

1BWSCON寄存器(BUS WIDTH & WAIT CONTROL REGISTER

2-17 SDRAM控制寄存器(BWSCON

 

 

 

根據開發板的存儲器配置和芯片型號,設置每個BANK焊接芯片的位寬和等待狀態

BWSCON,每4位對應一個BANK,這4位分別表示:

l  STx:啓動/禁止SDRAM的數據掩碼引腳(UB/LB),SDRAM沒有高低位掩碼引腳,此位爲0SRAM連接有UB/LB管腳,設置爲1

l  注:UB/LB數據掩碼引腳用來控制芯片讀取/寫入的高字節和低字節(對比硬件手冊SDRAMSRAM的接線圖)

l  WSx:是否使用存儲器的WAIT信號,通常設爲0

l  DWx:設置焊接存儲器芯片的位寬,筆者開發板使用兩片容量爲32M,位寬爲16SDRAM組成64M32位存儲器,因此DW7DW6位設置爲0b10,其它BANK不用設置採用默認值即可。

l  BANK0對應的是系統引導BANK,這4位比較特殊,它的設置是由硬件跳線決定的,因此不用設置

l  BWSCON設置結果:0x22000000

2BANKCON0~BANKCON5 (BANK CONTROL REGISTER)

2-18 BANKCON0~BANKCON5控制寄存器(BANKCON0~BANKCON5

 

6個寄存器用來設置對應BANK0~BANK5的訪問時序,採用默認值0x700即可

3BANKCON6~BANKCON7 (BANK CONTROL REGISTER)

2-19 BANKCON6~BANKCON7控制寄存器(BANKCON6~BANKCON7

 

 

 

由於內存都焊接在這兩個BANK上,因此內存驅動主要是對這兩個寄存器進行設置

l  MT:設置BANK6~BANK7的存儲器類型,

00=ROM or SRAM 01=保留

10=保留         11=SDRAM

內存爲SDRAM,設置爲0b11,對應的應該設置TrcdSCAN位,其它位和SDRAM無關

l  TrcdRAS to CAS Delay行地址選通到列地址選通延遲,這個參數請看後面的內存工作原理擴展部分解釋,筆者內存芯片爲HY57V561620,由其芯片手冊可知其Trcd爲最少20ns,如果內存工作在100MHz,則該值至少要爲2個時鐘週期,通常設置爲3個時鐘週期,因此設置爲0b01

l  SCANSDRAM Column Address Number SDRAM的列地址數,筆者內存芯片爲HY57V561620,列地址數爲9,設置爲0b01

l  BANK6BANK7設置結果爲:0x18005

4REFRESH (REFRESH CONTROL REGISTER)

2-20刷新頻率設置寄存器(REFRESH

 

 

 

SDRAM的刷新有效,刷新頻率設置寄存器(刷新)

l  REFEN:開啓/關閉刷新功能,設置爲1,開啓刷新

l  TREFMDSDRAM刷新模式,0=CBR/AutoRefresh,  1=Self Refresh,設置爲0,自動刷新

l  Trp:行地址選通預充電時間,一般設置爲0b00即可

l  Tsrc:單行刷新時間,設置爲0b11即可。

l  Refresh Counter:內存存儲單元刷新數,它通過下面公式計算出:

Refresh Counter = 2^11 + 1 – SDRAM時鐘頻率(MHz* SDRAM刷新週期(uS

SDRAM的刷新週期,也就是內存存儲單元間隔需要多久進行一次刷新,前面內存工作原理分析可知電容數據保存上限爲64ms,筆者使用內存芯片每個L-Bank共有8192行,因此每次刷新最大間隔爲:64ms/8192 = 7.8125uS,如果內存工作在外部晶振頻率12MHz下,Refresh Counter = 1955,如果內存工作在100MHz下,那麼Refresh Counter = 1269(取大整數)

l  REFRESH寄存器設置爲:

0x8e0000 + 1269 = 0x008e04f5HCLK = 100MHz

0x8e0000 + 1955 = 0x008e07a3HCLK = 12MHz

5BANKSIZE寄存器(BANKSIZE REGISTER

2-21 BANKSIZE寄存器(BANKSIZE

 

 

設置內存的突發傳輸模式,省電模式和內存容量。

l  BURST_EN:是否開啓突發模式, 0 = ARM內核禁止突發傳輸 1 = 開啓突發傳輸,設置爲1,開啓突發傳輸

l  SCKE_EN:是否使用SCKE信號作爲省電模式控制信號, 0 = 不使用SCKE信號作爲省電模式控制信號 1 = 使用SCKE信號作爲省電模式控制信號,通常設置爲1

l  SCLK_EN: 設置向存儲器輸入工作頻率,0 = 一直輸入SCLK頻率,即使沒有內存操作也會輸入, 1 = 僅當進行內存數據操作時才輸入SCLK頻率,通常設置爲1

l  BK76MAP:設置Bank6/7的內存容量,筆者使用開發板內存爲兩片32M內存芯片並聯成64M,它們全部都外接到Bank6上,因此選擇0b001

l  BANKSIZE寄存器設置爲:0xb1

6SDRAM模式設置寄存器MRSRx (SDRAM MODE REGISTER SET REGISTER)

2-22 SDRAM模式設置寄存器(MRSRx

 

 

 

該寄存器用於設置CAS潛伏週期,可以手動設置的位只有CL[6:4]位,通過前面內存工作原理可知,筆者使用開發板CL=3,即0b011

l  MRSR6MRSR7設置爲:0x00000030

1.1.8   內存驅動實驗

設置該工程加載時運行時地址爲0x30000000,如圖2-55所示:

 

2-55設置加載時運行時地址

init.s:本程序文件主要實現了,關閉看門狗,初始化內存,拷貝ROM數據到內存中,然後跳往內存中執行xmain函數,從xmain函數返回之後,將全部led點亮,進入死循環。

;

; 內存初始化實驗

;

AREA Init, CODE, READONLY

ENTRY

start

; close watchdog

ldr r0, = 0x53000000                      ; 將看門狗控制寄存器地址放入r0

mov r1, #0                   

str r1, [r0]                                        ; 設置看門狗控制寄存器的值爲0

 

bl initmem                                       ; 跳轉到initmem代碼段,初始化內存

 

bl copyall                                         ; 跳轉到數據拷貝代碼段,將ROM中數據拷貝到內存中

 

IMPORT xmain                              ; 引入main.c中的xmain函數

ldr sp, =0x34000000                       ; 調用C程序之前先初始化棧指針

ldr lr, =endxmain                             ; 設置xmain函數的返回地址

ldr pc, =xmain                                 ; 跳轉到C程序中的xmain函數的入口處執行

 

endxmain

 ldr r0, =0x56000010                      ; LEDGPIO接口配置寄存器

ldr r1, =0x00015400                       ; GPIO配置數據

str r1, [r0]                                     ; 設置GPIO

ldr r0, =0x56000014                    ; LED控制寄存器地址

ldr r1, =0x0                                  ; 全部LED

str r1,[r0]  

loop

    b loop                                       ; 死循環

 

copyall      

IMPORT |Image$$RO$$Base|                 ; 引入編譯器Image$$RO$$Base符號變量

IMPORT |Image$$RW$$Limit|                ; 引入編譯器Image$$RW$$Limit符號變量

ldr r0, = |Image$$RO$Base|                     ; 取得Image$$RO$Base域基址的值

ldr r1, = |Image$$RW$$Limit|                  ; 取得Image$$RW$Base域結束地址的值

ldr r2, =0x0                                              ; 數據拷貝源地址

copyallloop

teq r0,r1                                                    ; 測試是否拷貝完成

beq quitcopyallloop                                  ; 拷貝完成跳往quitcopyallloop退出

ldr r3, [r2], #4                                           ; 四字節加載

str r3, [r0], #4                                           ; 四字節存儲

b copyallloop                                            ; 返回繼續執行

quitcopyallloop

mov pc, lr                                                 ; 調用返回

 

initmem                                                     ; 內存初始化

ldr r0, =0x48000000                                ; 加載內存相關寄存器首地址r0

ldr r1, =0x48000034                                ; 加載內存相關寄存器尾地址到r1

adr r2, memdata                              ; 將寄存器配置數據地址段首地址加載到r2

initmemloop

ldr r3, [r2], #4                                           ; 循環設置存寄存器

str r3, [r0], #4

teq r0, r1

bne initmemloop                                       ; 循環到最後一個寄存器時退出函數

mov pc,lr                                                           

 

memdata

DCD 0x22000000                 ;BWSCON

DCD 0x00000700                 ;BANKCON0    

DCD 0x00000700                 ;BANKCON1    

DCD 0x00000700                 ;BANKCON2    

DCD 0x00000700               ;BANKCON3             

DCD 0x00000700                 ;BANKCON4    

DCD 0x00000700                 ;BANKCON5    

DCD 0x00018005                 ;BANKCON6    

DCD 0x00018005                 ;BANKCON7    

DCD 0x008e07a3                  ;REFRESH        

DCD 0x000000b1                 ;BANKSIZE      

DCD 0x00000030                 ;MRSRB6 

DCD 0x00000030                 ;MRSRB7

 

END

main.c:本程序文件主要實現led燈的初始化,然後四個led燈循環滾動亮5遍,xmain函數返回。

/* C語言函數 */

/* 端口F寄存器預定義 */

#define        GPBCON           (*(volatile unsigned long *)0x56000010)

#define        GPBDAT            (*(volatile unsigned long *)0x56000014)

#define       LEDS               (1<<5|1<<6|1<<7|1<<8)

#define       DELAYVAL    (0x1ffff)

extern int delay(int time);        /* 聲明外部聲明彙編函數 */

 

int i = 5;

int xmain()

{

         GPBCON  = 0x00015400;          //GPF4--GPF7設置爲output

         while(i > 0) {

                    //第一個LED燈亮

             GPBDAT=(GPBDAT&(~LEDS)) | (1<<6|1<<7|1<<8);

              delay(DELAYVAL);              //調用匯編語言編寫的延時程序

      

                    //第二個LED燈亮

             GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<7|1<<8);

             delay(DELAYVAL);              //調用匯編語言編寫的延時程序

      

                    //第三個LED燈亮

             GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<6|1<<8);

             delay(DELAYVAL);                       //調用匯編語言編寫的延時程序      

     

                    //第四個LED燈亮

             GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<6|1<<7);

             delay(DELAYVAL);                       //調用匯編語言編寫的延時程序

             i--;      

    }

    return 0;

 }

 

delay.s本程序文件主要通常彙編來實現延時功能。

;彙編指令延時程序     

EXPORT delay

AREA  DELAY,CODE,READONLY          ;該僞指令定義了一個代碼段段名爲Init屬性只讀

;下面是延遲子程序

delay

         sub r0,r0,#1             ;r0=r0-1           

           cmp r0,#0x0             ;r0的值與0相比較

           bne delay                 ;比較的結果不爲0r0不爲0),繼續調用delay,否則執行下一條語句

           mov pc,lr                 ;返回

  

       END                             ;程序結束符

   

內存的初始化也可以用下面的C程序實現

C語言版本

#define       MEM_CTL_BASE               0x48000000

#define       MEM_CTL_END                0x48000034

/* SDRAM 13個寄存器的值 */

unsigned long  const    mem_cfg_val[]={         // 聲明數組存放內存控制器設置數據

           0x22000000,                //BWSCON

           0x00000700,                //BANKCON0

           0x00000700,                //BANKCON1

           0x00000700,                //BANKCON2

           0x00000700,                //BANKCON3   

           0x00000700,                //BANKCON4

           0x00000700,                //BANKCON5

           0x00018005,                //BANKCON6

           0x00018005,                //BANKCON7

           0x008e07a3,                 //REFRESHHCLK = 12MHz該值爲0x008e07a3

                                                //HCLK = 100MHz 0x008e04f5

           0x000000b1,                //BANKSIZE

           0x00000030,                //MRSRB6

           0x00000030,                //MRSRB7

};

void mem_init(void)

{

         int    i = 0;

         unsigned long *p = (unsigned long *)MEM_CTL_BASE;

         for(; i < (MEM_CTL_END - MEM_CTL_BASE)/4; i++)

                    p[i] = mem_cfg_val[i];

}

 

 

++++++++++++++++++++++++++++++++++++++++++

 轉載:

http://blog.csdn.net/mr_raptor/article/details/6555786

++++++++++++++++++++++++++++++++++++++++++

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章