Nand Flash驅動
近些年來,相較于SDRAM和NAND flash存盤器的經濟性,NOR flash存盤器價格高,這就促使了很多用戶將啟動程式放在NAND flash,需要執行的主代碼放到SDRAM中,S3C2440A啟動代碼可以在外部的NAND flash中執行,為了支持NAND flash運行bootloader,S3C2440A內部有一個名為“踏腳石”的SRAM緩沖區,當系統上電啟動時,NAND flash中的前4KB資料將會被自動加載到“踏腳石”中,這樣加載到“踏腳石”中的啟動代碼將會被執行,通常,啟動代碼將會從NAND flash復制到SDRAM,使用了硬體ECC檢測機制,NAND flash中的資料將會進行校驗檢查,復制完成后,主程式將會在SDRAM中執行,

在復位程序中,Nand flash控制器通過引腳狀態(NOCON(Adv flash),GPG13(頁大小),GPG14(地址周期),GPG15(總線寬度))讀取與其相連的NAND flash資訊,系統上電或者復位時,NAND Flash控制器將會自動地將4Kb bootloader代碼加載,加載完畢后,bootloader代碼將會在“踏腳石”中執行,
開發板中用到的Nand Flash型號是K9F2G08U0B,下圖是引腳

8bit Nand Flash存盤器介面

引腳說明:
| 引腳名稱 | 引腳功能 |
| I/O0 ~ I/O7 | 資料輸入輸出 I/O引腳用于輸入命令,地址,資料,或者在讀資料的程序中輸出資料,當芯片未被選中或者輸出被禁用是,I/O 引腳浮動到高阻, |
| CLE | 命令鎖存使能(COMMAND LATCH ENABLE) CLE輸入引腳可以控制命令發送到命令暫存器的有效通道,當有效信號為高電平,WE是上升沿信號時,命令通過I/O口被鎖存到命令暫存器中, |
| ALE | 地址鎖存使能(ADDRESS LATCH ENABLE) ALE輸入引腳可以控制地址發送到內部地址暫存器的有效通道,當WE是上升沿信號時,地址將會被鎖存, |
| CE | 芯片使能(CHIP ENABLE) CE輸入引腳用于設備選擇的控制信號,當設備處于忙碌狀態,CE的高電平信號將被忽略,編程及操作操作時設備不會回到待機模式, |
| RE | 讀使能(READ ENABLE) RE輸入引腳是串行資料輸出控制信號,以及控制資料何時傳送到I/O總線上,RE出現下降沿信號后,資料成為有效的tREA,同時內部的列計數值會加1, |
| WE | 寫使能(WRITE ENABLE) WE輸入引腳用于控制資料寫入I/O端,當WE脈沖出現上升沿信號時,命令,地址和資料將會被鎖存, |
| WP | 寫保護(WRITE PROTECT) 當電源發生變化時,WP引腳提供編程擦除保護,當WP引腳是低電平有效信號時,內部的高壓生成器將會復位, |
| R/B | 就緒/忙碌狀態輸出(READY/BUSY OUTPUT) 該輸出引腳顯示設備操作的狀態,當引腳處于低電平時,表示處理器正在進行編程,擦除或者隨機讀操作,操作完成后引腳將會變成高電平,當芯片未選中或者輸出被禁用時,是開漏輸出,不會浮動到高阻上, |
| Vcc | POWER VCC是設備的供電, |
| Vss | GROUND |
| N.C | NO CONNECTION 引腳沒有內部連線, |
操作特性:

注意:在就緒狀態下,如果復位命令(FFh)被寫入,設備將會進入忙碌狀態,該狀態最多持續5μs,
Nand Flash操作時序圖

