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

📄 s3c2450_fil.c

📁 s3c2450 bsp for wince 5.0 PM_REL_0.04_080519 经验证,完全没问题
💻 C
📖 第 1 页 / 共 5 页
字号:
			//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 + -