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

📄 s3c6410_fil.c

📁 6410BSP3
💻 C
📖 第 1 页 / 共 5 页
字号:
	{
        NF_SETREG_8BITECC();
		Write_Spare_Separate(nBank, nPpn, pSpareCxt);
        NF_SETREG_4BITECC();
	}
	else
	{
		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_Write_Steploader	                                             */
/* 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_Steploader_Write(UINT32 nBank, UINT32 nPpn, UINT32 nSctBitmap,
			UINT32  nPlaneBitmap, UINT8* pDBuf, UINT8* pSBuf)
{
	UINT32 nCnt;
	UINT32 nPbn;
	UINT32 nPOffset;
	UINT32 i;

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

	SECCInfo tSECCInfo;


#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;
	}


#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

	pNANDFConReg->NFCONF = (pNANDFConReg->NFCONF & ~((1<<30)|(3<<23))) | (1<<23) | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1); // System Clock is more than 66Mhz, ECC type is MLC.
	pNANDFConReg->NFCONT |= (1<<18)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9); //ECC for programming.// Enable RnB Interrupt 
	pNANDFConReg->NFSTAT |= ((1<<6)|(1<<5)|(1<<4));

	// CE Select
	NF_CE_L(nBank);
	
	NF_CMD(CMD_PROGRAM);
	NF_SET_ADDR(nPpn, 0);

	WMR_MEMSET(&tSECCInfo, 0xFF, 53);		// Initialize the spare buffer
	// Write Main Sector
	if (pDBuf != NULL)
	{
		for (nCnt=0; nCnt<SECTORS_PER_PAGE; nCnt++)
		{
			NF_MECC_UnLock();
			NF_MECC_Reset();

			if ((UINT32)pDBuf&0x3)
			{
				_Write_512Byte_Unaligned(pDBuf+NAND_SECTOR_SIZE*nCnt);
			}
			else
			{
				_Write_512Byte(pDBuf+NAND_SECTOR_SIZE*nCnt);
			}

			NF_MECC_Lock();

			while(!(pNANDFConReg->NFSTAT&(1<<7))) ;
			pNANDFConReg->NFSTAT|=(1<<7);

			tSECCInfo.t8MECC[nCnt].n8MECC0 = NF_8MECC0();
			tSECCInfo.t8MECC[nCnt].n8MECC1 = NF_8MECC1();
			tSECCInfo.t8MECC[nCnt].n8MECC2 = NF_8MECC2();
			tSECCInfo.t8MECC[nCnt].n8MECC3 = (NF_8MECC3() & 0xff);
		}

		
	}

//	NF_DATA_W(tSECCInfo.nBadBlock); // 1 byte n8MECC3 ==> bad block marker

	for(i = 0; i < SECTORS_PER_PAGE; i++) {
		NF_DATA_W4(tSECCInfo.t8MECC[i].n8MECC0); // 4 byte n8MECC0
		NF_DATA_W4(tSECCInfo.t8MECC[i].n8MECC1); // 4 byte n8MECC1
		NF_DATA_W4(tSECCInfo.t8MECC[i].n8MECC2); // 4 byte n8MECC2
		NF_DATA_W((tSECCInfo.t8MECC[i].n8MECC3) & 0xff); // 1 byte n8MECC3
	}

	pNANDFConReg->NFSTAT |=  (1<<4); //NF_CLEAR_RB
	NF_CMD(CMD_PROGRAM_CONFIRM);

//	NF_DETECT_RB();
	NF_WAIT_RnB(nBank);

	NF_CMD(CMD_READ_STATUS);   // Read status command       

	for(i=0;i<3;i++);  //twhr=60ns
    
   	 if (NF_DATA_R()&NAND_STATUS_ERROR) 
    	{// Page write error
		NF_CE_H(nBank);
		RETAILMSG(1,(TEXT("##### Error write operation #####\r\n")));
		pNANDFConReg->NFCONF = NF_4BIT_ECC | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
		return;
	} 
	else
	{
		NF_CE_H(nBank);
		pNANDFConReg->NFCONF = NF_4BIT_ECC | NF_TACLS(DEFAULT_TACLS) | NF_TWRPH0(DEFAULT_TWRPH0) | NF_TWRPH1(DEFAULT_TWRPH1);
		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));
//	NAND_ERR((_T("[FIL]++NAND_Erase(%d, %d, 0x%02x)\r\n"), nBank, nPbn, nPlaneBitmap));

	if (nBank >= BANKS_TOTAL || nPbn >= BLOCKS_PER_BANK)
	{
    	NAND_ERR((_T("[FIL]++NAND_Erase(%d, %d, 0x%02x)\r\n"), nBank, nPbn, nPlaneBitmap));
		NAND_ERR((_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);

⌨️ 快捷键说明

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