📄 nandflash.c
字号:
#include <S3C2440.H>
#define RnB (NFSTAT&0x0001) //读取RnB状态
#define DectRnB (NFSTAT&0x0003)
#define NandEnable NFCONT&=0xfffd;
#define NandDisable NFCONT|=0x0002;
#define DATA NFDATA //32位
#define COMD NFCMD //8位
#define ADDR NFADDR //8位
#define SHOW 0
int CheckRnB(void) //检查数据线是否忙
{
#define BUSY 0
#define READY 1
if(DectRnB==0) //没有接收到忙结束信号
return BUSY;
if(DectRnB==1)
{
NFSTAT=NFSTAT|0x0003;
return READY;
}
}
int NandReadID(void) //度芯片ID
{
int NAND_DATA;
COMD=0x90;
ADDR=0x00;
NAND_DATA=DATA;
SciTx('I');
SciTx('D');
SciTx(':');
SciTxHexWord(NAND_DATA);
SciTx('\n');
SciTx('\r');
return NFDATA;
}
void CopyNandToSdram(unsigned int Source,unsigned int Destination,unsigned int Lenght)
{
unsigned int Cntx,Cnty,PageCnt;
PageCnt=(Lenght/512)+1;
if(((Source>>8)&0x0001)==0) //起始地址有奇偶,在这个上我跳了很久才出来
COMD=0x00;
if(((Source>>8)&0x0001)==1)
COMD=0x01;
ADDR=(Source&0x000000ff);
ADDR=((Source>> 9)&0x000000ff);
ADDR=((Source>>17)&0x000000ff);
ADDR=((Source>>25)&0x000000ff); //连续读取
while((CheckRnB())==BUSY);
for(Cnty=0;Cnty<PageCnt;Cnty++)//需要读取的页数
{
for(Cntx=(Source%512)/4;Cntx<(512/4);Cntx++)//从气势除开始,至一页末尾结束
{
*(unsigned int *)Destination=DATA;
Destination+=4;
}
Source=((Source%512)+1)*512;
Cntx=DATA;
Cntx=DATA;
Cntx=DATA;
Cntx=DATA;
while((CheckRnB())==BUSY);
}
}
unsigned int PageData[132];
unsigned int Stat;
unsigned int NandPageRead(int Addr)//读NandFlash,返回Page存储地址,读取线性地址一夜的数据和寄存器数据
{
int Cnt;
COMD=0x00;
ADDR=0; //PageRead是从一页的开始读取的 ,共512字节
ADDR=((Addr>>9)&0x000000ff);
ADDR=((Addr>>17)&0x000000ff);
ADDR=((Addr>>25)&0x000000ff);
while((CheckRnB())==BUSY);
for(Cnt=0;Cnt<132;Cnt++) //Cnt后的数字是Int,1个Page实际上是128*4;也就是128int;
{
PageData[Cnt]=DATA;
}
for(Cnt=0;Cnt<132;Cnt++)
{
SciTxHexWord(PageData[Cnt]);
SciTx(' ');
if(Cnt%8==7)
{
SciTx('\n');
SciTx('\r');
}
}
SciTx('\n');
SciTx('\r');
return (unsigned int)PageData;
}
unsigned int NandWordRead(int Addr) //返回独处的数据,读取的是线性地址的数据,程序自动分辨是Section1还是2不能读取标志
{ //注意:有关地址4Byte对其的问题
unsigned int Cnt;
if(((Addr>>8)&0x0001)==0)
COMD=0x00;
if(((Addr>>8)&0x0001)==1)
COMD=0x01;
ADDR=((Addr)&0x000000ff);
ADDR=((Addr>>9)&0x000000ff);
ADDR=((Addr>>17)&0x000000ff);
ADDR=((Addr>>25)&0x000000ff);
while((CheckRnB())==BUSY);
Cnt=DATA;
return Cnt;
}
unsigned int RegData[4];
unsigned int NandRegRead(int Addr)//程序自动识别地址所处的页,然后读取他的16Byte寄存器
{
int Cnt;
COMD=0x50;
ADDR=0; //从0号寄存器开始读取
ADDR=((Addr>>9)&0x000000ff);
ADDR=((Addr>>17)&0x000000ff);
ADDR=((Addr>>25)&0x000000ff);
while((CheckRnB())==BUSY);
for(Cnt=0;Cnt<4;Cnt++)
{
RegData[Cnt]=DATA;
}
#if SHOW==1
for(Cnt=0;Cnt<4;Cnt++)
{
SciTxHexWord(RegData[Cnt]);
SciTx(' ');
if(Cnt%8==7)
{
SciTx('\n');
SciTx('\r');
}
}
#endif
return (unsigned int)RegData;
}
#define BADBLOCK 0
#define NORMALBLOCK 1
unsigned int NandBlocStatCheck(int Block) //读取地址所在Block的第一第二页的寄存器的第0个值,用于检测坏块
{
unsigned int x1,x2;
//COMD=0xff;
//while((CheckRnB())==BUSY);
COMD=0x50;
ADDR=5;
ADDR=(Block<< 5)&0x000000ff;
ADDR=(Block>> 3)&0x000000ff;
ADDR=(Block>>11)&0x000000ff;
while((CheckRnB())==BUSY);
x1=DATA;//Block的第一页第一个寄存器
if(x1==0xffffffff) return NORMALBLOCK;
else return BADBLOCK;
}
int BadBlocks[10];
int BadCnt;
void NandCheckBadBlocks(void)
{
int Cnt;
BadCnt=0;
for(Cnt=1;Cnt<4096;Cnt++)
{
if(NandBlocStatCheck(Cnt)==BADBLOCK)
{
BadBlocks[BadCnt]=Cnt;
#if SHOW==1
SciTxData(4,Cnt);SciTx('\n');SciTx('\r');
#endif
BadCnt++;
//NandPageRead(Cnt<<13);
//SciTxHexWord(NandWordRead((Cnt<<14)+516));
//SciTx('\n');SciTx('\r');
}
}
}
int NandPageProgram(int Addr,int *Data) //对一块没有擦除过的Flash编程会出错
{
int Cnt;
COMD=0x80;
//ADDR=((Addr)&0x000000ff);
ADDR=0;
ADDR=((Addr>>9)&0x000000ff);
ADDR=((Addr>>17)&0x000000ff);
ADDR=((Addr>>25)&0x000000ff);
for(Cnt=0;Cnt<132;Cnt++)
{
DATA=Data[Cnt];
}
COMD=0x10;
while((CheckRnB())==BUSY);
COMD=0x70;
Stat=DATA;
#if SHOW==1
SciTxHexWord(Stat);
SciTx('\n');
SciTx('\r');
#endif
return Stat;
}
void NandBlockErase(int Block)
{
COMD=0x60;
ADDR=((Block<<5)&0x000000ff);
ADDR=((Block>>3)&0x000000ff);
ADDR=((Block>>11)&0x000000ff);
COMD=0xD0;
while((CheckRnB())==BUSY);
}
void NandFlash(void)
{
int Cnt;
int x,y;
UartInit();
NFCONF = (2 << 12) | (7 << 8) | (4 << 4); //时间可以打不可以小
NFCONT = (1 << 6) | (1 << 5) | (1 << 4) | (1 << 0);
NandEnable;
COMD=0xff;
while((CheckRnB())==BUSY);
NandReadID();
for(Cnt=0;Cnt<10;Cnt++)
{
SciTxData(2,Cnt);SciTx(':');SciTx('\n');SciTx('\r');
NandPageRead(512*Cnt);
}
//while(1)
//{
// SciTx('A');
//}
}
/*
IMPORT |Load$$StartSram$$Base|
IMPORT |Image$$StartSram$$Base|
IMPORT |Image$$StartSram$$Length| ;初始化代码区
IMPORT |Load$$CodeSdram$$Base|
IMPORT |Image$$CodeSdram$$Base|
IMPORT |Image$$CodeSdram$$Length| ;其他的RO段
IMPORT |Load$$DataSdram$$Base|
IMPORT |Image$$DataSdram$$Base|
IMPORT |Image$$DataSdram$$Length| ;其他的RW,ZI段
StartSramBase DCD |Load$$StartSram$$Base|
StartSramLength DCD |Image$$StartSram$$Length|
StartSramRun DCD |Image$$StartSram$$Base|
CodeSdramBase DCD |Load$$CodeSdram$$Base|
CodeSdramLength DCD |Image$$CodeSdram$$Length|
CodeSdramRun DCD |Image$$CodeSdram$$Base|
DataSdramBase DCD |Load$$DataSdram$$Base|
DataSdramLength DCD |Image$$DataSdram$$Length|
DataSdramRun DCD |Image$$DataSdram$$Base|
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -