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

📄 s3c2450_fil.c

📁 s3c2450 bsp for wince 5.0 PM_REL_0.04_080519 经验证,完全没问题
💻 C
📖 第 1 页 / 共 5 页
字号:
/*      This function reads manufacturer id, device id and hidden id. 		 */
/* PARAMETERS                                                                */
/*      nBank    [IN] 		Physical device number				             */
/*      pDID     [OUT] 		NAND flash density id							 */
/*		pHID	 [OUT]		NAND flash hidden id							 */
/* RETURN VALUES                                                             */
/*		nScanIdx			Device's stDEVInfo[nScanIdx]					 */
/* NOTES                                                                     */
/*                                                                           */
/*****************************************************************************/
PRIVATE INT32
Read_DeviceID(UINT32 nBank, UINT8 *pDID, UINT8 *pHID)
{
	UINT8 nMID, nDID, nHID[3];
	UINT32 nScanIdx;
	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, pSECCCxt pSpareCxt, BOOL32 bCheckAllFF)
{
	UINT32 nOffSet;
	UINT32 nRet = 0;
	UINT32 nRetEcc = 0;
	int i = 0;
	unsigned char bECC[4];

	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 1-bit ECC Decoding
	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();		

	if (bCheckAllFF)
	{
		NF_WRMECCD0(ECCVAL_ALLFF);	// All 0xFF ECC
		NF_WRMECCD1(ECCVAL_ALLFF);
	}
	else
	{
		bECC[0] =  (unsigned char)(((pSpareCxt->aMECC[nSctOffset])>>0)&0xffffffff);
		bECC[1] =  (unsigned char)(((pSpareCxt->aMECC[nSctOffset])>>8)&0xffffffff);
		bECC[2] =  (unsigned char)(((pSpareCxt->aMECC[nSctOffset])>>16)&0xffffffff);
		bECC[3] =  (unsigned char)(((pSpareCxt->aMECC[nSctOffset])>>24)&0xffffffff);

		NF_WRMECCD0(((bECC[1]&0xff)<<16)|(bECC[0]&0xff));
		NF_WRMECCD1(((bECC[3]&0xff)<<16)|(bECC[2]&0xff));
	}
	nRetEcc = NF_ECC_ERR0();

	switch(nRetEcc & 0x3)
	{
	case 0:	// No Error
		break;
	case 1:	// 1-bit Error(Correctable)
		(pBuf)[(nRetEcc>>7)&0x7ff] ^= (1<<((nRetEcc>>4)&0x7));
		nRet = ECC_CORRECTABLE_ERROR;		
		break;
	case 2:	// Multiple Error
	case 3:	// ECC area Error
		nRet = ECC_UNCORRECTABLE_ERROR;			
		break;
	}
	
	NAND_MSG((_T("[FIL]--Read_Sector()\r\n")));

	return nRet;
}

PRIVATE UINT32
Read_Spare(UINT32 nBank, UINT32 nPpn, pSECCCxt pSpareCxt)
{
	UINT32 nOffset;
	UINT32 nRet = 0;
	UINT32 nResult = 0;

	BOOL32 bCheckAllFF = FALSE32;

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

	// Read Spare Area
	pSpareCxt->cBadMark = NF_DATA_R();			// 1 byte Bad Mark
	pSpareCxt->cCleanMark = NF_DATA_R();		// 1 byte Clean Mark

	pSpareCxt->cReserved[0]  = NF_DATA_R();		// 2 byte Reserved
	pSpareCxt->cReserved[1]  = NF_DATA_R();

	if (IS_CHECK_SPARE_ECC == TRUE32)
	{
		// Initialize 1-bit ECC Decoding
		NF_SECC_Reset();
		NF_SECC_UnLock();

		if (WMR_GetChkSum(&pSpareCxt->cCleanMark, 1) < 4)
		{
			bCheckAllFF = TRUE32;
		}
	}

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

		if (IS_CHECK_SPARE_ECC == TRUE32)
		{
			NF_SECC_Lock();
		}

		//CommentPilsun 
		//Only Use 4Byte for SLC ECC x 4 (Because, there is 4 sector in each page)
		pSpareCxt->aMECC[0] = NF_DATA_R4();			// 4 byte Sector0 ECC data
		pSpareCxt->aMECC[1] = NF_DATA_R4();			// 4 byte Sector1 ECC data
		pSpareCxt->aMECC[2] = NF_DATA_R4();			// 4 byte Sector2 ECC data
		pSpareCxt->aMECC[3] = NF_DATA_R4();			// 4 byte Sector3 ECC data
		pSpareCxt->aMECC[4] = NF_DATA_R4();			// 4 byte Sector4 ECC data if 4KByte/Page
		pSpareCxt->aMECC[5] = NF_DATA_R4();			// 4 byte Sector5 ECC data if 4KByte/Page
		pSpareCxt->aMECC[6] = NF_DATA_R4();			// 4 byte Sector6 ECC data if 4KByte/Page
		pSpareCxt->aMECC[7] = NF_DATA_R4();			// 4 byte Sector7 ECC data if 4KByte/Page
	}
	else if (SECTORS_PER_PAGE == 8)
	{
		pSpareCxt->aSpareData[0] = NF_DATA_R4();		// 20 byte Spare Context for 4KByte/Page
		pSpareCxt->aSpareData[1] = NF_DATA_R4();
		pSpareCxt->aSpareData[2] = NF_DATA_R4();
		pSpareCxt->aSpareData[3] = NF_DATA_R4();
		pSpareCxt->aSpareData[4] = NF_DATA_R4();

		if (IS_CHECK_SPARE_ECC == TRUE32)
		{
			NF_SECC_Lock();
		}

		//CommentPilsun 
		//Only Use 4Byte for SLC ECC x 4 (Because, there is 4 sector in each page)
		pSpareCxt->aMECC[0] = NF_DATA_R4();			// 4 byte Sector0 ECC data
		pSpareCxt->aMECC[1] = NF_DATA_R4();			// 4 byte Sector1 ECC data
		pSpareCxt->aMECC[2] = NF_DATA_R4();			// 4 byte Sector2 ECC data
		pSpareCxt->aMECC[3] = NF_DATA_R4();			// 4 byte Sector3 ECC data
		pSpareCxt->aMECC[4] = NF_DATA_R4();			// 4 byte Sector4 ECC data if 4KByte/Page
		pSpareCxt->aMECC[5] = NF_DATA_R4();			// 4 byte Sector5 ECC data if 4KByte/Page
		pSpareCxt->aMECC[6] = NF_DATA_R4();			// 4 byte Sector6 ECC data if 4KByte/Page
		pSpareCxt->aMECC[7] = NF_DATA_R4();			// 4 byte Sector7 ECC data if 4KByte/Page
		pSpareCxt->aMECC[8] = NF_DATA_R4();			// 4 byte dummy data
		pSpareCxt->aMECC[9] = NF_DATA_R4();			// 4 byte dummy data
		pSpareCxt->aMECC[10] = NF_DATA_R4();			// 4 byte dummy data
		pSpareCxt->aMECC[11] = NF_DATA_R4();			// 4 byte dummy data
		pSpareCxt->aMECC[12] = NF_DATA_R4();			// 4 byte dummy data
		pSpareCxt->aMECC[13] = NF_DATA_R4();			// 4 byte dummy data
		pSpareCxt->aMECC[14] = NF_DATA_R4();			// 4 byte dummy data
		pSpareCxt->aMECC[15] = NF_DATA_R4();			// 4 byte dummy data
	}
	else
	{
		WMR_ASSERT(FALSE32);
	}

	if (IS_CHECK_SPARE_ECC == TRUE32)
	{

		if (bCheckAllFF)
		{
			NF_WRSECCD(0x3FF03FF);
		}
		else
		{
			pSpareCxt->aSECC[0] = NF_DATA_R4();	// Read 4 byte Spare ECC data
			pSpareCxt->aSECC[1] = NF_DATA_R4();	// Read 4 byte dummy ECC data
			pSpareCxt->aSECC[2] = NF_DATA_R4();	// Read 4 byte dummy ECC data
			pSpareCxt->aSECC[3] = NF_DATA_R4();	// Read 4 byte dummy ECC data

			NF_WRSECCD(((pSpareCxt->aSECC[0]&0xff)<<16)|(pSpareCxt->aSECC[0]&0xff));

		}

		nResult = NF_ECC_ERR0();		

		if (bCheckAllFF)
		{
			pSpareCxt->aSECC[0] = NF_DATA_R4();	// Read 4 byte Spare ECC data
			pSpareCxt->aSECC[1] = NF_DATA_R4();	// Read 4 byte dummy ECC data
			pSpareCxt->aSECC[2] = NF_DATA_R4();	// Read 4 byte dummy ECC data
			pSpareCxt->aSECC[3] = NF_DATA_R4();	// Read 4 byte dummy ECC data
		}

	}
	else
	{
//CommentPilsun
		// just read Spare ECC from NAND for read pointer, NOT decoding ECC
		pSpareCxt->aSECC[0] = NF_DATA_R4();			// 4 byte Spare ECC data
		pSpareCxt->aSECC[1] = NF_DATA_R4();			// 4 byte dummy ECC data
		pSpareCxt->aSECC[2] = NF_DATA_R4();			// 4 byte dummy ECC data
		pSpareCxt->aSECC[3] = NF_DATA_R4();			// 4 byte dummy ECC data

		NF_WRSECCD(((pSpareCxt->aSECC[0]&0xff)<<16)|(pSpareCxt->aSECC[0]&0xff));	
		nResult = NF_ECC_ERR0();				
	}

	switch(nResult & 0xc)
	{
		case 0:	// No Error
		{
			break;
		}
		case 1:	// 1-bit Error(Correctable)
		{
			NAND_ERR((_T("[FIL:ERR] Read_Spare() : ECC Uncorrectable Error in Spare of Page %d\r\n"), nPpn));
			(pSpareCxt->aSpareData)[(nRet>>21)&0x3] ^= (1<<((nRet>>18)&0x7));
			break;
		}
		case 2:	// Multiple Error
		case 3:	// ECC area Error
		{
			NAND_MSG((_T("[FIL] Read_Spare() : ECC Correctable Error in Spare of Page %d\r\n"), nPpn));
			break;
		}
	}

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

	return nRet;
}

PRIVATE VOID
Write_Sector(UINT32 nPpn, UINT32 nSctOffset, UINT8* pBuf)
{
	UINT32 nOffset;
	int i = 0;

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

	nOffset = NAND_SECTOR_SIZE*nSctOffset;

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

	if (IS_CHECK_SPARE_ECC == TRUE32)
	{
		NF_MECC_Reset();
		NF_MECC_UnLock();		
	}

#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 (IS_CHECK_SPARE_ECC == TRUE32)
	{
		NF_MECC_Lock();		
	}

	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 1-bit ECC Encoding
		NF_SECC_Reset();
		NF_SECC_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]);
		
			//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(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 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]);
		

⌨️ 快捷键说明

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