📄 nand.c
字号:
}
}
if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
{
NF_CMD(Controller, 0x71); // Read Multi-plane status command
}
else
NF_CMD(Controller, 0x70); // Read status command
while(!((uStatus = NF_RDDATA8(Controller)) & (1<<6)));
if(uStatus & 0x01)
{
eError = eNAND_EraseError; // Error in Erase
NF_nFCE_H(Controller);
uTemp = NAND_ReadNFCONRegister(Controller);
uTemp &= ~((1<<10)|(1<<9)); // Illegal Access & RnB Transition Interrupt disable
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
INTC_Disable(NUM_NFC);
return eError;
}
else
eError = eNAND_NoError;
//if (NF_RDDATA8(Controller)&0x1) // Erase error check
//{
// eError = eNAND_EraseError;
// return eError;
//}
//else
// eError = eNAND_NoError;
NF_nFCE_H(Controller);
}
uTemp = NAND_ReadNFCONRegister(Controller);
uTemp &= ~((1<<10)|(1<<9)); // Illegal Access & RnB Transition Interrupt disable
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
INTC_Disable(NUM_NFC);
return eError;
}
//////////
// Function Name : NAND_SoftLockingBlock
// Function Description : This function lock the blocks, then when you try to write or erase the locked area, the illegal access will be occured
// Input : Controller - Nand Controller Port Number
// uStartBlock, uEndBlock - Enable Soft-Locking the other blocks except from uStartBlock[block] to uEndBlock-1[block]
// Output : Nand Error Type
NAND_eERROR NAND_SoftLockingBlock(u32 Controller, u32 uStartBlock, u32 uEndBlock)
{
u32 uTemp;
if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
{
Outp32(&(NAND(Controller)->rNFSBLK), uStartBlock<<5);
Outp32(&(NAND(Controller)->rNFEBLK), (uEndBlock+1)<<5);
}
else if(NAND_Inform[Controller].uNandType == NAND_Advanced8bit)
{
Outp32(&(NAND(Controller)->rNFSBLK), uStartBlock<<6);
Outp32(&(NAND(Controller)->rNFEBLK), (uEndBlock+1)<<6);
}
else if(NAND_Inform[Controller].uNandType == NAND_MLC8bit)
{
Outp32(&(NAND(Controller)->rNFSBLK), uStartBlock<<7);
Outp32(&(NAND(Controller)->rNFEBLK), (uEndBlock+1)<<7);
}
uTemp = NAND_ReadNFCONRegister(Controller);
uTemp |= (1<<16); // Enable Soft lock
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
return eNAND_NoError;
}
//////////
// Function Name : NAND_LockTightBlock
// Function Description : This function lock-tight the blocks, then when you try to write or erase the locked area, the illegal access will be occured
// You cannot disable lock-tight by software. Only reset or wakeup from sleep mode can make disable lock-tight
// Input : Controller - Nand Controller Port Number
// uStartBlock, uEndBlock - Enable Lock-tight the other blocks except from uStartBlock[block] to uEndBlock-1[block]
// Output : Nand Error Type
NAND_eERROR NAND_LockTightBlock(u32 Controller, u32 uStartBlock, u32 uEndBlock)
{
u32 uTemp;
if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
{
Outp32(&(NAND(Controller)->rNFSBLK), uStartBlock<<5);
Outp32(&(NAND(Controller)->rNFEBLK), (uEndBlock+1)<<5);
}
else if(NAND_Inform[Controller].uNandType == NAND_Advanced8bit)
{
Outp32(&(NAND(Controller)->rNFSBLK), uStartBlock<<6);
Outp32(&(NAND(Controller)->rNFEBLK), (uEndBlock+1)<<6);
}
else if(NAND_Inform[Controller].uNandType == NAND_MLC8bit)
{
Outp32(&(NAND(Controller)->rNFSBLK), uStartBlock<<7);
Outp32(&(NAND(Controller)->rNFEBLK), (uEndBlock+1)<<7);
}
uTemp = NAND_ReadNFCONRegister(Controller);
uTemp |= (1<<17); // Enable Lock-tight
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
return eNAND_NoError;
}
//////////
// Function Name : NAND_UnLockBlock
// Function Description : This function unlock the soft-locked blocks
// Input : Controller - Nand Controller Port Number
// Output : Nand Error Type
NAND_eERROR NAND_UnLockBlock(u32 Controller)
{
u32 uTemp;
uTemp = NAND_ReadNFCONRegister(Controller);
if(!(uTemp & (1<<16)))
return eNAND_NoError;
Outp32(&(NAND(Controller)->rNFSBLK), 0);
Outp32(&(NAND(Controller)->rNFEBLK), 0);
//uTemp = NAND_ReadNFCONRegister(Controller);
uTemp &= ~(1<<16); // Disable Soft lock
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
uTemp = NAND_ReadNFCONRegister(Controller);
if(uTemp & (1<<16))
return eNAND_EtcError;
return eNAND_NoError;
}
//////////
// Function Name : NAND_UnLockTightBlock
// Function Description : This function unlock the lock-tight blocks, but cannot unlock those blocks. This is for test..!!!
// Input : Controller - Nand Controller Port Number
// Output : Nand Error Type
NAND_eERROR NAND_UnLockTightBlock(u32 Controller)
{
u32 uTemp;
uTemp = NAND_ReadNFCONRegister(Controller);
if(!(uTemp & (1<<17)))
return eNAND_NoError;
Outp32(&(NAND(Controller)->rNFSBLK), 0);
Outp32(&(NAND(Controller)->rNFEBLK), 0);
//uTemp = NAND_ReadNFCONRegister(Controller);
uTemp &= ~(1<<17); // Disable lock-tight. but this bit is not cleared...for test
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
uTemp = NAND_ReadNFCONRegister(Controller);
if(!(uTemp & (1<<17)))
return eNAND_EtcError;
return eNAND_NoError;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////// For ECC Error Test //////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////
// Function Name : NAND_WritePageSLCWithInvalidData
// Function Description : This function write the 1 page invalid data test ECC Error
// Input : Controller - Nand Controller Port Number
// uBlock - Write Block
// uPage - Write Page
// pBuffer - Write data buffer
// uErrorType - ECC Error Type
// Output : ECC Error Type
NAND_eERROR NAND_WritePageSLCWithInvalidData(u32 Controller, u32 uBlock, u32 uPage, u8 *pBuffer, u32 uErrorType)
{
u32 i, uBlockPage, uPageSize, uSpareSize, uTemp, uStatus;
u8 *pErrorBuffer;
NAND_eERROR eError;
pErrorBuffer = pBuffer;
uTemp = NAND_ReadNFCONRegister(Controller);
uTemp &= ~((1<<13)|(1<<12)); // 4bit ECC encoding/decoding completion Interrupt disable
uTemp |= (1<<10) | (1<<9); // Illegal Access & RnB Transition Interrupt enable
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
Outp32(&(NAND(Controller)->rNFSTAT), (1<<5)|(1<<4)); // Illegal Access & RnB Interrupt Pending bit clear
INTC_Enable(NUM_NFC);
if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
{
uBlockPage=(uBlock<<5) + uPage;
uPageSize = NAND_Inform[Controller].uPageSize;
uSpareSize = NAND_Inform[Controller].uSpareSize;
}
else //if(NAND_Inform[Controller].uNandType == NAND_Advanced8bit)
{
uBlockPage=(uBlock<<6) + uPage;
uPageSize = NAND_Inform[Controller].uPageSize;
uSpareSize = NAND_Inform[Controller].uSpareSize;
}
//////////////////////////
// Generate the Error Data
//////////////////////////
// The ECC value of valid data(1 page) has in the aNand_Spare_Data_Temp[] array
#if 0
if(uErrorType == NAND_ECCERR_1BIT)
{
pErrorBuffer[100] ^= 0x01; // 1st bit toggle, then generate the 1bit ecc error
}
else if(uErrorType == NAND_ECCERR_MULTI)
{
pErrorBuffer[100] ^= 0x01; // 1st bit toggle, then generate the 1bit ecc error
pErrorBuffer[200] ^= 0x01; // 1st bit toggle, then generate the 1bit ecc error
}
#else
if(uErrorType == NAND_ECCERR_1BIT)
{
pErrorBuffer[NAND_EccError.uEccErrByte1] ^= (1<<NAND_EccError.uEccErrBit1);
}
else if(uErrorType == NAND_ECCERR_MULTI)
{
pErrorBuffer[NAND_EccError.uEccErrByte1] ^= (1<<NAND_EccError.uEccErrBit1);
pErrorBuffer[NAND_EccError.uEccErrByte2] ^= (1<<NAND_EccError.uEccErrBit2);
}
#endif
//////////////////////////
// Write 0 ~ uPageSize
//////////////////////////
NF_RSTECC(Controller); // Initialize ECC
NF_MECC_UnLock(Controller);
NF_nFCE_L(Controller);
NF_CLEAR_RnB(Controller);
NF_CMD(Controller, 0x80); // Read command
NF_ADDR(Controller, 0);
//if(NAND_Inform[Controller].uNandType == NAND_Advanced8bit)
if(NAND_Inform[Controller].uAddrCycle == 5)
NF_ADDR(Controller, 0);
NF_ADDR(Controller, uBlockPage&0xff); //
NF_ADDR(Controller, (uBlockPage>>8)&0xff); // Block & Page num.
NF_ADDR(Controller, (uBlockPage>>16)&0xff); //
for(i=0 ; i<uPageSize/4 ; i++)
{
NF_WRDATA(Controller, *pBuffer++); // Write one page
}
NF_MECC_Lock(Controller);
for(i=0 ; i<uSpareSize; i++)
{
NF_WRDATA8(Controller, aNand_Spare_Data_Temp[i]); // The ECC value of the valid data
}
NF_CLEAR_RnB(Controller);
g_Nand_RnBTransition = 0;
NF_CMD(Controller, 0x10); // Write 2nd command
while(!g_Nand_RnBTransition);
//Read Program Status
NF_CMD(Controller, 0x70);
while(!((uStatus = NF_RDDATA8(Controller)) & (1<<6)));
if(uStatus & 0x01)
eError = eNAND_ProgramError; // Error in Program
else
eError = eNAND_NoError;
NF_nFCE_H(Controller);
uTemp = NAND_ReadNFCONRegister(Controller);
uTemp &= ~((1<<10) | (1<<9)); // Illegal Access & RnB Transition Interrupt disable
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
// rb1004 : must be modify...Interrupt Controller
//INT_Disable1(BIT_INT_NFC);
INTC_Disable(NUM_NFC);
// restore the valid data
if(uErrorType == NAND_ECCERR_1BIT)
{
pErrorBuffer[NAND_EccError.uEccErrByte1] ^= (1<<NAND_EccError.uEccErrBit1);
}
else if(uErrorType == NAND_ECCERR_MULTI)
{
pErrorBuffer[NAND_EccError.uEccErrByte1] ^= (1<<NAND_EccError.uEccErrBit1);
pErrorBuffer[NAND_EccError.uEccErrByte2] ^= (1<<NAND_EccError.uEccErrBit2);
}
return eError;
}
//////////
// Function Name : NAND_WritePageMLCWithInvalidData
// Function Description : This function write the 1 page invalid data to test ECC Error
// Input : Controller - Nand Controller Port Number
// uBlock - Write Block
// uPage - Write Page
// pBuffer - Write data buffer
// uErrorType - ECC Error Type
// Output : Nand Error Type
NAND_eERROR NAND_WritePageMLCWithInvalidData(u32 Controller, u32 uBlock, u32 uPage, u8 *pBuffer, u32 uErrorType)
{
u32 i, uBlockPage, uSpareSize, uTemp, uStatus;
u8 *pErrorBuffer;
NAND_eERROR eError;
u32 uDataPos[5]={0, }, uSparePos[5]={0, };
u32 uMLCECCErrBytePos[5]={0, };
u32 uMinusSpareArea;
pErrorBuffer = pBuffer;
g_Nand_IllegalAccError = 0;
uTemp = NAND_ReadNFCONRegister(Controller);
//uTemp |= (1<<13)|(1<<10)|(1<<9); // 4bit ECC encoding & Illegal Access & RnB Transition Interrupt enable
uTemp |= (1<<13)|(1<<12)|(1<<10)|(1<<9); // 4bit ECC encoding & Illegal Access & RnB Transition Interrupt enable..because error
uTemp |= (1<<18); // Encoding 4bit ECC selection
Outp32(&(NAND(Controller)->rNFCONT), uTemp);
Outp32(&(NAND(Controller)->rNFSTAT), (1<<7)); // 4bit ECC encoding finish bit clear
INTC_Enable(NUM_NFC);
uBlockPage=(uBlock<<7) + uPage;
uSpareSize = NAND_Inform[Controller].uSpareSize;
//////////////////////////
// Generate the Error Data
//////////////////////////
// The ECC value of valid data(512bytes) has in the aNand_Spare_Data_Temp[] array
if(uErrorType == NAND_ECCERR_1BIT)
{
uMLCECCErrBytePos[0] = NAND_Inform[Controller].uMLCECCErrBytePos[0]; // 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
uMinusSpareArea = NAND_Inform[Controller].uMLCECCPageWriteSector*NAND_MLC_ECC_SIZE;
uSparePos[0] = NAND_EccError.uEccErrByte1 - ((NAND_Inform[Controller].uMLCECCPageWriteSector+1)*NAND_MLC_TRANS_SIZE) + 1;
uDataPos[0] = NAND_EccError.uEccErrByte1 - uMinusSpareArea;
if( uMLCECCErrBytePos[0] < NAND_MLC_TRANS_SIZE)
pErrorBuffer[uDataPos[0]] ^= (1<<NAND_EccError.uEccErrBit1);
else
aNand_Spare_Data_Temp[uSparePos[0]] ^= (1<<NAND_EccError.uEccErrBit1);
}
else if(uErrorType == NAND_ECCERR_2BIT)
{
uMLCECCErrBytePos[0] = NAND_Inform[Controller].uMLCECCErrBytePos[0]; // 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
uMLCECCErrBytePos[1] = NAND_Inform[Controller].uMLCECCErrBytePos[1]; // 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
uMinusSpareArea = NAND_Inform[Controller].uMLCECCPageWriteSector*NAND_MLC_ECC_SIZE;
uSparePos[0] = NAND_EccError.uEccErrByte1 - ((NAND_Inform[Controller].uMLCECCPageWriteSector+1)*NAND_MLC_TRANS_SIZE) + 1;
uDataPos[0] = NAND_EccError.uEccErrByte1 - uMinusSpareArea;
uSparePos[1] = NAND_EccError.uEccErrByte2 - ((NAND_Inform[Controller].uMLCECCPageWriteSector+1)*NAND_MLC_TRANS_SIZE) + 1;
uDataPos[1] = NAND_EccError.uEccErrByte2 - uMinusSpareArea;
if( uMLCECCErrBytePos[0] < NAND_MLC_TRANS_SIZE)
pErrorBuffer[uDataPos[0]] ^= (1<<NAND_EccError.uEccErrBit1);
else
aNand_Spare_Data_Temp[uSparePos[0]] ^= (1<<NAND_EccError.uEccErrBit1);
if( uMLCECCErrBytePos[1] < NAND_MLC_TRANS_SIZE)
pErrorBuffer[uDataPos[1]] ^= (1<<NAND_EccError.uEccErrBit2);
else
aNand_Spare_Data_Temp[uSparePos[1]] ^= (1<<NAND_EccError.uEccErrBit2);
}
else if(uErrorType == NAND_ECCERR_3BIT)
{
uMLCECCErrBytePos[0] = NAND_Inform[Controller].uMLCECCErrBytePos[0]; // 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
uMLCECCErrBytePos[1] = NAND_Inform[Controller].uMLCECCErrBytePos[1]; // 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
uMLCECCErrBytePos[2] = NAND_Inform[Controller].uMLCECCErrBytePos[2]; // 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
uMinusSpareArea = NAND_Inform[Controller].uMLCECCPageWriteSector*NAND_MLC_ECC_SIZE;
uSparePos[0] = NAND_EccError.uEccErrByte1 - ((NAND_Inform[Controller].uMLCECCPageWriteSector+1)*NAND_MLC_TRANS_SIZE) + 1;
uDataPos[0] = NAND_EccError.uEccErrByte1 - uMinusSpareArea;
uSparePos[1] = NAND_EccError.uEccErrByte2 - ((NAND_Inform[Controller].uMLCECCPageWriteSector+1)*NAND_MLC_TRANS_SIZE) + 1;
uDataPos[1] = NAND_EccError.uEccErrByte2 - uMinusSpareArea;
uSparePos[2] = NAND_EccError.uEccErrByte3 - ((NAND_Inform[Controller].uMLCECCPageWriteSector+1)*NAND_MLC_TRANS_SIZE) + 1;
uDataPos[2] = NAND_EccError.uEccErrByte3 - uMinusSpareArea;
if( uMLCECCErrBytePos[0] < NAND_MLC_TRANS_SIZE)
pErrorBuffer[uDataPos[0]] ^= (1<<NAND_EccError.uEccErrBit1);
else
aNand_Spare_Data_Temp[uSparePos[0]] ^= (1<<NAND_EccError.uEccErrBit1);
if( uMLCECCErrBytePos[1] < NAND_MLC_TRANS_SIZE)
pErrorBuffer[uDataPos[1]] ^= (1<<NAND_EccError.uEccErrBit2);
else
aNand_Spare_Data_Temp[uSparePos[1]] ^= (1<<NAND_EccError.uEccErrBit2);
if( uMLCECCErrBytePos[2] < NAND_MLC_TRANS_SIZE)
pErrorBuffer[uDataPos[2]] ^= (1<<NAND_EccError.uEccErrBit3);
else
aNand_Spare_Data_Temp[uSparePos[2]] ^= (1<<NAND_EccError.uEccErrBit3);
}
else if(uErrorType == NAND_ECCERR_4BIT)
{
uMLCECCErrBytePos[0] = NAND_Inform[Controller].uMLCECCErrBytePos[0]; // 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
uMLCECCErrBytePos[1] = NAND_Inform[Controller].uMLCECCErrBytePos[1]; // 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
uMLCECCErrBytePos[2] = NAND_Inform[Controller].uMLCECCErrBytePos[2]; // 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExcep
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -