NAND Flash
關于NAND Flash
S5PV210的NAND Flash控制器有如下特點:
1) 支持512byte,2k,4k,8k的頁大小
2) 通過各種軟件模式來進行NAND Flash的讀寫擦除等
3) 8bit的總線
4) 支持SLC和MCL的NAND Flash
5) 支持1/4/8/12/16bit的ECC
6) 支持以字節/半字/字為單位訪問數據/ECC寄存器,以字為單位訪問其他寄存器。
注意:在此使用的Mini210S的NAND Flash類型為SLC,大小為1G,型號為K9K8G08U0A。所以本章的內容是針對SLC類型的NAND Flash(包括256M/512M/1GB等),并不適用MLC類型的NAND Flash。
程序例子:(完整代碼見鏈接)
代碼多了nand.c這個文件,里面包含了對NAND Flash的相關操作。
/*nand.c*/
<1> NAND Flash初始化函數nand_init(),代碼如下
void nand_init(void)
{
// 1. 配置NAND Flash
NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0);
NFCONT =(0<<18)|(0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0x3<<1)|(1<<0);
// 2. 配置引腳
MP0_1CON = 0x22333322;
MP0_2CON = 0x00002222;
MP0_3CON = 0x22222222;
// 3. 復位
nand_reset();
}
共3個步驟:
第一步 配置NAND Flash
主要是設置NFCONF和NFCONT兩個寄存器
NFCONF寄存器
AddrCycle = 1,When page size is 2K or 4K, 1 = 5 address cycle,Mini210S的NAND Flash的頁大小為2k,所有是5個地址周期;
PageSize = 0,When MLCFlash is 0, the value of PageSize is as follows: 0 = 2048 Bytes/page,Mini210S使用的是SLC NAND Flash且每頁大小為2k;
MLCFlash = 0,在此使用的是SLC NAND Flash;
TWRPH1/TWRPH0/TACLS是關于訪問時序的設置,需對照NAND Flash芯片手冊設置,這里不再詳細解釋,分別取TWRPH1=1,TWRPH0=4,TACLS=1;
ECCType0/MsgLength,我們的裸機代碼沒有使用到ECC,所有不用設置這兩個標志。
MODE = 1,使能NAND Flash控制器;
Reg_nCE0 = 1,取消片選,需要操作NAND Flash時再發片選;
Reg_nCE1 = 1, 取消片選,需要操作NAND Flash時再發片選;
InitMECC/InitSECC/SECCLock/MECCLock,我們的裸機代碼不涉及ECC,這4個標志位隨便設置即可;
RnB_TransMode = 0,Detect rising edge,RnB是NAND Flash的狀態探測引腳,我們使用上升沿觸發;
EnbRnBINT = 0 ,禁止RnB中斷;
EnbIllegalAccINT = 0,禁止Illegal access 中斷 ;
EnbMLCDecInt/EnbMLCEncInt為MCL相關,不用設置;
LOCK = 0,我們沒有用到Soft Lock,所以禁止Soft Lock;
LockTight = 0,我們沒有用到Lock-tight,所有禁止Lock-tight;
MLCEccDirection,MLC相關,可不用設置
第二步 配置引腳
用于NAND Flash相關功能;
第三步 復位
復位函數nand_reset的相關代碼如下:
static void nand_reset(void)
{
nand_select_chip();
nand_send_cmd(NAND_CMD_RES);
nand_wait_idle();
nand_deselect_chip();
}
NAND Flash的復位操作共4個步驟:
1) 發片選,實質就是NFCONT &= ~(1<<1);往NFCONT的bit[1]寫0;
2) 發命令復位命令NAND_CMD_RES (0xff);實質就是NFCMMD = cmd;將命令寫到NFCMMD寄存器;完整的NAND Flash命令信息見下圖:
3) 等待NAND Flash 就緒;實質就是while( !(NFSTAT & (BUSY<<4)) ),讀NFSTAT的bit[4]檢查NAND Flash是否就緒;
4) 取消片選,實質就是NFCONT |= (1<<1); 往NFCONT的bit[1]寫1;
<2> NAND Flash讀ID函數nand_read_id(),代碼如下
void nand_read_id(void)
{
nand_id_info nand_id;
// 1. 發片選
nand_select_chip();
// 2. 讀ID
nand_send_cmd(NAND_CMD_READ_ID);
nand_send_addr(0x00);
nand_wait_idle();
nand_id.IDm = nand_read();
nand_id.IDd = nand_read();
nand_id.ID3rd = nand_read();
nand_id.ID4th = nand_read();
nand_id.ID5th = nand_read();
printf('NANDFlash: makercode = %x,devicecode = %xrn',nand_id.IDm,nand_id.IDd);
nand_deselect_chip();
}
NAND Flash 讀ID操作
根據上圖,NAND Flash的讀ID操作共4個步驟:
第一步 發片選;
第二步 發讀ID命令NAND_CMD_READ_ID(0x90);
第三步 發地址0x00;調用函數nand_send_addr();
第四步 等待NAND Flash 就緒;
第五步 讀ID;調用了nand_read()函數,實質就是讀NFDATA寄存器;
下面解釋一下函數nand_send_addr(),核心代碼如下:
{
// 列地址,即頁內地址
col = addr % NAND_PAGE_SIZE;
// 行地址,即頁地址
row = addr / NAND_PAGE_SIZE;
// Column Address A0~A7
NFADDR = col & 0xff;
for(i=0; i<10; i++);
// Column Address A8~A11
NFADDR = (col >> 8) & 0x0f;
for(i=0; i<10; i++);
// Row Address A12~A19
NFADDR = row & 0xff;
for(i=0; i<10; i++);
// Row Address A20~A27
NFADDR = (row >> 8) & 0xff;
for(i=0; i<10; i++);
// Row Address A28~A30
NFADDR = (row >> 16) & 0xff;
for(i=0; i<10; i++);
}
首先根據頁大小來獲取頁地址和頁內偏移地址,然后通過5個周期將地址發送出去,實質就是寫NFADDR寄存器,具體每個周期如何發送,查閱NAND Flash芯片手冊可知,見下圖:
發送地址后,就可以連續讀出5個ID了,其中第一個是MAKDER CODE, 第二個是DEVICE CODE。
<3> NAND Flash擦除函數nand_erase(),核心代碼如下:
{
// 獲得row地址,即頁地址
unsigned long row = block_num * NAND_BLOCK_SIZE;
// 1. 發出片選信號
nand_select_chip();
// 2. 擦除:第一個周期發命令0x60,第二個周期發塊地址,第三個周期發命令0xd0 nand_send_cmd(NAND_CMD_BLOCK_ERASE_1st);
for(i=0; i<10; i++);
// Row Address A12~A19
NFADDR = row & 0xff;
for(i=0; i<10; i++);
// Row Address A20~A27
NFADDR = (row >> 8) & 0xff;
for(i=0; i<10; i++);
// Row Address A28~A30
NFADDR = (row >> 16) & 0xff;
NFSTAT = (NFSTAT)|(1<<4);
nand_send_cmd(NAND_CMD_BLOCK_ERASE_2st);
for(i=0; i<10; i++);
// 3. 等待就緒
nand_wait_idle();
// 4. 讀狀態
unsigned char status = read_nand_status();
}
根據上圖,NAND Flash的擦除操作共6個步驟:
第一步 發片選;
第二步 發擦除命令1 NAND_CMD_BLOCK_ERASE_1(0x60);
第三步 發頁地址,只需發頁地址;
第四步 發擦除命令2 NAND_CMD_BLOCK_ERASE_2st(0xD0);
第五步 等待NAND Flash就緒;
第六步 讀狀態,判斷擦除是否成功。若擦除失敗,則打印是壞塊再取消片選;否則直接直接取消片選即可。讀狀態調用了函數read_nand_status(),它的實質就是nand_send_cmd(NAND_CMD_READ_STATUS);ch = nand_read();先發讀狀態命令NAND_CMD_READ_STATUS,然后再讀狀態值。
<4> NAND Flash讀函數copy_nand_to_sdram(),從NAND Flash中讀數據到DRAM,核心代碼如下:
{
// 1. 發出片選信號 nand_select_chip();
// 2. 從nand讀數據到sdram,第一周期發命令0x00,第二周期發地址nand_addr,第三個周期發命令0x30,可讀一頁(2k)的數據
while(length)
{
nand_send_cmd(NAND_CMD_READ_1st);
nand_send_addr(nand_addr);
NFSTAT = (NFSTAT)|(1<<4);
nand_send_cmd(NAND_CMD_READ_2st);
nand_wait_idle();
// 列地址,即頁內地址
unsigned long col = nand_addr % NAND_PAGE_SIZE;
i = col;
// 讀一頁數據,每次拷1byte,共拷2048次(2k),直到長度為length的數據拷貝完畢
for(; i
*sdram_addr = nand_read();
sdram_addr++; nand_addr++;
}
}
// 3. 讀狀態
unsigned char status = read_nand_status();
}
NAND Flash 讀操作
根據上圖,NAND Flash的讀操作共7個步驟:
第一步 發片選;
第二步 發讀命令1 NAND_CMD_READ_1st(0x00);
第三步 發地址,調用函數nand_send_cmd(),發5個地址周期;
第四步 發讀命令2 NAND_CMD_READ_2st(0xD0);
第五步 等待NAND Flash就緒;
第六步 從頁內偏移地址開始讀,讀到頁結尾即結束,每次讀1byte;
第七步 讀狀態,判斷是否讀成功。
<5> NAND Flash寫函數copy_sdram_to_nand (),從DRAM寫數據到NAND Flash,核心代碼如下:
{
// 1. 發出片選信號
nand_select_chip();
// 2. 從sdram讀數據到nand,第一周期發命令0x80,第二周期發地址nand_addr,第三個周期寫一頁(2k)數據,第四周期發0x10
while(length)
{
nand_send_cmd(NAND_CMD_WRITE_PAGE_1st);
nand_send_addr(nand_addr);
// 列地址,即頁內地址
unsigned long col = nand_addr % NAND_PAGE_SIZE;
i = col;
// 寫一頁數據,每次拷1byte,共拷2048次(2k),直到長度為length的數據拷貝完畢
for(; i
nand_write(*sdram_addr);
sdram_addr++;
nand_addr++;
}
NFSTAT = (NFSTAT)|(1<<4);
nand_send_cmd(NAND_CMD_WRITE_PAGE_2st);
nand_wait_idle();
}
// 3. 讀狀態
unsigned char status = read_nand_status();
}
根據上圖,NAND Flash的寫操作共7個步驟:
第一步 發片選;
第二步 發寫命令1 NAND_CMD_WRITE_PAGE_1st (0x80);
第三步 發地址地址,調用函數nand_send_cmd(),發5個地址周期;
第四步 發讀命令2 NAND_CMD_WRITE_PAGE_2st (0x10);
第五步 等待NAND Flash就緒;
第六步 從頁內偏移地址開始寫,讀到頁結尾即結束,每次寫1byte;
第七步 讀狀態,判斷是否讀成功。
2. main.c
在main.c中,首先會調用nand_init()來初始化NAND Flash,然后打印一個菜單,提供4種選擇測試NAND Flash:
讀ID功能(nand_read_id());
擦除功能(nand_erase());
讀功能(copy_nand_to_sdram());
寫功能(copy_sdram_to_nand());
上一篇:S5PV210串口
下一篇:S5PV210 PWM定時器
推薦閱讀最新更新時間:2025-04-19 06:41


設計資源 培訓 開發板 精華推薦
- AM2G-2415DH30Z ±15V 2 瓦 DC-DC 轉換器的典型應用
- AM6TW-4818SH35Z 18V 6瓦單路輸出DC-DC轉換器的典型應用
- LT1307CN8 外部控制突發模式操作的典型應用電路
- 用于 DECT 和其他高速 GFSK 應用的 FM/IF 系統
- SlimSASCEMx8_EVM
- LT1767EMS8E-3.3 12V 至 3.3V 降壓轉換器的典型應用電路
- 【涂鴉智能】物聯網溫濕度機
- 帶有NUCLEO-G431RB和X-NUCLEO-IHM16M1的電機控制Nucleo Pack
- 【涂鴉智能】酷斃燈驅動器
- LT3502A 演示板、2.2MHz、500mA、2mm-2mm DFN 降壓穩壓器