K9F2G08X0B共有2112Mbit約256M容量,由131072行(頁)和2112x8列(頁內索引)組成,空閑區(用于校驗等非資料區)的 64x8列的列地址編號范圍是2048~2111,一個2112位元組的資料暫存器和存盤器單元矩陣連接對應起來,用于在I/O快取和存盤器之間進行頁讀取和頁寫入,存盤器矩陣是由32個單元以串行方式組成形成NAND結構,32個單元中的每一個分布在不同的頁中,一個塊由兩個NAND連在一起構成,一個NAND結構由32個單元組成,一個塊中共有1081344個NAND單元存在, 編程和讀操做以頁為基本單位進行操作,擦除操作是以塊單位進行操作,存盤器矩陣由2048個單獨的128KB大小的可擦除塊組成,在K9F2G08X0B上禁止按bit進行擦除操作,
K9F2G08X0B的8個IO口為地址復用形式,這種方案可以顯著的減少引腳的數量以及在將來系統升級時可以保持系統板設計密度的一致性,當CE是低電平時,可通過設定WE為低電平來向IO口寫入命令、地址和資料,WE上升沿時這些內容將會被鎖存,命令鎖存使能(CLE) 和地址鎖存使能(ALE) 用于復用命令、地址來實作單獨訪問IO口,有些命令需要一個總線周期,例如,復位命令,狀態讀取命令等只需要一個周期的總線時間,其他的一些命令,比如頁讀取,塊擦除以及頁編程則需要兩個周期:一個周期用來設定,另外一個周期用來執行,264M位元組的物理空間需要29個地址bit,從而需要5個周期用來進行編址:順序是,2個周期的列地址,3個周期的行地址,頁讀取和頁編程需要相同的5個地址周期進行相應的命令輸入,對于塊草除操作,僅需要3個地址周期, 對設備的操作是通過向命令暫存器寫特殊的命令來實作的,

下表描述了K9F2G08X0B 的一些特殊命令,

提示:1.除了70h/F1h/FFh,所有11h~81h之間的命令都是被禁止的,
2.在一頁中可以進行資料的隨機讀寫,
警告:除了上表列出的命令集,其他任何未定義的命令輸入都是禁止的,
在一頁中隨機讀取資料的時序圖:

