📄 s3c2450_fil.c
字号:
//CommentPilsun
if (IS_CHECK_SPARE_ECC == TRUE32)
{
NF_SECC_Lock();
}
//CommentPilsun
//Only Use 4Byte for SLC ECC
NF_DATA_W4(pSpareCxt->aMECC[0]); // 4 byte Sector0 ECC data
NF_DATA_W4(pSpareCxt->aMECC[1]); // 4 byte Sector1 ECC data
NF_DATA_W4(pSpareCxt->aMECC[2]); // 4 byte Sector2 ECC data
NF_DATA_W4(pSpareCxt->aMECC[3]); // 4 byte Sector3 ECC data
NF_DATA_W4(pSpareCxt->aMECC[4]); // 4 byte Sector4 ECC data
NF_DATA_W4(pSpareCxt->aMECC[5]); // 4 byte Sector5 ECC data
NF_DATA_W4(pSpareCxt->aMECC[6]); // 4 byte Sector6 ECC data
NF_DATA_W4(pSpareCxt->aMECC[7]); // 4 byte Sector7 ECC data
NF_DATA_W4(0xffffffff); // 4 byte dummy ECC data
NF_DATA_W4(0xffffffff); // 4 byte dummy ECC data
NF_DATA_W4(0xffffffff); // 4 byte dummy ECC data
NF_DATA_W4(0xffffffff); // 4 byte dummy ECC data
NF_DATA_W4(0xffffffff); // 4 byte dummy ECC data
NF_DATA_W4(0xffffffff); // 4 byte dummy ECC data
NF_DATA_W4(0xffffffff); // 4 byte dummy ECC data
NF_DATA_W4(0xffffffff); // 4 byte dummy ECC data
}
else
{
WMR_ASSERT(FALSE32);
}
if (IS_CHECK_SPARE_ECC == TRUE32)
{
pSpareCxt->aSECC[0] = NF_SECC(); // Spare ECC x 2 copies
}
NF_DATA_W4(pSpareCxt->aSECC[0]); // Spare ECC 4 bytes
NF_DATA_W4(0xffffffff); // dummy ECC 4 bytes
NF_DATA_W4(0xffffffff); // dummy ECC 4 bytes
NF_DATA_W4(0xffffffff); // dummy ECC 4 bytes
NAND_MSG((_T("[FIL]--Write_Spare()\r\n")));
return;
}
PRIVATE UINT32
Decoding_MainECC(UINT8* pBuf)
{
UINT32 nError0, nError1;
UINT32 nErrorCnt, nErrorByte, nErrorPattern;
UINT32 nRet = 0;
NAND_MSG((_T("[FIL]++Decoding_MainECC()\r\n")));
nError0 = NF_ECC_ERR0();
nError1 = NF_ECC_ERR1();
//NAND_MSG((_T("[FIL] NF_ECC_ERR0 = 0x%08x()\r\n"), nError0));
//NAND_MSG((_T("[FIL] NF_ECC_ERR1 = 0x%08x()\r\n"), nError1));
nErrorCnt = (nError0>>26)&0x7;
if (nErrorCnt == 0) // No Error
{
NAND_MSG((_T("[FIL] Decoding_MainECC() : No ECC Error\r\n")));
}
else if (nErrorCnt > 4) // Uncorrectable Error
{
NAND_ERR((_T("[FIL:ERR] Decoding_MainECC() : Uncorrectable Error\r\n")));
nRet = ECC_UNCORRECTABLE_ERROR;
}
else // Correctable Error
{
NAND_MSG((_T("[FIL] Decoding_MainECC() : Correctable Error %d bit\r\n"), nErrorCnt));
nErrorPattern = NF_ECC_ERR_PATTERN();
// 1st Bit Error Correction
nErrorByte = nError0&0x3ff;
if (nErrorByte < 512)
{
NAND_MSG((_T("[FIL] Decoding_MainECC() : 1st Error Buf[%d] [%02x]->"), nErrorByte, pBuf[nErrorByte]));
pBuf[nErrorByte] = pBuf[nErrorByte]^(nErrorPattern&0xff);
NAND_MSG((_T("[%02x]\r\n"), pBuf[nErrorByte]));
}
if (nErrorCnt > 1)
{
// 2nd Bit Error Correction
nErrorByte = (nError0>>16)&0x3ff;
if (nErrorByte < 512)
{
NAND_MSG((_T("[FIL] Decoding_MainECC() : 2nd Error Buf[%d] [%02x]->"), nErrorByte, pBuf[nErrorByte]));
pBuf[nErrorByte] = pBuf[nErrorByte]^((nErrorPattern>>8)&0xff);
NAND_MSG((_T("[%02x]\r\n"), pBuf[nErrorByte]));
}
if (nErrorCnt > 2)
{
// 3rd Bit Error Correction
nErrorByte = nError1&0x3ff;
if (nErrorByte < 512)
{
NAND_MSG((_T("[FIL] Decoding_MainECC() : 3rd Error Buf[%d] [%02x]->"), nErrorByte, pBuf[nErrorByte]));
pBuf[nErrorByte] = pBuf[nErrorByte]^((nErrorPattern>>16)&0xff);
NAND_MSG((_T("[%02x]\r\n"), pBuf[nErrorByte]));
}
if (nErrorCnt > 3)
{
// 4 th Bit Error Correction
nErrorByte = (nError1>>16)&0x3ff;
if (nErrorByte < 512)
{
NAND_MSG((_T("[FIL] Decoding_MainECC() : 4th Error Buf[%d] [%02x]->"), nErrorByte, pBuf[nErrorByte]));
pBuf[nErrorByte] = pBuf[nErrorByte]^((nErrorPattern>>24)&0xff);
NAND_MSG((_T("[%02x]\r\n"), pBuf[nErrorByte]));
}
}
}
}
nRet = ECC_CORRECTABLE_ERROR;
}
NAND_MSG((_T("[FIL]--Decoding_MainECC()\r\n")));
return nRet;
}
//////////////////////////////////////////////////////////////////////////////
//
// Meaningful ECC error is first 24 bytes of 512 byte
//
// SpareData + MECC_Data + DummyData
// 12 byte + MECC 8x4 byte + 468 byte Dummy = 512 bytes : 2KByte/Page
// 20 byte + MECC 8x8 byte + 428 byte Dummy = 512 bytes : 4KByte/Page
//
//////////////////////////////////////////////////////////////////////////////
PRIVATE UINT32
Decoding_SpareECC(UINT8* pBuf)
{
UINT32 nError0, nError1;
UINT32 nErrorCnt;
UINT32 nRet = 0;
UINT32 nEffectiveByte;
BOOL32 bDummyError = FALSE32;
NAND_MSG((_T("[FIL]++Decoding_SpareECC()\r\n")));
if (SECTORS_PER_PAGE == 8)
{
nEffectiveByte = NAND_SECC_OFFSET_4K - NAND_SCXT_OFFSET; // 20B + 8*8B
}
else
{
nEffectiveByte = NAND_SECC_OFFSET - NAND_SCXT_OFFSET; // 12B + 8*4B
}
nError0 = NF_ECC_ERR0();
nError1 = NF_ECC_ERR1();
//NAND_MSG((_T("[FIL] NF_ECC_ERR0 = 0x%08x()\r\n"), nError0));
//NAND_MSG((_T("[FIL] NF_ECC_ERR1 = 0x%08x()\r\n"), nError1));
nErrorCnt = (nError0>>26)&0x7;
if (nErrorCnt == 0) // No ECC Error
{
NAND_MSG((_T("[FIL] Decoding_SpareECC() : No ECC Error\r\n")));
}
else if (nErrorCnt > 4) // Uncorrectable Error
{
NAND_ERR((_T("[FIL:ERR] Decoding_SpareECC() : Uncorrectable Error\r\n")));
nRet = ECC_UNCORRECTABLE_ERROR;
}
else // Check ECC error occurs in first 44 (12+32) bytes (468 byte is Dummy 0xFF) for 2KByte/Page
{
UINT32 nErrorByte, nErrorPattern;
UINT8 cTempBuf;
nErrorPattern = NF_ECC_ERR_PATTERN();
// 1st Bit Error Correction
nErrorByte = nError0&0x3ff;
if (nErrorByte < nEffectiveByte)
{
cTempBuf = pBuf[nErrorByte];
pBuf[nErrorByte] = cTempBuf^(nErrorPattern&0xff);
NAND_MSG((_T("[FIL] Decoding_SpareECC() : 1st Error Buf[%d] [%02x]->[%02x]\r\n"), nErrorByte, cTempBuf, pBuf[nErrorByte]));
}
else if (nErrorByte < 512)
{
NAND_MSG((_T("[FIL] Decoding_SpareECC() : 1st Error in Dummy Data Buf[%d]\r\n"), nErrorByte));
bDummyError = TRUE32;
}
if (nErrorCnt > 1)
{
// 2nd Bit Error Correction
nErrorByte = (nError0>>16)&0x3ff;
if (nErrorByte < nEffectiveByte)
{
cTempBuf = pBuf[nErrorByte];
pBuf[nErrorByte] = cTempBuf^((nErrorPattern>>8)&0xff);
NAND_MSG((_T("[FIL] Decoding_SpareECC() : 2nd Error Buf[%d] [%02x]->[%02x]\r\n"), nErrorByte, cTempBuf, pBuf[nErrorByte]));
}
else if (nErrorByte < 512)
{
NAND_MSG((_T("[FIL] Decoding_SpareECC() : 2nd Error in Dummy Data Buf[%d]\r\n"), nErrorByte));
bDummyError = TRUE32;
}
if (nErrorCnt > 2)
{
// 3rd Bit Error Correction
nErrorByte = nError1&0x3ff;
if (nErrorByte < nEffectiveByte)
{
cTempBuf = pBuf[nErrorByte];
pBuf[nErrorByte] = cTempBuf^((nErrorPattern>>16)&0xff);
NAND_MSG((_T("[FIL] Decoding_SpareECC() : 3rd Error Buf[%d] [%02x]->[%02x]\r\n"), nErrorByte, cTempBuf, pBuf[nErrorByte]));
}
else if (nErrorByte < 512)
{
NAND_MSG((_T("[FIL] Decoding_SpareECC() : 3rd Error in Dummy Data Buf[%d]\r\n"), nErrorByte));
bDummyError = TRUE32;
}
if (nErrorCnt > 3)
{
// 4 th Bit Error Correction
nErrorByte = (nError1>>16)&0x3ff;
if (nErrorByte < nEffectiveByte)
{
cTempBuf = pBuf[nErrorByte];
pBuf[nErrorByte] = cTempBuf^((nErrorPattern>>24)&0xff);
NAND_MSG((_T("[FIL] Decoding_SpareECC() : 4th Error Buf[%d] [%02x]->[%02x]\r\n"), nErrorByte, cTempBuf, pBuf[nErrorByte]));
}
else if (nErrorByte < 512)
{
NAND_MSG((_T("[FIL] Decoding_SpareECC() : 4th Error in Dummy Data Buf[%d]\r\n"), nErrorByte));
bDummyError = TRUE32;
}
}
}
}
if (bDummyError) // ECC Error in Dummy Data
{
NAND_ERR((_T("[FIL] Decoding_SpareECC() : ECC Error in Dummy Data\r\n")));
nRet = ECC_UNCORRECTABLE_ERROR;
}
else // Correctable Error
{
NAND_MSG((_T("[FIL] Decoding_SpareECC() : Correctable Error %d bits\r\n"), nErrorCnt));
nRet = ECC_CORRECTABLE_ERROR;
}
}
NAND_MSG((_T("[FIL]--Decoding_SpareECC()\r\n")));
return nRet;
}
/*****************************************************************************/
/* */
/* NAME */
/* _IsAllFF */
/* DESCRIPTION */
/* This function inspects the specific area whether its data is */
/* all 0xFF or not */
/* PARAMETERS */
/* pBuf [IN] Data buffer to inspect */
/* pSize [IN] Amount of data to inspect */
/* RETURN VALUES */
/* FALSE There is a data that is not 0xFF */
/* TURE All data is 0xFF */
/* NOTES */
/* */
/*****************************************************************************/
PRIVATE UINT32
_IsAllFF(UINT8* pBuf, UINT32 nSize)
{
register UINT32 nIdx;
register UINT32 nLoop;
UINT32 *pBuf32;
pBuf32 = (UINT32 *)pBuf;
nLoop = nSize / sizeof(UINT32);
for (nIdx = nLoop; nIdx > 0; nIdx--)
{
if(*pBuf32++ != 0xFFFFFFFF)
{
return FALSE32;
}
}
return TRUE32;
}
/*****************************************************************************/
/* */
/* NAME */
/* _TRDelay */
/* DESCRIPTION */
/* This function wait TR. */
/* PARAMETERS */
/* None */
/* RETURN VALUES */
/* None */
/* NOTES */
/* */
/*****************************************************************************/
PRIVATE UINT32
_TRDelay(UINT32 nNum)
{
volatile int count;
//count = 2200; // 55us
count = 2500; // 62.5us
while(count--)
{
nNum++;
}
return nNum;
}
PRIVATE UINT32
_TRDelay2(UINT32 nNum)
{
volatile int count;
count = 50; // 1.25us
while(count--)
{
nNum++;
}
return nNum;
}
#if (NAND_TRANS_MODE == DMA) // for DMA Trasfer Function
PRIVATE VOID
Read_512Byte_DMA(UINT8* pBuf)
{
NAND_MSG((_T("[FIL] ++Read_512Byte_DMA()\r\n")));
pDMAConReg->DISRC0 = 0x4E000010; // Nand flash data register
pDMAConReg->DISRCC0 = (0<<1) | (1<<0); //arc=AHB,src_addr=fix
pDMAConReg->DIDST0 = NAND_DMA_BUFFER_PA; // DMA Buffer
pDMAConReg->DIDSTC0 = (0<<1) | (0<<0); //dst=AHB, dst_addr=inc;
pDMAConReg->DCON0 = (1<<31) | (1<<30) | (0<<29) | (1<<28) | (1<<27) | (0<<23) | (1<<22) | (2<<20) | (512/4/4);
//Handshake, AHB, No interrupt, (4-burst), whole, S/W, no_autoreload, word, count=512/4/4;
// DMA on and start.
pDMAConReg->DMASKTRIG0 = (1<<1)|(1<<0);
// Wait for DMA transfer finished
while(pDMAConReg->DSTAT0&0xfffff);
memcpy((void *)pBuf, (void *)NAND_DMA_BUFFER_UA, 512);
NAND_MSG((_T("[FIL] --Read_512Byte_DMA()\r\n")));
}
PRIVATE VOID
Write_512Byte_DMA(UINT8* pBuf)
{
NAND_MSG((_T("[FIL] ++Write_512Byte_DMA()\r\n")));
memcpy( (void *)NAND_DMA_BUFFER_UA, (void *)pBuf, 512);
// Memory to Nand dma setting
pDMAConReg->DISRC0 = NAND_DMA_BUFFER_PA; // DMA Buffer
pDMAConReg->DISRCC0 = (0<<1) | (0<<0); //arc=AHB,src_addr=inc
pDMAConReg->DIDST0 = 0x4E000010; // Nand flash data register
pDMAConReg->DIDSTC0 = (0<<1) | (1<<0); //dst=AHB,dst_addr=fix;
pDMAConReg->DCON0 = (1<<31) | (1<<30) | (0<<29) | (0<<28) | (1<<27) | (0<<23) | (1<<22) | (2<<20) | (512/4);
// only unit transfer in writing!!!!
// Handshake,AHB, No interrupt,(unit),whole,S/W,no_autoreload,word,count=512/4;
// DMA on and start.
pDMAConReg->DMASKTRIG0 = (1<<1) | (1<<0);
// Wait for DMA transfer finished
while(pDMAConReg->DSTAT0&0xfffff);
NAND_MSG((_T("[FIL] --Write_512Byte_DMA()\r\n")));
}
PRIVATE VOID
Write_Dummy_468Byte_AllFF_DMA(void)
{
NAND_MSG((_T("[FIL] ++Write_Dummy_468Byte_AllFF_DMA()\r\n")));
*((UINT32 *)NAND_DMA_BUFFER_UA) = 0xffffffff;
// Memory to Nand dma setting
pDMAConReg->DISRC0 = NAND_DMA_BUFFER_PA; // DMA Buffer
pDMAConReg->DISRCC0 = (0<<1) | (1<<0); //arc=AHB,src_addr=fix
pDMAConReg->DIDST0 = 0x4E000010; // Nand flash data register
pDMAConReg->DIDSTC0 = (0<<1) | (1<<0); //dst=AHB,dst_addr=fix;
pDMAConReg->DCON0 = (1<<31) | (1<<30) | (0<<29) | (0<<28) | (1<<27) | (0<<23) | (1<<22) | (2<<20) | (468/4);
// only unit transfer in writing!!!!
// Handshake,AHB, No interrupt,(unit),whole,S/W,no_autoreload,word,count=500/4;
// DMA on and start.
pDMAConReg->DMASKTRIG0 = (1<<1) | (1<<0);
// Wait for DMA transfer finished
while(pDMAConReg->DSTAT0&0xfffff);
NAND_MSG((_T("[FIL] --Write_Dummy_468Byte_AllFF_DMA()\r\n")));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -