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

📄 nand.c

📁 s3c6410基于USB OTG下载内核至NORFLASH的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		
		DMACH_Start(&g_oNandDmac1);
		while(!Nand_DmaDone);	
		pBufferW += NAND_MLC_TRANS_SIZE/4;
	#endif

	NF_CMD(Controller, 0x05);
	NF_ADDR(Controller, (uPageSize+15)&0xFF);
	NF_ADDR(Controller, ((uPageSize+15)>>8)&0xFF);
	NF_CMD(Controller, 0xE0);

	for(i=15;i<22;i++) 
	{
		aNand_Spare_Data[i] = NF_RDDATA8(Controller);	
		if(NAND_Inform[Controller].uPerformanceCheck == 0)
			*pSpareBuffer++ = aNand_Spare_Data[i];	
	}	

	while(g_Nand_4bitEccDecDone == 0);

	eError = NAND_CheckECCError(Controller);
	if(eError != eNAND_NoError)
	{
		NF_MECC_Lock(Controller);		
		NF_nFCE_H(Controller);
		uTemp = NAND_ReadNFCONRegister(Controller);
		uTemp &= ~(1<<12);		// 4bit ECC decoding Interrupt enable
		Outp32(&(NAND(Controller)->rNFCONT), uTemp);	
		NAND_Inform[Controller].uMLCECCPageReadSector = 2;		//1024 ~ 1535 Bytes
		return eError;
	}
	
	//////////////////////////
	// Read 1536 ~ 2047
	//////////////////////////
	g_Nand_4bitEccDecDone = 0;
	NF_RSTECC(Controller);    // Initialize ECC

#if (NAND_REG_BUG == TRUE)
	uTemp = NAND_ReadNFCONRegister(Controller);
	uTemp |= (1<<12)|(1<<13);		// 4bit ECC decoding/encoding Interrupt enable...because error
	Outp32(&(NAND(Controller)->rNFCONT), uTemp);	
#endif

	NF_CMD(Controller, 0x05);
	NF_ADDR(Controller, (512*3)&0xFF);
	NF_ADDR(Controller, ((512*3)>>8)&0xFF);
	NF_CMD(Controller, 0xE0);

    	#if NAND_TRANSFER_MODE == POLLING_TRANSFER
	#if 0	
		for(i=0 ; i<NAND_MLC_TRANS_SIZE ; i++) 	// MLC ECC Size : 512bytes
		{
			*pBuffer++ = NF_RDDATA8(Controller);	// Read one page
		}
	#else
		for(i=0 ; i<NAND_MLC_TRANS_SIZE/4 ; i++) 
		{
			*pBufferW++ = NF_RDDATA(Controller);	// Read one page
		}
	#endif
	#elif NAND_TRANSFER_MODE == DMA_TRANSFER
		Nand_DmaDone = 0;
		DMACH_Setup(DMA_A, 0x0, (u32)(&(NAND(Controller)->rNFDATA)), 1, (u32)pBufferW, 0, WORD, NAND_MLC_TRANS_SIZE/4, DEMAND, DMA1_NAND_TX, MEM, BURST128, &g_oNandDmac1);
		
		DMACH_Start(&g_oNandDmac1);
		while(!Nand_DmaDone);	
		pBufferW += NAND_MLC_TRANS_SIZE/4;
	#endif

	NF_CMD(Controller, 0x05);
	NF_ADDR(Controller, (uPageSize+22)&0xFF);
	NF_ADDR(Controller, ((uPageSize+22)>>8)&0xFF);
	NF_CMD(Controller, 0xE0);

	for(i=22;i<29;i++) 
	{
		aNand_Spare_Data[i] = NF_RDDATA8(Controller);	
		if(NAND_Inform[Controller].uPerformanceCheck == 0)
			*pSpareBuffer++ = aNand_Spare_Data[i];	
	}	

	while(g_Nand_4bitEccDecDone == 0);

	eError = NAND_CheckECCError(Controller);
	if(eError != eNAND_NoError)
	{
		NF_MECC_Lock(Controller);		
		NF_nFCE_H(Controller);
		uTemp = NAND_ReadNFCONRegister(Controller);
		uTemp &= ~(1<<12);		// 4bit ECC decoding Interrupt enable
		Outp32(&(NAND(Controller)->rNFCONT), uTemp);		
		NAND_Inform[Controller].uMLCECCPageReadSector = 3;		// 1536 ~ 2047 Bytes
		return eError;
	}

	NF_nFCE_H(Controller);

	NF_MECC_Lock(Controller);	

	uTemp = NAND_ReadNFCONRegister(Controller);
	uTemp &= ~((1<<12)|(1<<13));		// 4bit ECC decoding/encoding Interrupt disable
	Outp32(&(NAND(Controller)->rNFCONT), uTemp);
	
	INTC_Disable(NUM_NFC);
	
	return eNAND_NoError;
}



//////////
// Function Name : NAND_ReadPage
// Function Description : This function read the 1 page data of external NAND device
// Input : 	Controller - Nand Controller Port Number 
//			uBlock - Read Block
//			uPage - Read Page
//			pBuffer - Read data buffer
// Output : 	Nand Error Type
NAND_eERROR NAND_ReadPage(u32 Controller, u32 uBlock, u32 uPage, u8 *pBuffer, u8 *pSpareBuffer)
{
	NAND_eERROR eError;

	if( (NAND_Inform[Controller].uNandType == NAND_Normal8bit) || (NAND_Inform[Controller].uNandType == NAND_Advanced8bit) )
		eError = NAND_ReadPageSLC(Controller, uBlock, uPage, pBuffer, pSpareBuffer);
	else //if(NAND_Inform[Controller].uNandType == NAND_MLC8bit)
		eError = NAND_ReadPageMLC(Controller, uBlock, uPage, pBuffer, pSpareBuffer);

	return eError;
}


//////////
// Function Name : NAND_ReadMultiPage
// Function Description : This function read the multi page data of external NAND device
// Input : 	Controller - Nand Controller Port Number 
//			uBlock - Read Block
//			uPage - Read Page
//			pBuffer - Read data buffer
// Output : 	Nand Error Type
NAND_eERROR NAND_ReadMultiPage(u32 Controller, u32 uStartBlock, u32 uStartPage, u8 *pBuffer, u32 uSize)
{
	u8 aSpareBuffer[NAND_SPARE_MAX];
	u32 i, uPageCnt, uBlock, uPage;
	NAND_eERROR eError;

	uPageCnt = uSize/NAND_Inform[Controller].uPageSize;
	uBlock = uStartBlock;
	uPage = uStartPage;
	
	for(i=0 ; i<uPageCnt ; i++)
	{
		if( (NAND_Inform[Controller].uNandType == NAND_Normal8bit) || (NAND_Inform[Controller].uNandType == NAND_Advanced8bit) )
			eError = NAND_ReadPageSLC(Controller, uBlock, uPage, pBuffer, aSpareBuffer);
		else
			eError = NAND_ReadPageMLC(Controller, uBlock, uPage, pBuffer, aSpareBuffer);

		if(eError != eNAND_NoError)
			return eError;
		
		pBuffer += NAND_Inform[Controller].uPageSize;
		uPage++;

		if(uPage == NAND_Inform[Controller].uPageNum)
		{
			uBlock++;
			uPage = 0;
		}
	}
	
	return eError;
}


