可以得到這個地址及其後續地址的數據。相應的命令字和地址序列如表8.2、8.3所示。
K9F1208U0M一頁大小爲528字節,而列地址A0~A7可以尋址的範圍是256字節,所
以必須輔以其他手段才能完全尋址這528字節。將一頁分爲A、B、C三個區:A區爲0~255
字節,B區爲256~511字節,C區爲512~527字節。訪問某頁時,需要選定特定的區,這
稱爲“使地址指針指向特定的區”。這通過3個命令來實現:
命令00h讓地址指針指向A區、命令01h讓地址指針指向B區、命令50h讓地址指針指向C區。
命令00h和50h會使得訪問Flash的地址指針一直從A區或C區開始,除非發出了其他的修改
地址指針的命令。
命令01h的效果只能維持一次,當前的讀、寫、擦除、復位或者上電操作完成後,地址指針
重新指向A區。
寫A區或C區數據時,必須在發出命令80h之前發出命令00h或者50h;
寫B區數據時,發出命令01h後必須緊接着發出命令80h。
圖8.5形象地表示了K9F1208U0M的這個特性。
(1)Read1:命令字爲00h或01h。
如圖8.5所示,發出命令00h或者01h後,就選定了讀操作從A區還是B區開始。從表8.3
可知,列地址A0~A7可以尋址的範圍是256字節,命令00h和01h使得可以在512字節大小
的頁內任意尋址——這相當於A8被命令00h設爲0,而被命令01h設爲1。
發出命令字後,依照表8.3發出4個地址序列,然後就可以檢測R/nB引腳以確定Flash
是否準備好。如果準備好了,就可以發起讀操作依次讀入數據。
(2)Read2:命令字爲50h。
與Read1類似,不過讀取的是C區數據,操作序列爲:發出命令字50h、發出4個地址
序列、等待R/nB引腳爲高,最後讀取數據。不同的是,地址序列中A0~A3用於設定C區
(大小爲16字節)要讀取的起始地址,A4~A7被忽略。
(3)ReadID:命令字位90h。
發出命令字90h,發出4個地址序列(都設爲0),然後就可以連續讀入5個數據,分別
表示:廠商代碼(對於SAMSUNG公司爲Ech)、設備代碼(對於K9F1208U0M爲76h)、保
留的字節(對於K9F1208U0M爲A5h)、多層操作代碼(C0h表示支持多層操作)。
(4)Reset:命令字位FFh。
發出命令字FFh即可復位NAND Flash芯片。如果芯片正處於讀、寫、擦除狀態,復位
命令會終止這些命令。
(5)Page Program(True):命令字分兩段,80h和10h。
它的操作序列如圖8.6所示。
NAND Flash的寫操作一般是以頁爲單位的,但是可以只寫一頁中的一部分。發出命令
字80h後,緊接着是4個地址序列,然後向Flash發送數據(最大可以達到528字節),然後發
出命令字10h啓動寫操作,此時Flash內部會自動完成寫、校驗操作。一旦發出命令字10h
後,就可以通過讀狀態命令70h獲知當前操作是否完成、是否成功。
(6)Page Program(Dummy):命令字分兩階段,80h和11h。
NAND Flash K9F1208U0M分爲4個128Mbit的存儲層(plane),每個存儲層包含1024個
block和528字節的寄存器。這使得可以同時寫多個頁(page)或者同時擦除多個塊(block)。
塊的地址經過精心安排,可以在4個連續的塊內同時進行寫或者擦除操作。
如圖8.7所示位K9F1208U0M的塊組織圖。
命令Page Program(Dummy)正是在這種結構下對命令Page Program(True)的擴展,後
者僅能對一頁進行寫操作,前者可以同時寫4頁。命令Page Program(Dummy)的操作序列
如圖8.8所示。
發出命令字80h、4個地址序列及最多528字節的數據之後,發出命令字11h(11h稱爲
“Dummy Page Program command”,相對地,10h稱爲“True Page Program command”);
接着對相鄰層(plane)上的頁進行同樣的操作;僅在第4頁的最後使用10h替代11h,這樣
即可啓動Flash內部的寫操作。此時可以通過命令71h獲知這些操作是否完成、是否成功。
(7)Copy-Back Program(True):命令字分3階段,00h、8Ah、10h。
此命令用於將一頁複製到同一層(plane)內的另一頁,它省略了讀出源數據、將數據重新
載入Flash,這使得效率大爲提高。此命令有兩個限制:源頁、目的頁必須在同一層(plane)
中,並且源地址、目的地址的A14、A15必須相同。
操作序列如圖8.9所示。
首先發出命令Read1(00h)、4個源地址序列,此時源頁的528字節數據很快就被全部
讀入內部寄存器中;
接着發出命令字8Ah(Page-Copy Data-input command),隨之發出4個目的地址序列;
最後發出命令字10h啓動對目的頁的寫操作。
此後,可以使用命令70h來查看此操作是否完成、是否成功。
(8)Copy-Back Program(Dummy):命令字分3階段,03h、8Ah、11h。
與命令Page Program(Dummy)類似,Copy-Back Program(Dummy)可以同時啓動對多
達4個連續plane內的Copy-Back Program操作。操作序列如圖8.10所示。
從圖8.10 可知,首先發出命令字00h、源頁地址,這使得源頁的528字節數據被讀入
所在plane的寄存器;對於隨後的其他plane的源頁,發出命令字03h和相應的源頁地址
將數據讀入該plane的寄存器;按照前述說明讀出最多4頁的數據到寄存器後,發出命令
字8Ah、目的地址、命令字11h,在發出最後一頁的地址後,用10h代替11h以啓動寫操作。
(9)Block Erase:命令字分3階段,60h、D0h。
此命令用於擦除NAND Flash塊(block,大小爲16KB)。發出命令字60h之後,發出block
地址——僅需要3個地址序列(請參考表8.3,僅需要發出2、3、4 cycle所示地址),並且
A9~A13被忽略。操作序列如圖8.11所示。
(10)Multi-Plane Block Erase:60h——60h D0h
此命令用於同時擦除不同的plane中的塊。發出命令字60h之後,緊接着發出block地址
序列,如此最多可以發出4個block地址,最後發出命令字D0h啓動擦除操作。操作序列如
圖8.12所示。
① Read Status:命令字位70h;
② Read Multi-Plane Status:命令字位71h。
Flash中有狀態寄存器,發出命令字70h或者71h之後,啓動讀操作即可讀入此寄存器。
狀態寄存器中各位的含義如表8.4所示。
8.1.4 S3C2410/S3C2440 NAND Flash控制器介紹
NAND Flash控制器提供幾個寄存器來簡單對NAND Flash的操作。比如要發出讀命令時,
只需要向NFCMD寄存器中寫入0即可,NAND Flash控制器會自動發出各種控制信號。
1.操作方法概述
訪問NAND Flash時需要先發出命令,然後發出地址序列,最後讀寫數據;需要使用各個
使能信號來分辨是命令、地址還是數據。S3C2410的NAND Flash控制器提供了NFCONF、
NFCMD、NFADDR、NFDATA、NFSTAT和NFECC等6個寄存器來簡化這些操作。S3C2440
的NAND Flash控制器則提供了NFCONF、NFCONT、NFCMMD、NFADDR、NFDATA、
NFSTAT和其他與ECC有關的寄存器。對NAND Flash控制器的操作,S3C2410/S3C2440
有一點不同:有些寄存器的地址不一樣,有些寄存器的內容不一樣,這在示例程序中會體現
出來。
NAND Flash的讀寫操作次序如下:
① 設置NFCONF(對於S3C2410,還要設置NFCONT)寄存器,配置NAND Flash;
② 向NFCMD寄存器寫入命令,這些命令字可參考表8.2;
③ 向NFADDR寄存器寫入地址;
④ 讀寫數據:通過寄存器NFSTAT檢測NAND Flash的狀態,在啓動某個操作後,應該檢
測R/nB信號以確定該操作是否完成,是否成功。
2.寄存器介紹
下面講解這些寄存器的功能及具體用法。
(1)NFCONF:NAND Flash配置寄存器。
這個寄存器在S3C2410、S3C2440上功能有所不同。
① S3C2410的NFCONF寄存器。
被用來使能/禁止NAND Flash控制器、使能/禁止控制引腳信號nFCE、初始化ECC、設
置NAND Flash的時序參數等。
TACLS、TWRPH0和TWRPH1這3個參數控制的是NAND Flash信號線CLE/ALE與寫控
制信號nWE的時序關係,如圖8.13所示。
② S3C2440的NFCONF寄存器。
被用來設置NAND Flash的時序參數TACLS、TWRPH0、TWRPH1,設置數據尾款;還
有一些只讀位,用來指示是否支持其他大小頁(比如一頁大小爲256/512/1024/2048字節)。
它沒有實現S3C2410的NFCONF寄存器的控制功能,這些功能在S3C2440的NFCONT
寄存器裏實現。
(2)NFCONT:NAND Flash控制寄存器,S3C2410沒有這個寄存器。
被用來使能/禁止NAND Flash控制器、使能/禁止控制引腳信號nFCE、初始化ECC。它
還有其他功能,在一般的應用中用不到,比如鎖定NAND Flash。
(3)NFCMD:NAND Flash命令寄存器。
對於不同信號的Flash,操作命令一般不一樣。對於本開發板使用的K9F1208U0M,請參
考表8.2.
(4)NFADDR:NAND Flash地址寄存器
當寫這個寄存器時,它將對Flash發出地址信號。
(5)NFDATA:NAND Flash數據寄存器。
只用到低8位,讀、寫此寄存器將啓動對NAND Flash的讀、寫數據操作。
(6)NFSTAT:NAND Flash狀態寄存器。
只用到位0,0:busy;1:ready。
8.2 NAND Flash 控制器操作實例:讀Flash
本實例講述如何讀取NAND Flash,擦除、寫Flash的操作與讀Flash類似,讀者可以
自行編寫程序。
8.2.1 讀NAND Flash的步驟
下面講述如何從NAND Flash中讀出數據,假設讀地址爲addr。
1.設置NFCONF(對於S3C2440,還要設置NFCONT)
(1)對於S3C2420。
在本章實例中設爲0x9830——使能NAND Flash控制器、初始化ECC、NAND Flash片
選信號nFCE = 1(inactive,真正使用時再讓它等於0),設置TACLS = 0,TWRPH0 = 3,
TWRPH1= 0。這些時序參數的含義爲:TACLS = 1個HCLK時鐘,TWRPH0 = 4個HCLK
時鐘,TWRPH1 = 1個HCLK時鐘。
K9F1208U0M的時間特性如下:
CLE setup Time = 0 ns,CLE Hold Time = 10ns,
ALE setup Time = 0 ns,ALE Hold Time = 10ns,
WE Pulse Width = 25ns
參考圖8.13,可以計算:即使在HCLK = 100MHz的情況下,
TACLS + TWRPH0 + TWRPH1 = 6/100us = 60ns ,
也是可以滿足NAND Flash K9F1208U0M的時序要求的。
(2)對於S3C2440。
時間參數也設爲:TACLS = 0,TWRPH0 = 3,TWRPH1= 0.NFCONF寄存器的值如下:
NFCONF = 0x300
NFCONT寄存器的取值如下,表示使能NAND Flash控制器、禁止控制引腳信號nFCE、
初始化ECC。
NFCONT = (1 << 4) | (1 << 1) | (1 << 0)
2.在第一次操作NAND Flash前,通常復位一下NAND Flash
(1)對於S3C2410。
NFCONF &= ~(1 << 11) (發出片選信號)
NFCMD = 0xff (reset命令)
然後循環查詢NFSTAT的位0,直到它等於1。
最後禁止片選信號,在實際使用NAND Flash時再使能。
NFCONF |= (1 << 11) (禁止NAND Flash)
(2)對於S3C2440。
NFCONT &= ~(1 << 1) (發出片選信號)
NFCMD = 0xff (reset命令)
然後循環查詢NFSTAT位0,知道它等於1。
最後禁止片選信號,在實際使用NAND Flash時再使能。
NFCONT |= 0x2 (禁止NAND Flash)
3.發出讀命令
先使能NAND Flash,然後發出讀命令。
(1)對於S3C2410。
NFCONF &= ~(1 << 11) (發出片選信號)
NFCMD = 0 (讀命令)
(2)對於S3C2440。
NFCONT &= ~(1 << 1) (發出片選信號)
NFCMD = 0 (讀命令)
4.發出地址信號
這步請注意,表8.3列出了在地址操作的4個步驟對應的地址線,沒有用到A8(它由讀命令
設置,當讀命令位0時,A8 = 0;當爲1時,A8 = 1),如下所示:
5.循環查詢NFSTAT位0,直到它等於1,這時可以讀取數據了
6.連續讀NFDATA寄存器512次,得到一頁數據(512字節)
循環執行第3、4、5、6這4個步驟,直到讀出所要求的所有數據。
7.最後,禁止NAND Flash的片選信號
(1)對於S3C2410。
NFCONF |= (1 << 11)
(2)對於S3C2440。
NFCONT |= (1 << 1)
8.2.2 代碼詳解
實驗代碼在/work/hardware/nand目錄下,源文件爲head.S、init.c和main.c。本實例的目的
是把一部分代碼存放在NAND Flash地址4096之後,當程序啓動後通過NAND Flash控制器將
它們讀出來、執行。以前的代碼都小於4096字節,開發板啓動後它們被自動複製進
“Steppingstone”中。
連接腳本nand.lds把它們分爲兩部分,nand.lds代碼如下:
第2行表示head.o、init.o、nand.o這3個文件的運行地址爲0,它們在生成的映像文件中
的偏移地址也爲0(從0開始存放)。
第3行表示main.o的運行地址爲0x30000000,它在生成的映像文件中的偏移地址爲4096。
head.S調用init.c中的函數來關看門狗、初始化SDRAM;
調用nand.c中的函數來初始化NAND
Flash,
然後將main.c中的代碼從NAND Flash地址4096開始複製到SDRAM中;
最後跳到main.c中的main函數繼續執行。
由於S3C2410、S3C2440的NAND Flash控制器並非完全一樣,這個程序要能分辨出是
S3C2410還是S3C2440,然後使用不同的函數進行處理。
讀取GSTATUS1寄存器,如果它的值爲0x3241 0000或0x3241 0002,就表示處理器是
S3C2410,否則是S3C2440。
nand.c向外引出兩個函數:初始化NAND Flash的nand_init函數、將數據從NAND Flash
讀到SDRAM的nand_read函數。
1.nand_init函數分析
代碼如下:
2.nand_read函數分析
它的原型如下,表示從NAND Flash位置start addr開始,將數據複製到SDRAM地址
buf處,共複製size字節。
代碼如下:
可以看到,讀取NAND Flash的操作分爲6步:
① 選擇芯片;
② 發出讀命令;
③ 發出地址;
④ 等待數據就緒;
⑤ 讀取數據;
⑥ 結束後,取消片選信號。
流程圖如圖8.14所示。
爲了更形象地瞭解程序執行時代碼複製、程序執行位置,請參考圖8.15。
附:代碼:
鏈接: https://pan.baidu.com/s/1kV24a9L 密碼: tfab