本節只講解頁內隨機讀資料操作,其他操作請自行查閱資料手冊,
以下是Nand Flash隨機讀資料的代碼:
1 #define NF_READ_BYTE() (rNFDATA & 0xFF)
2 int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
3 {
4 int i, block, page, add;
5 nf_init();
6 for(i=start_addr; i < (start_addr + size); i++) {
7 block = i / 131072;
8 page = (i % 131072) / 2048;
9 add = i % 2048;
10 *buf = nf_read(block, page, add);
11 buf++;
12 }
13 return 0;
14 }
15 void nf_init(void)
16 {
17 rNFCONF=((1<<12)|(1<<8)|(0<<4));
18 rNFCONF&=(~(1<<0));
19 rNFCONT =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
20 nf_reset();
21 }
22 void nf_reset(void)
23 {
24 nf_select(1);
25 nf_cmd(0xff);
26 nf_readly();
27 nf_select(0);
28 }
29 void nf_select(int n){
30 if(n==1){
31 NAND_CHIP_ENABLE;
32 }else if(n==0){
33 NAND_CHIP_DISABLE;
34 }else{
35 ;
36 }
37 }
38 void nf_cmd(unsigned char cmd){
39 rNFCMD = cmd
40 }
41 void nf_readly(void){
42 while(!(rNFSTAT &(1<<0)));
43 }
44 void nf_addr(unsigned char addr)
45 {
46 rNFADDR = addr;
47 }
48 unsigned char nf_read(unsigned int block, unsigned int page, unsigned int add)
49 {
50 unsigned char buffer=0;
51 unsigned int page_number =(block<<6) + page;
52 nf_reset();
53 nf_select(1);
54 nf_cmd(0);
55 nf_addr(0x00);
56 nf_addr(0x00);
57 nf_addr((page_number)& 0xff); //取出行地址(頁間地址的低8位)
58 nf_addr((page_number>> 8) & 0xff); //取出行地址(頁間地址的次低8位)
59 nf_addr((page_number>> 16) & 0xff); //取出行地址(頁間地址的次高8位)
60 nf_cmd(0x30);
61 nf_readly();
62 nf_cmd(0x05);
63 nf_addr((char)(add&0xff));
64 nf_addr((char)((add>>8)&0x0f));
65 nf_cmd(0xe0);
66 nf_readly();
67 buffer=NF_READ_BYTE();
68 nf_select(0);
69 return buffer;
70 }
Line2函式nand_read_ll為資料讀取主函式,引數buf,是SDRAM資料保存的地址,引數start_addr,是Nand Flash的起始地址,該值的取值范圍為0x00~ 0xFFFFFFF(將Nand Flash的地址空間抽象成了256M的線性地址),引數size是需要連續讀取的位元組數,本函式僅作為演示,采用是回圈隨機讀取頁內資料,效率不高,讀者可自行撰寫程式,采用頁批次讀進行優化,
Line5對應的函式nf_init用于初始化Nand flash,
Line17 暫存器NFCONF[12~13],用于設定CLE和ALE時間周期,公式為HCLK*X,X此處設定為1,NFCONF[8~10],用于設定TWRPH0的時間周期,公式為HCLK*(X+1),X此處為1,NFCONF[4~6],用于設定TWRPH1的時間周期,公式為HCLK*(X+1),X此處為0,
Line18 暫存器NFCONF[0]用于選擇IO總線寬度,此處設定為0:8-bit總線,
Line19 暫存器NFCONT[13]用于配置鎖定存盤器,如果設定為1,寫入和擦除命令都是無效的,且只能在復位或者喚醒的情況下設定為0,此處設定為0:禁用鎖定功能,暫存器NFCONT[12]用于配置軟體鎖,如果設定為1,寫入和擦除命令都是無效的,可以在任何時候由軟體改成0,此處設定為0:禁用軟體鎖定,暫存器NFCONT[10]用于設定非法訪問中斷控制,如果設定為1 ,非法訪問將產生中斷,此處設定為0:禁用中斷,暫存器NFCONT[9]用于設定RnB狀態轉變中斷控制,如果設定為1,使能RnB中斷,此處設定為0:禁用RnB中斷,暫存器NFCONT[8]用于設定RnB狀態轉變檢測控制,如果設定為1,檢測下降沿,此處設定為0:檢測上升沿,暫存器NFCONT[6]用于設定spare區ECC生成鎖定功能,如果設定為0,不鎖定ECC,此處設定為1:鎖定ECC,暫存器NFCONT[5]用于設定Main資料區域ECC生成鎖定功能,如果設定為0,不鎖定ECC,此處設定為1:鎖定ECC,暫存器NFCONT[4]用于設定初始化ECC解碼器/編碼器,如果設定為0,不初始化,此處設定為1:初始化ECC解碼器和編碼器,暫存器NFCONT[1]用于設定Nand flash存盤器nFCE信號控制,如果設定為0,將nFCE信號設定為低電平,即選中芯片,此處設定為1:將nFCE信號設定為高電平,即不選中芯片,暫存器NFCONT[0]用于設定Nand flash控制器操作模式,如果設定為0,Nand flash控制器被禁用,此處設定為1:使能Nand flash控制器的功能,
Line20對應的函式nf_reset用于復位Nand flash,
Line24對應的函式nf_select用于選中/不選中芯片,對應于暫存器NFCONT[1]的功能,此處設定為選中芯片,
Line25對應的函式nf_cmd用于設定命令,即NFCMD暫存器低8位,通過上面的介紹可知,0xFF表示復位命令,
Line26對應的函式nf_readly()用于等待暫存器NFSTAT[0]的值變成1,即RnB輸入引腳的值變1:Nand Flash已就緒可以操作,
Line27對應的函式nf_select(0)用于不選中芯片,
Line7~9將flash線性地址轉換成塊號,行號(頁號),列號,
Line10對應的函式用于從指定nand flash特定位置讀取資料,
Line51由于每塊有64(2^6=64)頁得到頁的絕對地址,
Line54發送按頁讀的第一個周期的讀命令,0x00
Line55~59先設定3次行地址,
Line60發送按頁讀的第二個周期的讀命令
Line61等待完成要求動作
Line62發送按位元組讀的第一個周期的讀命令
Line63~64先發送頁間地址
Line65發送按位元組讀的第二個周期的讀命令
Line66等待完成要求動作
Line67讀取值
Line68關閉片選
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/302862.html
標籤:其他
下一篇:python-mqtt自動化測驗
