📄 secnand.c
字号:
else //addr cycle : 5
{
rNFCONF |= (1<<1);
if(sNandInfo.u512BytesPerPage == 4)
{
rNFCONF &= ~(1<<3);
}
else
{
rNFCONF |= (1<<3);
}
}
}
else //small block
{
rNFCONF &= ~(1<<2);
if(sNandInfo.uAddrCycle ==3)
{
rNFCONF &= ~(1<<1); //addr cycle : 3
if(sNandInfo.u512BytesPerPage == 1)
{
rNFCONF &= ~(1<<3);
}
else
{
rNFCONF |= (1<<3);
}
}
else
{
rNFCONF |= (1<<1); //addr cycle : 4
if(sNandInfo.u512BytesPerPage == 1)
{
rNFCONF &= ~(1<<3);
}
else
{
rNFCONF |= (1<<3);
}
}
}
sNandInfo.uPagesPerBlock = uSize;
for(i=0; uSize>1; i++) uSize>>=1;
sNandInfo.uBlockShift = i;
PrintNandInfo();
}
unsigned char ReadNandStatus(void)
{
// Read status
unsigned char ch;
int i;
NF_nFCE_L();
NF_CMD(CMD_STATUS);
for(i=0; i<10; i++);
ch = NF_RDDATA();
NF_nFCE_H();
return ch;
}
void __irq IsrNFC(void)
{
printf("[INT]");
//rINTMSK|=BIT_NFCON;
ClearPending(BIT_NFCON);
if(rNFSTAT&0x20)
{
rNFSTAT|=0x20;
printf("Illegal Access is detected!!!\n");
}
else if(rNFSTAT&0x40)
{
if ((rNFECCERR0&(0x7<<26)) == 0x0)
{
printf("ECC OK!\n");
}
else
{
printf("ECC FAIL!\n");
printf("status0:0x%x|status1:0x%x|bit:0x%x\n", rNFECCERR0, rNFECCERR1, rNFMLCBITPT);
}
NFECCDecDone=1;
rNFSTAT|=0x40;
printf("ECC decoding is completed!!!\n");
}
else if(rNFSTAT&0x10)
{
NFConDone=1;
rNFSTAT|=0x10;
printf("RnB is Detected!!!\n");
}
else if(rNFSTAT&0x80)
{
NFECCEncDone=1;
rNFSTAT|=0x80;
printf("ECC Encoding is completed!!!\n");
}
}
//#define SET_NAND_INT(ISR_FUNC)
int EraseBlock(unsigned int uBlock)
{
//unsigned int blockPage=(block<<5);
unsigned int uCurBlockAddr;// = (uBlock<<sNandInfo.uBlockShift);
unsigned int i=0;
uCurBlockAddr = (uBlock<<sNandInfo.uBlockShift);
//rNFSTAT = rNFSTAT|(1<<6)|(1<<7)|(1<<5)|(1<<4);
rNFSTAT |= ((1<<6)|(1<<5)|(1<<4));
NFConDone=0;
rNFCONT|=(1<<9);
rNFCONT|=(1<<10);
pISR_NFCON= (unsigned)IsrNFC;
rSRCPND=BIT_NFCON;
rINTMSK=~(BIT_NFCON);
NF_nFCE_L();
NF_CMD(CMD_ERASE1); // Erase one block 1st command, Block Addr:A9-A25
for(i=0; i<sNandInfo.uRowCycle; i++) //Row Addressing
NF_ADDR((uCurBlockAddr>>(i<<3))&0xFF);
NF_CLEAR_RB();
NF_CMD(CMD_ERASE2); // Erase one blcok 2nd command
#if __POLLING
NF_DETECT_RB();
#else
while(NFConDone==0);
rNFCONT&=~(1<<9);
rNFCONT&=~(1<<10); // Disable Illegal Access Interrupt
if(rNFSTAT&0x20)
{
rNFSTAT|=0x20;
printf("\nError to erase a block");
return FAIL;
}
#endif
NF_CMD(CMD_STATUS); // Read status command
if (NF_RDDATA()&0x1) // Erase error
{
NF_nFCE_H();
rGPGDAT|=(1<<1);
printf("[ERASE_ERROR:block#=%d]\n",uBlock);
//NF8_MarkBadBlock(block); //MGR
return FAIL;
}
else
{
NF_nFCE_H();
return OK;
}
}
void TestEraseBlock(void)
{
unsigned int block=0;
//printf("SMC(K9S1208V0M) NAND Block erase\n");
if((ReadNandStatus()&0x80)==0) {
printf("Write protected.\n");
return;
}
printf("Block # to erase: ");
block = GetIntNum();
if(EraseBlock(block)==FAIL) return;
printf("%d-block erased.\n", block);
}
int CorrectECC8Data(unsigned char *pEncodingBaseAddr)
{
unsigned int i,uErrorByte[9];
unsigned char uErrorBit[9];
unsigned int uErrorType;
uErrorType = (rNF8ECCERR0>>25)&0xf;// Searching Error Type //How many Error bits does exist?
uErrorByte[1] = rNF8ECCERR0&0x3ff;// Searching Error Byte //Where is the error byte?
uErrorByte[2] = (rNF8ECCERR0>>15)&0x3ff;
uErrorByte[3] = (rNF8ECCERR1)&0x3ff;
uErrorByte[4] = (rNF8ECCERR1>>11)&0x3ff;
uErrorByte[5] = (rNF8ECCERR1>>22)&0x3ff;
uErrorByte[6] = (rNF8ECCERR2)&0x3ff;
uErrorByte[7] = (rNF8ECCERR2>>11)&0x3ff;
uErrorByte[8] = (rNF8ECCERR2>>22)&0x3ff;
uErrorBit[1] = rNFMLC8BITPT0&0xff;// Searching Error Bit //Where is the error bit?
uErrorBit[2] = (rNFMLC8BITPT0>>8)&0xff;
uErrorBit[3] = (rNFMLC8BITPT0>>16)&0xff;
uErrorBit[4] = (rNFMLC8BITPT0>>24)&0xff;
uErrorBit[5] = rNFMLC8BITPT1&0xff;
uErrorBit[6] = (rNFMLC8BITPT1>>8)&0xff;
uErrorBit[7] = (rNFMLC8BITPT1>>16)&0xff;
uErrorBit[8] = (rNFMLC8BITPT1>>24)&0xff;
if(!uErrorType)
return 0;
if(uErrorType == 0x9)
return 1;
for(i=1;i<=uErrorType ;i++)
{
if(uErrorByte[i] < 512)
pEncodingBaseAddr[uErrorByte[i]]^=uErrorBit[i];
else
{; }
}
return 0;
}
/*
int ReadPage(unsigned char* uRBuf,unsigned int uBlock, unsigned int uPage)
{
int i,m;
unsigned char Addr_Cycle, option2;
unsigned int uResult[8]={0, };
unsigned char *pSpare;
unsigned int uCurPageAddr, uRet=0;
pSpare = g_uSpareData;
uCurPageAddr = uBlock*sNandInfo.uPagesPerBlock + uPage;
rNFCONF = ( rNFCONF&~(0x3<<23) ) |(2<<30)|(0<<23)|(0x7<<12)|(0x7<<8)|(0x7<<4);
rNFCONT = ( rNFCONT&~(0x1<<18) ) |(0<<18)|(0<<11)|(0<<10)|(0<<9)|(1<<6)|(1<<0); // Init NFCONT
rNFSTAT |= ((1<<6)|(1<<5)|(1<<4));
NF_MECC_Lock(); // Main ECC Lock
NF_nFCE_L(); // Chip Select Low
NF_CLEAR_RB(); // RnB Clear
for(i=0; i<sNandInfo.u512BytesPerPage; i++)
{
NF_MECC_Lock(); // Main ECC Lock
NF_CLEAR_RB(); // RnB Clear
if(!i)
{
NF_CMD(CMD_READ0); // Read command
for(m=0; m<sNandInfo.uColCycle; m++) //Addr Cycle
NF_ADDR(0);
for(m=0; m<sNandInfo.uRowCycle; m++)
NF_ADDR((uCurPageAddr>>(m<<3))&0xFF);
NF_CMD(CMD_READ0_2CYCLE); // Read command
#if __POLLING
NF_DETECT_RB(); // RnB Detect.
#else
while(NFConDone==0);
#endif
rNFSTAT = rNFSTAT | (1<<4); // RnB Pending Clear
}
else
{
NF_CMD(CMD_RANDOM_DATA_OUT_1ST_CYCLE); // Random Address Access = 512K start
NF_ADDR(((PAGE_LEN_ECC8*i)>>0)&0xFF);
NF_ADDR(((PAGE_LEN_ECC8*i)>>8)&0xFF);
NF_CMD(CMD_RANDOM_DATA_OUT_2ND_CYCLE)
}
NF_MECC_UnLock(); // Main ECC Unlock
NF_RSTECC(); // Initialize ECC
for(m=0;m<PAGE_LEN_ECC8;m++)
*uRBuf++=NF_RDDATA8(); // Read Main data
// Spare Area Address Setting.
if(sNandInfo.uPageSize > 512)
{
NF_CMD(CMD_RANDOM_DATA_OUT_1ST_CYCLE);
NF_ADDR(((sNandInfo.uPageSize + VAL_LEN_ECC8*i)>>0)&0xFF);
NF_ADDR(((sNandInfo.uPageSize + VAL_LEN_ECC8*i)>>8)&0xFF);
NF_CMD(CMD_RANDOM_DATA_OUT_2ND_CYCLE);
}
for(m=0; m<VAL_LEN_ECC8 ; m++)
*pSpare++ = NF_RDDATA8(); // Spare Data Read
NF_MECC_Lock(); // Main ECC Lock
while(!(rNFSTAT&(1<<6))); // Check decoding done
rNFSTAT = rNFSTAT | (1<<6); // Decoding done Clear
while( rNF8ECCERR0 & (unsigned int)(1<<31) ) ; // 8bit ECC Decoding Busy Check.
uResult[i] = CorrectECC8Data((uRBuf-PAGE_LEN_ECC8));
//printf("\nuResult[%d] : %d", i, uResult[i]);
uRet += uResult[i];
}
NF_nFCE_H(); // Chip Select is High
return uRet;
}
*/
int ReadPage(unsigned char* uRBuf,unsigned int uBlock, unsigned int uPage)
{
int i,m;
unsigned char Addr_Cycle, option2;
unsigned int uResult[8]={0, };
unsigned char *pSpare;
unsigned int uCurPageAddr, uRet=0;
pSpare = g_uSpareData;
uCurPageAddr = uBlock*sNandInfo.uPagesPerBlock + uPage;
//rNFCONF &= ~(0x3<<23)|(1<<23);
//rNFCONT = ( rNFCONT&~(0x1<<18) ) |(0<<18)|(1<<11)|(1<<10)|(1<<9); // Init NFCONT
rNFCONT &= ~(0x1<<18);
rNFCONF &= ~(0x3<<23);
rNFCONF|=(1<<23);
rNFSTAT = rNFSTAT|(1<<6)|(1<<7)|(1<<5)|(1<<4);
NF_MECC_Lock(); // Main ECC Lock
NF_nFCE_L(); // Chip Select Low
NF_CLEAR_RB(); // RnB Clear
#if __POLLING
#else
rNFCONT |= (1<<12);
rNFCONT |= (1<<11);
rNFCONT |= (1<<10);
rNFCONT |= (1<<9);
NFConDone=0;
NFECCDecDone=0;
NFECCEncDone=0;
pISR_NFCON= (unsigned)IsrNFC;
rSRCPND=BIT_NFCON;
rINTMSK=~(BIT_NFCON);
#endif
for(i=0; i<sNandInfo.u512BytesPerPage; i++)
{
NF_MECC_Lock(); // Main ECC Lock
NF_CLEAR_RB(); // RnB Clear
if(!i)
{
NF_CMD(CMD_READ0); // Read command
for(m=0; m<sNandInfo.uColCycle; m++) //Addr Cycle
NF_ADDR(0);
for(m=0; m<sNandInfo.uRowCycle; m++)
NF_ADDR((uCurPageAddr>>(m<<3))&0xFF);
NF_CMD(CMD_READ0_2CYCLE); // Read command
#if __POLLING
NF_DETECT_RB();
rNFSTAT = rNFSTAT | (1<<4); // RnB Pending Clear
#else
while(!NFConDone);
NFConDone = 0;
#endif
}
else
{
NF_CMD(CMD_RANDOM_DATA_OUT_1ST_CYCLE); // Random Address Access = 512K start
NF_ADDR(((PAGE_LEN_ECC8*i)>>0)&0xFF);
NF_ADDR(((PAGE_LEN_ECC8*i)>>8)&0xFF);
NF_CMD(CMD_RANDOM_DATA_OUT_2ND_CYCLE)
}
NF_MECC_UnLock(); // Main ECC Unlock
NF_RSTECC(); // Initialize ECC
for(m=0;m<PAGE_LEN_ECC8;m++)
*uRBuf++=NF_RDDATA8(); // Read Main data
// Spare Area Address Setting.
if(sNandInfo.uPageSize > 512)
{
NF_CMD(CMD_RANDOM_DATA_OUT_1ST_CYCLE);
NF_ADDR(((sNandInfo.uPageSize + VAL_LEN_ECC8*i)>>0)&0xFF);
NF_ADDR(((sNandInfo.uPageSize + VAL_LEN_ECC8*i)>>8)&0xFF);
NF_CMD(CMD_RANDOM_DATA_OUT_2ND_CYCLE);
}
for(m=0; m<VAL_LEN_ECC8 ; m++)
*pSpare++ = NF_RDDATA8(); // Spare Data Read
NF_MECC_Lock(); // Main ECC Lock
#if __POLLING
while(!(rNFSTAT&(1<<6))); // Check decoding done
rNFSTAT = rNFSTAT | (1<<6); // Decoding done Clear
#else
while(!NFECCDecDone);
NFECCDecDone=0;
#endif
while( rNF8ECCERR0 & (unsigned int)(1<<31) ) ; // 8bit ECC Decoding Busy Check.
uResult[i] = CorrectECC8Data((uRBuf-PAGE_LEN_ECC8));
//printf("\nuResult[%d] : %d", i, uResult[i]);
uRet += uResult[i];
}
#if __POLLING
if(rNFSTAT&0x20)
{
rNFSTAT|=0x20;
printf("\nError to erase a block");
NF_nFCE_H(); // Chip Select is High
return FAIL;
}
#else
rNFCONT&=~(1<<9);
rNFCONT&=~(1<<10); // Disable Illegal Access Interrupt
rNFCONT&=~(1<<12);
#endif
NF_nFCE_H(); // Chip Select is High
return uRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -