NandFlash讀寫


1.NandFlash分類

根據物理結構上的區別,NandFlash主要分為如下兩類:
•SLC (Single Level Cell): 單層式存儲
•MLC (Multi Level Cell): 多層式存儲
SLC在存儲格上只存一位數據,而MLC則存放兩位數據。

2.MLC與SLC對比

價格:由於MLC采用了更高密度的存儲方式,因此同容量的MLC價格上遠低於SLC.
訪問速度:SLC的訪問速度一般要比MLC快3倍以上.
使用壽命:SLC能進行10萬次的擦寫,MLC能進行1萬次
功耗:MLC功耗比SLC高15%左右

3.NandFlash初始化

3.1 設置時間參數TACLS 、TWRPH0、TWRPH1 

3.2 使能NandFlash

3.3 NandFlash復位

3.3.1 選中芯片

3.3.2 清除RnB

 

3.3.3 發出復位信號(0xff)

3.3.4 等待就緒

 

3.3.5 取消選中

 4.按頁讀取NandFlash的值

 

步驟:

1.選中芯片;2.清除RnB;3.發出命令0x00;4.發送列地址;5.發送行地址;6.發出命令0x30;7.等待就緒;8.讀數據 ;9.取消片選

5.向NandFlash寫入數據

5.1 擦除(寫之前要進行擦除)

步驟:

1.選中芯片;2.清除RnB;3.發出命令0x60;4.發送行地址(3個周期);5.發送命令D0;6.等待RnB;7.發送命令70;8.讀取擦除結果;9.取消片選

 5.2 寫入數據

步驟:

1.選中芯片;2.清除RnB;3.發出命令0x80;4.發送列地址(2個周期);5.發送行地址(3個周期);6.寫入數據;7.發送命令0x10;8.等待RnB;9.發送命令70;10.讀取寫入結果;10.取消片選

6.代碼

nand.c

  1 /*
  2 tiny6410用的nandflash為 一頁2K
  3 */
  4 
  5 
  6 #define NFCONF             (*((volatile unsigned long*)0x70200000))
  7 #define NFCONT             (*((volatile unsigned long*)0x70200004))
  8 #define NFCMMD             (*((volatile unsigned char*)0x70200008))
  9 #define NFSTAT             (*((volatile unsigned char*)0x70200028))
 10 #define NFADDR             (*((volatile unsigned char*)0x7020000c))
 11 #define NFDATA             (*((volatile unsigned char*)0x70200010))
 12 
 13 void select_ship(void)
 14 {
 15     NFCONT &= ~(1<<1);    
 16 }
 17 
 18 void delselect_ship(void)
 19 {
 20     NFCONT |= (1<<1);
 21 }
 22 
 23 void clean_RnB()
 24 {
 25     NFSTAT |= (1<<4);
 26 } 
 27 void nand_cmd(unsigned char cmd)
 28 {
 29     NFCMMD = cmd;   
 30 }
 31 
 32 void wait_RnB(void)
 33 {
 34     while(!(NFSTAT & 0x1));
 35 }
 36 
 37 void nand_addr(unsigned char addr)
 38 {
 39     NFADDR = addr;
 40 }
 41 
 42 void nand_reset(void)
 43 {
 44     /* 選中 */
 45     select_ship();
 46     
 47     /* 清除RnB */
 48     clean_RnB();
 49     
 50     /* 發出復位信號 */
 51     nand_cmd(0xff);
 52     
 53     /* 等待就緒 */
 54     wait_RnB();
 55     
 56     /* 取消選中 */
 57     delselect_ship();
 58 }
 59 
 60 void nand_init(void)
 61 { 
 62 
 63     
 64     /* 設置時間參數 */
 65 #define TACLS  7
 66 #define TWRPH0 7
 67 #define TWRPH1 7
 68     
 69     NFCONF &= ~((7<<12)|(7<<8)|(7<<4));
 70     NFCONF |= (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
 71     
 72     /* 使能 nandflash controller*/
 73     NFCONT = 1 | (1<<1);
 74     
 75     
 76     
 77     /* 復位 */
 78     nand_reset();
 79 }
 80 
 81 void NF_PageRead(unsigned long addr,unsigned char* buff)
 82 {
 83     int i;
 84     
 85     
 86     /* 選中芯片 */
 87     select_ship();
 88     
 89     /* 清除RnB */
 90     clean_RnB();
 91     
 92     /* 發出命令0x00 */
 93      nand_cmd(0x00);
 94         
 95      /* 發出列地址 */
 96     nand_addr(0x00);
 97     nand_addr(0x00);
 98 
 99     /* 發出行地址 */
100     nand_addr(addr&0xff);
101     nand_addr((addr >>8 ) & (0xff));
102     nand_addr((addr >>16 ) & (0xff));
103         
104     /* 發出命令0x30 */
105      nand_cmd(0x30);
106         
107     /* 等待就緒 */
108      wait_RnB();
109         
110     /* 讀數據 */
111      for(i = 0; i<1024*2; i++)
112     {
113         *buff++ = NFDATA;
114     }
115         
116       
117      /* 取消片選 */
118      
119      delselect_ship();
120      
121 }
122 
123 
124 int NF_Erase(unsigned long addr)
125 {
126     int ret;
127     
128     //選中flash芯片
129     select_ship();
130     
131     //清除RnB
132     clean_RnB();
133     
134     //發送命令60
135     nand_cmd(0x60);
136     
137     //發送行地址(3個周期)
138     nand_addr(addr&0xff);
139         nand_addr((addr >>8 ) & (0xff));
140         nand_addr((addr >>16 ) & (0xff));
141     
142     //發送命令D0
143     nand_cmd(0xD0);
144     
145     //等待RnB
146     wait_RnB();
147     
148     //發送命令70
149     nand_cmd(0x70);
150     
151     //讀取擦除結果
152     ret = NFDATA;
153     
154     //取消選中flash芯片
155     delselect_ship();
156     
157     return ret;
158 }
159 
160 int NF_WritePage(unsigned long addr,unsigned char* buff)
161 {
162     int ret,i;
163     
164     //選中flash芯片
165     select_ship();
166     
167     //清除RnB
168     clean_RnB();
169     
170     //發送命令80
171     nand_cmd(0x80);
172     
173     //發送列地址(2個周期)
174     nand_addr(0x00);
175         nand_addr(0x00);
176     
177     //發送行地址(3個周期)
178     nand_addr(addr&0xff);
179         nand_addr((addr >>8 ) & (0xff));
180         nand_addr((addr >>16 ) & (0xff));
181     
182     //寫入數據
183     for(i=0;i<1024*2;i++)
184     {
185         NFDATA = buff[i];    
186     }
187     
188     //發送命令10
189     nand_cmd(0x10);
190     
191     //等待RnB
192     wait_RnB();
193     
194     //發送命令70
195     nand_cmd(0x70);
196     
197     //讀取寫入結果
198     ret = NFDATA;
199     
200     //取消選中flash芯片
201     delselect_ship();
202     
203     return ret;
204 }
nand.c

nand_to_ram

匯編和C語言的參數傳遞,不超過4個的時候,直接用r0--r3傳遞,且順序和從函數的形參一致

 1 copy_to_ram:
 2     mov r0,#0
 3     ldr r1,=_start
 4     ldr r2,=bss_end
 5     
 6     sub r2,r2,r1
 7     mov ip,lr
 8     bl nand_to_ram
 9     
10     mov lr,ip
11     
12     
13     mov pc,lr
start.S
 1 void nand_to_ram(unsigned long start_addr,unsigned char* sdram_addr,int size)
 2 {
 3         int i;
 4                
 5     for( i=(start_addr >>11); size>0;)
 6     {
 7         NF_PageRead(i,sdram_addr);    
 8         size -= 2048;
 9         sdram_addr += 2048;
10         i++;
11     }
12         
13 }
nand_to_ram

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM