📄 nand.c
字号:
// 512~1023
NF_RSTECC(); // Initialize ECC
NF_MECC_UnLock();
for(i=512;i<1024;i++) {
NF_WRDATA8(i); // Write one page to NFM from buffer
}
while(!(rNFSTAT&(1<<7))) ;
rNFSTAT|=(1<<7);
Mecc2 = rNFMECC0;
Mecc3 = rNFMECC1;
// 1024~1535
NF_RSTECC(); // Initialize ECC
NF_MECC_UnLock();
for(i=1024;i<1536;i++) {
NF_WRDATA8(i); // Write one page to NFM from buffer
}
while(!(rNFSTAT&(1<<7))) ;
rNFSTAT|=(1<<7);
Mecc4 = rNFMECC0;
Mecc5 = rNFMECC1;
// 1536~2047
NF_RSTECC(); // Initialize ECC
NF_MECC_UnLock();
for(i=1536;i<2048;i++) {
NF_WRDATA8(i); // Write one page to NFM from buffer
}
while(!(rNFSTAT&(1<<7))) ;
rNFSTAT|=(1<<7);
Mecc6 = rNFMECC0;
Mecc7 = rNFMECC1;
for(i=0;i<64;i++) {
NF_WRDATA8(Adv_se8Buf[i]); // Write spare array(Main ECC)
Adv_NF8_Spare_Data[i]=Adv_se8Buf[i];
}
NF_CLEAR_RB();
NF_CMD(0x10); // Write 2nd command
NF_DETECT_RB();
//while(NFConDone==0);
rNFCONT&=~(1<<9);
rNFCONT&=~(1<<10); // Disable Illegal Access Interrupt
if(rNFSTAT&0x20) {
printf("Error\n");
return;
}
NF_CMD(0x70); // Read status command
for(i=0;i<30;i++); //twhr=60ns
if (NF_RDDATA8()&0x1) {// Page write error
NF_nFCE_H();
printf("Second[PROGRAM_ERROR:block#=%d]\n",block);
// Adv_NF8_MarkBadBlock(block);
return;
} else {
NF_nFCE_H();
}
/////////////////////////////////////////////////
// block1, page1 reading with invalid data, ecc /
/////////////////////////////////////////////////
pISR_NFCON= (unsigned)NFCon_Int;
rSRCPND|=BIT_NFCON;
rINTMSK&=~(BIT_NFCON);
block=1;
page=1;
blockPage=(block<<6)+page;
printf("[1] NFCONF: %x NFCONT: %x NFSTAT: %x SRCPND: %x INTMSK: %x\n", rNFCONF, rNFCONT, rNFSTAT, rSRCPND, rINTMSK);
rNFCONF = (rNFCONF & ~(1<<30))|(1<<24); // System Clock is more than 66Mhz, ECC type is MLC.
rNFCONT &= ~(1<<18); //ECC for reading.
NF_RSTECC(); // Initialize ECC
NF_MECC_UnLock();
NF_nFCE_L();
NF_CLEAR_RB();
rNFCONT|=(1<<12); // Eccdone clear
NF_CMD(0x00); // Read command
NF_ADDR(0); // Column (A[7:0]) = 0
NF_ADDR(0); // A[11:8]
NF_ADDR((blockPage)&0xff); // A[19:12]
NF_ADDR((blockPage>>8)&0xff); // A[27:20]
NF_ADDR((blockPage>>16)&0xff); // A[27:20]
NF_CMD(0x30); // 2'nd command
NF_DETECT_RB();
for(i=0;i<512;i++) {
*bufPt++=NF_RDDATA8(); // Read one page
}
NF_CMD(0x05);
NF_ADDR((2048+1)&0xff); // 2060 = 0x080c
NF_ADDR(((2048+1)>>8)&0xff); // A[10:8]
NF_CMD(0xe0);
// for(i=0;i<10;i++);
for(i=1;i<8;i++) {
Adv_NF8_Spare_Data[i]=NF_RDDATA8(); // Read one page
}
// NF_MECC_Lock();
printf("[2] NFCONF: %x NFCONT: %x NFSTAT: %x SRCPND: %x INTMSK: %x\n", rNFCONF, rNFCONT, rNFSTAT, rSRCPND, rINTMSK);
while(!(rNFSTAT&(1<<6))) ;
printf("[3] NFCONF: %x NFCONT: %x NFSTAT: %x SRCPND: %x INTMSK: %x\n", rNFCONF, rNFCONT, rNFSTAT, rSRCPND, rINTMSK);
// while(NFECCDecDone==0);
rNFSTAT|=(1<<6);
printf("1st ECC check!\n");
if ((rNFECCERR0&(0x7<<26)) == 0x0){
printf("ECC OK!\n");
// return;
}
else {
printf("ECC FAIL!\n");
printf("status0:0x%x|status1:0x%x|bit:0x%x\n", rNFECCERR0, rNFECCERR1, rNFMLCBITPT);
// return;
}
// 512 ~ 1023
NF_RSTECC(); // Initialize ECC
// NF_MECC_UnLock();
NF_CMD(0x05);
NF_ADDR((512)&0xff); // 2060 = 0x080c
NF_ADDR(((512)>>8)&0xff); // A[10:8]
NF_CMD(0xe0);
for(i=0;i<10;i++);
for(i=0;i<512;i++) {
*bufPt++=NF_RDDATA8(); // Read one page
}
// NF_MECC_Lock();
NF_CMD(0x05);
NF_ADDR((2048+8)&0xff); // 2060 = 0x080c
NF_ADDR(((2048+8)>>8)&0xff); // A[10:8]
NF_CMD(0xe0);
for(i=0;i<10;i++);
for(i=8;i<15;i++) {
Adv_NF8_Spare_Data[i]=NF_RDDATA8(); // Read one page
}
while(!(rNFSTAT&(1<<6))) ;
// while(NFECCDecDone==0);
rNFSTAT|=(1<<6);
printf("2nd ECC check!\n");
if ((rNFECCERR0&(0x7<<26)) == 0x0){
printf("ECC OK!\n");
// return;
}
else {
printf("ECC FAIL!\n");
printf("status0:0x%x|status1:0x%x|bit:0x%x\n", rNFECCERR0, rNFECCERR1, rNFMLCBITPT);
// return;
}
// 1024 ~ 1535
NF_RSTECC(); // Initialize ECC
// NF_MECC_Lock();
NF_CMD(0x05);
NF_ADDR((1024)&0xff); // 2060 = 0x080c
NF_ADDR(((1024)>>8)&0xff); // A[10:8]
NF_CMD(0xe0);
for(i=0;i<10;i++);
for(i=0;i<512;i++) {
*bufPt++=NF_RDDATA8(); // Read one page
}
// NF_MECC_Lock();
NF_CMD(0x05);
NF_ADDR((2048+15)&0xff); // 2060 = 0x080c
NF_ADDR(((2048+15)>>8)&0xff); // A[10:8]
NF_CMD(0xe0);
for(i=0;i<10;i++);
for(i=15;i<22;i++) {
Adv_NF8_Spare_Data[i]=NF_RDDATA8(); // Read one page
}
while(!(rNFSTAT&(1<<6))) ;
// while(NFECCDecDone==0);
rNFSTAT|=(1<<6);
printf("3rd ECC check!\n");
if ((rNFECCERR0&(0x7<<26)) == 0x0){
printf("ECC OK!\n");
// return;
}
else {
printf("ECC FAIL!\n");
printf("status0:0x%x|status1:0x%x|bit:0x%x\n", rNFECCERR0, rNFECCERR1, rNFMLCBITPT);
// return;
}
// 1536 ~ 2047
NF_RSTECC(); // Initialize ECC
// NF_MECC_UnLock();
NF_CMD(0x05);
NF_ADDR((1536)&0xff); // 2060 = 0x080c
NF_ADDR(((1536)>>8)&0xff); // A[10:8]
NF_CMD(0xe0);
for(i=0;i<10;i++);
for(i=0;i<512;i++) {
*bufPt++=NF_RDDATA8(); // Read one page
}
// NF_MECC_Lock();
NF_CMD(0x05);
NF_ADDR((2048+22)&0xff); // 2060 = 0x080c
NF_ADDR(((2048+22)>>8)&0xff); // A[10:8]
NF_CMD(0xe0);
for(i=0;i<10;i++);
for(i=22;i<29;i++) {
Adv_NF8_Spare_Data[i]=NF_RDDATA8(); // Read one page
}
while(!(rNFSTAT&(1<<6))) ;
// while(NFECCDecDone==0);
rNFSTAT|=(1<<6);
printf("4th ECC check!\n");
if ((rNFECCERR0&(0x7<<26)) == 0x0){
printf("ECC OK!\n");
// return;
}
else {
printf("ECC FAIL!\n");
printf("status0:0x%x|status1:0x%x|bit:0x%x\n", rNFECCERR0, rNFECCERR1, rNFMLCBITPT);
// return;
}
NF_nFCE_H();
}
void Test_MLC_ECC(void)
{
int i;
U32 block, page;
U32 blockPage, Mecc0, Mecc1, Secc;
//U8 *bufPt=buffer;
U8 *bufPt;
bufPt=(unsigned char *)0x31100000;
NF8_EraseBlock(1);
NFConDone=0;
rNFCONF = (rNFCONF & ~(1<<30))|(1<<24); // System Clock is more than 66Mhz, ECC type is MLC.
rNFCONT |= (1<<18); //ECC for programming.
rNFCONT|=(1<<9); // Enable RnB Interrupt
rNFCONT|=(1<<10); // Enable Illegal Access Interrupt
pISR_NFCON= (unsigned)NFCon_Int;
rSRCPND=BIT_NFCON;
rINTMSK=~(BIT_NFCON);
NF_RSTECC(); // Initialize ECC
NF_MECC_UnLock();
/////////////////////////////////////////////////
// block1, page0 writing with valid data, ecc /
/////////////////////////////////////////////////
block=1;
page=0;
blockPage=(block<<5)+page;
NF_nFCE_L();
NF_CMD(0x0);//??????
NF_CMD(0x80); // Write 1st command
NF_ADDR(0); // Column 0
NF_ADDR(blockPage&0xff); //
NF_ADDR((blockPage>>8)&0xff); // Block & page num.
NF_ADDR((blockPage>>16)&0xff); //
//NF_RSTECC(); // Initialize ECC
for(i=0;i<512;i++) {
NF_WRDATA8(i); // Write one page to NFM from buffer
}
//NF_MECC_Lock();
// Get ECC data.
// Spare data for 8bit
// byte 0 1 2 3 4 5 6 7 8 9
// ecc [0] [1] [2] [3] [4] [5] [6]
Mecc0 = rNFMECC0;
Mecc1 = rNFMECC1;
se8Buf[0]=(U8)(Mecc0&0xff);
se8Buf[1]=(U8)((Mecc0>>8) & 0xff);
se8Buf[2]=(U8)((Mecc0>>16) & 0xff);
se8Buf[3]=(U8)((Mecc0>>24) & 0xff);
se8Buf[4]=(U8)(Mecc1&0xff);
se8Buf[5]=(U8)((Mecc1>>8) & 0xff);
se8Buf[6]=(U8)((Mecc1>>16) & 0xff);
for(i=0;i<7;i++) {
NF_WRDATA8(se8Buf[i]); // Write spare array(Main ECC)
NF8_Spare_Data[i]=se8Buf[i];
}
for(i=7;i<16;i++) {
NF_WRDATA8(se8Buf[i]); // Write spare array(Spare ECC and Mark)
NF8_Spare_Data[i]=se8Buf[i];
}
while(!(rNFSTAT&(1<<7))) ;
NF_CLEAR_RB();
NF_CMD(0x10); // Write 2nd command
NF_DETECT_RB();
// while(NFConDone==0);
rNFCONT&=~(1<<9);
rNFCONT&=~(1<<10); // Disable Illegal Access Interrupt
if(rNFSTAT&0x20)
{
printf("Error\n");
return;
}
NF_CMD(0x70); // Read status command
for(i=0;i<3;i++); //twhr=60ns
if (NF_RDDATA8()&0x1) {// Page write error
NF_nFCE_H();
printf("first[PROGRAM_ERROR:block#=%d]\n",block);
NF8_MarkBadBlock(block);
return;
} else {
NF_nFCE_H();
}
/////////////////////////////////////////////////
// block1, page1 writing with invalid data, ecc /
/////////////////////////////////////////////////
NFConDone=0;
rSRCPND=BIT_NFCON;
rINTMSK=~(BIT_NFCON);
NF_RSTECC(); // Initialize ECC
NF_MECC_UnLock();
block=1;
page=1;
blockPage=(block<<5)+page;
NF_nFCE_L();
NF_CMD(0x0);//??????
NF_CMD(0x80); // Write 1st command
NF_ADDR(0); // Column 0
NF_ADDR(blockPage&0xff); //
NF_ADDR((blockPage>>8)&0xff); // Block & page num.
NF_ADDR((blockPage>>16)&0xff); //
//NF_RSTECC(); // Initialize ECC
#if 0 // No Error
for(i=0;i<512;i++) {
NF_WRDATA8(i);
}
#elif 0 //1-bit Error
for(i=0;i<512;i++) {
if(i==200) {
NF_WRDATA8(0xc0);
}
else {
NF_WRDATA8(i);
}
}
#elif 0 //2-bit Error
for(i=0;i<512;i++) {
if(i==128) {
NF_WRDATA8(129);
}
else if(i==255) {
NF_WRDATA8(0x7f);
}
else {
NF_WRDATA8(i);
}
}
#elif 0 //3-bit Error
for(i=0;i<512;i++) {
if(i==10) {
NF_WRDATA8(11);
}
else if(i==511) {
NF_WRDATA8(0xdf);
}
else if(i==128) {
NF_WRDATA8(0x82);
}
else {
NF_WRDATA8(i);
}
}
#elif 1 // 4-bit Error
for(i=0;i<512;i++) {
if(i==10) {
NF_WRDATA8(11);
}
else if(i==500) {
NF_WRDATA8(0xf0);
}
else if(i==200) {
NF_WRDATA8(0xc0);
}
else if(i==30) {
NF_WRDATA8(0x16);
}
else {
NF_WRDATA8(i);
}
}
#endif
//NF_MECC_Lock();
// Get ECC data.
// Spare data for 8bit
// byte 0 1 2 3 4 5 6 7 8 9
// ecc [0] [1] [2] [3] [4] [5] [6]
/*
Mecc0 = rNFMECC0;
Mecc1 = rNFMECC1;
se8Buf[0]=(U8)(Mecc0&0xff);
se8Buf[1]=(U8)((Mecc0>>8) & 0xff);
se8Buf[2]=(U8)((Mecc0>>16) & 0xff);
se8Buf[3]=(U8)((Mecc0>>24) & 0xff);
se8Buf[4]=(U8)(Mecc1&0xff);
se8Buf[5]=(U8)((Mecc1>>8) & 0xff);
se8Buf[6]=(U8)((Mecc1>>16) & 0xff);*/
Mecc0 = rNFMECC0;
Mecc1 = rNFMECC1;
for(i=0;i<7;i++) {
NF_WRDATA8(se8Buf[i]); // Write spare array(Main ECC)
NF8_Spare_Data[i]=se8Buf[i];
}
NF_SECC_Lock();
for(i=7;i<16;i++) {
NF_WRDATA8(se8Buf[i]); // Write spare array(Spare ECC and Mark)
NF8_Spare_Data[i]=se8Buf[i];
}
while(!(rNFSTAT&(1<<7))); // Wait until 4-bit ECC encoding is completed.
NF_CLEAR_RB();
NF_CMD(0x10); // Write 2nd command
NF_DETECT_RB();
//while(NFConDone==0);
rNFCONT&=~(1<<9);
rNFCONT&=~(1<<10); // Disable Illegal Access Interrupt
if(rNFSTAT&0x20) {
printf("Error\n");
return;
}
NF_CMD(0x70); // Read status command
for(i=0;i<30;i++); //twhr=60ns
if (NF_RDDATA8()&0x1) {// Page write error
NF_nFCE_H();
printf("Second[PROGRAM_ERROR:block#=%d]\n",block);
NF8_MarkBadBlock(block);
return;
} else {
NF_nFCE_H();
}
/////////////////////////////////////////////////
// block1, page1 reading with invalid data, ecc /
/////////////////////////////////////////////////
block=1;
page=1;
blockPage=(block<<5)+page;
rNFCONF = (rNFCONF & ~(1<<30))|(1<<24); // System Clock is more than 66Mhz, ECC type is MLC.
rNFCONT &= ~(1<<18); //ECC for reading.
NF_RSTECC(); // Initialize ECC
NF_MECC_UnLock();
NF_nFCE_L();
NF_CLEAR_RB();
NF_CMD(0x00); // Read command
NF_ADDR(0); // Column = 0
NF_ADDR(blockPage&0xff); //
NF_ADDR((blockPage>>8)&0xff); // Block & Page num.
NF_ADDR((blockPage>>16)&0xff); //
NF_DETECT_RB();
for(i=0;i<512;i++) {
*bufPt++=NF_RDDATA8(); // Read one page
}
for(i=0; i<7; i++)
{
*bufPt++=NF_RDDATA8();
}
while(!(rNFSTAT&(1<<6))); //wait until 4-bit ECC decoding is completed.
rNF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -