S3C2440 bare metal experiment (6) ----NAND FLASH

Publisher:数字梦行Latest update time:2022-02-17 Source: eefocusKeywords:S3C2440 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Nand flash is read and written in page units and erased in block units. Each page is divided into main area and spare area. The main area is used to store normal data, and the spare area is used to store some additional information.


2. S3c2440 supports booting from Nand because there is an internal SRAM buffer called Steppingstone. When booting, the first 4k of code in Nand will be copied to Steppingstone for execution. Note that the first 4k of code will not be ECC-checked, so the accuracy of these codes must be ensured.


3. All operations on nand are implemented by using commands. Some operations can be completed with just one command, while others require two commands. The following is the command table of K9F1G08U0B:

  

 

4. Regarding the numerical values ​​of several parameters such as TACLS, TWRPH0, and TWRH1:


It is not difficult to see the meaning of these parameters from the timing diagram below, so I will not go into details here.


Figure 2 (K9F1G08U0B)


Comparing the above two timing diagrams, we find that TWRPH0 is twp in K9F1G08U0B, and TWRH1 is tCLH


TACLS is tcls-twp, and the manual of K9F1G08U0B gives the minimum time for these parameters, as shown in the figure

#include "def.h"

#include "2440addr.h"

#include "mynand.h"


//define command

#define CMD_READ1 0x00 //Page read command 1

#define CMD_READ2 0x30 //Page read command 2

#define CMD_READID 0x90 //Read ID

#define CMD_RESET 0xff //Reset

#define CMD_WRITE1 0x80 //Page write command 1

#define CMD_WRITE2 0x10 //Page write command 2

#define CMD_ERASE1 0x60 //Block erase command 1

#define CMD_ERASE2 0xd0 //Block erase command 2

#define CMD_STATUS 0x70 //Read status command

#define CMD_RANDOMREAD1 0X05 //Random read command 1

#define CMD_RANDOMREAD2 0xe0 //Random read command 2

#define CMD_RANDOMWRITE 0x85 //Random write command


#define NF_CE_L() {rNFCONT &=~(1<<1);} // Enable chip select

#define NF_CE_H() {rNFCONT |=(1<<1);} //Disable chip select

#define NF_MECC_UnLock() {rNFCONT&=~(1<<5);} //Unlock main to ECC

#define NF_MECC_Lock() {rNFCONT|=(1<<5);} //Lock main to ECC

#define NF_SECC_UnLock() {rNFCONT &= ~(1<<6); } //Unlock spare area ECC

#define NF_SECC_Lock() {rNFCONT |= (1<<6); } //Lock spare area ECC

#define NF_RSTECC() {rNFCONT |= (1<<4); } //Reset ECC


#define NF_WAITRB() {while(!(rNFSTAT &(1<<0))) ;} //Wait for nand flash to be idle

#define NF_CLEAR_RB() {rNFSTAT |= (1<<2); } // Clear RnB signal

#define NF_DETECT_RB()    {while(!(rNFSTAT&(1<<2)));}  


#define NF_RDDATA8() ((*(volatile unsigned char*)0x4E000010) )           

#define NF_CMD(cmd)   {rNFCMD = (cmd);}  //命令

#define NF_ADDR( addr)  {rNFADDR = (addr);}  //地址

#define NF_RDDATA() (rNFDATA) //Read 32-bit data  

//#define NF_RDDATA8() (rNFDATA) //Read 8-bit data  

#define NF_WRDATA(data) { rNFDATA = (data);} //Write 32-bit data

#define NF_WRDATA8(data) { rNFDATA8 = (data);} //Write 8-bit data


#define TACLS  1

#define TWRPH0 2

#define TWRPH1 0


extern void Delay(int time);

void nand_init(void)

{

rGPACON = rGPACON & (~(0x3f<<17)) |(0x3f<<17) ;

rNFCONF = (TACLS<<12) |(TWRPH0<<8) |(TWRPH1<<4) |(0<<0) ;

//Unlock, shield nandflash interrupt, initialize ECC and lock main area and spare area ECC, enable nandflash chip select and controller

    rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);



}


//Reset nand

 void nand_reset()

{

    int i;

NF_CE_L(); //cs

NF_CLEAR_RB(); //Clear RnB signal

    for(i=0;i<10;i++)  ;

NF_CMD(CMD_RESET); //Write reset command

NF_DETECT_RB(); //Wait for RnB signal to become high, i.e. not busy

    NF_CE_H(); //Close nandflash chip select


}



// To read the nand ID number, first write the read ID command, then write the 0x00 address, and you can read the chip ID in a total of five cycles. The first cycle is the manufacturer ID, and the second cycle is the device ID.

//The third to fifth cycles include some specific information about the chip

 U8 read_id(void)

{

int i;

U8 first, second, third, forth, fifth; //Read 1-5 cycles of data respectively

NF_CE_L(); //cs

//NF_CLEAR_RB(); //Clear RnB signal

   // for(i=0;i<10;i++)  ;

NF_CMD(CMD_READID); //Read ID command

    NF_ADDR(0x0); //Write 0x00 address

first = NF_RDDATA8() ; //Manufacturer ID: 0Xec

second = NF_RDDATA8() ; //Device ID, generally some parameters of nand can be determined from this parameter

third = NF_RDDATA8()  ; //0x00

forth = NF_RDDATA8()  ; //0x95

fifth = NF_RDDATA8()  ; // 0x40

    NF_CE_H(); //Close nandflash chip select

return second;

}


//Read with hardware ECC check, page_numer is the page number, 2K per page

U8 nand_readpage_ecc(U32 page_number, U8 *buffer)

{

int i;

U32 mainecc0, spareecc; //Used to store temporary value of ecc

NF_RSTECC(); //Reset ECC

NF_MECC_UnLock() //Unlock the main area ECC

NF_CE_L(); //cs

NF_CLEAR_RB(); //Clear RnB signal

NF_CMD(CMD_READ1); //Page read command cycle 1

//Write the address, first write the column address (that is, the address relative to the start of each page), then write the row address (that is, the page number)

NF_ADDR(0x00); //Column address A0~A7, here directly read from the beginning of each page can be optimized using the following 4 lines of code commented

    NF_ADDR(0x00); //column address A8~A11

     

// page = page_number/4;

// data_addr = 512 *(page_number%4);

// NF_ADDR(data_addr&0xff);

// NF_ADDR((data_addr>>8)&0xff);

NF_ADDR((page_number) & 0xff); //row address A12~A19

NF_ADDR((page_number >> 8) & 0xff); //row address A20~A27

    

NF_CMD(CMD_READ2); //Page read command cycle 2

NF_DETECT_RB(); //Wait for RnB signal to become high, i.e. not busy


for(i=0;i<2048;i++)

   buffer[i] = NF_RDDATA8() ;

NF_MECC_Lock(); //Lock the ECC value of the main area

    NF_SECC_UnLock(); //Unlock spare area ECC

mainecc0=NF_RDDATA(); //Read the first 4 addresses of the spare area, that is, addresses 2048~2051. These 4 bytes are the ECC of the main area.

    //Put the ECC check code of the main area read into the corresponding position of NFMECCD0/1

rNFMECCD0=((mainecc0&0xff00)<<8)|(mainecc0&0xff);

rNFMECCD1=((mainecc0&0xff000000)>>8)|((mainecc0&0xff0000)>>16);


NF_SECC_Lock(); //Lock the ECC value of the spare area

spareecc=NF_RDDATA(); //Continue to read the contents of the 4 addresses in the spare area, i.e., addresses 2052 to 2055, where the first 2 bytes are the ECC values ​​of the spare area

//Put the ECC check code of the spare area read into the corresponding position of NFSECCD

rNFSECCD=((spareecc&0xff00)<<8)|(spareecc&0xff);

NF_CE_H(); //Close nandflash chip select

//Judge whether the data read is correct

if ((rNFESTAT0&0xf) == 0x0)

  return 0x66; //Correct

else 

       return 0x44;   

}


