📄 nand_test.c
字号:
}
eError = NAND_EraseMultiBlock(g_NandContNum, uBlock, uBlockNum);
if(eError != eNAND_NoError)
{
NANDT_PrintErrorType(eError);
UART_Getc();
}
else
{
if(eTest == eTest_Manual)
UART_Printf("NAND Erase Block[%d ~ %d Block] : Success\n\n", uBlock, uBlock+uBlockNum-1);
}
}
const AutotestFuncMenu nand_erase_menu[] =
{
NANDT_EraseSingleBlock, "Single Block Erase ",
NANDT_EraseMultiBlock, "Multi Block Erase ",
0, 0
};
void NANDT_Erase(void)
{
u32 i;
s32 uSel;
oFunctionT_AutoVar oAutoTest;
UART_Printf("\n[NANDT_Erase]\n");
while(1)
{
UART_Printf("\n");
for (i=0; (u32)(nand_erase_menu[i].desc)!=0; i++)
UART_Printf("%2d: %s\n", i, nand_erase_menu[i].desc);
UART_Printf("\nSelect the function to test : ");
uSel =UART_GetIntNum();
UART_Printf("\n");
if(uSel == -1)
break;
if (uSel>=0 && uSel<(sizeof(nand_erase_menu)/8-1))
(nand_erase_menu[uSel].func) (eTest_Manual, oAutoTest);
}
}
//////////
// Function Name : NANDT_ProgramBinary
// Function Description : Write the Binary file to NAND Memory(ex. Boot Code)
// Input : None
// Output : None
void NANDT_ProgramBinary(void)
{
u32 j, uBlock, uPage, uSize;
u8 *uSourceAddr;
u32 uWriteBlock, uWritePage, uPageNumToWrite, uRemainedPage;
bool bWriteEnd;
u8 aSpareBuffer[NAND_SPARE_MAX];
NAND_eERROR eError;
UART_Printf("[NANDT_ProgramBinary]\n\n");
uSourceAddr = (u8 *)(_DRAM_BaseAddress+0x00a00000);
UART_Printf("Caution : You must put BINARY file into 0x%08x before programming\n",uSourceAddr);
UART_Printf("Input the Block Number to write[0~%d]", NAND_Inform[g_NandContNum].uBlockNum-1);
uBlock = UART_GetIntNum();
UART_Printf("Input the Page Number to write[0~%d]", NAND_Inform[g_NandContNum].uPageNum-1);
uPage = UART_GetIntNum();
UART_Printf("Input the Size to program[Bytes] : ");
uSize = UART_GetIntNum();
uPageNumToWrite = uSize/NAND_Inform[g_NandContNum].uPageSize;
if(uSize%NAND_Inform[g_NandContNum].uPageSize)
uPageNumToWrite++;
uRemainedPage = uPageNumToWrite;
uWriteBlock = uBlock;
uWritePage = uPage;
bWriteEnd = FALSE;
while(1)
{
// Invalid Block Check
eError = NAND_CheckInvalidBlock(g_NandContNum, uWriteBlock);
while(eError != eNAND_NoError)
{
NANDT_PrintErrorType(eError);
UART_Printf("Block Number: %d\n", uWriteBlock);
uWriteBlock++; // for next block
eError = NAND_CheckInvalidBlock(g_NandContNum, uWriteBlock);
}
// Erase Block
eError = NAND_EraseSingleBlock(g_NandContNum, uWriteBlock);
while(eError != eNAND_NoError)
{
NANDT_PrintErrorType(eError);
UART_Printf("Block Number: %d\n", uWriteBlock);
uWriteBlock++; // for next block
eError = NAND_CheckInvalidBlock(g_NandContNum, uWriteBlock);
}
// Write Block
for(j=uWritePage ; j<NAND_Inform[g_NandContNum].uPageNum ; j++)
{
eError = NAND_WritePage(g_NandContNum, uWriteBlock, j, uSourceAddr, aSpareBuffer);
if(eError != eNAND_NoError)
{
NANDT_PrintErrorType(eError);
break;
}
uRemainedPage--;
if(uRemainedPage == 0)
{
bWriteEnd = TRUE;
break;
}
uSourceAddr += NAND_Inform[g_NandContNum].uPageSize;
}
if(bWriteEnd == TRUE)
break;
uWritePage = 0;
uWriteBlock++;
UART_Printf(".");
}
UART_Printf("\n");
UART_Printf("NAND Program Complete\n\n");
}
//////////
// Function Name : NANDT_SoftLock
// Function Description : Soft-lock the NAND Memory
// Input : None
// Output : None
void NANDT_SoftLock(void)
{
u32 uStartBlock, uEndBlock;
NAND_eERROR eError;
UART_Printf("[NANDT_SoftLock]\n\n");
UART_Printf("Input the Start Block Number to soft-lock[0~%d]", NAND_Inform[g_NandContNum].uBlockNum-1);
uStartBlock = UART_GetIntNum();
UART_Printf("Input the End Block Number to soft-lock[%d~%d]", uStartBlock, NAND_Inform[g_NandContNum].uBlockNum-1);
uEndBlock = UART_GetIntNum();
eError = NAND_SoftLockingBlock(g_NandContNum, uStartBlock, uEndBlock);
if(eError != eNAND_NoError)
{
UART_Printf("NAND Soft-Lock Block Error.....!!\n\n");
UART_Getc();
}
else
UART_Printf("NAND Soft-Lock Block Complete[except %d ~ %d Block]\n\n", uStartBlock, uEndBlock);
}
//////////
// Function Name : NANDT_LockTight
// Function Description : Lock-tight the NAND Memory
// Input : None
// Output : None
void NANDT_LockTight(void)
{
u32 uStartBlock, uEndBlock;
NAND_eERROR eError;
UART_Printf("[NANDT_LockTight]\n\n");
UART_Printf("Input the Start Block Number to lock-tight[0~%d]", NAND_Inform[g_NandContNum].uBlockNum-1);
uStartBlock = UART_GetIntNum();
UART_Printf("Input the End Block Number to lock-tight[%d~%d]", uStartBlock, NAND_Inform[g_NandContNum].uBlockNum-1);
uEndBlock = UART_GetIntNum();
eError = NAND_LockTightBlock(g_NandContNum, uStartBlock, uEndBlock);
if(eError != eNAND_NoError)
{
UART_Printf("NAND Lock-tight Block Error.....!!\n\n");
UART_Getc();
}
else
UART_Printf("NAND Lock-tight Block Complete[except %d ~ %d Block]\n\n", uStartBlock, uEndBlock);
}
//////////
// Function Name : NANDT_DisableSoftLock
// Function Description : Disable Soft-lock of the NAND Memory
// Input : None
// Output : None
void NANDT_DisableSoftLock(void)
{
NAND_eERROR eError;
UART_Printf("[NANDT_DisableSoftLock]\n\n");
eError = NAND_UnLockBlock(g_NandContNum);
if(eError != eNAND_NoError)
{
UART_Printf("UnLock the Soft-locked Block Error.....!!\n\n");
UART_Getc();
}
else
UART_Printf("UnLock the Soft-locked Block Complete\n\n");
}
//////////
// Function Name : NANDT_DisableLockTight
// Function Description : Disable Lock-tight of the NAND Memory
// Input : None
// Output : None
void NANDT_DisableLockTight(void)
{
NAND_eERROR eError;
UART_Printf("[NANDT_DisableLockTight]\n\n");
eError = NAND_UnLockTightBlock(g_NandContNum);
if(eError != eNAND_NoError)
{
UART_Printf("Fail - cleared Lock-tight bit by software\n\n");
UART_Getc();
}
else
UART_Printf("Success - not cleared Lock-tight bit by software\n\n");
}
const testFuncMenu nandlock_menu[] =
{
NANDT_SoftLock, "Soft Lock ",
NANDT_LockTight, "Lock Tight ",
NANDT_DisableSoftLock, "Soft Unlock ",
NANDT_DisableLockTight, "Lock-tight Unlock ",
0, 0
};
void NANDT_LockUnlock(void)
{
u32 i;
s32 uSel;
while(1)
{
for (i=0; (u32)(nandlock_menu[i].desc)!=0; i++)
UART_Printf("%2d: %s\n", i, nandlock_menu[i].desc);
UART_Printf("\nSelect the function to test : ");
uSel =UART_GetIntNum();
UART_Printf("\n");
if(uSel == -1)
break;
if (uSel>=0 && uSel<(sizeof(nandlock_menu)/8-1))
(nandlock_menu[uSel].func) ();
}
}
//////////
// Function Name : NANDT_SLCECC
// Function Description : SLC ECC function test
// Input : None
// Output : None
void NANDT_SLCECC(void)
{
u32 i, uBlock, uPage, uError, uErrorType;
u8 aBuffer[NAND_PAGE_MAX];
u8 aSpareBuffer[NAND_SPARE_MAX];
NAND_eERROR eError;
UART_Printf("[NANDT_SLCECC]\n");
if(NAND_Inform[g_NandContNum].uNandType == NAND_MLC8bit)
{
UART_Printf("The current Nand Memory is MLC type.....!!\n\n");
return;
}
UART_Printf("Input the Block Number to test[0~%d]", NAND_Inform[g_NandContNum].uBlockNum-1);
uBlock = UART_GetIntNum();
UART_Printf("Input the Page Number to test[0~%d]", NAND_Inform[g_NandContNum].uPageNum-1);
uPage = UART_GetIntNum();
UART_Printf("Input the ECC Error Type\n");
UART_Printf("1: 1bit error(D), 2: multiple error\n");
uError = UART_GetIntNum();
switch(uError)
{
case 1 : uErrorType = NAND_ECCERR_1BIT;
break;
case 2 : uErrorType = NAND_ECCERR_MULTI;
break;
default : uErrorType = NAND_ECCERR_1BIT;
break;
}
srand(0);
for(i=0 ; i<NAND_Inform[g_NandContNum].uPageSize ; i++)
{
aBuffer[i] = rand()%0xFF;
}
for(i=0 ; i<NAND_Inform[g_NandContNum].uSpareSize ; i++)
aSpareBuffer[i] = 0xFF;
NAND_EccError.uEccErrByte1 = 100;
NAND_EccError.uEccErrBit1 = 0;
NAND_EccError.uEccErrByte2 = 200;
NAND_EccError.uEccErrBit2 = 0;
UART_Printf("\n");
UART_Printf("The specific bit ecc check : [%dByte : %dBit]\n", NAND_EccError.uEccErrByte1, NAND_EccError.uEccErrBit1);
if(uErrorType == NAND_ECCERR_MULTI)
UART_Printf("The specific bit ecc check : [%dByte : %dBit]\n", NAND_EccError.uEccErrByte2, NAND_EccError.uEccErrBit2);
UART_Printf("\n");
// Erase Block for test
UART_Printf("Erase the block ( %d[block] )\n", uBlock);
eError = NAND_EraseSingleBlock(g_NandContNum, uBlock);
if(eError != eNAND_NoError)
{
NANDT_PrintErrorType(eError);
UART_Getc();
return;
}
NAND_Inform[g_NandContNum].uECCtest = 1;
NAND_Inform[g_NandContNum].uAllBitEccCheck = 0;
// Write the valid data to page 0 ( uBlock[block] 0[page] ) ...for ECC generation
UART_Printf("Write the valid data to page ( %d[block] %d[page] )\n", uBlock, uPage);
eError = NAND_WritePage(g_NandContNum, uBlock, uPage, aBuffer, aSpareBuffer);
if(eError != eNAND_NoError)
{
NANDT_PrintErrorType(eError);
UART_Getc();
NAND_Inform[g_NandContNum].uECCtest = 0;
return;
}
// Erase Block for test
UART_Printf("Erase the block ( %d[block] )\n", uBlock);
eError = NAND_EraseSingleBlock(g_NandContNum, uBlock);
if(eError != eNAND_NoError)
{
NANDT_PrintErrorType(eError);
UART_Getc();
NAND_Inform[g_NandContNum].uECCtest = 0;
return;
}
//uPage++;
// Write the invalid data to page( uBlock[block] 1[page] )....with Invalid Main Data0
UART_Printf("Write the invalid data to page ( %d[block] %d[page] )\n", uBlock, uPage);
eError = NAND_WritePageWithInvalidData(g_NandContNum, uBlock, uPage, aBuffer, uErrorType);
if(eError != eNAND_NoError)
{
NANDT_PrintErrorType(eError);
UART_Getc();
NAND_Inform[g_NandContNum].uECCtest = 0;
return;
}
// Read the invalid data to detect the ECC error
UART_Printf("Read the invalid data to page ( %d[block] %d[page] )\n", uBlock, uPage);
eError = NAND_ReadPage(g_NandContNum, uBlock, uPage, aBuffer, aSpareBuffer);
UART_Printf("\n");
if(eError != eNAND_NoError)
{
NANDT_PrintErrorType(eError);
}
NAND_Inform[g_NandContNum].uECCtest = 0;
UART_Printf("SLC Nand ECC test complete\n");
UART_Printf("\n");
}
//////////
// Function Name : NANDT_SLCSpareECC
// Function Description : SLC Spare ECC function test
// Input : None
// Output : None
void NANDT_SLCSpareECC(void)
{
u32 i, uBlock, uPage, uError, uErrorType;
u8 aBuffer[NAND_PAGE_MAX];
u8 aSpareBuffer[NAND_SPARE_MAX];
NAND_eERROR eError;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -