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

📄 nand.c

📁 s3c6410基于USB OTG下载内核至NORFLASH的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			}
		}
		
		if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
		{
			NF_CMD(Controller, 0x71); 						// Read Multi-plane status command	
		}
		else
			NF_CMD(Controller, 0x70);   						// Read status command

		while(!((uStatus = NF_RDDATA8(Controller)) & (1<<6)));
		if(uStatus & 0x01)
		{
			eError = eNAND_EraseError;		// Error in Erase
			NF_nFCE_H(Controller);
			uTemp = NAND_ReadNFCONRegister(Controller);
			uTemp &= ~((1<<10)|(1<<9));		// Illegal Access & RnB Transition Interrupt disable
			Outp32(&(NAND(Controller)->rNFCONT), uTemp);

			INTC_Disable(NUM_NFC);			
			return eError;
		}
		else
			eError = eNAND_NoError;
	
		//if (NF_RDDATA8(Controller)&0x1) 						// Erase error check
		//{
		//	eError = eNAND_EraseError;
		//	return eError;
		//}
		//else 
		//	eError = eNAND_NoError;
		   
		NF_nFCE_H(Controller);
	}

	uTemp = NAND_ReadNFCONRegister(Controller);
	uTemp &= ~((1<<10)|(1<<9));		// Illegal Access & RnB Transition Interrupt disable
	Outp32(&(NAND(Controller)->rNFCONT), uTemp);

	INTC_Disable(NUM_NFC);
	
	return eError;
}


//////////
// Function Name : NAND_SoftLockingBlock
// Function Description : This function lock the blocks, then when you try to write or erase the locked area, the illegal access will be occured
// Input : 	Controller - Nand Controller Port Number 
//			uStartBlock, uEndBlock - Enable Soft-Locking the other blocks except from uStartBlock[block] to uEndBlock-1[block]
// Output : 	Nand Error Type
NAND_eERROR NAND_SoftLockingBlock(u32 Controller, u32 uStartBlock, u32 uEndBlock)
{
	u32 uTemp;

	if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
	{
		Outp32(&(NAND(Controller)->rNFSBLK), uStartBlock<<5);
		Outp32(&(NAND(Controller)->rNFEBLK), (uEndBlock+1)<<5);
	}
	else if(NAND_Inform[Controller].uNandType == NAND_Advanced8bit)
	{
		Outp32(&(NAND(Controller)->rNFSBLK), uStartBlock<<6);
		Outp32(&(NAND(Controller)->rNFEBLK), (uEndBlock+1)<<6);
	}
	else if(NAND_Inform[Controller].uNandType == NAND_MLC8bit)
	{
		Outp32(&(NAND(Controller)->rNFSBLK), uStartBlock<<7);
		Outp32(&(NAND(Controller)->rNFEBLK), (uEndBlock+1)<<7);
	}
	
	uTemp = NAND_ReadNFCONRegister(Controller);
	uTemp |= (1<<16);		// Enable Soft lock
	Outp32(&(NAND(Controller)->rNFCONT), uTemp);	

	return eNAND_NoError;
}


//////////
// Function Name : NAND_LockTightBlock
// Function Description : This function lock-tight the blocks, then when you try to write or erase the locked area, the illegal access will be occured
//					  You cannot disable lock-tight by software. Only reset or wakeup from sleep mode can make disable lock-tight
// Input : 	Controller - Nand Controller Port Number 
//			uStartBlock, uEndBlock - Enable Lock-tight the other blocks except from uStartBlock[block] to uEndBlock-1[block]
// Output : 	Nand Error Type
NAND_eERROR NAND_LockTightBlock(u32 Controller, u32 uStartBlock, u32 uEndBlock)
{
	u32 uTemp;

	if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
	{
		Outp32(&(NAND(Controller)->rNFSBLK), uStartBlock<<5);
		Outp32(&(NAND(Controller)->rNFEBLK), (uEndBlock+1)<<5);
	}
	else if(NAND_Inform[Controller].uNandType == NAND_Advanced8bit)
	{
		Outp32(&(NAND(Controller)->rNFSBLK), uStartBlock<<6);
		Outp32(&(NAND(Controller)->rNFEBLK), (uEndBlock+1)<<6);
	}
	else if(NAND_Inform[Controller].uNandType == NAND_MLC8bit)
	{
		Outp32(&(NAND(Controller)->rNFSBLK), uStartBlock<<7);
		Outp32(&(NAND(Controller)->rNFEBLK), (uEndBlock+1)<<7);
	}
	
	uTemp = NAND_ReadNFCONRegister(Controller);
	uTemp |= (1<<17);		// Enable Lock-tight
	Outp32(&(NAND(Controller)->rNFCONT), uTemp);	

	return eNAND_NoError;
}


//////////
// Function Name : NAND_UnLockBlock
// Function Description : This function unlock the soft-locked blocks
// Input : 	Controller - Nand Controller Port Number 
// Output : 	Nand Error Type
NAND_eERROR NAND_UnLockBlock(u32 Controller)
{
	u32 uTemp;

	uTemp = NAND_ReadNFCONRegister(Controller);
	if(!(uTemp & (1<<16)))
		return eNAND_NoError;
	
	Outp32(&(NAND(Controller)->rNFSBLK), 0);
	Outp32(&(NAND(Controller)->rNFEBLK), 0);
	
	//uTemp = NAND_ReadNFCONRegister(Controller);
	uTemp &= ~(1<<16);		// Disable Soft lock
	Outp32(&(NAND(Controller)->rNFCONT), uTemp);	

	uTemp = NAND_ReadNFCONRegister(Controller);

	if(uTemp & (1<<16))
		return eNAND_EtcError;
	
	return eNAND_NoError;
}


//////////
// Function Name : NAND_UnLockTightBlock
// Function Description : This function unlock the lock-tight blocks, but cannot unlock those blocks.  This is for test..!!!
// Input : 	Controller - Nand Controller Port Number 
// Output : 	Nand Error Type
NAND_eERROR NAND_UnLockTightBlock(u32 Controller)
{
	u32 uTemp;

	uTemp = NAND_ReadNFCONRegister(Controller);
	if(!(uTemp & (1<<17)))
		return eNAND_NoError;
		
	Outp32(&(NAND(Controller)->rNFSBLK), 0);
	Outp32(&(NAND(Controller)->rNFEBLK), 0);
	
	//uTemp = NAND_ReadNFCONRegister(Controller);
	uTemp &= ~(1<<17);		// Disable lock-tight. but this bit is not cleared...for test
	Outp32(&(NAND(Controller)->rNFCONT), uTemp);	

	uTemp = NAND_ReadNFCONRegister(Controller);

	if(!(uTemp & (1<<17)))
		return eNAND_EtcError;
	
	return eNAND_NoError;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////                     For ECC Error Test                   //////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////

//////////
// Function Name : NAND_WritePageSLCWithInvalidData
// Function Description : This function write the 1 page invalid data test ECC Error
// Input : 	Controller - Nand Controller Port Number 
//			uBlock - Write Block
//			uPage - Write Page
//			pBuffer - Write data buffer
//			uErrorType - ECC Error Type
// Output : 	ECC Error Type 
NAND_eERROR NAND_WritePageSLCWithInvalidData(u32 Controller, u32 uBlock, u32 uPage, u8 *pBuffer, u32 uErrorType)
{
	u32 i, uBlockPage, uPageSize, uSpareSize, uTemp, uStatus;
	u8 *pErrorBuffer;
	NAND_eERROR eError;	

	pErrorBuffer = pBuffer;
	
	uTemp = NAND_ReadNFCONRegister(Controller);
	uTemp &= ~((1<<13)|(1<<12));		// 4bit ECC encoding/decoding completion Interrupt disable
	uTemp |= (1<<10) | (1<<9);		// Illegal Access & RnB Transition Interrupt enable
	Outp32(&(NAND(Controller)->rNFCONT), uTemp);
	
	Outp32(&(NAND(Controller)->rNFSTAT), (1<<5)|(1<<4));		// Illegal Access & RnB Interrupt Pending bit clear
	INTC_Enable(NUM_NFC);
	
	if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
	{
		uBlockPage=(uBlock<<5) + uPage;
		uPageSize = NAND_Inform[Controller].uPageSize;
		uSpareSize = NAND_Inform[Controller].uSpareSize;
	}
	else //if(NAND_Inform[Controller].uNandType == NAND_Advanced8bit)
	{
		uBlockPage=(uBlock<<6) + uPage;
		uPageSize = NAND_Inform[Controller].uPageSize;
		uSpareSize = NAND_Inform[Controller].uSpareSize;
	}

	//////////////////////////
	// Generate the Error Data
	//////////////////////////
	// The ECC value of valid data(1 page) has in the aNand_Spare_Data_Temp[] array
#if 0	
	if(uErrorType == NAND_ECCERR_1BIT)
	{
		pErrorBuffer[100] ^= 0x01;		// 1st bit toggle, then generate the 1bit ecc error		
	}
	else if(uErrorType == NAND_ECCERR_MULTI)
	{
		pErrorBuffer[100] ^= 0x01;		// 1st bit toggle, then generate the 1bit ecc error		
		pErrorBuffer[200] ^= 0x01;		// 1st bit toggle, then generate the 1bit ecc error			
	}
#else
	if(uErrorType == NAND_ECCERR_1BIT)
	{
		pErrorBuffer[NAND_EccError.uEccErrByte1] ^= (1<<NAND_EccError.uEccErrBit1);		
	}
	else if(uErrorType == NAND_ECCERR_MULTI)
	{
		pErrorBuffer[NAND_EccError.uEccErrByte1] ^= (1<<NAND_EccError.uEccErrBit1);	
		pErrorBuffer[NAND_EccError.uEccErrByte2] ^= (1<<NAND_EccError.uEccErrBit2);	
	}
#endif

	//////////////////////////
	// Write 0 ~ uPageSize
	//////////////////////////
	
	NF_RSTECC(Controller);    // Initialize ECC
	NF_MECC_UnLock(Controller);
    
	NF_nFCE_L(Controller);    
	NF_CLEAR_RnB(Controller);

	NF_CMD(Controller, 0x80);	// Read command
	NF_ADDR(Controller, 0); 
		
	//if(NAND_Inform[Controller].uNandType == NAND_Advanced8bit)
	if(NAND_Inform[Controller].uAddrCycle == 5)
		NF_ADDR(Controller, 0); 
	
	NF_ADDR(Controller, uBlockPage&0xff);		//
	NF_ADDR(Controller, (uBlockPage>>8)&0xff);	// Block & Page num.
	NF_ADDR(Controller, (uBlockPage>>16)&0xff);	//

	for(i=0 ; i<uPageSize/4 ; i++) 
	{
		NF_WRDATA(Controller, *pBuffer++);		// Write one page
	}

	NF_MECC_Lock(Controller);

	for(i=0 ; i<uSpareSize; i++) 
	{
		NF_WRDATA8(Controller, aNand_Spare_Data_Temp[i]);  		// The ECC value of the valid data
	}

	NF_CLEAR_RnB(Controller);
	
	g_Nand_RnBTransition = 0;	
	NF_CMD(Controller, 0x10);	 // Write 2nd command	

	while(!g_Nand_RnBTransition);
	
	//Read Program Status
	NF_CMD(Controller, 0x70);

	while(!((uStatus = NF_RDDATA8(Controller)) & (1<<6)));
	if(uStatus & 0x01)
		eError = eNAND_ProgramError;		// Error in Program
	else
		eError = eNAND_NoError;

	NF_nFCE_H(Controller);
	
	uTemp = NAND_ReadNFCONRegister(Controller);
	uTemp &= ~((1<<10) | (1<<9));		// Illegal Access & RnB Transition Interrupt disable
	Outp32(&(NAND(Controller)->rNFCONT), uTemp);

	// rb1004 : must be modify...Interrupt Controller
	//INT_Disable1(BIT_INT_NFC);
	INTC_Disable(NUM_NFC);	

	// restore the valid data
	if(uErrorType == NAND_ECCERR_1BIT)
	{
		pErrorBuffer[NAND_EccError.uEccErrByte1] ^= (1<<NAND_EccError.uEccErrBit1);		
	}
	else if(uErrorType == NAND_ECCERR_MULTI)
	{
		pErrorBuffer[NAND_EccError.uEccErrByte1] ^= (1<<NAND_EccError.uEccErrBit1);	
		pErrorBuffer[NAND_EccError.uEccErrByte2] ^= (1<<NAND_EccError.uEccErrBit2);	
	}
	
	return eError;
}


//////////
// Function Name : NAND_WritePageMLCWithInvalidData
// Function Description : This function write the 1 page invalid data to test ECC Error
// Input : 	Controller - Nand Controller Port Number 
//			uBlock - Write Block
//			uPage - Write Page
//			pBuffer - Write data buffer
//			uErrorType - ECC Error Type
// Output : 	Nand Error Type
NAND_eERROR NAND_WritePageMLCWithInvalidData(u32 Controller, u32 uBlock, u32 uPage, u8 *pBuffer, u32 uErrorType)
{
	u32 i, uBlockPage, uSpareSize, uTemp, uStatus;
	u8 *pErrorBuffer;
	NAND_eERROR eError;
	u32 uDataPos[5]={0, }, uSparePos[5]={0, };
	u32 uMLCECCErrBytePos[5]={0, };
	u32 uMinusSpareArea;
	
	pErrorBuffer = pBuffer;
	g_Nand_IllegalAccError = 0;
	
	uTemp = NAND_ReadNFCONRegister(Controller);
	//uTemp |= (1<<13)|(1<<10)|(1<<9);		// 4bit ECC encoding & Illegal Access & RnB Transition Interrupt enable
	uTemp |= (1<<13)|(1<<12)|(1<<10)|(1<<9);		// 4bit ECC encoding & Illegal Access & RnB Transition Interrupt enable..because error
	uTemp |= (1<<18);		// Encoding 4bit ECC selection
	Outp32(&(NAND(Controller)->rNFCONT), uTemp);

	Outp32(&(NAND(Controller)->rNFSTAT), (1<<7));		// 4bit ECC encoding finish bit clear
	INTC_Enable(NUM_NFC);

	uBlockPage=(uBlock<<7) + uPage;
	uSpareSize = NAND_Inform[Controller].uSpareSize;

	//////////////////////////
	// Generate the Error Data
	//////////////////////////
	// The ECC value of valid data(512bytes) has in the aNand_Spare_Data_Temp[] array
	if(uErrorType == NAND_ECCERR_1BIT)
	{
		uMLCECCErrBytePos[0] = NAND_Inform[Controller].uMLCECCErrBytePos[0];	// 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
		uMinusSpareArea = NAND_Inform[Controller].uMLCECCPageWriteSector*NAND_MLC_ECC_SIZE;
	
		uSparePos[0] = NAND_EccError.uEccErrByte1 - ((NAND_Inform[Controller].uMLCECCPageWriteSector+1)*NAND_MLC_TRANS_SIZE) + 1;	
		uDataPos[0] = NAND_EccError.uEccErrByte1 - uMinusSpareArea;
		
		if( uMLCECCErrBytePos[0] < NAND_MLC_TRANS_SIZE)
			pErrorBuffer[uDataPos[0]] ^= (1<<NAND_EccError.uEccErrBit1);
		else
			aNand_Spare_Data_Temp[uSparePos[0]] ^= (1<<NAND_EccError.uEccErrBit1);
	}
	else if(uErrorType == NAND_ECCERR_2BIT)
	{
		uMLCECCErrBytePos[0] = NAND_Inform[Controller].uMLCECCErrBytePos[0];	// 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
		uMLCECCErrBytePos[1] = NAND_Inform[Controller].uMLCECCErrBytePos[1];	// 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
		uMinusSpareArea = NAND_Inform[Controller].uMLCECCPageWriteSector*NAND_MLC_ECC_SIZE;
		
		uSparePos[0] = NAND_EccError.uEccErrByte1 - ((NAND_Inform[Controller].uMLCECCPageWriteSector+1)*NAND_MLC_TRANS_SIZE) + 1;	
		uDataPos[0] = NAND_EccError.uEccErrByte1 - uMinusSpareArea;

		uSparePos[1] = NAND_EccError.uEccErrByte2 - ((NAND_Inform[Controller].uMLCECCPageWriteSector+1)*NAND_MLC_TRANS_SIZE) + 1;	
		uDataPos[1] = NAND_EccError.uEccErrByte2 - uMinusSpareArea;

		if( uMLCECCErrBytePos[0] < NAND_MLC_TRANS_SIZE)
			pErrorBuffer[uDataPos[0]] ^= (1<<NAND_EccError.uEccErrBit1);
		else
			aNand_Spare_Data_Temp[uSparePos[0]] ^= (1<<NAND_EccError.uEccErrBit1);

		if( uMLCECCErrBytePos[1] < NAND_MLC_TRANS_SIZE)
			pErrorBuffer[uDataPos[1]] ^= (1<<NAND_EccError.uEccErrBit2);
		else	
			aNand_Spare_Data_Temp[uSparePos[1]] ^= (1<<NAND_EccError.uEccErrBit2);
	}
	else if(uErrorType == NAND_ECCERR_3BIT)
	{
		uMLCECCErrBytePos[0] = NAND_Inform[Controller].uMLCECCErrBytePos[0];	// 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
		uMLCECCErrBytePos[1] = NAND_Inform[Controller].uMLCECCErrBytePos[1];	// 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
		uMLCECCErrBytePos[2] = NAND_Inform[Controller].uMLCECCErrBytePos[2];	// 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
		uMinusSpareArea = NAND_Inform[Controller].uMLCECCPageWriteSector*NAND_MLC_ECC_SIZE;
		
		uSparePos[0] = NAND_EccError.uEccErrByte1 - ((NAND_Inform[Controller].uMLCECCPageWriteSector+1)*NAND_MLC_TRANS_SIZE) + 1;	
		uDataPos[0] = NAND_EccError.uEccErrByte1 - uMinusSpareArea;

		uSparePos[1] = NAND_EccError.uEccErrByte2 - ((NAND_Inform[Controller].uMLCECCPageWriteSector+1)*NAND_MLC_TRANS_SIZE) + 1;	
		uDataPos[1] = NAND_EccError.uEccErrByte2 - uMinusSpareArea;

		uSparePos[2] = NAND_EccError.uEccErrByte3 - ((NAND_Inform[Controller].uMLCECCPageWriteSector+1)*NAND_MLC_TRANS_SIZE) + 1;	
		uDataPos[2] = NAND_EccError.uEccErrByte3 - uMinusSpareArea;
		
		if( uMLCECCErrBytePos[0] < NAND_MLC_TRANS_SIZE)
			pErrorBuffer[uDataPos[0]] ^= (1<<NAND_EccError.uEccErrBit1);
		else
			aNand_Spare_Data_Temp[uSparePos[0]] ^= (1<<NAND_EccError.uEccErrBit1);

		if( uMLCECCErrBytePos[1] < NAND_MLC_TRANS_SIZE)
			pErrorBuffer[uDataPos[1]] ^= (1<<NAND_EccError.uEccErrBit2);
		else	
			aNand_Spare_Data_Temp[uSparePos[1]] ^= (1<<NAND_EccError.uEccErrBit2);

		if( uMLCECCErrBytePos[2] < NAND_MLC_TRANS_SIZE)
			pErrorBuffer[uDataPos[2]] ^= (1<<NAND_EccError.uEccErrBit3);
		else	
			aNand_Spare_Data_Temp[uSparePos[2]] ^= (1<<NAND_EccError.uEccErrBit3);
	}
	else if(uErrorType == NAND_ECCERR_4BIT)
	{
		uMLCECCErrBytePos[0] = NAND_Inform[Controller].uMLCECCErrBytePos[0];	// 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
		uMLCECCErrBytePos[1] = NAND_Inform[Controller].uMLCECCErrBytePos[1];	// 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExceptCnt)....0 ~ 518
		uMLCECCErrBytePos[2] = NAND_Inform[Controller].uMLCECCErrBytePos[2];	// 0 ~ (NAND_MLC_TRANS_SIZE + NAND_MLC_ECC_SIZE-uExcep

⌨️ 快捷键说明

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