S5PV210 Development Series seven NAND drive implementations
Chess Boy 1048272975
Nand Flash has the advantages of large capacity, fast rewriting speed, simple interface and so on, which is suitable for storage of large amount of data, which provides a cheap and effective solution for solid-state mass storage. A variety of electronic products such as mobile phone memory, SD card, u disk, etc. are using NAND flash storage, the author here on the NAND drive implementation as a simple introduction.
1. Nand Flash Overview
Toshiba first published the NAND flash structure in 1989, emphasizing lower cost per bit, higher performance, and the ability to easily upgrade through interfaces like disks. With the development of NAND technology, according to the NAND granular storage unit, it can be divided into SLC (single level cell), MLC (Multi Levelcell) and TLC (Trinary level cell). SLC is a 1bit/cell, 1 storage unit storing 1bit data, characterized by high cost, small capacity, fast speed, long life (about 100,000 times erase). MLC for 2bit/cell, that is, 1 storage units to store 2bit of data, compared to SLC, the price of general, capacity can be larger, the general speed, life expectancy (about 10,000 times erase). TLC, which stores 3bit of data for 3bit/cell, 1 storage units, has the lowest cost and the largest capacity compared to the same capacity, but with the slowest speed and shortest life (about 1000 erase writes). Currently on the market based on NAND flash memory, such as SD card, U disk and so on are mostly MLC type, but for high-capacity NAND memory, such as SD card 64G or more, it is possible for TLC-type NAND flash.
2. NAND Drive Implementation
Nand Flash is made up of blocks, the basic unit of Block is page (page), and each page is divided into data area (datastore) and spare area (alternate zone). Due to the Nand flash in the factory and in the use of the bad block, as well as the problem of bit reversal, in order to the reliability of the data, usually need to use ECC (Error correcting Code) algorithm, generally for SLC Nand, with 1bit ECC, For MLC Nand, more than 4bit ECC is required, and spare area is used to store additional information such as bad block markers and ECC data. Typically NAND flash is read and programmed on a page basis, while erasing is block-based. Nand Flash programming can only be programmed to 1 to 0, and not 0 programming to 1, so in the page programming, must have been erased first.
I use NAND flash for Samsung's k9f4g08u0e, a page with (2048+64) Byte, a block has 64 pages, the capacity size is (512m+16m) byte, is a 8-bit wide SLC Nand flash.
NAND flash drivers should generally implement NAND initialization, page reading, page programming, bad block tagging, bad block checking, block erase, and many other interfaces.
2.1. NAND initialization
NAND initialization is primarily a function of the NAND pin initialization, based on the specific NAND flash, set the best NAND access timing.
void Nand_init (void)
{
Configuring the NAND control PIN
Mp01con_reg = (Mp01con_reg & ~ (0xf<<8)) | (0X3<<8); NFCS0
mp01pud_reg&= ~ (3<<4); Pull-up/down Disable
Mp03con_reg =0x22222222;
Mp03pud_reg = 0;
Nfconf_reg = (2<<12) | (2<<8) | (1<<4) | (0<<3) | (0<<2) | (1<<1);
Nfcont_reg = (1<<23) | (1<<22) | (1<<5) | (1<<4) | (1<<2) | (1<<1) | (1<<0);
Nand_reset ();
}
2.2. NAND page Read
The k9f4g08u0e page is divided into 2k data area and a 64-byte spare Area,data area for storing the normal information, Sparearea is used to store additional data such as ECC data. For flash memory, there will be a bit reversal or bad block problem, the data written to flash or read from Flash may be wrong, so the ECC algorithm must be used to ensure that the data written and read the data is consistent. For SLC Nand Flash, 1-bit ECC is required, each byte produces 4 byte of ECC data, up to 1 bits can be corrected, spare area 0~1 bytes hold the bad block tag, 2~17 bytes hold the page ECC data, 18~19 bytes stored spare Area generated ECC data, the remaining spare area storage interface needs to write other spare area data.
int32_t Nand_readwithoob (uint32_t page, uint8_t *data,uint32_t Data_len, uint8_t *oob, uint32_t Oob_len)
{
uint8_t ecc[16];
uint32_t i;
uint8_t *PECC;
uint8_t *pbuffer;
uint32_t MECC, SECC;
uint16_t Col;
uint8_t Status;
if (!data && (data_len!=0)) {
return-1;
}
if (!oob && (oob_len!=0)) {
return-1;
}
Preserve OOB front 20 bytes as bad block tag and data ECC
if ((data_len>2048) | | | (oob_len>64-20)) {
Return-2;
}
ECC Data 16 byte starts at the 2nd byte offset in the spare area
Col = 2048 + 2;
NF_INIT_SECC ();
Nf_secc_unlock (); Unlock Spare ECC
Nf_ce_enable ();
NF_CLEAR_RB ();
Nf_cmd (NAND_CMD_READ0); Page Read Cycle 1
Nf_addr (Col & 0xff); Column Address
NF_ADDR (Col >> 8); Columu Address
NF_ADDR (page & 0xff); Transfer 3-byte page address
Nf_addr ((page>>8) & 0xff);
Nf_addr ((page>>16) & 0xff);
Nf_cmd (Nand_cmd_readstart); Page Read Cycle 2
Nf_wait_ready (); Wait for page read to complete
for (i=0; i<16; i++) {
Ecc[i] =nf_read_byte ();
}
Nf_secc_lock ();
SECC = Nf_read_byte ();
SECC |= nf_read_byte () << 8;
for (i=0; i<oob_len; i++) {
Oob[i] =nf_read_byte ();
}
Nfseccdata0_reg= ((secc&0xff00) <<8) | (SECC&0XFF);
Nf_ce_disable ();
Read ECC Status
Status = Nfestat0_reg;
if (((status>>2) & 0x3) = = 1) {
ECC 1biterror, correctable
ecc[(status>>21) &0xf]^= (1 << (status>>18) & 0x7);
} else if (((status>>2) & 0x3) > 1) {
Debug ("eccuncorrectable error detected\r\n");
return-3;
}
if (Data_len = = 0) {
return 0;
}
Nf_ce_enable (); Enable the chip to choose
NF_CLEAR_RB (); Clear data transfer flag
Nf_cmd (NAND_CMD_READ0); Page Read Cycle 1
NF_ADDR (0); Column Address
NF_ADDR (0); Columu Address
NF_ADDR (page & 0xff); Write 3-byte page address
Nf_addr ((page>>8) & 0xff);
Nf_addr ((page>>16) & 0xff);
Nf_cmd (Nand_cmd_readstart); Page Read Cycle 2
Nf_wait_ready (); Wait for the command to complete
Read Main area
PECC = ECC;
while (Data_len) {
Pbuffer =data;
NF_INIT_MECC ();//main area ECC empty
Nf_mecc_unlock ()//main area ECC unlock, start ECC calculation
for (i=0;i<512; i++) {
*data++ =nf_read_byte ();
data_len--;
if (Data_len = = 0) {
Break
}
}
Nf_mecc_lock ();//Lock main ECC
SLC:WRITEECC to compare
MECC = (pecc[1] << 16) | (Pecc[0] << 0);
Nfmeccdata0_reg= MECC;
MECC = (Pecc[3] << 16) | (Pecc[2] << 0);
Nfmeccdata1_reg= MECC;
PECC + = 4;
Read Eccstatus
Status =nfestat0_reg;
if ((status& 0x3) = = 1) {
1biterror, correctable
pbuffer[(status>>7) &0x7ff]^= (1 << (status>>4) & 0x7);
} else if (Status & 0x3) > 1) {
Debug ("eccuncorrectable error detected\r\n");
Nf_ce_disable ();
return-4;
}
}
Nf_ce_disable ();
return 0;
}
2.3. NAND page Programming
When you want to write data to a page, make sure that the block has been erased. After the data has been written, the ECC value of the data should be written to the spare area Convention location to ensure that the data written and read are consistent.
int32_t Nand_writewithoob (uint32_t page, const uint8_t*data, uint32_t data_len, const uint8_t *oob, uint32_t Oob_len)
{
uint8_t ecc[16];
uint32_t i;
uint8_t *PECC;
uint32_t MECC, SECC;
uint32_t data_len_temp;
uint16_t Col;
uint8_t State;
if (!data && (data_len!=0)) {
return-1;
}
if (!oob && (oob_len!=0)) {
return-1;
}
Preserve OOB front 20 bytes as bad block tag with data ECC
if ((data_len>2048) | | | (oob_len>64-20)) {
Return-2;
}
Nf_ce_enable (); Enable the chip to choose
NF_CLEAR_RB (); Clear data transfer flag
Nf_cmd (Nand_cmd_seqin); Page Program Cycle 1
NF_ADDR (0); Column Address
NF_ADDR (0); Columu Address
NF_ADDR (page & 0xff); Write 3-byte page address
Nf_addr ((page>>8) & 0xff);
Nf_addr ((page>>16) & 0xff);
PECC = ECC;
Data_len_temp = Data_len;
Write Main Area
while (data_len_temp) {
NF_INIT_MECC ();//main area ECC empty
Nf_mecc_unlock ()//main area ECC unlock, start ECC calculation
Write Bufferto Main Area
for (i=0;i<512; i++) {
Nf_write_byte (*data++);
data_len_temp--;
if (data_len_temp = = 0) {
Break
}
}
Nf_mecc_lock ();//Lock main ECC
MECC =nfmecc0_reg; 4 bytes ECC for writing main area data
*pecc++ =MECC & 0xFF;
*pecc++ = (mecc>>8) & 0xFF;
*pecc++ = (mecc>>16) & 0xFF;
*pecc++ = (mecc>>24) & 0xFF;
}
if (Data_len < 2048) {
Adjust to OOB area
Col = 2048;
Nf_cmd (Nand_cmd_rndin);//Random Write command in page
NF_ADDR (col& 0xff); 2-byte in-page address
Nf_addr ((col>>8) & 0xff);
}
Reserved for Bad block (2 byte)
Nf_write_byte (0xFF);
Nf_write_byte (0xFF);
NF_INIT_SECC ();
Nf_secc_unlock (); Unlock Spare ECC
Main ECC Byte, start spare area offset 2
for (i=0; i<16; i++) {
Nf_write_byte (Ecc[i]);
}
Nf_secc_lock (); Locking Spare ECC
SECC = Nfsecc_reg; 2 bytes of spare write data ECC
Nf_write_byte (SECC & 0xff); Continue writing SECC
Nf_write_byte ((secc>>8) & 0xff);
for (i=0; i<oob_len; i++) {
Nf_write_byte (Oob[i]);
}
Nf_cmd (Nand_cmd_pageprog); Page Program Cycle 2
Nf_wait_ready (); Waiting to finish writing
Nf_cmd (Nand_cmd_status); Read NAND state
do {
State =nf_read_byte ();
} while (! ( State & (1<<6)); Wait status becomes ready
Nf_ce_disable ();
If the write succeeds, the No. 0 digit is 0 pass, otherwise fail
if (State & (1<<0)) {
return-3; Write not successful
}
return 0;
}
2.4. NAND bad block check
The bad block marking convention uses the spare area No. 0 to 1th byte as the flag, the bad block this two byte flag is not 0xFF, the good block is 0xFF. We can tell if the block is bad if we read the value of the No. 0 to 1th byte of the page 0,spare area in block.
int32_t Nand_isbadblock (uint32_t Block)
{
UINT8_TOOB[2];
Each block first page spare area 0, 1 bytes non 0xff mark for good or bad
Nand_read (block,0, 2048, 2, OOB);
if ((Oob[0]==0xff) && (Oob[1]==0xff)) {
return 0; Good piece
}
return 1; Bad block
}
2.5. Bad block mark
If the page programming is unsuccessful or the erase fails, checking for bad blocks requires that the corresponding block be marked at the agreed location, so that the bad block is not read and written. Its code is implemented as follows:
int32_t Nand_markbadblock (uint32_t Block)
{
Each block first page spare District No. 0, 1 byte mark not 0xff bad block
uint8_t oob[2];
Oob[0] = 0;
OOB[1] = 0;
Returnnand_write (Block, 0, 2048, 2, OOB);
}
2.6. Block Area Erase
The corresponding block should have been erased before the data is written to the block area.
int32_t Nand_eraseblock (uint32_t Block)
{
Uint8_tstate;
Nf_ce_enable ();
NF_CLEAR_RB ();
Nf_cmd (NAND_CMD_ERASE1);//Erase block command Cycle 1
Write 3cycle block Address[a28:a18]
Nf_addr ((block<<6) & 0xff); [A19:a18]
Nf_addr ((block>>2) & 0xff); [A27:A20]
Nf_addr ((block>>10) & 0xff); A28
Nf_cmd (NAND_CMD_ERASE2);//Erase block command Cycle 2
Nf_wait_ready ();
Nf_cmd (Nand_cmd_status);
do {
State =nf_read_byte ();
}while (! ( State & (1<<6)); Wait status becomes ready
Nf_ce_disable ();
If the erase is successful, the No. 0 bit is 0 pass, otherwise fail
if (state& (1<<0)) {
return-1;
}
return 0; Successful Erase
}
3. NAND Boot
For Onenand/nand start-up equipment, BL0 In addition to testing BL1 inspection and, will also use 8bit ECC test BL1 code correctness, BL1 when burned into the NAND device, should also generate the corresponding 8/16-bit ECC data, written to the spare area of the specified location, Otherwise, ECC failure will not boot from the NAND device. NAND booting requires 8bit ECC processing, and the corresponding nandboot.c in the 8bit ECC reference bootloader is the NAND driver.
Figure 3-1 Nand ECC test
4. Appendix
Nand.rar,nand Drive implementation.
Http://pan.baidu.com/s/1gd6fEIv
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
S5PV210 Development Series Seven _nand drive implementation