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

📄 s3c2450_fil.c

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

	if (bSecondWrite)
	{
		NF_CMD(CMD_2PLANE_PROGRAM);
		NF_SET_ADDR(nPpn, 0);
	}
	else
	{
		NF_CMD(CMD_PROGRAM);
		NF_SET_ADDR(nPpn, 0);
	}

	// Write Main Sector
	if (pDBuf != NULL)
	{
		// In case of the second write, the position of buffer pointer is moved backward as much as 1 page size
		if (bSecondWrite)
		{
			pDBuf += BYTES_PER_MAIN_PAGE;
		}

		for (nCnt=0; nCnt<SECTORS_PER_PAGE; nCnt++)
		{
			if (nSctBitmap&(0x1<<nCnt))
			{
				Write_Sector(nPpn, nCnt, pDBuf);

				if (IS_CHECK_SPARE_ECC == TRUE32)
				{
					pSpareCxt->aMECC[nCnt] = NF_MECC0();
				}
			}
			else
			{
				pSpareCxt->aMECC[nCnt] = ECCVAL_ALLFF;	// All 0xFF ECC
			}
		}
	}
	else if (IS_CHECK_SPARE_ECC == TRUE32)
	{
		for (nCnt=0; nCnt<SECTORS_PER_PAGE; nCnt++)
		{
			pSpareCxt->aMECC[nCnt] = ECCVAL_ALLFF;	// All 0xFF ECC
		}
	}

	// Write Spare
	Write_Spare(nBank, nPpn, pSpareCxt);

	// Write Confirm
	if(TWO_PLANE_PROGRAM == TRUE32 && !bSecondWrite && bLoopNeed)
	{
		bSecondWrite = TRUE32;
		NF_CMD(CMD_2PLANE_PROGRAM_DUMMY);

		_TRDelay2(0);

		goto _B_SecondWrite;
	}

	NF_CMD(CMD_PROGRAM_CONFIRM);

	// Chip Unselect
	NF_CE_H(nBank);

#ifdef	USE_SETKMODE
	SetKMode(bLastMode);
#endif

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

	return;
}


/*****************************************************************************/
/*                                                                           */
/* NAME                                                                      */
/*      NAND_Erase		                                                     */
/* DESCRIPTION                                                               */
/*      This function erases NAND block area						 		 */
/* PARAMETERS                                                                */
/*      nBank    	[IN] 	Physical device number			               	 */
/*      nPpn     	[IN] 	Physical page number				         	 */
/*      nPlaneBitmap[IN]    The indicator of the plane  					 */
/*																			 */
/* RETURN VALUES                                                             */
/*		None																 */
/* NOTES                                                                     */
/*                                                                           */
/*****************************************************************************/
VOID
NAND_Erase (UINT32 nBank, UINT32 nPbn, UINT32 nPlaneBitmap)
{
	UINT32	nVBank;
	UINT32	nPageAddr;
	UINT32 	nPairBank;
	UINT32  nSyncRet;

	BOOL32	bSecondErase = FALSE32;
	BOOL32	bLoopNeed = FALSE32;


#ifdef	USE_SETKMODE
	BOOL bLastMode;
#endif

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

	if (nBank >= BANKS_TOTAL || nPbn >= BLOCKS_PER_BANK)
	{
		NAND_MSG((_T("[FIL:ERR]--NAND_Erase() : Parameter overflow\r\n")));
		WMR_ASSERT(FALSE32);
		return;
	}

	nVBank = nBank;

	// 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)
		{
			nPbn += BLOCKS_PER_BANK;
		}
		nBank /= 2;
	}

	if (TWO_PLANE_PROGRAM == TRUE32)
	{
		if (nPlaneBitmap == enuBOTH_PLANE_BITMAP)
		{
			bLoopNeed = TRUE32;
		}
		else if (nPlaneBitmap == enuRIGHT_PLANE_BITMAP)
		{
			bSecondErase = TRUE32;
		}
	}

	nPbn = nPbn*(1+(TWO_PLANE_PROGRAM == TRUE32));

	/* 
	   In the Internal Interleaving, it's forbidden NAND to do Write operation & the other operation
	   at the same time. When Write is going on in Bank 1, Bank 0 has to wait to finish 
	   the operation of Bank 1 if the next operation is not Write.

	   While Bank 1 is erased, Bank 0 do not start Write operation. (But, Erase or Read is allowed)
	   Internal Interleaving concept is only existed between Write and Write.	   
	*/
	if (bInternalInterleaving == TRUE32)
	{
		NAND_Sync(nVBank, &nSyncRet);

		// TODO: what does this means???
#if	1
		NF_CE_L(nBank);
		NF_CMD(CMD_READ);
		NF_CE_H(nBank);
#endif

		NAND_Sync(nPairBank, &nSyncRet);

		aNeedSync[nVBank] = TRUE32;
	}

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

	// Chip Select
	NF_CE_L(nBank);

_B_SecondErase:

	if(bSecondErase)
	{
		nPbn++;
	}

	// Calculate Row Address of the Block (128 page/block)
	nPageAddr = (nPbn << (6 + IS_MLC));

	// Erase Command
	NF_CMD(CMD_ERASE);

	// Write Row Address
	NF_ADDR(nPageAddr&0xff);
	NF_ADDR((nPageAddr>>8)&0xff);
	NF_ADDR((nPageAddr>>16)&0xff);

	if (TWO_PLANE_PROGRAM == TRUE32 && !bSecondErase && bLoopNeed)
	{
		bSecondErase = TRUE32;
		goto _B_SecondErase;
	}

	// Erase confirm command
	NF_CMD( CMD_ERASE_CONFIRM);

	// Chip Unselect
	NF_CE_H(nBank);

#ifdef	USE_SETKMODE
	SetKMode(bLastMode);
#endif

	/* In the Internal Interleaving, it's forbidden NAND to do Write operation & the other operation
	   at the same time. When Write is going on in Bank 1, Bank 0 has to wait to finish 
	   the operation of Bank 1 if the next operation is not Write.

	   While Bank 1 is erased, Bank 0 do not start Write operation. (But, Erase or Read is allowed)
	   Internal Interleaving concept is only existed between Write and Write.	   
	*/
	if (bInternalInterleaving == TRUE32)
	{
		NAND_Sync(nVBank, &nSyncRet);
	}

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

	return;
}


/*****************************************************************************/
/*                                                                           */
/* NAME                                                                      */
/*      NAND_Sync		                                                     */
/* DESCRIPTION                                                               */
/*      This function checks the R/B signal of NAND					 		 */
/*		When it's busy, it means NAND is under operation.					 */
/*		When it's ready, it means NAND is ready for the next operation.		 */
/* PARAMETERS                                                                */
/*      nBank    	[IN] 	Physical device number			               	 */
/*																			 */
/* RETURN VALUES                                                             */
/*		FIL_CRITICAL_ERROR													 */
/*				When the input value is more than its range					 */
/*				or it has erase fail										 */
/*		FIL_SUCCESS															 */
/*				When the erase operation has done clearly					 */
/* NOTES                                                                     */
/*                                                                           */
/*****************************************************************************/
INT32
NAND_Sync(UINT32 nBank, UINT32 *nPlaneBitmap)
{
	UINT32	nData;
	UINT32	nPairBank;
	UINT32	nVBank;

	INT32	nRet = FIL_SUCCESS;

	BOOL32	bInternalBank = FALSE32;

#ifdef	USE_SETKMODE
	BOOL bLastMode;
#endif

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

	if (nBank >= BANKS_TOTAL)
	{
		NAND_ERR((_T("[FIL:ERR]--NAND_Sync() : Parameter overflow\r\n")));
		WMR_ASSERT(FALSE32);
		return FIL_CRITICAL_ERROR;
	}

	WMR_ASSERT(nPlaneBitmap != NULL);

	nVBank = nBank;

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

	if (bInternalInterleaving == TRUE32)
	{
		if ((nBank & 0x1) == 1)
		{
			bInternalBank = TRUE32;
		}
		nBank = (nBank >> 1);
	}

	if ((bInternalInterleaving == TRUE32) && (aNeedSync[nPairBank] == FALSE32))
	{
		// TODO: what does this means???
#if	1
		NF_CE_L(nBank);
		NF_ADDR(0x0);
		NF_CE_H(nBank);
#else
		BLUES_NF_ADDR0(0x0);
		rFMCTRL1 = (1 << BLUES_FM_ADDR_SET);

		BLUES_NF_CPU_CTRL0(nBank);
#endif
	}

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

	// Chip Select
	NF_CE_L(nBank);

	if (bInternalInterleaving || TWO_PLANE_READ_STATUS)
	{
		if (bInternalBank)
		{
			NF_CMD(CMD_READ_STATUS_CHIP1);
		}
		else
		{
			NF_CMD(CMD_READ_STATUS_CHIP0);
		}
	}
	else
	{
		// Read Status Command is acceptable during Busy
		NF_CMD(CMD_READ_STATUS);
	}

	do
	{
		nData = NF_DATA_R();
	}
	while(!(nData&NAND_STATUS_READY));

	*nPlaneBitmap = enuNONE_PLANE_BITMAP;

	// Read Status
	if (nData&NAND_STATUS_ERROR)
	{
		if (TWO_PLANE_READ_STATUS == TRUE32)
		{
			if (nData & NAND_STATUS_PLANE0_ERROR)
			{
				NAND_ERR((_T("[FIL:ERR] NAND_Sync() : Left-plane Sync Error\r\n")));
				*nPlaneBitmap = enuLEFT_PLANE_BITMAP;
			}
			if (nData & NAND_STATUS_PLANE1_ERROR)
			{
				NAND_ERR((_T("[FIL:ERR] NAND_Sync() : Right-plane Sync Error\r\n")));
				*nPlaneBitmap = enuRIGHT_PLANE_BITMAP;
			}
		}
		else
		{
			NAND_ERR((_T("[FIL:ERR] NAND_Sync() : Status Error\r\n")));
			*nPlaneBitmap = enuLEFT_PLANE_BITMAP;
		}

		nRet = FIL_CRITICAL_ERROR;
	}

	// Chip Unselect
	NF_CE_H(nBank);

#ifdef	USE_SETKMODE
	SetKMode(bLastMode);
#endif

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

	return nRet;
}

VOID
NAND_Reset(UINT32 nBank)
{
#ifdef	USE_SETKMODE
	BOOL bLastMode;
#endif

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

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

	// Chip Select
	NF_CE_L(nBank);

	// Reset Command is accepted during Busy
	NF_CMD(CMD_RESET);

	// Chip Unselect
	NF_CE_H(nBank);

#ifdef	USE_SETKMODE
	SetKMode(bLastMode);
#endif

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

	return;
}


/*****************************************************************************/
/*                                                                           */
/* NAME                                                                      */
/*      Read_DeviceID		                                                 */
/* DESCRIPTION                                                               */

⌨️ 快捷键说明

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