//////////
// Function Name : NAND_WritePageSLC
// Function Description : This function write the 1 page data of external SLC Type NAND device
// Input : 	Controller - Nand Controller Port Number 
//			uBlock - Write Block
//			uPage - Write Page
//			pBuffer - Write data buffer
//			aSpareBuffer - Memory to store the spare data
// Output : 	ECC Error Type 
NAND_eERROR NAND_WritePageSLC(u32 Controller, u32 uBlock, u32 uPage, u8 *pBuffer, u8 *aSpareBuffer)
{
	u32 i, uBlockPage, uPageSize, uSpareSize, uTemp;
	u32 uMecc, uSecc, uStatus;
	NAND_eERROR eError;	
	u32 *pBufferW;
			
	pBufferW = (u32 *)pBuffer;			
	g_Nand_RnBTransition = 0;

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

	NF_RSTECC(Controller);    // Initialize ECC
	NF_MECC_UnLock(Controller);
    
	NF_nFCE_L(Controller);    
	NF_CLEAR_RnB(Controller);

	NF_CMD(Controller, 0x80);	// Program 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);	//

    	#if NAND_TRANSFER_MODE == POLLING_TRANSFER
	#if 0
		for(i=0 ; i<uPageSize ; i++) 
		{
			NF_WRDATA8(Controller, *pBuffer++);		// Write one page
		}
	#else
		for(i=0 ; i<uPageSize/4 ; i++) 
		{
			NF_WRDATA(Controller, *pBufferW++);	// Read one page
		}
	#endif		
	#elif NAND_TRANSFER_MODE == DMA_TRANSFER
		Nand_DmaDone = 0;
		DMACH_Setup(DMA_A, 0x0, (u32)pBufferW, 0, (u32)(&(NAND(Controller)->rNFDATA)), 1, WORD, uPageSize/4, DEMAND, MEM, DMA1_NAND_RX, BURST128, &g_oNandDmac1);
			
		DMACH_Start(&g_oNandDmac1);
		while(!Nand_DmaDone);	
	#endif

	NF_MECC_Lock(Controller);
	g_Nand_IllegalAccError  = 0;

	if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
	{
		// Main Area ECC
		uMecc = Inp32(&NAND(Controller)->rNFMECC0);

		aNand_Spare_Data[0] = (u8)(uMecc&0xFF);
		aNand_Spare_Data[1] = (u8)((uMecc&0xFF00)>>8);
		aNand_Spare_Data[2] = (u8)((uMecc&0xFF0000)>>16);
		aNand_Spare_Data[3] = (u8)((uMecc&0xFF000000)>>24);
		aNand_Spare_Data[5] = (u8)0xFF;			//Marking Valid Block

		NF_SECC_UnLock(Controller);

		for(i=0;i<4;i++) 
		{
			NF_WRDATA8(Controller, aNand_Spare_Data[i]);		// Write spare array(Main ECC)
			//NF8_Spare_Data[i]=aNand_Spare_Data[i];
    		} 
	
		NF_SECC_Lock(Controller);

		// Spare Area ECC
		uSecc = Inp32(&NAND(Controller)->rNFSECC) & 0xFFFF;

		aNand_Spare_Data[8] = (u8)(uSecc&0xFF);
		aNand_Spare_Data[9] = (u8)((uSecc&0xFF00)>>8);

		for(i=4 ; i<uSpareSize; i++) 
		{
			NF_WRDATA8(Controller, aNand_Spare_Data[i]);  // Write spare array(Spare ECC and Mark)
			//NF8_Spare_Data[i]=aNand_Spare_Data[i];
		}  

		NF_CLEAR_RnB(Controller);
		NF_CMD(Controller, 0x10);	 // Write 2nd command	
	}
	else if(NAND_Inform[Controller].uNandType == NAND_Advanced8bit)
	{	
		// Main Area ECC
		uMecc = Inp32(&NAND(Controller)->rNFMECC0);

		aNand_Spare_Data[0] = (u8)0xFF;				//Marking Valid Block
		aNand_Spare_Data[1] = (u8)(uMecc&0xFF);
		aNand_Spare_Data[2] = (u8)((uMecc&0xFF00)>>8);
		aNand_Spare_Data[3] = (u8)((uMecc&0xFF0000)>>16);
		aNand_Spare_Data[4] = (u8)((uMecc&0xFF000000)>>24);

		NF_WRDATA8(Controller, aNand_Spare_Data[0]);	//Write Marking Valid Block
		
		NF_SECC_UnLock(Controller);
		for(i=1;i<5;i++) 
		{
			NF_WRDATA8(Controller, aNand_Spare_Data[i]);		// Write spare array(Main ECC)
			//NF8_Spare_Data[i]=aNand_Spare_Data[i];
    		} 
		NF_SECC_Lock(Controller);

		// Spare Area ECC
		uSecc = Inp32(&NAND(Controller)->rNFSECC) & 0xFFFF;

		aNand_Spare_Data[8] = (u8)(uSecc&0xFF);
		aNand_Spare_Data[9] = (u8)((uSecc&0xFF00)>>8);

		for(i=5 ; i<uSpareSize; i++) 
		{
			NF_WRDATA8(Controller, aNand_Spare_Data[i]);  // Write spare array(Spare ECC and Mark)
			//NF8_Spare_Data[i]=aNand_Spare_Data[i];
		}  

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

	while(!g_Nand_RnBTransition)
	{
		if(g_Nand_IllegalAccError == 1)
		{
			NAND_Reset(Controller);
			g_Nand_IllegalAccError = 0;
			return eNAND_ProgramError;
		}
	}

	//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;
	
//	if(NF_RDDATA8(Controller) & 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);

	if(NAND_Inform[Controller].uECCtest == 1)
	{
		for(i=0 ; i<uSpareSize ; i++)
			aNand_Spare_Data_Temp[i] = aNand_Spare_Data[i];
	}

	for(i=0 ; i<uSpareSize ; i++)
	{
		*aSpareBuffer++ = aNand_Spare_Data[i];
	}
	
	INTC_Disable(NUM_NFC);

	return eError;
}


//////////
// Function Name : NAND_WritePageMLC
// Function Description : This function write the 1 page data of external NAND device
// Input : 	Controller - Nand Controller Port Number 
//			uBlock - Write Block
//			uPage - Write Page
//			pBuffer - Write data buffer
// Output : 	Nand Error Type
NAND_eERROR NAND_WritePageMLC(u32 Controller, u32 uBlock, u32 uPage, u8 *pBuffer, u8 *aSpareBuffer)
{
	u32 i, uBlockPage, uSpareSize, uTemp;
	u32 uMecc0, uMecc1, uStatus;
	//u32 uSecc;
	NAND_eERROR eError;
	u32 *pBufferW;
			
	pBufferW = (u32 *)pBuffer;
	g_Nand_4bitEccEncDone = 0;
	g_Nand_RnBTransition = 0;
	g_Nand_IllegalAccError = 0;
	
	uTemp = NAND_ReadNFCONRegister(Controller);
#if (NAND_REG_BUG == TRUE)
	uTemp |= (1<<18)|(1<<13)|(1<<12)|(1<<10)|(1<<9);		// 4bit ECC encoding& decoding & Illegal Access & RnB Transition Interrupt enable..because error
#else
	uTemp |= (1<<18)|(1<<13)|(1<<10)|(1<<9);		// 4bit ECC encoding & Illegal Access & RnB Transition Interrupt enable
#endif	
	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;

	//////////////////////////
	// Write 0 ~ 511
	//////////////////////////
	NF_RSTECC(Controller);    // Initialize ECC
	NF_MECC_UnLock(Controller);
    
	NF_nFCE_L(Controller);    
#if (NAND_REG_BUG == TRUE)
	uTemp = NAND_ReadNFCONRegister(Controller);
	uTemp |= (1<<12)|(1<<13);		// 4bit ECC decoding/encoding Interrupt enable...because error
	Outp32(&(NAND(Controller)->rNFCONT), uTemp);	
#endif	
	NF_CLEAR_RnB(Controller);

	NF_CMD(Controller, 0x00);	// 1st Read command..????

⌨️ 快捷键说明

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