📄 mlc.c
字号:
rSRCPND=BIT_DMA;
#endif
// NF_MECC_Lock();
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++) {
MLC_Spare_Data[i]=NF_RDDATA8(); // Read one page
}
while(!(rNFSTAT&(1<<6))) ;
// 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();
// NFCONT=0x3045;
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++);
#if TRANS_MODE_MLC==C_LANG
for(i=0;i<512;i++) {
*bufPt++=NF_RDDATA8(); // Read one page
}
#elif TRANS_MODE_MLC==DMA
// Nand to memory dma setting
bufPt+=512;
rSRCPND=BIT_DMA; // Init DMA src pending.
rSUBSRCPND=BIT_SUB_DMA0;
rDISRC0=NFDATA; // Nand flash data register
rDISRCC0=(0<<1) | (1<<0); //arc=AHB,src_addr=fix
rDIDST0=(unsigned)bufPt;
rDIDSTC0=(0<<1) | (0<<0); //dst=AHB,dst_addr=inc;
rDCON0=(1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(0<<23)|(1<<22)|(2<<20)|(512/4/4);
//Handshake,AHB,interrupt,(4-burst),whole,S/W,no_autoreload,word,count=128;
// DMA on and start.
rDMASKTRIG0=(1<<1)|(1<<0);
while(!(rSUBSRCPND & BIT_SUB_DMA0)); // Wait until Dma transfer is done.
rSUBSRCPND=BIT_SUB_DMA0;
rSRCPND=BIT_DMA;
#endif
// 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++) {
//MLC_Spare_Data[i]=NF_RDDATA8(); // Read one page
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();
// NFCONT=0x3045;
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++);
#if TRANS_MODE_MLC==C_LANG
for(i=0;i<512;i++) {
*bufPt++=NF_RDDATA8(); // Read one page
}
#elif TRANS_MODE_MLC==DMA
// Nand to memory dma setting
bufPt+=512;
rSRCPND=BIT_DMA; // Init DMA src pending.
rSUBSRCPND=BIT_SUB_DMA0;
rDISRC0=NFDATA; // Nand flash data register
rDISRCC0=(0<<1) | (1<<0); //arc=AHB,src_addr=fix
rDIDST0=(unsigned)bufPt;
rDIDSTC0=(0<<1) | (0<<0); //dst=AHB,dst_addr=inc;
rDCON0=(1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(0<<23)|(1<<22)|(2<<20)|(512/4/4);
//Handshake,AHB,interrupt,(4-burst),whole,S/W,no_autoreload,word,count=128;
// DMA on and start.
rDMASKTRIG0=(1<<1)|(1<<0);
while(!(rSUBSRCPND & BIT_SUB_DMA0)); // Wait until Dma transfer is done.
rSUBSRCPND=BIT_SUB_DMA0;
rSRCPND=BIT_DMA;
#endif
// 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++) {
//MLC_Spare_Data[i]=NF_RDDATA8(); // Read one page
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();
// rNFCONT=0x3045;
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++);
#if TRANS_MODE_MLC==C_LANG
for(i=0;i<512;i++) {
*bufPt++=NF_RDDATA8(); // Read one page
}
#elif TRANS_MODE_MLC==DMA
// Nand to memory dma setting
bufPt+=512;
rSRCPND=BIT_DMA; // Init DMA src pending.
rSUBSRCPND=BIT_SUB_DMA0;
rDISRC0=NFDATA; // Nand flash data register
rDISRCC0=(0<<1) | (1<<0); //arc=AHB,src_addr=fix
rDIDST0=(unsigned)bufPt;
rDIDSTC0=(0<<1) | (0<<0); //dst=AHB,dst_addr=inc;
rDCON0=(1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(0<<23)|(1<<22)|(2<<20)|(512/4/4);
//Handshake,AHB,interrupt,(4-burst),whole,S/W,no_autoreload,word,count=128;
// DMA on and start.
rDMASKTRIG0=(1<<1)|(1<<0);
while(!(rSUBSRCPND & BIT_SUB_DMA0)); // Wait until Dma transfer is done.
rSUBSRCPND=BIT_SUB_DMA0;
rSRCPND=BIT_DMA;
#endif
// 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++) {
//MLC_Spare_Data[i]=NF_RDDATA8(); // Read one page
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();
return 1;
}
static int MLC_WritePage(U32 block,U32 page,U8 *buffer)
{
int i;
U32 blockPage, Mecc0, Mecc1, Mecc2, Mecc3, Mecc4, Mecc5, Mecc6, Mecc7, Secc1, Secc2;
//U8 *bufPt=buffer;
U8 *bufPt;
MLC_EraseBlock(1);
bufPt=(unsigned char *)0x31100000;
NFConDone_MLC=0, NFECCEncDone=0, NFECCDecDone=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
rNFCONT|=(1<<13); // Enable ECC encoding & decoding conpletion interrupt enable
rNFCONT|=(1<<12); // Enable ECC encoding & decoding conpletion interrupt enable
pISR_NFCON= (unsigned)NFCon_Int_MLC;
rSRCPND=BIT_NFCON;
rINTMSK&=~(BIT_NFCON);
/////////////////////////////////////////////////
// block1, page0 writing with valid data, ecc /
/////////////////////////////////////////////////
blockPage=(block<<7)+page;
NF_nFCE_L();
NF_CMD(0x0);//??????
NF_CMD(0x80); // Write 1st 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]
// 0~511
NF_RSTECC(); // Initialize ECC
NF_MECC_UnLock();
#if TRANS_MODE_MLC==C_LANG
for(i=0;i<512;i++) {
{NF_WRDATA8(*bufPt++);} // Write one page to NFM from buffer
}
#elif TRANS_MODE_MLC==DMA
// Memory to Nand dma setting
rSUBSRCPND=BIT_SUB_DMA0;
rSRCPND=BIT_DMA; // Init DMA src pending.
rDISRC0=(unsigned)bufPt; // Nand flash data register
rDISRCC0=(0<<1) | (0<<0); //arc=AHB,src_addr=inc
rDIDST0=NFDATA;
rDIDSTC0=(0<<1) | (1<<0); //dst=AHB,dst_addr=fix;
rDCON0=(1<<31)|(1<<30)|(1<<29)|(0<<28)|(1<<27)|(0<<23)|(1<<22)|(2<<20)|(512/4);
// only unit transfer in writing!!!!
//Handshake,AHB,interrupt,(unit),whole,S/W,no_autoreload,word,count=128;
// DMA on and start.
rDMASKTRIG0=(1<<1)|(1<<0);
while(!(rSUBSRCPND & BIT_SUB_DMA0)); // Wait until Dma transfer is done.
rSUBSRCPND=BIT_SUB_DMA0;
rSRCPND=BIT_DMA;
#endif
while(!(rNFSTAT&(1<<7))) ;
rNFSTAT|=(1<<7);
Mecc0 = rNFMECC0;
Mecc1 = rNFMECC1;
// 512~1023
NF_RSTECC(); // Initialize ECC
NF_MECC_UnLock();
#if TRANS_MODE_MLC==C_LANG
for(i=0;i<512;i++) {
{NF_WRDATA8(*bufPt++);} // Write one page to NFM from buffer
}
#elif TRANS_MODE_MLC==DMA
// Memory to Nand dma setting
bufPt+=512;
rSUBSRCPND=BIT_SUB_DMA0;
rSRCPND=BIT_DMA; // Init DMA src pending.
rDISRC0=(unsigned)bufPt; // Nand flash data register
rDISRCC0=(0<<1) | (0<<0); //arc=AHB,src_addr=inc
rDIDST0=NFDATA;
rDIDSTC0=(0<<1) | (1<<0); //dst=AHB,dst_addr=fix;
rDCON0=(1<<31)|(1<<30)|(1<<29)|(0<<28)|(1<<27)|(0<<23)|(1<<22)|(2<<20)|(512/4);
// only unit transfer in writing!!!!
//Handshake,AHB,interrupt,(unit),whole,S/W,no_autoreload,word,count=128;
// DMA on and start.
rDMASKTRIG0=(1<<1)|(1<<0);
while(!(rSUBSRCPND & BIT_SUB_DMA0)); // Wait until Dma transfer is done.
rSUBSRCPND=BIT_SUB_DMA0;
rSRCPND=BIT_DMA;
#endif
while(!(rNFSTAT&(1<<7))) ;
rNFSTAT|=(1<<7);
Mecc2 = rNFMECC0;
Mecc3 = rNFMECC1;
// 1024~1535
NF_RSTECC(); // Initialize ECC
NF_MECC_UnLock();
#if TRANS_MODE_MLC==C_LANG
for(i=0;i<512;i++) {
{NF_WRDATA8(*bufPt++);} // Write one page to NFM from buffer
}
#elif TRANS_MODE_MLC==DMA
// Memory to Nand dma setting
bufPt+=512;
rSUBSRCPND=BIT_SUB_DMA0;
rSRCPND=BIT_DMA; // Init DMA src pending.
rDISRC0=(unsigned)bufPt; // Nand flash data register
rDISRCC0=(0<<1) | (0<<0); //arc=AHB,src_addr=inc
rDIDST0=NFDATA;
rDIDSTC0=(0<<1) | (1<<0); //dst=AHB,dst_addr=fix;
rDCON0=(1<<31)|(1<<30)|(1<<29)|(0<<28)|(1<<27)|(0<<23)|(1<<22)|(2<<20)|(512/4);
// only unit transfer in writing!!!!
//Handshake,AHB,interrupt,(unit),whole,S/W,no_autoreload,word,count=128;
// DMA on and start.
rDMASKTRIG0=(1<<1)|(1<<0);
while(!(rSUBSRCPND & BIT_SUB_DMA0)); // Wait until Dma transfer is done.
rSUBSRCPND=BIT_SUB_DMA0;
rSRCPND=BIT_DMA;
#endif
while(!(rNFSTAT&(1<<7))) ;
rNFSTAT|=(1<<7);
Mecc4 = rNFMECC0;
Mecc5 = rNFMECC1;
// 1536~2047
NF_RSTECC(); // Initialize ECC
NF_MECC_UnLock();
#if TRANS_MODE_MLC==C_LANG
for(i=0;i<512;i++) {
{NF_WRDATA8(*bufPt++);} // Write one page to NFM from buffer
}
#elif TRANS_MODE_MLC==DMA
// Memory to Nand dma setting
bufPt+=512;
rSUBSRCPND=BIT_SUB_DMA0;
rSRCPND=BIT_DMA; // Init DMA src pending.
rDISRC0=(unsigned)bufPt; // Nand flash data register
rDISRCC0=(0<<1) | (0<<0); //arc=AHB,src_addr=inc
rDIDST0=NFDATA;
rDIDSTC0=(0<<1) | (1<<0); //dst=AHB,dst_addr=fix;
rDCON0=(1<<31)|(1<<30)|(1<<29)|(0<<28)|(1<<27)|(0<<23)|(1<<22)|(2<<20)|(512/4);
// only unit transfer in writing!!!!
//Handshake,AHB,interrupt,(unit),whole,S/W,no_autoreload,word,count=128;
// DMA on and start.
rDMASKTRIG0=(1<<1)|(1<<0);
while(!(rSUBSRCPND & BIT_SUB_DMA0)); // Wait until Dma transfer is done.
rSUBSRCPND=BIT_SUB_DMA0;
rSRCPND=BIT_DMA;
#endif
while(!(rNFSTAT&(1<<7))) ;
rNFSTAT|=(1<<7);
Mecc6 = rNFMECC0;
Mecc7 = rNFMECC1;
// 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]
MLC_Buf[1]=(U8)(Mecc0&0xff);
MLC_Buf[2]=(U8)((Mecc0>>8) & 0xff);
MLC_Buf[3]=(U8)((Mecc0>>16) & 0xff);
MLC_Buf[4]=(U8)((Mecc0>>24) & 0xff);
MLC_Buf[5]=(U8)(Mecc1&0xff);
MLC_Buf[6]=(U8)((Mecc1>>8) & 0xff);
MLC_Buf[7]=(U8)((Mecc1>>16) & 0xff);
MLC_Buf[8]=(U8)(Mecc2&0xff);
MLC_Buf[9]=(U8)((Mecc2>>8) & 0xff);
MLC_Buf[10]=(U8)((Mecc2>>16) & 0xff);
MLC_Buf[11]=(U8)((Mecc2>>24) & 0xff);
MLC_Buf[12]=(U8)(Mecc3&0xff);
MLC_Buf[13]=(U8)((Mecc3>>8) & 0xff);
MLC_Buf[14]=(U8)((Mecc3>>16) & 0xff);
MLC_Buf[15]=(U8)(Mecc4&0xff);
MLC_Buf[16]=(U8)((Mecc4>>8) & 0xff);
MLC_Buf[17]=(U8)((Mecc4>>16) & 0xff);
MLC_Buf[18]=(U8)((Mecc4>>24) & 0xff);
MLC_Buf[19]=(U8)(Mecc5&0xff);
MLC_Buf[20]=(U8)((Mecc5>>8) & 0xff);
MLC_Buf[21]=(U8)((Mecc5>>16) & 0xff);
MLC_Buf[22]=(U8)(Mecc6&0xff);
MLC_Buf[23]=(U8)((Mecc6>>8) & 0xff);
MLC_Buf[24]=(U8)((Mecc6>>16) & 0xff);
MLC_Buf[25]=(U8)((Mecc6>>24) & 0xff);
MLC_Buf[26]=(U8)(Mecc7&0xff);
MLC_Buf[27]=(U8)((Mecc7>>8) & 0xff);
MLC_Buf[28]=(U8)((Mecc7>>16) & 0xff);
// Spare ECC write
NF_RSTECC(); // Initialize ECC
NF_MECC_UnLock();
for(i=0;i<29;i++) {
NF_WRDATA8(MLC_Buf[i]); // Write spare array(Main ECC)
MLC_Spare_Data[i]=MLC_Buf[i];
}
NF_nFCE_H();
for(i=29;i<512;i++) {
NF_WRDATA8(0xff); // Write spare array(Dummy data)
}
while(!(rNFSTAT&(1<<7))) ;
rNFSTAT|=(1<<7);
Secc1 = rNFMECC0;
Secc2 = rNFMECC1;
MLC_Buf[29]=(U8)(Secc1&0xff);
MLC_Buf[30]=(U8)((Secc1>>8) & 0xff);
MLC_Buf[31]=(U8)((Secc1>>16) & 0xff);
MLC_Buf[32]=(U8)((Secc1>>24) & 0xff);
MLC_Buf[33]=(U8)(Secc2&0xff);
MLC_Buf[34]=(U8)((Secc2>>8) & 0xff);
MLC_Buf[35]=(U8)((Secc2>>16) & 0xff);
NF_nFCE_L();
for(i=29;i<64;i++) {
NF_WRDATA8(MLC_Buf[i]); // Write spare array(Main ECC)
MLC_Spare_Data[i]=MLC_Buf[i];
}
NF_CLEAR_RB();
NF_CMD(0x10); // Write 2nd command
NF_DETECT_RB();
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);
return 0;
} else {
NF_nFCE_H();
}
return 1;
}
static U16 MLC_CheckId(void)
{
int i;
U16 id;
U8 id0, id1, id2, id3;
NF_nFCE_L();
NF_CMD(0x90);
NF_ADDR(0x0);
for (i=0; i<10; i++);
id0=NF_RDDATA8(); // Maker code 0xec
id1=NF_RDDATA8(); //
id2=NF_RDDATA8();
id3=NF_RDDATA8();
id=(id0<<8)|id1;
NF_nFCE_H();
printf("id0:0x%02x, id1:0x%02x,id2:0x%02x,id3:0x%02x \n", id0, id1, id2, id3);
return id;
}
void Test_MLC_Adv_ECC(void)
{
int i;
U32 block, page;
U32 blockPage, Mecc0, Mecc1, Mecc2, Mecc3, Mecc4, Mecc5, Mecc6, Mecc7;
//U8 *bufPt=buffer;
U8 *bufPt;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -