📄 s3c2450_fil.c
字号:
UINT32 i;
#ifdef USE_SETKMODE
BOOL bLastMode;
#endif
NAND_MSG((_T("[FIL]++Read_DeviceID(%d)\r\n"), nBank));
#ifdef USE_SETKMODE
bLastMode = SetKMode(TRUE);
#endif
// Chip Select
NF_CE_L(nBank);
NF_WAIT_RnB(nBank);
// Read ID Command
NF_CMD(CMD_READ_ID);
NF_ADDR(0x00);
// Find Maker Code
for (i=0; i<5; i++)
{
nMID = NF_DATA_R(); // Maker Code
if (nMID == 0xEC) break;
}
// Read Device Code
nDID = NF_DATA_R(); // Device Code
nHID[0] = NF_DATA_R(); // Internal Chip Number
nHID[1] = NF_DATA_R(); // Page, Block, Redundant Area Size
nHID[2] = NF_DATA_R(); // Plane Number, Size
// Chip Unselect
NF_CE_H(nBank);
#ifdef USE_SETKMODE
SetKMode(bLastMode);
#endif
for (nScanIdx = 0; nScanIdx < sizeof(stDEVInfo)/sizeof(DEVInfo); nScanIdx++)
{
if ((nMID == (UINT8)0xEC) && (nDID == stDEVInfo[nScanIdx].nDevID) && (nHID[0] == stDEVInfo[nScanIdx].nHidID))
{
*pDID = nDID;
*pHID = nHID[0];
NAND_LOG((_T("[FIL] ################\r\n")));
NAND_LOG((_T("[FIL] MID = 0x%02x\r\n"), nMID));
NAND_LOG((_T("[FIL] DID = 0x%02x\r\n"), nDID));
NAND_LOG((_T("[FIL] HID[0] = 0x%02x\r\n"), nHID[0]));
NAND_LOG((_T("[FIL] HID[1] = 0x%02x\r\n"), nHID[1]));
NAND_LOG((_T("[FIL] HID[2] = 0x%02x\r\n"), nHID[2]));
NAND_LOG((_T("[FIL] ################\r\n")));
NAND_MSG((_T("[FIL] Bank %d Detect\r\n"), nBank));
return nScanIdx;
}
}
*pDID = 0x00;
*pHID = 0x00;
NAND_MSG((_T("[FIL]--Read_DeviceID()\r\n")));
return FIL_CRITICAL_ERROR;
}
PRIVATE UINT32
Read_Sector(UINT32 nBank, UINT32 nPpn, UINT32 nSctOffset, UINT8* pBuf, UINT32* pSpareCxt, BOOL32 bCheckAllFF)
{
UINT32 nOffSet;
UINT32 nRet = 0;
UINT32 nMECC[2];
NAND_MSG((_T("[FIL]++Read_Sector(%d, %d)\r\n"), nPpn, nSctOffset));
// Move pointer to Sector Offset
nOffSet = nSctOffset * NAND_SECTOR_SIZE;
// Random data output command
NF_CMD(CMD_RANDOM_DATA_OUTPUT);
NF_ADDR(nOffSet&0xFF);
NF_ADDR((nOffSet>>8)&0xFF);
NF_CMD(CMD_RANDOM_DATA_OUTPUT_CONFIRM);
// Initialize 4-bit ECC Decoding
NF_SET_ECC_DEC();
NF_MECC_Reset();
NF_MECC_UnLock();
// Read 512 bytes Sector data
#if (NAND_TRANS_MODE == ASM)
if ((UINT32)pBuf&0x3)
{
_Read_512Byte_Unaligned(pBuf+NAND_SECTOR_SIZE*nSctOffset);
}
else
{
_Read_512Byte(pBuf+NAND_SECTOR_SIZE*nSctOffset);
}
#elif (NAND_TRANS_MODE == DMA)
Read_512Byte_DMA(pBuf+NAND_SECTOR_SIZE*nSctOffset);
#endif
//NF_MECC_Lock(); // Do NOT Lock MECC when using 4-bit ECC Decoding
NF_CLEAR_ECC_DEC_DONE();
NF_CE_H(nBank);
NF_SET_CLK(DUMMY_R_TACLS, DUMMY_R_TWRPH0, DUMMY_R_TWRPH1); // Don't set clk to (0, 0, 0) !!! Decoding error occurs
// Instead of Read Main ECC from NAND, Write Main ECC with CE don't care
if (bCheckAllFF)
{
NF_DATA_W4(ECCVAL_ALLFF0); // All 0xFF ECC
NF_DATA_W4(ECCVAL_ALLFF1);
}
else
{
nMECC[0] = pSpareCxt[(((SECTORS_PER_PAGE==4)?NAND_MECC_OFFSET:NAND_MECC_OFFSET_4K)/4)+nSctOffset*2];
nMECC[1] = pSpareCxt[(((SECTORS_PER_PAGE==4)?NAND_MECC_OFFSET:NAND_MECC_OFFSET_4K)/4)+nSctOffset*2+1];
NF_DATA_W4(nMECC[0]); // pSpareCxt->aMECC[nSctOffset*2]
NF_DATA_W4(nMECC[1]); // pSpareCxt->aMECC[nSctOffset*2+1]
}
NF_SET_CLK(DEFAULT_TACLS, DEFAULT_TWRPH0, DEFAULT_TWRPH1);
NF_CE_L(nBank);
// Waiting for Main ECC compare
NF_WAIT_ECC_DEC_DONE();
nRet = Decoding_MainECC(pBuf+NAND_SECTOR_SIZE*nSctOffset);
if (nRet&ECC_MODULE_ERROR)
{
NAND_MSG((_T("[FIL:ERR] Read_Sector() : ECC Module Error in Page %d Sector %d\r\n"), nPpn, nSctOffset));
nRet = Read_Sector2(nBank, pBuf+NAND_SECTOR_SIZE*nSctOffset, bCheckAllFF, nMECC);
if (nRet & ECC_MODULE_ERROR) nRet &= ~ECC_MODULE_ERROR;
}
if (nRet&ECC_UNCORRECTABLE_ERROR)
{
NAND_ERR((_T("[FIL:ERR] Read_Sector() : ECC Uncorrectable Error in Page %d Sector %d\r\n"), nPpn, nSctOffset));
}
else if (nRet&ECC_CORRECTABLE_ERROR)
{
NAND_MSG((_T("[FIL] Read_Sector() : ECC Correctable Error in Page %d Sector %d\r\n"), nPpn, nSctOffset));
}
NAND_MSG((_T("[FIL]--Read_Sector()\r\n")));
return nRet;
}
PRIVATE UINT32
Read_Sector2(UINT32 nBank, UINT8* pBuf, BOOL32 bCheckAllFF, UINT32 nMECC[2])
{
UINT32 nRet = 0;
NAND_MSG((_T("[FIL]++Read_Sector2\r\n")));
// Initialize 4-bit ECC Decoding
NF_SET_ECC_DEC();
NF_MECC_Reset();
NF_MECC_UnLock();
NF_CE_H(nBank);
NF_SET_CLK(DUMMY_R_TACLS, DUMMY_R_TWRPH0, DUMMY_R_TWRPH1);
if ((UINT32)pBuf&0x3)
{
_Write_512Byte_Unaligned(pBuf);
}
else
{
_Write_512Byte(pBuf);
}
// Read Main ECC
NF_CLEAR_ECC_DEC_DONE();
// Instead of Read Main ECC from NAND, Write Main ECC with CE don't care
if (bCheckAllFF)
{
NF_DATA_W4(ECCVAL_ALLFF0); // All 0xFF ECC
NF_DATA_W4(ECCVAL_ALLFF1);
}
else
{
NF_DATA_W4(nMECC[0]);
NF_DATA_W4(nMECC[1]);
}
// Wait Spare ECC Compare Done
NF_WAIT_ECC_DEC_DONE();
NF_SET_CLK(DEFAULT_TACLS, DEFAULT_TWRPH0, DEFAULT_TWRPH1);
NF_CE_L(nBank);
nRet = Decoding_MainECC(pBuf);
NAND_MSG((_T("[FIL]--Read_Sector2(), nRet = 0x%x\r\n"), nRet));
return nRet;
}
PRIVATE UINT32
Read_Spare(UINT32 nBank, UINT32 nPpn, UINT32* pSpareCxt)
{
UINT32 nOffset;
UINT32 nRet = 0;
BOOL32 bCheckMore = FALSE32;
BOOL32 bCheckAllFF = FALSE32;
UINT32 nCnt;
UINT32 nPosPtr;
UINT8 cCleanMark;
UINT8* pSBuf;
NAND_MSG((_T("[FIL]++Read_Spare(%d)\r\n"), nPpn));
// Read Spare Area
pSpareCxt[0] = NF_DATA_R4(); // 1 byte Bad Mark(->cBadMark) + 1 byte Clean Mark(->cCleanMark) + 2 byte Reserved(->cReserved)
//NAND_MSG((_T("[FIL]++Read_Spare_MLC_2(%d)\r\n"), nPpn));
if (IS_CHECK_SPARE_ECC == TRUE32)
{
// Initialize 4-bit ECC Decoding
NF_SET_ECC_DEC();
NF_MECC_Reset();
NF_MECC_UnLock();
//NAND_MSG((_T("[FIL]++Read_Spare_MLC_2_1(%d)\r\n"), nPpn));
cCleanMark = (UINT8)((pSpareCxt[0]&0xff00)>>8); // ->cCleanMark
if (WMR_GetChkSum(&cCleanMark, 1) < 4)
{
bCheckAllFF = TRUE32;
}
}
//NAND_MSG((_T("[FIL]++Read_Spare_MLC_3(%d)\r\n"), nPpn));
nPosPtr = NAND_SCXT_OFFSET/4;
if (SECTORS_PER_PAGE == 4)
{
for (nCnt = 0; nCnt < (NAND_SECC_OFFSET-NAND_SCXT_OFFSET)/4; nCnt++)
pSpareCxt[nPosPtr++] = NF_DATA_R4(); // 12 byte Spare Context(->aSpareData) + 32 byte Sector ECC data(->aMECC)
}
else if (SECTORS_PER_PAGE == 8)
{
for (nCnt = 0; nCnt < (NAND_SECC_OFFSET_4K-NAND_SCXT_OFFSET)/4; nCnt++)
pSpareCxt[nPosPtr++] = NF_DATA_R4(); // 20 byte Spare Context(->aSpareData) + 64 byte Sector ECC data(->aMECC)
}
else
{
WMR_ASSERT(FALSE32);
}
// NAND_MSG((_T("[FIL]++Read_Spare_MLC_4(%d)\r\n"), nPpn));
if (IS_CHECK_SPARE_ECC == TRUE32)
{
NF_CE_H(nBank);
NF_SET_CLK(DUMMY_R_TACLS, DUMMY_R_TWRPH0, DUMMY_R_TWRPH1); // Don't set clk to (0, 0, 0) !!! Decoding error occurs
#if (NAND_TRANS_MODE == ASM)
if (SECTORS_PER_PAGE == 4)
{
_Write_Dummy_468Byte_AllFF();
}
else if (SECTORS_PER_PAGE == 8)
{
_Write_Dummy_428Byte_AllFF();
}
#elif (NAND_TRANS_MODE == DMA)
Write_Dummy_468Byte_AllFF_DMA();
#endif
//NAND_MSG((_T("[FIL]++Read_Spare_MLC_5(%d)\r\n"), nPpn));
NF_SET_CLK(DEFAULT_TACLS, DEFAULT_TWRPH0, DEFAULT_TWRPH1);
NF_CE_L(nBank);
//NF_MECC_Lock(); // Do NOT Lock MECC when using 4-bit ECC Decoding
// Read Spare ECC
NF_CLEAR_ECC_DEC_DONE();
if (bCheckAllFF)
{
NF_CE_H(nBank);
NF_SET_CLK(DUMMY_R_TACLS, DUMMY_R_TWRPH0, DUMMY_R_TWRPH1); // Don't set clk to (0, 0, 0) !!! Decoding error occurs
NF_DATA_W4(ECCVAL_ALLFF0); // All 0xFF ECC
NF_DATA_W4(ECCVAL_ALLFF1);
NF_SET_CLK(DEFAULT_TACLS, DEFAULT_TWRPH0, DEFAULT_TWRPH1);
NF_CE_L(nBank);
}
else
{
pSpareCxt[nPosPtr++] = NF_DATA_R4(); // Read 8 byte Spare ECC data, ->ASECC[0]
pSpareCxt[nPosPtr++] = NF_DATA_R4(); // Actually after read 7th byte, ECC decoding starts!!, ->ASECC[1]
}
// Wait Spare ECC Compare Done
NF_WAIT_ECC_DEC_DONE();
//NAND_MSG((_T(" dbg(0x%x), Cnt : %d\r\n"), pNANDFConReg->NFSTAT,i));
pSBuf = &(pSpareCxt[NAND_SCXT_OFFSET/4]);
nRet = Decoding_SpareECC(pSBuf);
if (bCheckAllFF)
{
pSpareCxt[nPosPtr++] = NF_DATA_R4(); // Read 8 byte Spare ECC data ->ASECC[0]
pSpareCxt[nPosPtr++] = NF_DATA_R4(); // Actually after read 7th byte, ECC decoding starts!! ->ASECC[1]
// NAND_MSG((_T("[FIL]++Read_Spare_MLC_8(%d)\r\n"), nPpn));
}
pSpareCxt[nPosPtr++] = NF_DATA_R4(); // Read 2nd Spare ECC ->ASECC[2]
pSpareCxt[nPosPtr++] = NF_DATA_R4(); // Actually after read 7th byte, ECC decoding starts!! ->ASECC[3]
//NAND_MSG((_T("[FIL]++Read_Spare_MLC_9(%d)\r\n"), nPpn));
_B_CheckMore:
// 2nd Try
if (nRet == ECC_UNCORRECTABLE_ERROR)
{
NAND_ERR((_T("[FIL:ERR] Read_Spare() : ECC Uncorrectable Error in Spare of Page %d 1st Time : 0x%x\r\n"), nPpn, nRet));
if (bCheckMore == TRUE32) NAND_ERR((_T("[FIL:ERR] Read_Spare() : Try ECC Decoding again with 2nd SECC copy\r\n")));
else NAND_ERR((_T("[FIL:ERR] Read_Spare() : Try ECC Decoding again with SECC bit change\r\n")));
nOffset = BYTES_PER_MAIN_PAGE+NAND_SCXT_OFFSET; // Position to SpareData
NF_CMD(CMD_RANDOM_DATA_OUTPUT);
NF_ADDR(nOffset&0xFF);
NF_ADDR((nOffset>>8)&0xFF);
NF_CMD(CMD_RANDOM_DATA_OUTPUT_CONFIRM);
// Initialize 4-bit ECC Decoding
NF_SET_ECC_DEC();
NF_MECC_Reset();
NF_MECC_UnLock();
nPosPtr = NAND_SCXT_OFFSET/4;
if (SECTORS_PER_PAGE == 4)
{
for (nCnt = 0; nCnt < (NAND_SECC_OFFSET-NAND_SCXT_OFFSET)/4; nCnt++)
pSpareCxt[nPosPtr++] = NF_DATA_R4(); // 12 byte Spare Context(->aSpareData) + 32 byte Sector ECC data(->aMECC)
}
if (SECTORS_PER_PAGE == 8)
{
for (nCnt = 0; nCnt < (NAND_SECC_OFFSET_4K-NAND_SCXT_OFFSET)/4; nCnt++)
pSpareCxt[nPosPtr++] = NF_DATA_R4(); // 20 byte Spare Context(->aSpareData) + 64 byte Sector ECC data(->aMECC)
}
NF_CE_H(nBank);
NF_SET_CLK(DUMMY_R_TACLS, DUMMY_R_TWRPH0, DUMMY_R_TWRPH1); // Don't set clk to (0, 0, 0) !!! Decoding error occurs
#if (NAND_TRANS_MODE == ASM)
if (SECTORS_PER_PAGE == 4)
{
_Write_Dummy_468Byte_AllFF();
}
else if (SECTORS_PER_PAGE == 8)
{
_Write_Dummy_428Byte_AllFF();
}
#elif (NAND_TRANS_MODE == DMA)
Write_Dummy_468Byte_AllFF_DMA();
#endif
//NF_MECC_Lock(); // Do NOT Lock MECC when using 4-bit ECC Decoding
NF_CLEAR_ECC_DEC_DONE();
if (bCheckMore == TRUE32)
{
NF_DATA_W4(pSpareCxt[(((SECTORS_PER_PAGE==4)?NAND_SECC2_OFFSET:NAND_SECC2_OFFSET_4K)/4)]); // Write 2nd Spare ECC, ->aSECC[2]
NF_DATA_W4(pSpareCxt[(((SECTORS_PER_PAGE==4)?NAND_SECC2_OFFSET:NAND_SECC2_OFFSET_4K)/4)+1]); // Actually after read 7th byte, ECC decoding starts!! ->aSECC[3]
bCheckMore = FALSE32;
}
else
{
NF_DATA_W4(pSpareCxt[(((SECTORS_PER_PAGE==4)?NAND_SECC_OFFSET:NAND_SECC_OFFSET_4K)/4)]); // Write modified ECC for the 53th bit on SECC data ->aSECC[0]
NF_DATA_W4((pSpareCxt[(((SECTORS_PER_PAGE==4)?NAND_SECC_OFFSET:NAND_SECC_OFFSET_4K)/4)])^(1<<19)); // position to be modified on SECC[1] ->aSECC[1]
bCheckMore = TRUE32;
}
NF_SET_CLK(DEFAULT_TACLS, DEFAULT_TWRPH0, DEFAULT_TWRPH1);
NF_CE_L(nBank);
// Wait Spare ECC Compare Done
NF_WAIT_ECC_DEC_DONE();
nRet = Decoding_SpareECC((UINT8 *)pSpareCxt[NAND_SCXT_OFFSET/4]); // ->aSpareData
if (bCheckMore == TRUE32)
goto _B_CheckMore;
}
}
else
{
// just read Spare ECC from NAND for read pointer, NOT decoding ECC
pSpareCxt[nPosPtr++] = NF_DATA_R4(); // 8 byte Spare ECC data, ->aSECC[0]
pSpareCxt[nPosPtr++] = NF_DATA_R4();
pSpareCxt[nPosPtr++] = NF_DATA_R4(); // 8 byte Spare ECC data 2nd copy ->aSECC[2]
pSpareCxt[nPosPtr++] = NF_DATA_R4();
}
if (nRet&ECC_UNCORRECTABLE_ERROR)
{
NAND_ERR((_T("[FIL:ERR] Read_Spare() : ECC Uncorrectable Error in Spare of Page %d\r\n"), nPpn));
}
else if (nRet&ECC_CORRECTABLE_ERROR)
{
NAND_MSG((_T("[FIL] Read_Spare() : ECC Correctable Error in Spare of Page %d\r\n"), nPpn));
}
NAND_MSG((_T("[FIL]--Read_Spare()\r\n")));
return nRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -