📄 2410.c
字号:
//2410寄存器
#define NF_CMD(cmd) {rNFCMD=cmd;}
#define NF_ADDR(addr) {rNFADDR=addr;}
#define NF_nFCE_L() {rNFCONF&=~(1<<11);}
#define NF_nFCE_H() {rNFCONF|=(1<<11);}
#define NF_RSTECC() {rNFCONF|=(1<<12);}
#define NF_RDDATA() (rNFDATA)
#define NF_WRDATA(data) {rNFDATA=data;}
#define NF_WAITRB() {while(!(rNFSTAT&(1<<0)));}
//NAND 设备命令
#define NAND_CMD_READ0 0x00
#define NAND_CMD_READ1 0x01
#define NAND_CMD_PAGEPROG 0x10
#define NAND_CMD_READOOB 0x50
#define NAND_CMD_ERASE1 0x60
#define NAND_CMD_STATUS 0x70
#define NAND_CMD_SEQIN 0x80
#define NAND_CMD_READID 0x90
#define NAND_CMD_READID1 0x91
#define NAND_CMD_ERASE2 0xd0
#define NAND_CMD_RESET 0xff
//NAND 设备初始化代码如下
void NF_Init(void)
{
int i;
rNFCONF=(1<<15)| /*使能2410的NAND接口*/
(1<<14)| /*Page大小: 512Bytes*/
(1<<13)| /*地址周期为4*/
(1<<12)| /*初始化ECC*/
(1<<11)| /*nFCE=HIGH*/
(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); //设置时间参数
/*Reset NAND*/
NF_nFCE_L();
NF_CMD(NAND_CMD_RESET);
NF_WAITRB();
NF_nFCE_H();
}
//NAND 设备测试代码如下
int NF_Test(void)
{
unsigned char buffer[1000];
NF_Init();
printk("testing Smart Media Card...\n\r");
printk("ID1=%x(using command 0x90)\n\r",NF_CheckId(NAND_CMD_READID));
printk("ID2=%x(using command 0x91)\n\r",NF_CheckId(NAND_CMD_READID1));
NF_ReadPage(1,0,buffer); //读取第1个block的第0个page的内容
for(i=0;i<528;i++)
{
printk("%2x",buffer[i]);
if(i%16==15)
printk("\n\r");
}
printk("\n\r");
}
//NF_ReadPage函数的代码如下
int NF_ReadPage(unsigned block,unsigned page,unsigned char *buffer)
{
register unsigned char * bufPt=buffer;
unsigned int blockPage,i;
U8 ecc0,ecc1,ecc2,ecc3,ecc4,ecc5;
U8 se[16];
blockPage=(block<<5)+page; //一个block包含32page
NF_RSTECC(); /*初始化ECC*/
NF_nFCE_L();
NF_CMD(NAND_CMD_READ0); //发出Read命令
//发送4个地址周期
NF_ADDR(0); /*页内起始地址设为0*/
NF_ADDR(blockPage & 0xff);
NF_ADDR((blockPage>>8) & 0xff);
NF_ADDR((blockPage>>16) & 0xff);
NF_WAITRB();
for(i=0;i<256;i++)
bufPt[i]=NF_RDDATA(); //读出页内前256字节
//记录前256字节的ECC校验和
ecc0=rNFECC0;
ecc1=rNFECC1;
ecc2=rNFECC2;
NF_RSTECC();
for(i=256;i<512;i++)
bufPt[i]=NF_RDDATA(); //读出页内后256字节
//记录后256字节的ECC校验和
ecc3=rNFECC0;
ecc4=rNFECC1;
ecc5=rNFECC2;
for(i=0;i<16;i++)
bufPt[i+512]=se[i]=NF_RDDATA(); //读出页内冗余的16字节
NF_nFCE_H();
//比较ECC校验码和事先存在页内的校验和是否一致
//se[5]应该为0xff,否则表示该block为bad block
if(ecc0==se[13] && ecc1==se[14] && ecc2==se[15] && se[5]=0xff)
printk("[first 256 bytes ECC OK:%x,%x,%x]\n\r",se[13],se[14],se[15]);
else{
printk("[ECC ERROR(RD):read:%x,%x,%x,reg:%x,%x,%x]\n\r",se[13],se[14],se[15],ecc0,ecc1,ecc2);
return 0;
}
if(ecc3==se[8] && ecc4==se[9] && ecc5==se[10] && se[5]==0xff)
printk("[last 256 bytes ECC OK:%x,%x,%x]\n\r",se[8],se[9],se[10]);
else{
printk("[ECC ERROR(RD):read:%x,%x,%x,reg:%x,%x,%x]\n\r",se[8],se[9].se[10],ecc3,ecc4,ecc5);
return 0;
}
return 1;
}
//NAND 设备擦除和写函数的代码如下
int NF_EraseBlock(unsigned block)
{
unsigned blockPage;
unsigned char data;
blockPage=(block<<5);
NF_nFCE_L();
NF_CMD(NAND_CMD_ERASE1); //发出擦除命令
NF_ADDR(blockPage&0xff);
NF_ADDR((blockPage>>8)&0xff);
NF_ADDR((blockPage>>16) & 0xff);
NF_CMD(NAND_CMD_ERASE2); //确认并开始擦除
NF_WAITRB(); //等待状态查询命令
NF_CMD(NAND_CMD_STATUS); //发出状态查询命令
data=NF_RDDATA();
NF_nFCE_H();
return !(data & 1); //data=0:擦除成功 data=1:擦除失败
}
int NF_WritePage(unsigned block,unsigned page,unsigned char *buffer)
{
register unsigned char *bufPt=buffer;
unsigned int blockPage,i;
unsigned char se[16],data;
blockPage=(block<<5)+page;
NF_CMD(NAND_CMD_SEQIN); //发出送数据的命令
NF_ADDR(0); //从页内地址为0的地方开始写数据
NF_ADDR(blockPage & 0xff);
NF_ADDR((blockPage>>8) & 0xff);
NF_ADDR((blockPage>>16) & 0xff);
for(i=0;i<256;i++)NF_WRDATA(*bufPt++);
se[13]=rNFECC0;se[14]=rNFECC1;se[15]=rNFECC2|3;
NF_RSTECC(); //复位ECC
for(i=0;i<256;i++)NF_WRDATA(*buftPt++);
se[8]=rNFECC0;se[9]=rNFECC1;se[10]=rNFECC2|3;
for(i=0;i<16;i++)NF_WRDATA(se[i]); //写入16个的冗余字节spare array
NF_CMD(NAND_CMD_PAGEPROG); //开始编程
NF_WAITRB(); //等待R/B#信号有效
NF_CMD(NAND_CMD_STATUS); //发出状态查询命令
data=NF_RDDATA();
NF_nFCE_H();
return !(data & 1); //data=0;编程成功 data=1:编程失败
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -