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);
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
- Popular Resources
- Popular amplifiers
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- NXP Rapid IoT Review] +4. Learn the design ideas of POWER circuits
- [Theme Month] Why do headphones not need to be plugged into a power source, but speakers do?
- 1. The relationship between the register value and the analog signal voltage. Different voltage values have different states in the register...
- Industry-leading isolated power management chip
- The age of information overload
- Undergraduate Electronic Design Competition Embedded System Special Invitational Competition Held
- Application of ADXL202 in Combined Vehicle Navigation System
- Understanding the configuration of C2000 series CMD files
- An interpolation filter design for oversampling DAC and class D audio power amplifier
- Positive and negative integrated regulated power supply starting from 0V