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

📄 s3c2450_fil.c

📁 s3c2450 bsp for wince 5.0 PM_REL_0.04_080519 经验证,完全没问题
💻 C
📖 第 1 页 / 共 5 页
字号:
	pSECCCxt pSpareCxt;

#ifdef	USE_SETKMODE
	BOOL bLastMode;
#endif

	NAND_MSG((_T("[FIL]++NAND_Read(%d, %d, 0x%02x, 0x%02x, %d)\r\n"), nBank, nPpn, nSctBitmap, nPlaneBitmap, bCleanCheck));

	// pDBuf & pSBuf can't be the NULL at the same time
	if (nBank >= BANKS_TOTAL || nPpn >= PAGES_PER_BANK || (pDBuf == NULL && pSBuf == NULL))
	{
		NAND_ERR((_T("[FIL:ERR]--NAND_Read() : Parameter overflow\r\n")));
		WMR_ASSERT(FALSE32);
		return FIL_CRITICAL_ERROR;
	}

	WMR_ASSERT((nPlaneBitmap == enuBOTH_PLANE_BITMAP) || (nPlaneBitmap == enuLEFT_PLANE_BITMAP) || (nPlaneBitmap == enuRIGHT_PLANE_BITMAP));

	nVBank = nBank;	// Do not change nBank before copy to nVBank

	// avoid r/b check error with internal interleaving
	if (bInternalInterleaving == TRUE32)
	{
		nPairBank = ((nBank & 0x1) == 1) ? (nBank - 1) : (nBank + 1);
	}

	/* 
	In case of Internal Interleaving, the first address of the second bank should be 
	the half of toal block number of NAND.
	For example, In 4Gbit DDP NAND, its total block number is 4096.
	So, the bank 0 has 2048 blocks (Physical number : 0 ~ 2047),
	the bank 1 has another 2048 blocks (Physical number : 2048 ~ 4095).
	therefore, first block address of Bank 1 could be the physically 2048th block.
	*/
	if (bInternalInterleaving == TRUE32)
	{
		if ((nBank & 0x1) == 1)
		{
			nPpn += PAGES_PER_BANK;
		}
		nBank /= 2;
	}

	nSctBitmap &= FULL_SECTOR_BITMAP_PAGE;

#if (WMR_STDLIB_SUPPORT)
	nPbn = nPpn / PAGES_PER_BLOCK;
	nPOffset = nPpn % PAGES_PER_BLOCK;
#else
	nPbn = DIV(nPpn, PAGES_PER_BLOCK_SHIFT);
	nPOffset = REM(nPpn, PAGES_PER_BLOCK_SHIFT);
#endif

	// In case of 2 Plane Program, re-calculate the page address
	if (TWO_PLANE_PROGRAM == TRUE32)
	{
		nPpn = nPbn * 2 * PAGES_PER_BLOCK + nPOffset;

		if (nPlaneBitmap == enuBOTH_PLANE_BITMAP)
		{
			if(pDBuf != NULL)
			{
				if ((nSctBitmap & LEFT_SECTOR_BITMAP_PAGE) > 0 && (nSctBitmap & RIGHT_SECTOR_BITMAP_PAGE) > 0)
				{
					// read from both plane
					bLoopNeed = TRUE32;
				}
				else if ((nSctBitmap & LEFT_SECTOR_BITMAP_PAGE) > 0 && (nSctBitmap & RIGHT_SECTOR_BITMAP_PAGE) == 0)
				{
					// read from left plane
					bLoopNeed = FALSE32;
				}
				else if ((nSctBitmap & LEFT_SECTOR_BITMAP_PAGE) == 0 && (nSctBitmap & RIGHT_SECTOR_BITMAP_PAGE) > 0)
				{
					// read from right plane
					bLoopNeed = FALSE32;
					bSecondRead = TRUE32;
				}
			}
			else
			{
				// When read only the spare area, must read twice
				bLoopNeed = TRUE32;
			}
		}
		else if (nPlaneBitmap == enuRIGHT_PLANE_BITMAP)
		{
			nPpn += PAGES_PER_BLOCK;
		}
	}

	nLoopCount = SECTORS_PER_PAGE;

	NAND_Sync(nVBank, &nSyncRet);

	if (bInternalInterleaving == TRUE32)
	{
		// avoid r/b check error with internal interleaving
		aNeedSync[nVBank] = FALSE32;
	}

_B_SecondRead:	// back here again for read right plane

	if(bSecondRead)
	{
		nPpn += PAGES_PER_BLOCK;
		nSctBitmap = (nSctBitmap >> SECTORS_PER_PAGE);

		if(pDBuf != NULL)
		{
			pDBuf += BYTES_PER_MAIN_PAGE;
		}
		else
		{
			// When read only the spare, read 64 + 64 bytes to check the Bad Block
			pSBuf += BYTES_PER_SPARE_PAGE;
		}
	}

#if (WMR_READ_RECLAIM)
	READ_ERR_FLAG = FALSE32;
#endif

	if(pSBuf == NULL)
	{
		pSBuf = aTempSBuf;
		bIsSBufNull = TRUE32;
	}

	pSpareCxt = (pSECCCxt)pSBuf;

	//NAND_Sync(nVBank, &nSyncRet);

#ifdef	USE_SETKMODE
	bLastMode = SetKMode(TRUE);
#endif

	// Chip Select
	NF_CE_L(nBank);

	NF_WAIT_RnB(nBank);

	// Read Command (Always read spare area before main area in a page
	NF_CMD(CMD_READ);
	NF_SET_ADDR(nPpn, BYTES_PER_MAIN_PAGE);
	NF_CMD(CMD_READ_CONFIRM);

	if (bInternalInterleaving == TRUE32)
	{
#if	1
		_TRDelay(nPpn);
#else
		if (nVBank%2)
		{
			NF_CMD(CMD_READ_STATUS_CHIP1);
		}
		else
		{
			NF_CMD(CMD_READ_STATUS_CHIP0);
		}
		while(!(NF_DATA_R()&0x40));

		// Dummy Command to Set Proper Pointer to Read Position after NF_WAIT_RnB()
		NF_CMD(CMD_READ);
#endif
	}
	else
	{
		NF_WAIT_RnB(nBank);

		// Dummy Command to Set Proper Pointer to Read Position after NF_WAIT_RnB()
		NF_CMD(CMD_READ);
	}

	// Read Spare Area
	nRet = Read_Spare(nBank, nPpn, pSpareCxt);
	if ((nRet & ECC_UNCORRECTABLE_ERROR) == 0)
	{
		nPageReadStatus = (nRet<<16);

		if (WMR_GetChkSum(&pSpareCxt->cCleanMark, 1) >= 4)
		{
			// Not Clean Page
			bPageClean = FALSE32;
		}

		// Read Main Area
		if(pDBuf != NULL)
		{
			for (nCnt=0; nCnt<nLoopCount; nCnt++)
			{
				if (nSctBitmap&(0x1<<nCnt))
				{
					nRet = Read_Sector(nBank, nPpn, nCnt, pDBuf, pSpareCxt, bPageClean);
					//nPageReadStatus |= (nRet<<(nCnt*4));  // if 2KByte/Page
					nPageReadStatus |= (nRet<<(nCnt*2));  // if both non-case for all-ff and 4KByte/Page
				}
			}
		}
	}

	// Chip Unselect
	NF_CE_H(nBank);

#ifdef	USE_SETKMODE
	SetKMode(bLastMode);
#endif

	if(bSecondRead)
	{
		nPageReadStatus2nd = nPageReadStatus;
	}
	else
	{
		nPageReadStatus1st = nPageReadStatus;
	}

	if(bLoopNeed && !bSecondRead)
	{
		bSecondRead = TRUE32;
		goto _B_SecondRead;
	}

	if(nPageReadStatus1st&PAGE_UNCORRECTABLE_ERROR_MASK || nPageReadStatus2nd&PAGE_UNCORRECTABLE_ERROR_MASK)
	{
		// Uncorrectable ECC Error
		NAND_ERR((_T("[FIL:ERR]--NAND_Read() : Uncorrectable Error in Bank %d, Page %d [0x%08x] [0x%08x]\r\n"), nBank, nPpn, nPageReadStatus1st, nPageReadStatus));
		return FIL_U_ECC_ERROR;
	}
	else
	{

#if (WMR_READ_RECLAIM)
		if (nPageReadStatus1st&PAGE_CORRECTABLE_ERROR_MASK || nPageReadStatus2nd&PAGE_CORRECTABLE_ERROR_MASK)
		{
			READ_ERR_FLAG = TRUE32;
			NAND_MSG((_T("[FIL:INF] NAND_Read() : Correctable Error in Bank %d, Page %d [0x%08x] [0x%08x]\r\n"), nBank, nPpn, nPageReadStatus1st, nPageReadStatus2nd));
		}
#endif
		if (bCleanCheck&&bPageClean)
		{
			if (bIsSBufNull == FALSE32)
			{
				BOOL32 bClean;

				// Check 32 bytes is all 0xFF & don't care about ECC Value
				if ((pDBuf == NULL) && (bECCIn))
				{
					// When the pMBuf is NULL, read 128 bytes(twice read) in the spare area
					if (bSecondRead)
					{
						pSBuf -= BYTES_PER_SPARE_PAGE;
					}

					bClean = _IsAllFF(pSBuf, BYTES_PER_SPARE_SUPAGE);
				}
				else
				{
					// TODO: to be changed all FF check Size
					bClean = _IsAllFF(pSBuf, ((SECTORS_PER_PAGE == 8) ? NAND_MECC_OFFSET_4K : NAND_MECC_OFFSET));
				}

				if (bClean)
				{
					NAND_MSG((_T("[FIL]--NAND_Read() : FIL_SUCCESS_CLEAN\r\n")));
					return FIL_SUCCESS_CLEAN;
				}
				else
				{
					NAND_MSG((_T("[FIL]--NAND_Read()[bClean==FASLE32]\r\n")));
					return FIL_SUCCESS;
				}
			}
			else
			{
				NAND_MSG((_T("[FIL]--NAND_Read()[bIsSBufNull != FALSE32] : FIL_SUCCESS_CLEAN\r\n")));
				return FIL_SUCCESS_CLEAN;
			}
		}
		else
		{
			NAND_MSG((_T("[FIL]--NAND_Read()[bCleanCheck&&bPageClean == FASLE32]\r\n")));
			return FIL_SUCCESS;
		}
	}
}


/*****************************************************************************/
/*                                                                           */
/* NAME                                                                      */
/*      NAND_Write		                                                     */
/* DESCRIPTION                                                               */
/*      This function writes NAND page area							 		 */
/* PARAMETERS                                                                */
/*      nBank    	[IN] 	Physical device number			               	 */
/*      nPpn     	[IN] 	Physical page number				         	 */
/*      nSctBitmap 	[IN] 	The indicator for the sector to write         	 */
/*      nPlaneBitmap[IN]    The indicator of the plane  					 */
/*      pDBuf		[IN]	Buffer pointer of main area to write          	 */
/*      pSBuf		[IN]	Buffer pointer of spare area to write         	 */
/*																			 */
/* RETURN VALUES                                                             */
/*		None																 */
/* NOTES                                                                     */
/*                                                                           */
/*****************************************************************************/
VOID
NAND_Write(UINT32 nBank, UINT32 nPpn, UINT32 nSctBitmap,
			UINT32  nPlaneBitmap, UINT8* pDBuf, UINT8* pSBuf)
{
	UINT32 nCnt;
	UINT32 nPbn;
	UINT32 nPOffset;

	//BOOL32	bFirstWrite = TRUE32;
	BOOL32	bSecondWrite = FALSE32;
	BOOL32  bLoopNeed = FALSE32;

	UINT32  nSyncRet;

	pSECCCxt pSpareCxt = NULL;

#ifdef	USE_SETKMODE
	BOOL bLastMode;
#endif

	NAND_MSG((_T("[FIL] ++NAND_Write(%d, %d, 0x%02x, 0x%02x)\r\n"), nBank, nPpn, nSctBitmap, nPlaneBitmap));

	if (nBank >= BANKS_TOTAL || nPpn >= PAGES_PER_BANK || (pDBuf == NULL && pSBuf == NULL))
	{
		NAND_ERR((_T("[FIL:ERR]--NAND_Write() : Parameter Overflow\r\n")));
		WMR_ASSERT(FALSE32);
		return;
	}

	// avoid r/b check error with internal interleaving
	if (bInternalInterleaving == TRUE32)
	{
		aNeedSync[nBank] = TRUE32;
	}

	/* 
	In case of Internal Interleaving, the first address of the second bank should be 
	the half of toal block number of NAND.
	For example, In 4Gbit DDP NAND, its total block number is 4096.
	So, the bank 0 has 2048 blocks (Physical number : 0 ~ 2047),
	the bank 1 has another 2048 blocks (Physical number : 2048 ~ 4095).
	therefore, first block address of Bank 1 could be the physically 2048th block.
	*/
	if (bInternalInterleaving == TRUE32)
	{
		if ((nBank & 0x1) == 1)
		{
			nPpn += PAGES_PER_BANK;
		}
		nBank /= 2;
	}

#if (WMR_STDLIB_SUPPORT)
	nPbn = nPpn / PAGES_PER_BLOCK;
	nPOffset = nPpn % PAGES_PER_BLOCK;
#else
	nPbn = DIV(nPpn, PAGES_PER_BLOCK_SHIFT);
	nPOffset = REM(nPpn, PAGES_PER_BLOCK_SHIFT);
#endif

	// In case of 2-Plane Program, re-calculate the page address
	if(TWO_PLANE_PROGRAM == TRUE32)
	{
		nPpn = nPbn * 2 * PAGES_PER_BLOCK + nPOffset;

		if (nPlaneBitmap == enuBOTH_PLANE_BITMAP)
		{
			bLoopNeed = TRUE32;
		}
		else if (nPlaneBitmap == enuRIGHT_PLANE_BITMAP)
		{
			nPpn += PAGES_PER_BLOCK;
			//nSctBitmap = nSctBitmap>>4;
		}
	}

	nSctBitmap &= FULL_SECTOR_BITMAP_PAGE;

#ifdef	USE_SETKMODE
	bLastMode = SetKMode(TRUE);
#endif

	// CE Select
	NF_CE_L(nBank);

_B_SecondWrite:

	// 2-Plane Program, page address is changed
	if (bSecondWrite)
	{
		nPpn += PAGES_PER_BLOCK;
		nSctBitmap = nSctBitmap >> SECTORS_PER_PAGE;
	}

	if(pSBuf == NULL)
	{
		pSBuf = aTempSBuf;
		memset(pSBuf, 0xFF, BYTES_PER_SPARE_PAGE);		// Initialize the spare buffer
	}
	else
	{
		// Set 0xFF to ECC Area
		if (IS_CHECK_SPARE_ECC == TRUE32)
		{
			pSBuf[2] = 0xff;	// Reserved
			pSBuf[3] = 0xff;
			//WMR_MEMSET(pSBuf+2, 0xFF, 2);						// Clear Reserved area in Spare Buffer
			memset(pSBuf+((SECTORS_PER_PAGE == 8) ? NAND_MECC_OFFSET_4K : NAND_MECC_OFFSET),
					0xFF,
					BYTES_PER_SPARE_PAGE-((SECTORS_PER_PAGE == 8) ? NAND_MECC_OFFSET_4K : NAND_MECC_OFFSET));		// Clear ECC area in Spare Buffer
		}
	}

	pSpareCxt = (pSECCCxt)pSBuf;
	pSpareCxt->cCleanMark = 0x0;	// Clean mark to 0. It means that page is written

⌨️ 快捷键说明

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