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

📄 onenand.c

📁 s3c6400 ADS下官方测试程序
💻 C
📖 第 1 页 / 共 4 页
字号:
	{
		return eOND_NOERROR;
	}
		
#endif


#if 0
	ONENAND_WriteCmd(Controller, uEndBlkAddr, 0, 0x00);
	ONENAND_ReadCmd(Controller, uEndBlkAddr, 0, &uData);

	// Wait Erase Completion
	while(uData)
	{
		ONENAND_ReadCmd(Controller, uEndBlkAddr, &uData);
	}

	return eOND_ERSCMP;
#endif
	if(OneNandT_oIntFlag.ErsCmpInt == 1)
		return eOND_NOERROR;
	else
		return eOND_ERSFAIL;

}

#else
OneNAND_eINTERROR ONENAND_EraseBlock(u32 Controller, u32 uStartBlkAddr, u32 uEndBlkAddr)
{
	u32 i, j, uBlockSize, uQuotient, uRemainder;
	u32 uBlock;

	if(uEndBlkAddr < uStartBlkAddr)
		return eOND_NOERROR;

	OneNandT_oIntFlag.IntActInt = 0;
	OneNandT_oIntFlag.ErsFailInt = 0;
	OneNandT_oIntFlag.LockedBlkInt = 0;
	OneNandT_oIntFlag.ErsCmpInt = 0;

	if(uStartBlkAddr == uEndBlkAddr)
	{
		ONENAND_WriteCmd(Controller, uEndBlkAddr, 0, 0x03);
		while(!OneNandT_oIntFlag.IntActInt);

		OneNandT_oIntFlag.IntActInt = 0;
		ONENAND_WriteCmd(Controller, uEndBlkAddr, 0, 0x15);
		while(!OneNandT_oIntFlag.IntActInt);

		if(OneNandT_oIntFlag.ErsFailInt == 1)
		{
			OneNandT_oIntFlag.ErsFailInt = 0;
			if(OneNandT_oIntFlag.LockedBlkInt == 1)
				return (OneNAND_eINTERROR)(eOND_ERSFAIL | eOND_LOCKEDBLK);
			return eOND_ERSFAIL;
		}
	}
	else
	{
		uBlockSize = uEndBlkAddr - uStartBlkAddr + 1;
		uQuotient = uBlockSize/OND_MULTIERASE_SIZE;
		uRemainder = uBlockSize%OND_MULTIERASE_SIZE;
		uBlock = uStartBlkAddr;
	
		for(i=0 ; i<uQuotient ; i++)
		{
			for(j=uBlock ; j<(uBlock+OND_MULTIERASE_SIZE-1) ; j++)
			{
				OneNandT_oIntFlag.IntActInt = 0;
				ONENAND_WriteCmd(Controller, j, 0, 0x01);
				while(!OneNandT_oIntFlag.IntActInt);
			}
			ONENAND_WriteCmd(Controller, uBlock+OND_MULTIERASE_SIZE-1, 0, 0x03);

			while(!OneNandT_oIntFlag.IntActInt);

			// Verify Erase block
			for(j=uBlock ; j<=(uBlock+OND_MULTIERASE_SIZE-1) ; j++)
			{
				OneNandT_oIntFlag.IntActInt = 0;
				ONENAND_WriteCmd(Controller, j, 0, 0x15);
				while(!OneNandT_oIntFlag.IntActInt);
				
				if(OneNandT_oIntFlag.ErsFailInt == 1)
				{
					OneNandT_oIntFlag.ErsFailInt = 0;
					if(OneNandT_oIntFlag.LockedBlkInt == 1)
						return (OneNAND_eINTERROR)(eOND_ERSFAIL | eOND_LOCKEDBLK);
					return eOND_ERSFAIL;
				}			
			}
			uBlock +=  OND_MULTIERASE_SIZE;
		}

		if(uRemainder > 0)
		{
			for(i=uBlock ; i<(uBlock+uRemainder-1) ; i++)
			{
				OneNandT_oIntFlag.IntActInt = 0;
				ONENAND_WriteCmd(Controller, i, 0, 0x01);
				while(!OneNandT_oIntFlag.IntActInt);
			}
			ONENAND_WriteCmd(Controller, uBlock+uRemainder-1, 0, 0x03);

			while(!OneNandT_oIntFlag.IntActInt);

			// Verify Erase block
			for(i=uBlock ; i<=(uBlock+uRemainder-1) ; i++)
			{
				OneNandT_oIntFlag.IntActInt = 0;
				ONENAND_WriteCmd(Controller, i, 0, 0x15);
				while(!OneNandT_oIntFlag.IntActInt);
				
				if(OneNandT_oIntFlag.ErsFailInt == 1)
				{
					OneNandT_oIntFlag.ErsFailInt = 0;
					if(OneNandT_oIntFlag.LockedBlkInt == 1)
						return (OneNAND_eINTERROR)(eOND_ERSFAIL | eOND_LOCKEDBLK);
					return eOND_ERSFAIL;
				}			
			}
		}
	}

	if(OneNandT_oIntFlag.ErsCmpInt == 1)
		return eOND_NOERROR;
	else
		return eOND_ERSFAIL;

}
#endif


//////////
// Function Name : ONENAND_EraseVerify
// Function Description : Verify Memory Block Erase
// Input : 	Controller - OneNand Controller Port Number 
//			uBlkAddr - Block Number
// Version : v0.1
OneNAND_eINTERROR ONENAND_EraseVerify(u32 Controller, u32 uBlkAddr)
{
	bool uError;

	OneNandT_oIntFlag.IntActInt = 0;
	
	ONENAND_WriteCmd(Controller, uBlkAddr, 0, 0x15);

	//Interrupt肺 背眉 
	//while(!(ONENAND(Controller)->rIntErrStat & (1<<10)));
	//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<10));
	while(!OneNandT_oIntFlag.IntActInt);
	
	uError = Inp32(&ONENAND(Controller)->rIntErrStat);
	if (uError & (1<<3)) 
	{
		//Erase fail
		Outp32(&ONENAND(Controller)->rIntErrAck, (1<<3));
		return eOND_ERSFAIL;
	}
	return eOND_NOERROR;
}

//////////
// Function Name : ONENAND_CopyBack
// Function Description : Copy-back operation
// Input : 	Controller - OneNand Controller Port Number 
//			uSourceBlkAddr - Source Block number
//			uSourcePageAddr - Source Page number
//			uDestinationBlkAddr - Destination Block number
//			uDestinationPageAddr - Destination Page number
//			uPageSize - Page size to be copied
// Version : v0.1
bool ONENAND_CopyBack(u32 Controller, u32 uSourceBlkAddr, u8 uSourcePageAddr, u32 uDestinationBlkAddr, u8 uDestinationPageAddr, u32 uPageSize)
{
	OneNandT_oIntFlag.IntActInt = 0;
	OneNandT_oIntFlag.BlkRwCmpInt = 0;
	OneNandT_oIntFlag.PgmCmpInt = 0;
	
	ONENAND_WriteCmd(Controller, uSourceBlkAddr, uSourcePageAddr, 0x1000);
	ONENAND_WriteCmd(Controller, uDestinationBlkAddr, uDestinationPageAddr, (0x2000|(uPageSize&0xFF)));
	
	//Interrupt肺 背眉 
	//while(!(ONENAND(Controller)->rIntErrStat & (1<<10)));
	//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<10));
	while(!OneNandT_oIntFlag.IntActInt);
	
	//Interrupt肺 背眉 
	//while(!(ONENAND(Controller)->rIntErrStat & (1<<7)));
	//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<7));
	while(!OneNandT_oIntFlag.BlkRwCmpInt);
	
	//Interrupt肺 背眉 
	//while(!(ONENAND(Controller)->rIntErrStat & (1<<5)));
	//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<5));	
	while(!OneNandT_oIntFlag.PgmCmpInt);
		
	return TRUE;
}

//////////
// Function Name : ONENAND_WritePage
// Function Description : Write 1 Page
// Input : 	Controller - OneNand Controller Port Number 
//			uBlkAddr - Block Number to write
//			uPageAddr - Page number to write
//			aData - Start Address of the data array
// Version : v0.1

bool ONENAND_WritePage(u32 Controller, u32 uBlkAddr, u8 uPageAddr, u32* aData)
{
	OneNandT_oIntFlag.IntActInt = 0;
	OneNandT_oIntFlag.BlkRwCmpInt = 0;
	OneNandT_oIntFlag.PgmCmpInt = 0;

#if (OND_TRANS_MODE == OND_POLLING)
	{
		u32 i;
		
		for(i=0; i<ONENAND_PAGESIZE/4; i++)
		{
			ONENAND_WriteIntoFlash(Controller, uBlkAddr, uPageAddr, *aData);
			aData++;
		}
	}

#elif (OND_TRANS_MODE == OND_DMA)
	{
		u32 uDstAddr;

		OneNand_DmaDone = 0;
		uDstAddr = OneNAND_ARRAY_BASE[Controller]  + ((FbaMask[Controller] & uBlkAddr)<<FbaShift[Controller]) +((FpaMask[Controller] & uPageAddr)<<FpaShift[Controller]);

	#if (ONENAND_VERSION == ONENAND_EVT0)		
		DMACH_Setup(DMA_A, 0x0, (u32)aData, 0, (u32)uDstAddr, 1, WORD, ONENAND_PAGESIZE/4, DEMAND, MEM, MEM, BURST128, &g_oONDDmac0);
	#elif	(ONENAND_VERSION == ONENAND_EVT1)
		DMACH_Setup(DMA_D, 0, (u32)aData, 0, (u32)uDstAddr, 0, WORD, ONENAND_PAGESIZE/4, DEMAND, MEM, DMA0_OND_RX, BURST4, &g_oONDDmac0);
		//DMACH_Setup(DMA_A, 0x0, (u32)aData, 0, (u32)uDstAddr, 1, WORD, ONENAND_PAGESIZE/4, DEMAND, MEM, MEM, BURST128, &g_oONDDmac0);
	#endif
	
		DMACH_Start(&g_oONDDmac0);
		while(!OneNand_DmaDone);	
	}
#else
	{
		u32 uDstAddr, uContBaseAddr;

		if(Controller == 0)
			uContBaseAddr = ONENAND0_BASE;
		else
			uContBaseAddr = ONENAND1_BASE;
		
		uDstAddr = OneNAND_ARRAY_BASE[Controller]  + ((FbaMask[Controller] & uBlkAddr)<<FbaShift[Controller]) +((FpaMask[Controller] & uPageAddr)<<FpaShift[Controller]);
		OneNandPageWrite(uContBaseAddr, (u32)aData, uDstAddr);
	}	
#endif

	while(!OneNandT_oIntFlag.IntActInt);
	while(!OneNandT_oIntFlag.BlkRwCmpInt);
	while(!OneNandT_oIntFlag.PgmCmpInt);
	
	return TRUE;
}

//////////
// Function Name : ONENAND_ReadPage
// Function Description : Read 1 Page
// Input : 	Controller - OneNand Controller Port Number 
//			uBlkAddr - Block Number to read
//			uPageAddr - Page number to read
//			aData - Start Address of the data array
// Version : v0.1
extern void TCM_DMA_ReadTransfer(u32 uSrcAddr, u32 uDstAddr);
bool ONENAND_ReadPage(u32 Controller, u32 uBlkAddr, u8 uPageAddr, u32* aData)
{
	OneNandT_oIntFlag.IntActInt = 0;
	OneNandT_oIntFlag.BlkRwCmpInt = 0;
	OneNandT_oIntFlag.LoadCmpInt = 0;

#if (OND_TRANS_MODE == OND_POLLING)
	{
		u32 i;
	
		for(i=0; i<ONENAND_PAGESIZE/4; i++)
		{
			ONENAND_ReadOutFlash(Controller, uBlkAddr, uPageAddr, aData);
			aData++;
		}
	}
#elif (OND_TRANS_MODE == OND_DMA)
	{
#if 0		//TCM DMA
		u32 uSrcAddr;

		uSrcAddr = OneNAND_ARRAY_BASE[Controller]  + ((FbaMask[Controller] & uBlkAddr)<<FbaShift[Controller]) +((FpaMask[Controller] & uPageAddr)<<FpaShift[Controller]);

		TCM_DMA_ReadTransfer(uSrcAddr, (u32)aData);

#else	
		u32 uSrcAddr;

		OneNand_DmaDone = 0;
		uSrcAddr = OneNAND_ARRAY_BASE[Controller]  + ((FbaMask[Controller] & uBlkAddr)<<FbaShift[Controller]) +((FpaMask[Controller] & uPageAddr)<<FpaShift[Controller]);

	#if (ONENAND_VERSION == ONENAND_EVT0)		
		//ONENAND_SetLLI(uSrcAddr, (u32)aData);
		//DMACH_Setup(DMA_A, ONENAND_LLI_BASE+0x20, (u32)uSrcAddr, 0, (u32)aData, 0, WORD, 4, DEMAND, MEM, MEM, BURST4, &g_oONDDmac0);
		DMACH_Setup(DMA_A, 0, (u32)uSrcAddr, 1, (u32)aData, 0, WORD, ONENAND_PAGESIZE/4, DEMAND, MEM, MEM, BURST128, &g_oONDDmac0);
	#elif	(ONENAND_VERSION == ONENAND_EVT1)
		DMACH_Setup(DMA_D, 0, (u32)uSrcAddr, 0, (u32)aData, 0, WORD, ONENAND_PAGESIZE/4, DEMAND, DMA0_OND_TX, MEM, BURST4, &g_oONDDmac0);
		//DMACH_Setup(DMA_A, 0, (u32)uSrcAddr, 1, (u32)aData, 0, WORD, ONENAND_PAGESIZE/4, DEMAND, MEM, MEM, BURST128, &g_oONDDmac0);
	#endif
	
		DMACH_Start(&g_oONDDmac0);
		while(!OneNand_DmaDone);	
#endif		
	}
#else	// using the "LDM" instruction
	{
		u32 uSrcAddr, uContBaseAddr;

		if(Controller == 0)
			uContBaseAddr = ONENAND0_BASE;
		else
			uContBaseAddr = ONENAND1_BASE;
		
		uSrcAddr = OneNAND_ARRAY_BASE[Controller]  + ((FbaMask[Controller] & uBlkAddr)<<FbaShift[Controller]) +((FpaMask[Controller] & uPageAddr)<<FpaShift[Controller]);
		OneNandPageRead(uContBaseAddr, uSrcAddr, (u32)aData);
	}
#endif

	while(!OneNandT_oIntFlag.IntActInt);
	while(!OneNandT_oIntFlag.BlkRwCmpInt);
	while(!OneNandT_oIntFlag.LoadCmpInt);	

	OneNandT_oIntFlag.IntActInt = 0;
	OneNandT_oIntFlag.BlkRwCmpInt = 0;
	OneNandT_oIntFlag.LoadCmpInt = 0;
	
	return TRUE;
}



bool ONENAND_ReadPageForCacheRead(u32 Controller, u32 uBlkAddr, u8 uPageAddr, u32* aData, u32 uPageSize)
{
	OneNandT_oIntFlag.IntActInt = 0;
	OneNandT_oIntFlag.BlkRwCmpInt = 0;
	OneNandT_oIntFlag.LoadCmpInt = 0;
	
#if (OND_TRANS_MODE == OND_POLLING)
	{
		u32 i;
	
		for(i=0; i<ONENAND_PAGESIZE/4; i++)
		{
			ONENAND_ReadOutFlash(Controller, uBlkAddr, uPageAddr, aData);
			aData++;
		}
	}
#elif (OND_TRANS_MODE == OND_DMA)
	{
		u32 uSrcAddr;

		OneNand_DmaDone = 0;
		uSrcAddr = OneNAND_ARRAY_BASE[Controller]  + ((FbaMask[Controller] & uBlkAddr)<<FbaShift[Controller]) +((FpaMask[Controller] & uPageAddr)<<FpaShift[Controller]);

	#if (ONENAND_VERSION == ONENAND_EVT0)		
		//ONENAND_SetLLI(uSrcAddr, (u32)aData);
		//DMACH_Setup(DMA_A, ONENAND_LLI_BASE+0x20, (u32)uSrcAddr, 0, (u32)aData, 0, WORD, 4, DEMAND, MEM, MEM, BURST4, &g_oONDDmac0);
		DMACH_Setup(DMA_A, 0, (u32)uSrcAddr, 1, (u32)aData, 0, WORD, ONENAND_PAGESIZE/4, DEMAND, MEM, MEM, BURST128, &g_oONDDmac0);
	#elif	(ONENAND_VERSION == ONENAND_EVT1)
		DMACH_Setup(DMA_D, 0, (u32)uSrcAddr, 0, (u32)aData, 0, WORD, ONENAND_PAGESIZE/4, DEMAND, DMA0_OND_TX, MEM, BURST4, &g_oONDDmac0);
		//DMACH_Setup(DMA_A, 0, (u32)uSrcAddr, 1, (u32)aData, 0, WORD, ONENAND_PAGESIZE/4, DEMAND, MEM, MEM, BURST128, &g_oONDDmac0);
	#endif
	
		DMACH_Start(&g_oONDDmac0);
		while(!OneNand_DmaDone);	
	}
#else
	{
		u32 uSrcAddr, uContBaseAddr;

		if(Controller == 0)
			uContBaseAddr = ONENAND0_BASE;
		else
			uContBaseAddr = ONENAND1_BASE;
		
		uSrcAddr = OneNAND_ARRAY_BASE[Controller]  + ((FbaMask[Controller] & uBlkAddr)<<FbaShift[Controller]) +((FpaMask[Controller] & uPageAddr)<<FpaShift[Controller]);
		OneNandPageRead(uContBaseAddr, uSrcAddr, (u32)aData);
	}
#endif

#if 0
	// rb1004...When HCLK is low(~50MHz), Interrupt loss is occured.
	if(OneNandT_oIntFlag.IntActInt_Count  != uPageSize)
	{
		while(!OneNandT_oIntFlag.IntActInt);
		while(!OneNandT_oIntFlag.BlkRwCmpInt);
		while(!OneNandT_oIntFlag.LoadCmpInt);	
	}
#endif

	return TRUE;
}



//////////
// Function Name : ONENAND_ReadPageWithSpare
// Function Description : Read 1 Page with Spare area data
// Input : 	Controller - OneNand Controller Port Number 
//			uBlkAddr - Block Number to read
//			uPageAddr - Page number to read
//			aData - Start Address of the data array
// Version : v0.1
bool ONENAND_ReadPageWithSpare(u32 Controller, u32 uBlkAddr, u8 uPageAddr, u32* aData, u32 *aSpare)
{
	u32 i;

	OneNandT_oIntFlag.IntActInt = 0;
	OneNandT_oIntFlag.BlkRwCmpInt = 0;
	OneNandT_oIntFlag.LoadCmpInt = 0;
	
	for(i=0; i<ONENAND_PAGESIZE/4; i++)
	{
		ONENAND_ReadOutFlash(Controller, uBlkAddr, uPageAddr, aData);
		aData++;
	}

	for(i=0; i<ONENAND_SPARESIZE/4; i++)
	{
		ONENAND_ReadOutFlash(Controller, uBlkAddr, uPageAddr, aSpare);
		aSpare++;
	}
	
	//Interrupt肺 背眉 
	//while(!(ONENAND(Controller)->rIntErrStat & (1<<10)));
	//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<10));
	while(!OneNandT_oIntFlag.IntActInt);
	
	//Interrupt肺 背眉 
	//while(!(ONENAND(Controller)->rIntErrStat & (1<<7)));
	//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<7));
	while(!OneNandT_oIntFlag.BlkRwCmpInt);
	
	//Interrupt肺 背眉 
	//while(!(ONENAND(Controller)->rIntErrStat & (1<<4)));
	//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<4));	
	while(!OneNandT_oIntFlag.LoadCmpInt);	
	
	return TRUE;
}


//////////
// Function Name : ONENAND_LoadToXIPBuffer
// Function Description : Load the page specified by the FBA,FPA,FSA to the map00 XIP buffer
// Input : 	Controller - OneNand Controller Port Number 
//			uBlkAddr - Block Number to load
//			uPageAddr - Page number to load
// Version : v0.1
void ONENAND_LoadToXIPBuffer(u32 Controller, u32 uBlkAddr, u8 uPageAddr)
{
	OneNandT_oIntFlag.IntActInt = 0;
	OneNandT_oIntFlag.BlkRwCmpInt = 0;
	OneNandT_oIntFlag.LoadCmpInt = 0;
	
	ONENAND_WriteCmd(Controller, uBlkAddr, uPageAddr, 0x10);
#if 0
	while(!OneNandT_oIntFlag.IntActInt);	//Waiting Interrupt
	while(!OneNandT_oIntFlag.BlkRwCmpInt);	//Waiting Interrupt
	while(!OneNandT_oIntFlag.LoadCmpInt);	//Waiting Interrupt
#else
	//Interrupt肺 背眉 
	//while(!(ONENAND(Controller)->rIntErrStat & (1<<10)));
	//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<10));
	while(!OneNandT_oIntFlag.IntActInt);
	
	//Interrupt肺 背眉 
	//while(!(ONENAND(Controller)->rIntErrStat & (1<<7)));
	//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<7));
	while(!OneNandT_oIntFlag.BlkRwCmpInt);
	
	//Interrupt肺 背眉 
	//while(!(ONENAND(Controller)->rIntErrStat & (1<<4)));
	//Outp32(&ONENAND(Controller)->rIntErrAck, (1<<4));	
	while(!OneNandT_oIntFlag.LoadCmpInt);	
#endif
}



//////////
// Function Name : ONENAND_WriteFromXIPBuffer
// Function Description : Write the data int the map00 XIP buffer to the page specified by the FBA,FPA, and FSA
// Input : 	Controller - OneNand Controller Port Number 
//			uBlkAddr - Block Number to write
//			uPageAddr - Page number to write
// Version : v0.1
void ONENAND_WriteFromXIPBuffer(u32 Controller, u32 uBlkAddr, u8 uPageAddr)
{
	OneNandT_oIntFlag.IntActInt = 0;

⌨️ 快捷键说明

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