Author: Cai yuqing
Www.another-prj.com
(About modification)
Just as the disk of a hard disk is divided into tracks, each track is divided into several sectors, one NAND Flash is also divided into several blocks, and each block is divided into dry pages. Generally, the relationship between blocks and pages varies with chips. The typical allocation is as follows:
1 block = 32 page
1 page = 512 bytes (datafield) + 16 bytes (OOB)
It should be noted that all flash reads and writes start with a page, but flash must be erased before reading and writing, while Flash is written in a block. At the same time, it must be noted that 512bytes is theoretically divided into 1st half and 2SD half, each of which occupies 256 bytes.
The k9f1208u0b we discussed has a total of 4096 blocks, so we can know that the flash capacity is 4096 * (32*528) = 69206016 bytes = 66 MB
However, in fact, the last 16 bytes on each page are used to store the verification code and other information, and the actual data cannot be stored, therefore, we can actually operate on a chip capacity of 4096 * (32*512) = 67108864 bytes = 64 MB, as shown in. A page consists of a total of 528 bytes, these 528 bytes are arranged in order by column units (1 column represents a byte) from top to bottom. 0th million behaviors: 0th million bytes, 1st million bytes, and so on. Each row is composed of eight digits, each representing 1 bit in one byte ). These 528bytes are divided into two parts by function: Data Field and spare field. Spare field occupies 16 bytes of 528bytes, which is used to store verification codes during read/write operations, generally, you do not need to store ordinary data. Except for these 16 bytes, the remaining 528 bytes are the data field we use to store data. Therefore, although there are bytes on a page, however, we only calculate the capacity by bytes.
There are two read commands: read1 and read2. read1 is used to read data in the data field, while read2 is used to read data in the spare field. For NAND Flash, the minimum read operation unit is page. That is to say, when the starting position of the read operation is given, the read operation starts from this position, reads the last byte of the current page consecutively (which can include spare field)
Addressing of NAND Flash
The address register of NAND Flash Splits a complete NAND flash Address into column address and page address.
Column address: the column address. Column address specifies a byte on the page. Specifying this Byte actually specifies the read/write start address of the page.
Paage address: page address. Because the page address is always aligned with bytes, its 9-bit low is always 0. Determine the page on which the read/write operation is performed.
Read1 command
When we get a NAND flash Address src_addr, we can break down the column address and page address.
Column_addr = src_addr % 512; // column address
Page_address = (src_addr> 9); // page address
You can also think that the a0 ~ Of a NAND flash Address ~ A7 is its column_addr, A9 ~ A25 is its page address. (Note that the address bits A8 does not appear, that is, A8 is ignored. Here you will learn why)
The read1 command has four cycle operations. After sending the READ command 00h or 01 H (see the description below for the difference between 00h and 01h), four cycle sending parameters are divided into 1 st. cycle is used to send column address. 2nd. cycle, 3rd. cycle and 4th. cycle specifies the page address (each time the data sent to the address register can only be 8 bits, so the 17-bit page address must be sent three times
The read1 command contains two Command Options: 00h and 01 H. Here we see two read-only messages. What do you realize? Yes, 00h is the command used to read and write 1st half, while 01h is the command used to read 2nd half. Now I can explain to you why k9f1208u0b's datafield is divided into two half.
As I mentioned above, the 1st st of read1. cycle is used to send the column address. Suppose that the column address I specify is 0, the read operation reads the last byte (including spare field) of this page from byte 0th on this page. If the specified column address is 127, the situation is the same as the previous one, but you don't know. There are eight data lines (I/O0 ~ I/O7, corresponding to a0 ~ A7, Which is why A8 does not appear in the address bit we pass). That is to say, the range of the column address that we can specify is 0 ~ 255, but do not forget that the datafield of one page is composed of 512 bytes. Now I want to specify the READ command to read this page from 256th bytes, what will happen? I must set column address to 256, but column address can only be 255 at maximum, which causes data overflow... It is for this reason that we divide the data field into two half-partitions. When the starting address (column address) to be read is in the range of 0 ~ In 255, we use the 256 H command. When the starting address for reading is ~ 511, The 01h command is used. If I want to specify to read this page from 256th bytes, then I will send the command string like this
Column_addr = 256;
Nf_cmd = 0x01; read from 2nd half
Nf_addr = column_addr & 0xff; 1st Cycle
Nf_addr = page_address & 0xff; 2nd. Cycle
Nf_addr = (page_address> 8) & 0xff; 3rd. Cycle
Nf_addr = (page_address> 16) & 0xff; 4th. Cycle
Nf_cmd and nf_addr are the nandflash command registers and address register address unreferencing. I usually define them like this,
# Define rnfcmd (* (volatile unsigned char *) 0x4e000004) // nadd flash command
# Define rnfaddr (* (volatile unsigned char *) 0x4e000008) // NAND flash Address
In fact, when nf_cmd = 0x01, the 8th-bit (A8) in the address register will be set to 1. (for example, the A8 bit is not in the address we passed, in fact, the hardware circuit is set to a high position or a low position based on the 01h or 00h commands. In this way, the value of column_addr is 256, which is changed to 1 due to data overflow, however, the A8 bit has been set to 1 because of the nf_cmd = 0x01 relationship, so the value passed to the address register is changed
A0 A1 A2 A3 A4 A5 A6 A7 A8
1 0 0 0 0 0 0 1
The eight digits represent exactly 256, so that the read operation will start to read data from byte 256th (byte 0th of 2nd half) on this page. Nand_flash.c contains three functions.
Void nf_reset (void );
Void nf_init (void );
Void nf_read (unsigned int src_addr, unsigned char * desc_addr, int size );
Nf_reset () will be called by nf_init. Nf_init () is the nand_flash initialization function. Before performing any operation on NAND Flash, nf_init () must be called.
Nf_read (unsigned int src_addr, unsigned char * desc_addr, int size); For read functions, src_addr is the address on NAND Flash, desc_addr is the memory address, and size is the length of the read file.
Two macros exist in the nf_reset and nf_read functions.
Nf_nfce_l ();
Nf_nfce_h ();
You can see that nf_nfce_l () must be called before each operation on NAND Flash, and nf_nfce_h () must be called at the end of the operation. These two macros are used to start and disable flash chips (chip selection/cancel chip selection ). In nf_reset (),
Rnfconf = (1 <15) | (1 <14) | (1 <13) | (1 <12) | (1 <11) | (tacls <8) | (twrph0 <4) | (twrph1 <0 );
This line of code initializes the nandflash control register, and rnfconf is the configuration register of NAND Flash. For specific functions of each bit, see the S3C2410 Data Manual.
For example, if I want to read 5,000th bytes from 1024 bytes in NAND Flash to 0x30000000 in memory, we call the READ function
Nf_read (5000, 0 x );
Let's analyze 5000 this src_addr.
According
Column_addr = src_addr % 512;
Page_address = (src_addr> 9 );
We can conclude that column_addr = 5000% 512 392 =
Page_address = (5000> 9) = 9
So we can know that the address 5000 is at the 9th byte on page 392nd, so our nf_read function will send commands and parameters like this.
Column_addr = 5000% 512;
> Page_address = (5000> 9 );
Nf_cmd = 0x01; read from 2nd half
Nf_addr = column_addr & 0xff; 1st Cycle
Nf_addr = page_address & 0xff; 2nd. Cycle
Nf_addr = (page_address> 8) & 0xff; 3rd. Cycle
Nf_addr = (page_address> 16) & 0xff; 4th. Cycle
After sending the above commands and parameters to the nandflash command register and address register, we can read data from the rnfdata register (nandflash data register.
I use the following code to read data.
For (I = column_addr; I <512; I ++)
{
* Buf ++ = nf_rddata ();
}
Each time a page is read, the Data Pointer falls into column 0 (byte 0) of the next page ).
The source code is as follows:
/*
Www.another-prj.com
Author: caiyuqing
This code is only for communication and learning and cannot be used for commercial development.
*/
# Include "S3C2410. H"
# Include "nand_flash.h"
Static unsigned char sebuf [16] = {0xff };
// Configure //--------------------------------------------------------------------------------------
Unsigned short nf_checkid (void)
{
Int I;
Unsigned short ID;
Nf_nfce_l (); // chip enable
Nf_cmd (0x90); // read ID
Nf_addr (0x0 );
For (I = 0; I <10; I ++); // wait twb (100ns)
Id = nf_rddata () <8; // maker code (k9s1208v: 0xec)
Id | = nf_rddata (); // devide code (k9s1208v: 0x76)
Nf_nfce_h (); // chip enable
Return ID;
}
// Configure //--------------------------------------------------------------------------------------
Static void nf_reset (void)
{
Int I;
Nf_nfce_l (); // chip enable
Nf_cmd (0xff); // reset command
For (I = 0; I <10; I ++); // twb = 100ns.
Nf_waitrb (); // wait 200 ~ 500us;
Nf_nfce_h (); // chip disable
}
// Configure //--------------------------------------------------------------------------------------
Void nf_init (void)
{
Rnfconf = (1 <15) | (1 <14) | (1 <13) | (1 <12) | (1 <11) | (tacls <8) | (twrph0 <4) | (twrph1 <0 );
// 1 1 1 1 1 xxx r xxx, r xxx
// En r eccr nfce = H tacls twrph0 twrph1
Nf_reset ();
}
// Configure //--------------------------------------------------------------------------------------
Void nf_read (unsigned int src_addr, unsigned char * desc_addr, int size)
{
Int I;
Unsigned int column_addr = src_addr % 512; // column address
Unsigned int page_address = (src_addr> 9); // page addrress
Unsigned char * Buf = desc_addr;
While (unsigned INT) BUF <(unsigned INT) (desc_addr) + size)
{
Nf_nfce_l (); // enable Chip
/* Nf_addr and nf_cmd are nand_flash addresses and command registers for unreferencing */
If (column_addr> 255) // 2end halft
Nf_cmd (0x01); // read2 command. CMD 0x01: read command (start from 2end half page)
Else
Nf_cmd (0x00); // 1st halft?
Nf_addr (column_addr & 0xff); // column address
Nf_addr (page_address & 0xff); // page address
Nf_addr (page_address> 8) & 0xff );//...
Nf_addr (page_address> 16) & 0xff );//..
For (I = 0; I <10; I ++); // wait twb (100ns )/////??????
Nf_waitrb (); // wait tr (max 12us)
// Read from main area
For (I = column_addr; I <512; I ++)
{
* Buf ++ = nf_rddata ();
}
Nf_nfce_h (); // disable Chip
Column_addr = 0;
Page_address ++;
}
Return;
}