U8 nand_writepage_ecc(U32 page_number, U8 *buffer)

{

int i,stat;

U32 mecc0, secc; //Used to store temporary value of ecc

char ECCBuf[10];

i = nand_is_badblock(page_number>>6) ;

if( i ==0x33)

return 0x42 ; //Bad block

NF_RSTECC(); //Reset ECC

NF_MECC_UnLock() //Unlock the main area ECC

NF_CE_L(); //cs

NF_CLEAR_RB(); //Clear RnB signal

NF_CMD(CMD_WRITE1); //Page read command cycle 1

//Write the address, first write the column address (that is, the address relative to the start of each page), then write the row address (that is, the page number)

NF_ADDR(0x00); //Column address A0~A7, here directly read from the beginning of each page can be optimized using the following 4 lines of code commented

    NF_ADDR(0x00); //column address A8~A11

     

// page = page_number/4;

// data_addr = 512 *(page_number%4);

// NF_ADDR(data_addr&0xff);

// NF_ADDR((data_addr>>8)&0xff);

NF_ADDR((page_number) & 0xff); //row address A12~A19

NF_ADDR((page_number >> 8) & 0xff); //row address A20~A27

    

for(i=0;i<2048;i++)

   NF_WRDATA8(buffer[i]);


NF_MECC_Lock(); //Lock the ECC value of the main area

mecc0=rNFMECC0; //Read the ECC check code of the main area

  //Convert the ECC check code from font to byte type and save it to the global variable array ECCBuf

    ECCBuf[0]=(U8)(mecc0&0xff);

    ECCBuf[1]=(U8)((mecc0>>8) & 0xff);

ECCBuf[2]=(U8)((mecc0>>16) & 0xff);

ECCBuf[3]=(U8)((mecc0>>24) & 0xff);

NF_SECC_UnLock(); //Unlock spare area ECC

    for(i=0;i<4;i++)

       {

              NF_WRDATA8(ECCBuf[i]);

       } 

 

    NF_SECC_Lock(); //Lock the ECC value of the spare area

secc=rNFSECC; //Read the ECC check code in the spare area

//Save the ECC check code to the global variable array ECCBuf

ECCBuf[4]=(U8)(secc&0xff);

ECCBuf[5]=(U8)((secc>>8) & 0xff);

//Continue to write the ECC value of the spare area into the 2052~2053th address of the spare area


for(i=4;i<6;i++)

       {

              NF_WRDATA8(ECCBuf[i]);

       }


NF_CMD(CMD_WRITE2); //Page read command cycle 2

Delay(100);


NF_CMD(CMD_STATUS); //Read status command

// Check if the 6th bit of the status value is 1, that is, whether it is busy. This statement has the same effect as NF_DETECT_RB();

do {

state = NF_RDDATA8();


}while(!(stat&0x40));


NF_CE_H(); //Close nandflash chip select

//Judge whether the data read is correct

if (stat & 0x1)

{

i = rNF_MarkBadBlock(page_number>>6); //Mark the block where this page is located as a bad block

if (i == 0x21)

              return 0x43 ; // Bad block marking failed

else 

return 0x44; //Write operation failed

}

else 

return 0x66;



}



U8 nand_random_readpage(U32 page_number, U32 add)

{

NF_CE_L(); //cs

NF_CLEAR_RB(); //Clear RnB signal

NF_CMD(CMD_READ1); //Page read command cycle 1

//Write the address, first write the column address (that is, the address relative to the start of each page), then write the row address (that is, the page number)

NF_ADDR(0x00); //Column address A0~A7, here directly read from the beginning of each page can be optimized using the following 4 lines of code commented

    NF_ADDR(0x00); //column address A8~A11

     

// page = page_number/4;

// data_addr = 512 *(page_number%4);

[1] [2]
Keywords:S3C2440 Reference address:S3C2440 bare metal experiment (6) ----NAND FLASH

Previous article:S3C2440 bare metal experiment (3) ----watchdog
Next article:s3c2440 bare metal experiment (5) ----IIS

Recommended ReadingLatest update time:2024-11-23 21:25

S3C2440 bare metal -------NandFlash programming_chip id reading
1. Chip ID reading timing diagram Let's first look at the timing diagram for reading the ID in the NandFlash chip manual. Later we will write the code based on this timing diagram. 2. Enable chip From the previous timing diagram, we can see that we must first send out the chip select signal. We set it by setting the
[Microcontroller]
S3C2440 bare metal -------NandFlash programming_chip id reading
The "19 billion pieces" shipment milestone has been achieved! GigaDevice Flash builds the cornerstone of next-generation smart wearable storage
The wave of intelligent transformation has promoted the application integration of more IoT devices. Smart wearable devices are tending towards diversified development. Not only are mature products such as smart watches/bracelets, TWS headphones, etc. continuously iterating, but also innovative products such as XR gla
[Mobile phone portable]
The
s3c2440 learning path-003 assembly to C pass parameters to light up different LED lights
Hardware platform: jz2440 Software platform: Ubuntu16.04 arm-linux-gcc-3.4.5 Source code location: https://github.com/lian494362816/C/tree/master/2440/004_led_parma 1 Principle Analysis When using assembly to call a C function, if you need to pass parameters, you can use R0-R3 to pass parameters. R0 represents the f
[Microcontroller]
STM32_SPI read and write Flash
Today I will explain "STM32F103 SPI reading and writing Flash". In fact, this first stage mainly explains the SPI function of STM32. So today's focus is on SPI. I should talk about FLASH again later. The software project provided and explained today is modified based on the software project "A0.0.0 (STM32F10x_TIM dela
[Microcontroller]
STM32_SPI read and write Flash
The Principle and Implementation of NAND FLASH Simulation USB Disk Based on Microprocessor S3C6410
    This paper introduces the principle and implementation method of NAND FLASH emulation USB disk based on Samsung microprocessor S3C6410 under embedded Linux operating system. The operating system adopts Linux 2.6.28 version, and the platform is Feiling OK6410-A development board. The scheme adopted is to add a 512
[Microcontroller]
The Principle and Implementation of NAND FLASH Simulation USB Disk Based on Microprocessor S3C6410
Liangdao Intelligent launches the first pure solid-state Flash side-viewing LiDAR in the Chinese market, which will be mass-produced in the second half of 2023
On May 13, Liangdao Intelligent, a domestic lidar supplier, officially released its self-developed pure solid-state Flash lateral lidar, LDSense Satellite, to the Chinese market. This is a pure chip design, an automotive-grade lidar product with both performance and cost advantages. It is mainly used for lateral blind
[Automotive Electronics]
Liangdao Intelligent launches the first pure solid-state Flash side-viewing LiDAR in the Chinese market, which will be mass-produced in the second half of 2023
NAND FLASH driver framework and program implementation
1. Hardware connection of NAND FLASH: The NAND FLASH chip used in the experiment is K9F2G08U0C, which is a storage chip of Samsung Company. Its size is 256M. Its wiring diagram is as follows: Each of its pins is LDATA0-LDATA7 for data pins, CLE for sending command enable pin, ALE for sending address
[Microcontroller]
NAND FLASH driver framework and program implementation
s3c2440 android port
ARMv4 porting tutorial:       I believe that many friends in China have s3c2410/2440 chips, which are based on the armv4t (arm920t) instruction architecture. In the past, because some of the underlying codes of Android contained armv5t instructions, it was not possible to port to such a platform. Here we also release
[Microcontroller]
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号