2011-01-21 11:05:19| 分类: 默认分类|字号 订阅
static U32 WritePage(U32 addr, U8 *buf)
{
U32 i, mecc, secc;
U8 stat, tmp[6], value;
addr &= ~0x3f;
InitEcc(); //复位ECC
MEccUnlock(); //解锁Main区ECC
NFChipEn(); //打开nandflash片选
WaitNFBusy(); //等待忙信号
WrNFCmd(0x80); //页写命令周期1
WrNFAddr(0x00); //列地址A0~A7
WrNFAddr(0x00); //列地址A8~A11
WrNFAddr((addr>>0)& 0xFF); //行地址A12~A19
WrNFAddr((addr>>8)& 0xFF); //行地址A20~A27
WrNFAddr((addr>>16)& 0xFF); //行地址A28~A30
for(i=0; i<2048; i++)
WrNFDat(buf[i]); //写一页数据
WaitNFBusy(); //等待忙信号
MEccLock(); //锁定Main区的ECC校验码
mecc = RdNFMEcc(); //读取Main区的ECC校验码
//把Main区的ECC校验码由字型转换成字节型并保存到零时数组里
tmp[0] = (U8)(mecc&0xff);
tmp[1] = (U8)((mecc>>8)&0xff);
tmp[2] = (U8)((mecc>>16)&0xff);
tmp[3] = (U8)((mecc>>24)&0xff);
SEccUnlock(); //解锁Spare区的ECC
//把Main区的ECC值写入到Spare区的前四个字节,即第2048~2051地址
WrNFDat(tmp[0]);
WrNFDat(tmp[1]);
WrNFDat(tmp[2]);
WrNFDat(tmp[3]);
SEccLock(); //锁定Spare区的ECC校验码
secc = RdNFSEcc(); //读取Spare区的ECC校验码
//把Spare区的ECC校验码由字型转换成字节型并保存到零时数组里
tmp[4] = (U8)(secc&0xff);
tmp[5] = (U8)((secc>>8)&0xff);
//把Spare区的ECC值写入到Spare区的第2052~2053地址
WrNFDat(tmp[4]);
WrNFDat(tmp[5]);
WrNFCmd(0x10); //页写命令周期2
WaitNFBusy(); //等待忙信号
WrNFCmd(0x70); //写读状态命令
WaitNFBusy(); //等待忙信号
stat = RdNFDat(); //读取状态字
NFChipDs(); //关闭nandflash片选
if(stat&0x01)
{
MarkBadBlk(addr); //标注坏块
puts("WritePage Error!\n"); //写操作失败
return 0; //写操作失败
}
puts("WritePage No Error!\n"); //写操作成功
return 1; //写操作成功
}
static void ReadPage(U32 addr, U8 *buf)
{
U32 i, mecc, secc;
addr &= ~0x3f;
InitEcc(); //复位ECC
MEccUnlock(); //解锁Main区ECC
NFChipEn(); //打开nandflash片选
WaitNFBusy(); //等待忙信号
WrNFCmd(0x00); //页读命令周期1
WrNFAddr(0x00); //列地址A0~A7
WrNFAddr(0x00); //列地址A8~A11
WrNFAddr((addr>>0)& 0xFF); //行地址A12~A19
WrNFAddr((addr>>8)& 0xFF); //行地址A20~A27
WrNFAddr((addr>>16)& 0xFF); //行地址A28~A30
WrNFCmd(0x30); //页读命令周期2
WaitNFBusy(); //等待忙信号
for(i=0; i<2048; i++)
buf[i] = RdNFDat(); //读取一页数据
WaitNFBusy(); //等待忙信号
MEccLock(); //锁定main区的ECC值
SEccUnlock(); //解锁spare区的ECC值
mecc = RdNFDat32(); //读取spare区的前4个地址内容,即2048~2051,这四个字节是main区的ECC值
buf[i+1] = (U8)(mecc & 0xff); //把读取到的main区的ECC校验码放入到零时数组里
buf[i+2] = (U8)((mecc>>8) & 0xff); //把读取到的main区的ECC校验码放入到零时数组里
buf[i+3] = (U8)((mecc>>16) & 0xff); //把读取到的main区的ECC校验码放入到零时数组里
buf[i+4] = (U8)((mecc>>24) & 0xff); //把读取到的main区的ECC校验码放入到零时数组里
//把读取到的main区的ECC校验码放入到NFMECCD0/1的相应位置
rNFMECCD0 = ((mecc&0xff00)<<8)|(mecc&0xff);
rNFMECCD1 = ((mecc&0xff000000)>>8)|((mecc&0xff0000)>>16);
SEccLock(); //锁定spare区的ECC值
secc = RdNFDat32(); //读取spare区的4个地址内容,即2052~2055,其中前两个字节是spare区的ECC值
buf[i+5] = (U8)(secc & 0xff); //把读取到的spare区的ECC校验码放入到零时数组里
buf[i+6] = (U8)((secc>>8) & 0xff); //把读取到的spare区的ECC校验码放入到零时数组里
buf[i+7] = (U8)((secc>>16) & 0xff); //把读取到的spare区的ECC校验码放入到零时数组里
buf[i+8] = (U8)((secc>>24) & 0xff); //把读取到的spare区的ECC校验码放入到零时数组里
rNFSECCD = ((secc&0xff00)<<8)|(secc&0xff); //把读取到的spare区的ECC校验码放入到NFSECCD的相应位置
NFChipDs(); //关闭nandflash片选
if(((rNFESTAT0)&0x0f)==0) //判断main data area 和 spear date area 是否有bit位出错
puts("ECC No Error!\n"); //有ECC错误
else
puts("ECC Error!\n"); //没有ECC错误
puts("0x%8x\n",(rNFESTAT0)); //显示读到的rNFESTAT0寄存器