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

📄 nand_drv.c

📁 Nand Flash low driver。
💻 C
📖 第 1 页 / 共 5 页
字号:
	gNFlashInfo.multi_plane_code = (UINT8) (mNand_Read_Data() & 0xff) ;



	if ((gNFlashInfo.maker_code == 0xec) &&
		(gNFlashInfo.device_code == 0x76) &&
		(gNFlashInfo.multi_plane_code == 0xc0))
		return NAND_PASS ;
	else
		return NAND_FAIL;
#endif/*#if (NFLASH_TYPE == TYPE_IS_K9F1208X0B) */


#if (NFLASH_TYPE == TYPE_IS_NAND512R3A) 
	gNFlashInfo.maker_code = (UINT8) (mNand_Read_Data() & 0xff) ;
	gNFlashInfo.device_code = (UINT8) (mNand_Read_Data() & 0xff) ;
	
	if ((gNFlashInfo.maker_code == 0x20) &&
		(gNFlashInfo.device_code == 0x76) )
		return NAND_PASS ;
	else
		return NAND_FAIL ;
#endif/*(NFLASH_TYPE == TYPE_IS_NAND512R3A)  */
}

/*
 * Function:	HD_NFlashInit( )
 * DeSCRiption:    This function be used to initialize the flash controler and create the bad block table 					  
 * Input:      None	   
 * Output:    None   
 * Return:    None	   
 * Others:  	   
 */  

 NAND_Ret HD_NFlashInit(void)
{
	UINT8 flash_status ;

	SDAndNandFlag=1;

	EnableNANDControler();
	
#if  ((NFLASH_TYPE == TYPE_IS_K9F1208X0B) || (NFLASH_TYPE == TYPE_IS_NAND512R3A)) 	
	/*setting NFC timming */
	WRITE_REG32(NFLASH_NFTYPE_ADDR,0x00000000) ; //this is temp value
	/*
	*setting NFC size register
	*column Address bit size : 8bits
	*Row Address bit size : 17bits
	*NAND flash memony data width  :8 bit
	*/
	WRITE_REG32(NFLASH_NFSIZE_ADDR,0x00000018) ;
	/*clear the ready bit ,and make it to default value(busy)*/
	WRITE_REG32(NFLASH_NFINTP_ADDR,1) ;
	/*disable Nand interrupt*/
	WRITE_REG32(NFLASH_NFINTE_ADDR,1);

	NFlashReset() ;

	flash_status = NFlashReadID() ;
	if (flash_status != NAND_PASS)
	{
		DEBUG_OUT("NAND_ID_ERR\n\r") ;
		return  NAND_ID_ERR;
	}
#endif /*(NFLASH_TYPE == TYPE_IS_K9F1208X0B ) */

	return NAND_PASS;
}   

 NAND_Ret NAND_BlockErase(UINT32 udAddress)
{
	//UINT32 erase_address ;

#ifdef _NAND_DEBUG_
	DEBUG_OUT("Erase\n\r") ;
	if (udAddress >= FLASH_SIZE_64MB)
	{
		DEBUG_OUT("Erase NAND_SW_ERR\n\r") ;
		return NAND_SW_ERR ;
	}
	/*if Write protection is valid*/
	if (!IsWriteProtect())
	{
		DEBUG_OUT("Erase NAND_WRPRT_ERR\n\r") ;
		return NAND_WRPRT_ERR;
	}
#endif /*_NAND_DEBUG_*/

	//erase_address = udAddress & 0x03fffe00 ;
	WRITE_REG32(NFLASH_NFINTP_ADDR,1) ;
	mNandWrite_SET_CLE(BLOCK_ERASE_CMD1);
	mNandWrite_SET_ALE(((udAddress & 0x03fffe00) | 0x80000000)) ;
	mNandWrite_SET_CLE(BLOCK_ERASE_CMD2);

	if (!IsReadyToRW())
	{
		DEBUG_OUT("Erase NAND_HW_ERR\n\r") ;
		return NAND_HW_ERR ;
	}
	/*if failure it need to block placement*/
	if (!IsSucessProgram())
	{
		DEBUG_OUT("Erase NAND_PRG_FAIL\n\r") ;
		return NAND_FAIL;
	}

	return(NAND_PASS) ;
}



 NAND_Ret NAND_PageRead(UINT32 udAddress, dataWidth *pReadBuf,UINT32 len )
{
	UINT16 HalfSelect ;
#ifndef _NFLASH_DMA_
	UINT16 i = 0 ;
#endif /*_NFLASH_DMA_*/

	HalfSelect = udAddress &511 ; /*PAGE_DATA_SIZE-1*/ ;

#ifdef _NAND_DEBUG_
	DEBUG_OUT("NandReadNoEcc\n\r") ;
	if ((pReadBuf == NULL) || (len > PAGE_SIZE))
	{
		DEBUG_OUT("NandReadNoEcc NAND_SW_ERR\n\r") ;
		return NAND_SW_ERR ;
	}
	if (udAddress >= FLASH_SIZE_64MB)
	{
		DEBUG_OUT("NandReadNoEcc NAND_ADDR_OVERFLOW\n\r") ;
		return NAND_ADDR_OVERFLOW;
	}
#endif /*_NAND_DEBUG_*/
	//udAddress &= 0x03ffffff ;
	WRITE_REG32(NFLASH_NFINTP_ADDR,1) ;
	if (HalfSelect < 256)
	{
		mNandWrite_SET_CLE(READ1_CMD_00H);
	}
	else
	{
		mNandWrite_SET_CLE(READ1_CMD_01H);
	}
	mNandWrite_SET_ALE(udAddress&0x03ffffff) ;

	if (!IsReadyToRW())
	{
		DEBUG_OUT("NandReadNoEcc NAND_HW_ERR\n\r") ;
		return NAND_FAIL ;
	}

	/**************Read main data area*********/
#ifdef _NFLASH_DMA_
	{
		UINT32 temp = 0;
		UINT32 TimeOut = 0;

		OS_DRIVER_ObtainSemaphore(DMA_SEMAPHORE_ID);  
	#if (DMA_TYPE==TYPE_IS_MOSE_DMA)
			EnablePDClk(PD_CCKEN_DMAC_BIT);
			/*start ,byte width ,length is len, source fix ,dst increment*/
			temp = (1 << 0) | (0 << 4) | ((len - 1) << 8) | (1 << 20) | (0 << 21) ;  	  
			ProgramDMAChannel(NFLASH_NFDIN_ADDR + 1,(UINT32) pReadBuf,temp) ;
	      	#ifndef  _STAND_ALONE_
	      		{
		      		UINT32 EventResult; 	   /*The 32-bit variable to where the set bits is copied*/
				UINT16 EventStatus; 	   /* Event status*/

				EventStatus = OS_DRIVER_WaitEventOR(PERIPH_EVENT_ID,PERIPH_DMA_EVTBIT,
								&EventResult,NAND_DMA_TIMEOUT_VALUE);   
				if (EventStatus == OS_DRIVER_WAIT_EVENT_TIMEOUT)
				{
					DEBUG_OUT("NandReadNoEcc NAND_DMA_TIMEOUT\n\r") ;
					OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID); 
					return NAND_DMA_TIMEOUT;
				}
	      		}
     		#else
			temp = READ_REG32(DMA_DCR_ADDR);
			while (temp & 0x10000000)
			{
				temp = READ_REG32(DMA_DCR_ADDR);
				TimeOut++ ;
				if (TimeOut == NAND_TIMEOUT_VALUE)
				{
					OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
					return NAND_DMA_TIMEOUT ;
				}
			}
     		#endif/*_STAND_ALONE_*/
			DisablePDClk(PD_CCKEN_DMAC_BIT);
	#elif (DMA_TYPE==TYPE_IS_GPRS_DMA)
		{
			UINT32 CtlrParam = 0, CfgrParam = 0;
			UINT32 ErrorCode ;

			/*src busrt size 0 |dst burst size 0|src width 8bits|dst width 8bits|src fix,dst inc*/
			CtlrParam = 1 << 23 ;
			/*src dst peripheral is ignored | src master 0 | dst master 1| memory to memory | 512 bytes*/
			CfgrParam = (1 << 7) | (len << 12);

			ProgramDMAChannel(NFLASH_NFDIN_ADDR,(UINT32) pReadBuf,CtlrParam,CfgrParam);
		#ifndef  _STAND_ALONE_
			{
				UINT32 EventResult; 	   /*The 32-bit variable to where the set bits is copied*/
				UINT16 EventStatus; 	   /* Event status*/

				EventStatus = OS_DRIVER_WaitEventOR(PERIPH_EVENT_ID,PERIPH_DMA_EVTBIT,
								&EventResult,NAND_DMA_TIMEOUT_VALUE);   
				if (EventStatus == OS_DRIVER_WAIT_EVENT_TIMEOUT)
				{
					DEBUG_OUT("NandReadNoEcc NAND_DMA_TIMEOUT\n\r") ;
					OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID); 
					return NAND_DMA_TIMEOUT;
				}
			}
		#else
			temp = READ_REG32(DMA_ISR_ADDR);
			while ((temp & 0x4) == 0)//default to channel 2
			{
				temp = READ_REG32(DMA_ISR_ADDR);
				TimeOut++ ;
				if (TimeOut == NAND_TIMEOUT_VALUE)
				{	
					WRITE_REG32(DMA_ISR_ADDR, 0x4);
					OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
					return NAND_DMA_TIMEOUT ;
				}
			}
			WRITE_REG32(DMA_ISR_ADDR, 0x4);
		#endif/*_STAND_ALONE_*/
		}
	#endif/*(DMA_TYPE==TYPE_IS_MOSE_DMA)*/
		OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
	}
#else   /*_NFLASH_DMA_*/
	for (i = 0 ; i < len; i++)
		pReadBuf[i] = (UINT8) (mNand_Read_Data() & 0xff) ;

#endif /*_NFLASH_DMA_*/	

	return NAND_PASS ;
}




 NAND_Ret NAND_PageProgram(UINT32 udAddress,  dataWidth *pWritebuf,UINT32 len )
{
	UINT16 HalfSelect ;
#ifndef _NFLASH_DMA_
	UINT16 i = 0 ;
#endif /*_NFLASH_DMA_*/

	HalfSelect = udAddress &511 ; /*PAGE_DATA_SIZE-1*/ ;

#ifdef _NAND_DEBUG_
	DEBUG_OUT("NandWriteNoEcc\n\r") ;

	if ((pWritebuf == NULL) || (len > PAGE_SIZE))
	{
		DEBUG_OUT("WriteNoEcc NAND_SW_ERR\n\r") ;
		return NAND_SW_ERR ;
	}
	if (udAddress >= FLASH_SIZE_64MB)
	{
		DEBUG_OUT("WriteNoEcc NAND_ADDR_OVERFLOW\n\r") ;
		return NAND_ADDR_OVERFLOW;
	}
	/*if Write protection is valid*/
	if (!IsWriteProtect())
	{
		DEBUG_OUT("WriteNoEcc NAND_WRPRT_ERR\n\r") ;
		return NAND_WRPRT_ERR;
	}
#endif /*_NAND_DEBUG_*/

	//udAddress &= 0x03ffffff ;
	WRITE_REG32(NFLASH_NFINTP_ADDR,1) ;
	if (HalfSelect < 256)
	{
		mNandWrite_SET_CLE(READ1_CMD_00H);
	}  /*reset  pointer to 'a' area*/
	else
	{
		mNandWrite_SET_CLE(READ1_CMD_01H);
	}  /*reset  pointer to 'b' area*/
	mNandWrite_SET_CLE(PAGE_PRO_TRUE_CMD1);
	mNandWrite_SET_ALE(udAddress&0x03ffffff) ;

	/*********Write  the main data area***********/
#ifdef _NFLASH_DMA_
	{
		UINT32 temp = 0;
		UINT32 TimeOut = 0;

		/*start ,byte width ,length is len, source inc ,dst fix*/
		OS_DRIVER_ObtainSemaphore(DMA_SEMAPHORE_ID);  
	#if (DMA_TYPE==TYPE_IS_MOSE_DMA)
		EnablePDClk(PD_CCKEN_DMAC_BIT);
		temp = 1 << 0 | 0 << 4 | (len - 1) << 8 | 0 << 20 | 1 << 21 ;  
		ProgramDMAChannel((UINT32) pWritebuf,NFLASH_NFDOUT_ADDR,temp) ;
		#ifndef _STAND_ALONE_
		{
			UINT32 EventResult; 	   /* The 32-bit variable to where the set bits is copied*/
			UINT16 EventStatus; 	   /* Event status*/
			
			EventStatus = OS_DRIVER_WaitEventOR(PERIPH_EVENT_ID,PERIPH_DMA_EVTBIT,
							&EventResult,NAND_DMA_TIMEOUT_VALUE);   
			if (EventStatus == OS_DRIVER_WAIT_EVENT_TIMEOUT)
			{
				DEBUG_OUT("WriteNoEcc NAND_DMA_TIMEOUT\n\r") ;
				OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
				return NAND_DMA_TIMEOUT;
			} 
		}
		#else
			temp = READ_REG32(DMA_DCR_ADDR);
			while (temp & 0x10000000)
			{
				temp = READ_REG32(DMA_DCR_ADDR);
				TimeOut++ ;
				if (TimeOut == NAND_TIMEOUT_VALUE)
				{
					OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
					return NAND_DMA_TIMEOUT ;
				}
			}
		#endif/*_STAND_ALONE_*/
		DisablePDClk(PD_CCKEN_DMAC_BIT);
	#elif ((DMA_TYPE==TYPE_IS_GPRS_DMA))
		{
			UINT32 CtlrParam = 0, CfgrParam = 0;
			UINT32 ErrorCode ;

			/*src busrt size 0 |dst burst size 0|src width 8bits|dst width 8bits|src inc,dst fix*/
			CtlrParam = 1 << 22 ;
			/*src dst peripheral is ignored | src master 0 | dst master 1| memory to memory | len bytes*/
			CfgrParam = (1 << 7) | (len << 12);
			ProgramDMAChannel((UINT32) pWritebuf,NFLASH_NFDOUT_ADDR,CtlrParam,CfgrParam);
		#ifndef  _STAND_ALONE_
			{
				UINT32 EventResult; 	   /* The 32-bit variable to where the set bits is copied*/
				UINT16 EventStatus; 	   /* Event status*/
				
				EventStatus = OS_DRIVER_WaitEventOR(PERIPH_EVENT_ID,PERIPH_DMA_EVTBIT,
								&EventResult,NAND_DMA_TIMEOUT_VALUE);   
				if (EventStatus == OS_DRIVER_WAIT_EVENT_TIMEOUT)
				{
					DEBUG_OUT("NandReadNoEcc NAND_DMA_TIMEOUT\n\r") ;
					OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID); 
					return NAND_DMA_TIMEOUT;
				}
			}
		#else
			temp = READ_REG32(DMA_ISR_ADDR);
			while ((temp & 0x4) == 0)//default to channel 2
			{
				temp = READ_REG32(DMA_ISR_ADDR);
				TimeOut++ ;
				if (TimeOut == NAND_TIMEOUT_VALUE)
				{
					WRITE_REG32(DMA_ISR_ADDR, 0x4);
					OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
					return NAND_DMA_TIMEOUT ;
				}
			}
			WRITE_REG32(DMA_ISR_ADDR, 0x4);
		#endif/* _STAND_ALONE_*/
		}
	#endif/*(DMA_TYPE==TYPE_IS_MOSE_DMA)*/
		OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
	}
#else    /*_NFLASH_DMA_*/
	for (i = 0 ; i < len; i++)
		mNand_Write_Data(pWritebuf[i]) ;
#endif  /*_NFLASH_DMA_*/

	mNandWrite_SET_CLE(PAGE_PRO_TRUE_CMD2);

	if (!IsReadyToRW())
	{
		DEBUG_OUT("WriteNoEcc NAND_HW_ERR\n\r") ;
		return NAND_HW_ERR ;
	}

	/*if failure it need to block placement*/
	if (!IsSucessProgram())
	{
		DEBUG_OUT("WriteNoEcc NAND_PRG_FAIL\n\r") ;
		return NAND_FAIL ;
	}

#ifdef _NAND_VERIFY_WRITE_
	{
		UINT16 k;

		NandReadNoEcc(udAddress,len,ReadBackBuf) ;
		for (k = 0; k < len; k++)
		{
			if (ReadBackBuf[k] != pWritebuf[k])
			{
				DEBUG_OUT("WriteNoEcc NAND_VERIFY_ERR\n\r") ;
				return NAND_VERIFY_ERR;
			}
		}
	}
#endif/*_NAND_VERIFY_WRITE_*/

	return NAND_PASS ;
}

 NAND_Ret NAND_SpareProgram(UINT32 udAddress,   dataWidth *pWrOobBuf,UINT32 len)
{
#ifdef _NAND_DEBUG_
	DEBUG_OUT("NandWriteOOB\n\r") ;

	if ((pWrOobBuf == NULL) || (len > 16))
	{
		DEBUG_OUT("Woob NAND_SW_ERR\n\r") ;
		return NAND_SW_ERR ;
	}

	if (udAddress >= FLASH_SIZE_64MB)
	{
		DEBUG_OUT("Woob NAND_ADDR_OVERFLOW\n\r") ;
		return NAND_ADDR_OVERFLOW;
	}
	/* Control if the address is the buffer size is within the page*/   
	if (((udAddress % PAGE_SPARE_SIZE) + len) > PAGE_SPARE_SIZE)
	{
		DEBUG_OUT("Woob NAND_PAGE_OVERFLOW\n\r") ;
		return NAND_PAGE_OVERFLOW;
	}
	/*if Write protection is valid*/
	if (!IsWriteProtect())
	{
		DEBUG_OUT("Woob NAND_WRPRT_ERR\n\r") ;
		return NAND_WRPRT_ERR;
	}
#endif /*_NAND_DEBUG_*/

	//udAddress &= 0x03ffff0f ; /*a0-a3:valid address ,a4-a7:dont care*/
	WRITE_REG32(NFLASH_NFINTP_ADDR,1) ;
	mNandWrite_SET_CLE(READ2_CMD); 
	mNandWrite_SET_CLE(PAGE_PRO_TRUE_CMD1); 
	mNandWrite_SET_ALE(udAddress&0x03ffff0f) ;

#ifdef _NFLASH_DMA_
	{
		UINT32 temp = 0 ;
		UINT32 TimeOut = 0;
		OS_DRIVER_ObtainSemaphore(DMA_SEMAPHORE_ID);
	#if (DMA_TYPE==TYPE_IS_MOSE_DMA)
		EnablePDClk(PD_CCKEN_DMAC_BIT);
		/*start ,byte width ,length is len, source inc , dst fix*/													
		temp = 1 << 0 | 0 << 4 | (len - 1) << 8 | 0 << 20 | 1 << 21 ; 

		ProgramDMAChannel((UINT32) pWrOobBuf,NFLASH_NFDOUT_ADDR,temp) ;
		#ifndef _STAND_ALONE_

⌨️ 快捷键说明

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