⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s3c2450_fil.c

📁 s3c2450 bsp for wince 5.0 经验证,完全没问题
💻 C
📖 第 1 页 / 共 5 页
字号:

PRIVATE VOID
Write_Sector(UINT32 nPpn, UINT32 nSctOffset, UINT8* pBuf)
{
	UINT32 nOffset;
#if ECC_MODULE_TEST_SIMULATION
	BOOL32 bChangeData = FALSE;
#endif

	NAND_MSG((_T("[FIL]++Write_Sector(%d, %d)\r\n"), nPpn, nSctOffset));

#if ECC_MODULE_TEST_SIMULATION
Loop1:
#endif

	nOffset = NAND_SECTOR_SIZE*nSctOffset;

	NF_CMD(CMD_RANDOM_DATA_INPUT);
	NF_ADDR(nOffset&0xFF);
	NF_ADDR((nOffset>>8)&0xFF);

#if ECC_MODULE_TEST_SIMULATION
	if (IS_CHECK_SPARE_ECC == TRUE32 && bChangeData == FALSE)
#else
	if (IS_CHECK_SPARE_ECC == TRUE32)
#endif
	{
		// Initialize 4-bit ECC Encoding
		NF_SET_ECC_ENC();
		NF_MECC_Reset();
		NF_CLEAR_ECC_ENC_DONE();
		NF_MECC_UnLock();
	}
#if ECC_MODULE_TEST_SIMULATION
	else if (bChangeData == TRUE)
	{
		if (nSctOffset == 0)  // forcefully happen to error on 4-bit in case of ECC mobule error
		{
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+243) ^= (1<<4);
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+419) ^= (1<<3);
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+333) ^= (1<<2);
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+308) ^= (1<<4);
		}
		else if (nSctOffset == 1)  // forcefully happen to error on 4-bit in case of ECC mobule error
		{
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+228) ^= (1<<0);
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+400) ^= (1<<3);
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+486) ^= (1<<4);
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+165) ^= (1<<2);
		}
		else if (nSctOffset == 2)  // forcefully happen to error on 4-bit except ECC mobule error
		{
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+228) ^= (1<<0);
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+400) ^= (1<<3);
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+486) ^= (1<<4);
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+165) ^= (1<<1);
		}
		else if (nSctOffset == 3)  // forcefully happen to error on 3-bit in case of ECC mobule error
		{
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+148) ^= (1<<3);
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+435) ^= (1<<2);
			*(pBuf+NAND_SECTOR_SIZE*nSctOffset+501) ^= (1<<1);
		}
	}
#endif

#if (NAND_TRANS_MODE == ASM)
	if ((UINT32)pBuf&0x3)
	{
		_Write_512Byte_Unaligned(pBuf+NAND_SECTOR_SIZE*nSctOffset);
	}
	else
	{
		_Write_512Byte(pBuf+NAND_SECTOR_SIZE*nSctOffset);
	}
#elif (NAND_TRANS_MODE == DMA)
	Write_512Byte_DMA(pBuf+NAND_SECTOR_SIZE*nSctOffset);
#endif

#if ECC_MODULE_TEST_SIMULATION
	if (IS_CHECK_SPARE_ECC == TRUE32 && bChangeData == FALSE)
#else
	if (IS_CHECK_SPARE_ECC == TRUE32)
#endif
	{
		NF_MECC_Lock();

		// Waiting for Main ECC Encoding
		NF_WAIT_ECC_ENC_DONE();
	}

#if ECC_MODULE_TEST_SIMULATION
	if (bChangeData == FALSE)
	{
		bChangeData = TRUE;
		goto Loop1;
	}
#endif

	NAND_MSG((_T("[FIL]--Write_Sector()\r\n")));

	return;
}

PRIVATE VOID
Write_Spare(UINT32 nBank, UINT32 nPpn, pSECCCxt pSpareCxt)
{
	UINT32 nOffset;

	NAND_MSG((_T("[FIL]++Write_Spare(%d, %d)\r\n"), nBank, nPpn));

	nOffset = BYTES_PER_MAIN_PAGE;

	NF_CMD(CMD_RANDOM_DATA_INPUT);
	NF_ADDR(nOffset&0xFF);
	NF_ADDR((nOffset>>8)&0xFF);

	NF_DATA_W(pSpareCxt->cBadMark);			// 1 byte Bad Mark
	NF_DATA_W(pSpareCxt->cCleanMark);			// 1 byte Clean Mark

#if	1
	NF_DATA_W(0xff);			// 2 byte Reserved
	NF_DATA_W(0xff);
#else
	NF_DATA_W(pSpareCxt->cReserved[0]); 	// 2 byte Reserved
	NF_DATA_W(pSpareCxt->cReserved[1]);
#endif

	if (IS_CHECK_SPARE_ECC == TRUE32)
	{
		// Initialize 4-bit ECC Encoding
		NF_SET_ECC_ENC();
		NF_MECC_Reset();
		NF_CLEAR_ECC_ENC_DONE();
		NF_MECC_UnLock();
	}

	if (SECTORS_PER_PAGE == 4)
	{
		NF_DATA_W4(pSpareCxt->aSpareData[0]);		// 12 byte Spare Context
		NF_DATA_W4(pSpareCxt->aSpareData[1]);
		NF_DATA_W4(pSpareCxt->aSpareData[2]);

		NF_DATA_W4(pSpareCxt->aMECC[0]);		// 8 byte Sector0 ECC data
		NF_DATA_W4(pSpareCxt->aMECC[1]);
		NF_DATA_W4(pSpareCxt->aMECC[2]);		// 8 byte Sector1 ECC data
		NF_DATA_W4(pSpareCxt->aMECC[3]);
		NF_DATA_W4(pSpareCxt->aMECC[4]);		// 8 byte Sector2 ECC data
		NF_DATA_W4(pSpareCxt->aMECC[5]);
		NF_DATA_W4(pSpareCxt->aMECC[6]);		// 8 byte Sector3 ECC data
		NF_DATA_W4(pSpareCxt->aMECC[7]);
	}
	else if (SECTORS_PER_PAGE == 8)
	{
		NF_DATA_W4(pSpareCxt->aSpareData[0]);		// 20 byte Spare Context for 4KByte/Page
		NF_DATA_W4(pSpareCxt->aSpareData[1]);
		NF_DATA_W4(pSpareCxt->aSpareData[2]);
		NF_DATA_W4(pSpareCxt->aSpareData[3]);
		NF_DATA_W4(pSpareCxt->aSpareData[4]);

		NF_DATA_W4(pSpareCxt->aMECC[0]);		// 8 byte Sector0 ECC data
		NF_DATA_W4(pSpareCxt->aMECC[1]);
		NF_DATA_W4(pSpareCxt->aMECC[2]);		// 8 byte Sector1 ECC data
		NF_DATA_W4(pSpareCxt->aMECC[3]);
		NF_DATA_W4(pSpareCxt->aMECC[4]);		// 8 byte Sector2 ECC data
		NF_DATA_W4(pSpareCxt->aMECC[5]);
		NF_DATA_W4(pSpareCxt->aMECC[6]);		// 8 byte Sector3 ECC data
		NF_DATA_W4(pSpareCxt->aMECC[7]);
		NF_DATA_W4(pSpareCxt->aMECC[8]);		// 8 byte Sector4 ECC data
		NF_DATA_W4(pSpareCxt->aMECC[9]);
		NF_DATA_W4(pSpareCxt->aMECC[10]);		// 8 byte Sector5 ECC data
		NF_DATA_W4(pSpareCxt->aMECC[11]);
		NF_DATA_W4(pSpareCxt->aMECC[12]);		// 8 byte Sector6 ECC data
		NF_DATA_W4(pSpareCxt->aMECC[13]);
		NF_DATA_W4(pSpareCxt->aMECC[14]);		// 8 byte Sector7 ECC data
		NF_DATA_W4(pSpareCxt->aMECC[15]);
	}
	else
	{
		WMR_ASSERT(FALSE32);
	}

	if (IS_CHECK_SPARE_ECC == TRUE32)
	{
		// Write Dummy 500 byte for ECC Encoding using CE Don't care
		NF_CE_H(nBank);
		NF_SET_CLK(DUMMY_W_TACLS, DUMMY_W_TWRPH0, DUMMY_W_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_SET_CLK(DEFAULT_TACLS, DEFAULT_TWRPH0, DEFAULT_TWRPH1);
		NF_CE_L(nBank);

		NF_MECC_Lock();

		// Waiting for Main ECC Encoding
		NF_WAIT_ECC_ENC_DONE();

		pSpareCxt->aSECC[0] = NF_MECC0();	// Spare ECC x 2 copies
		pSpareCxt->aSECC[1] = NF_MECC1();
		pSpareCxt->aSECC[2] = NF_MECC0();
		pSpareCxt->aSECC[3] = NF_MECC1();
	}

	NF_DATA_W4(pSpareCxt->aSECC[0]);		// Spare ECC 8 bytes
	NF_DATA_W4(pSpareCxt->aSECC[1]);
	NF_DATA_W4(pSpareCxt->aSECC[2]);		// Spare ECC 8 bytes 2nd copy
	NF_DATA_W4(pSpareCxt->aSECC[3]);

	NAND_MSG((_T("[FIL]--Write_Spare()\r\n")));

	return;
}

#define NUMBER_OF_ECC_ERROR 3

PRIVATE UINT32
Decoding_MainECC(UINT8* pBuf)
{
	UINT32 nError0, nError1;
	UINT32 nErrorCnt, nErrorByte, nErrorPattern;
	UINT32 nRet = 0;
	UINT8  nErrorBitPat;

	NAND_MSG((_T("[FIL]++Decoding_MainECC()\r\n")));

	nError0 = NF_ECC_ERR0();
	nError1 = NF_ECC_ERR1();

	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;
		nErrorBitPat = (UINT8)(nErrorPattern&0xff);
		if (nErrorByte < 512)
		{
			NAND_MSG((_T("[FIL] Decoding_MainECC() : 1st Error Buf[%d] [%02x]->"), nErrorByte, pBuf[nErrorByte]));
			pBuf[nErrorByte] = pBuf[nErrorByte]^nErrorBitPat;
			NAND_MSG((_T("[%02x]\r\n"), pBuf[nErrorByte]));
		}
		else if ((nErrorByte == 518) && (nErrorBitPat == (1<<1)))
		{
			NAND_MSG((_T(" ECC Mobule Error, 1st Pattern\r\n")));
			nRet |= ECC_MODULE_ERROR;
		}

		if (nErrorCnt > 1)
		{
			// 2nd Bit Error Correction
			nErrorByte = (nError0>>16)&0x3ff;
			nErrorBitPat = (UINT8)((nErrorPattern>>8)&0xff);
			if (nErrorByte < 512)
			{
				NAND_MSG((_T("[FIL] Decoding_MainECC() : 2nd Error Buf[%d] [%02x]->"), nErrorByte, pBuf[nErrorByte]));
				pBuf[nErrorByte] = pBuf[nErrorByte]^nErrorBitPat;
				NAND_MSG((_T("[%02x]\r\n"), pBuf[nErrorByte]));
			}
			else if ((nErrorByte == 518) && (nErrorBitPat == (1<<1)))
			{
				NAND_MSG((_T(" ECC Mobule Error, 2nd Pattern\r\n")));
				nRet |= ECC_MODULE_ERROR;
			}

			if (nErrorCnt > 2)
			{
				// 3rd Bit Error Correction
				nErrorByte = nError1&0x3ff;
				nErrorBitPat = (UINT8)((nErrorPattern>>16)&0xff);
				if (nErrorByte < 512)
				{
					NAND_MSG((_T("[FIL] Decoding_MainECC() : 3rd Error Buf[%d] [%02x]->"), nErrorByte, pBuf[nErrorByte]));
					pBuf[nErrorByte] = pBuf[nErrorByte]^nErrorBitPat;
					NAND_MSG((_T("[%02x]\r\n"), pBuf[nErrorByte]));
				}
				else if ((nErrorByte == 518) && (nErrorBitPat == (1<<1)))
				{
					NAND_MSG((_T(" ECC Mobule Error, 3rd Pattern\r\n")));
					nRet |= ECC_MODULE_ERROR;
				}

				if (nErrorCnt > 3)
				{
					// 4 th Bit Error Correction
					nErrorByte = (nError1>>16)&0x3ff;
					nErrorBitPat = (UINT8)((nErrorPattern>>24)&0xff);
					if (nErrorByte < 512)
					{
						NAND_MSG((_T("[FIL] Decoding_MainECC() : 4th Error Buf[%d] [%02x]->"), nErrorByte, pBuf[nErrorByte]));
						pBuf[nErrorByte] = pBuf[nErrorByte]^nErrorBitPat;
						NAND_MSG((_T("[%02x]\r\n"), pBuf[nErrorByte]));
					}
					else if ((nErrorByte == 518) && (nErrorBitPat == (1<<1)))
					{
						NAND_MSG((_T(" ECC Mobule Error, 4th Pattern\r\n")));
						nRet |= ECC_MODULE_ERROR;
					}
				}
			}
		}

		if (nErrorCnt >= NUMBER_OF_ECC_ERROR) 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;
	UINT8  nErrorBitPat;

	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();

	nErrorCnt = (nError0>>26)&0x7;

	if (nErrorCnt == 0)			// No 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;
		nErrorBitPat = (UINT8)(nErrorPattern&0xff);
		if (nErrorByte < nEffectiveByte)
		{
			cTempBuf = pBuf[nErrorByte];
			pBuf[nErrorByte] = cTempBuf^nErrorBitPat;
			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;
			nErrorBitPat = (UINT8)((nErrorPattern>>8)&0xff);
			if (nErrorByte < nEffectiveByte)
			{
				cTempBuf = pBuf[nErrorByte];
				pBuf[nErrorByte] = cTempBuf^nErrorBitPat;
				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;
				nErrorBitPat = (UINT8)((nErrorPattern>>16)&0xff);
				if (nErrorByte < nEffectiveByte)
				{
					cTempBuf = pBuf[nErrorByte];
					pBuf[nErrorByte] = cTempBuf^nErrorBitPat;
					NAND_MSG((_T("[FIL] 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -