www.pudn.com > NAND.rar > NAND_DRV.c


 
 
#include "hdcfg.h" 
#include "HDRegdef.h"   
#include "NAND_DRV.h"   
#include "drivermmiif.h" 
#include "Driverosif.h" 
//#include "mmiSendMessage.h" 
 
//#define  _NAND_DEBUG_   
//#define _NFLASH_DMA_    
//#define  _NAND_VERIFY_WRITE_ 
#define _STAND_ALONE_ 
#define NAND_POWER_SAVING 
#define NAND_SPEED_OPTIMISE 
 
#define GPIO_NUMBER      10 
#define NAND_SEL_GPIO_PIN  GPIO_NUMBER     
 
#ifndef  _NAND_DEBUG_ 
extern UINT32 MMI_PutString(char *str); 
#define DEBUG_OUT(string)    MMI_PutString(string) 
#else    /*_NAND_DEBUG_*/ 
#define DEBUG_OUT(string)     NULL 
#endif  /*_NAND_DEBUG_*/ 
 
#if (NFLASH_TYPE == TYPE_IS_K9F1208X0B)  
#define PAGE_PRO_DUMMY_CMD1   		0x80 
#define PAGE_PRO_DUMMY_CMD2  			0x11  
 
#define COPY_BACK_PRO_DUMMY_CMD1  	0x00 
#define COPY_BACK_PRO_DUMMY_CMD2  	0x8a 
#define COPY_BACK_PRO_DUMMY_CMD3  	0x11  
 
#define READ_MULTI_PLANE_STATUS_CMD  0x71   
#endif //(NFLASH_TYPE == TYPE_IS_K9F1208X0B)  
 
/****************Command Sets define  start ********************/ 
#define READ1_CMD_00H    				0x00  
#define READ1_CMD_01H    				0x01  
#define READ2_CMD     					0x50  
#define READ_ID_CMD  					0x90   
#define RESET_CMD     					0xff    
#define PAGE_PRO_TRUE_CMD1   			0x80 
#define PAGE_PRO_TRUE_CMD2  			0x10   
 
#define COPY_BACK_PRO_TRUE_CMD1  		0x00 
#define COPY_BACK_PRO_TRUE_CMD2  		0x8a 
#define COPY_BACK_PRO_TRUE_CMD3  		0x10	 
 
#define BLOCK_ERASE_CMD1  				0x60 
#define BLOCK_ERASE_CMD2  				0xd0   
#define READ_STATUS_CMD  				0x70   
 
/****************Command Sets define  end********************/ 
 
#if  (ASIC_VERSION ==VT3363) 
#define mNandWrite_SET_CLE(NaFlash_Cmd) 	   WRITE_REG32((NFLASH_NFCMD_ADDR), (NaFlash_Cmd|0XC0000000)) 
#elif  (ASIC_VERSION==VT3341) 
#define mNandWrite_SET_CLE(NaFlash_Cmd) 	   WRITE_REG32((NFLASH_NFCMD_ADDR), (NaFlash_Cmd)) 
#elif  (ASIC_VERSION==VT3360) 
#define mNandWrite_SET_CLE(NaFlash_Cmd) 	   WRITE_REG32((NFLASH_NFCMD_ADDR), (NaFlash_Cmd)) 
#endif 
#define mNandWrite_SET_ALE( NaFlash_Adress)  WRITE_REG32((NFLASH_NFADDR_ADDR), (NaFlash_Adress))  
#define mNand_Read_Data()   					   (READ_REG32((NFLASH_NFDIN_ADDR))) 
#define mNand_Write_Data(NFalsh_Data)   		   WRITE_REG32((NFLASH_NFDOUT_ADDR), (NFalsh_Data)) 
 
 
 
#define SECTOR_SIZE 512 
#define NAND_DMA_TIMEOUT_VALUE 100 
#define NAND_TIMEOUT_VALUE 0x3FFFF 
 
UINT8 SDAndNandFlag=1 ; /*1: NAND; 0: SD*/ 
static tNLFASH_INFO_STRUCT gNFlashInfo; 
static int NandMountStatus=0; 
#ifdef _NAND_VERIFY_WRITE_ 
UINT8 ReadBackBuf[SECTOR_SIZE]; 
#endif 
 
#if (DMA_TYPE==TYPE_IS_MOSE_DMA) 
extern void ProgramDMAChannel(UINT32  src_addr, UINT32  des_addr, UINT32 ctl);  
#endif 
#if (DMA_TYPE==TYPE_IS_GPRS_DMA) 
extern UINT8 ProgramDMAChannel(UINT32 Source,UINT32 Destination,UINT32 CtlrParam,UINT32 CfgrParam); 
#endif 
 
extern UINT16 APIMISC_ObtainDSleepSemaphore (void) ; 
extern UINT16 APIMISC_ReleaseDSleepSemaphore (void) ; 
extern void EnablePDClk(UINT32 ); 
extern void DisablePDClk(UINT32 ); 
 
//static void NFlashDeselect(void); 
//static void NFlashSeselect(void); 
 
void EnableNANDControler(void) 
{ 
	UINT32 set_value; 
	/*enable NFC*/ 
	set_value = READ_REG32(GLOBAL_CGBR1_ADDR) ;/*NFC signal are selected*/ 
	set_value &= 0xf8ffffff;/*disable SD module and NAND*/ 
	set_value = set_value | 0x09000000 ; /*enable NAND module*/ 
	WRITE_REG32(GLOBAL_CGBR1_ADDR,set_value) ; 
} 
void DisableNANDControler(void) 
{ 
	UINT32 temp ; 
	temp = READ_REG32(GLOBAL_CGBR1_ADDR); 
	temp &= 0xf0ffffff;/*disable SD module and NAND Pull down Active*/ 
	WRITE_REG32(GLOBAL_CGBR1_ADDR, temp);	 
} 
void EnableNANDClock(void) 
{ 
	extern void EnablePDClk( UINT32 ) ; 
 
	EnablePDClk(PD_CCKEN_NFC_BIT); 
} 
void DisableNANDClock(void) 
{ 
	extern void DisablePDClk( UINT32 ) ; 
			 
       DisablePDClk(PD_CCKEN_NFC_BIT); 
} 
void EnableNANDPower(void) 
{ 
} 
void DisableNANDPower(void) 
{ 
} 
static  void NAND_ObtainSleepSema(void) 
 { 
	 APIMISC_ObtainDSleepSemaphore(); 
 
 } 
 static void NAND_ReleaseSleepSema(void) 
 { 
    	APIMISC_ReleaseDSleepSemaphore(); 
 } 
 
 
 
 
 
 UINT8  NAND_Mount(void) 
 { 
 	UINT8 status ; 
	  
	if(NandMountStatus<0)  
		return NAND_UNDEFINED_ERR ; 
	 
	NandMountStatus++ ; 
	if (NandMountStatus==1) 
	{	DEBUG_OUT("NAND_Mount\r\n");	 
		EnableNANDPower();    
		EnableNANDClock(); 
		EnableNANDControler() ; 
		status=NAND_Init() ; 
		return status;	 
	} 
 
	return NAND_PASS; 
			 
 } 
 
 UINT8  NAND_Unmout(void) 
 { 
 	NandMountStatus --; 
	 
	if (NandMountStatus==0) 
	{	 
		DisableNANDClock(); 
		DisableNANDControler(); 
		DisableNANDPower();	 
		return NAND_PASS; 
	} 
	if(NandMountStatus<0)  
		return NAND_UNDEFINED_ERR ; 
    return NAND_PASS; 
 
 } 
  
/********************************************************************************/ 
/*****************************Error Correction Code Part Start************************/ 
/********************************************************************************/ 
#ifdef NAND_SPEED_OPTIMISE 
__inline static  void EccClear(void) 
#else 
static  void EccClear(void) 
#endif 
{ 
	/*clear hardware ecc correction*/ 
	WRITE_REG32(NFLASH_NFECC_ADDR,0x80000000) ;  
	return ; 
} 
 
 
#ifdef NAND_SPEED_OPTIMISE 
__inline static void GenerateEcc(UINT8 *pEccBuf) 
#else 
 static void GenerateEcc(UINT8 *pEccBuf) 
 #endif 
{ 
	UINT32 ecc_code_page ; 
	/* 
	*Get the write data Ecc code 
	* here the ECCECC is not used. 
	*/ 
	ecc_code_page = READ_REG32(NFLASH_NFECC_ADDR) & 0x3fffffff; 
	pEccBuf[0] = (UINT8) (ecc_code_page & 0x000000ff); 
	pEccBuf[1] = (UINT8) ((ecc_code_page >> 8) & 0x000000ff); 
	pEccBuf[2] = (UINT8) ((ecc_code_page >> 16) & 0x000000ff); 
	//pEccBuf[3] = (UINT8) ((ecc_code_page >> 24) & 0x0000003f); 
 
	return; 
} 
static NAND_Ret CompareEcc(UINT8 *RdEccBuf, UINT8 *WrEccBuf) 
{ 
	if ((RdEccBuf[0] != WrEccBuf[0]) || 
		(RdEccBuf[1] != WrEccBuf[1]) || 
		(RdEccBuf[2] != WrEccBuf[2])) 
	{ 
		DEBUG_OUT("Read NAND_ECC_ERR\n\r") ; 
		return  NAND_ECC_ERR ; 
	} 
 
	return  NAND_PASS  ; 
} 
/********************************************************************************/ 
/********************************************************************************/ 
/********************************************************************************/ 
 
 
 
 
/********************************************************************************/ 
/*****************************Polling Nand FLASh Status Part   ************************/ 
/********************************************************************************/ 
/* 
 * Function:	ReadStatusRegister( ) 
 * DeSCRiption:    This function be used to read the Nand Flash Status register					   
 * Input:      None	    
 * Output:    None    
 * Return:    return device status	    
 * Others:  	    
 */   
static NAND_Ret ReadStatusRegister(void) 
{ 
	UINT8 device_status ; 
 
	mNandWrite_SET_CLE(READ_STATUS_CMD); 
	device_status = (UINT8) (mNand_Read_Data() & 0xff) ; 
 
	return (device_status) ; 
} 
 
/* 
 * Function:	IsSucessProgram( ) 
 * DeSCRiption:    This function be used to 	judge  if   wirting or erasing  is success ,once fail must make the 
						   block invalid 
 * Input:      None	    
 * Output:    None    
 * Return:    if success : NAND_PASS  ,or lese return NAND_FAIL    
 * Others:  	    
 */   
static NAND_Ret IsSucessProgram(void) 
{ 
	UINT8 device_status ; 
 
	device_status = ReadStatusRegister(); 
 
	if ((device_status & TOTAL_PASS_BIT) == 0) 
	{ 
		return NAND_PASS ; 
	} /* 1 is sucess*/ 
 
	return NAND_FAIL ; 
} 
 
#ifdef _NAND_DEBUG_ 
static NAND_Ret IsWriteProtect(void) 
{ 
	UINT8 device_status ; 
 
	device_status = ReadStatusRegister(); 
 
	if ((device_status & WRITE_PROTECT_BIT) == WRITE_PROTECT_BIT) 
	{ 
		return NAND_PASS ; 
	} /* Not write protect*/ 
 
	return NAND_FAIL; 
} 
#endif /*_NAND_DEBUG_*/ 
 
/* 
 * Function:	IsReadyToRW( ) 
 * DeSCRiption:    This function be used to 	judge  if   wirting ,reading or erasing  is ready by checking  
						   the  Nand controler register 
 * Input:      None	    
 * Output:    None    
 * Return:    if success : NAND_PASS  ,or lese return NAND_FAIL    
 * Others:  	    
 */   
static NAND_Ret IsReadyToRW(void) 
{ 
	UINT32 device_status ; 
	UINT32 timeout = 1; 
 
	device_status = READ_REG32(NFLASH_NFINTP_ADDR)  ; 
	while ((device_status & 0x1) != 0x01)//busy 
	{ 
		device_status = READ_REG32(NFLASH_NFINTP_ADDR) ; 
		//timeout++ ; 
		if ((++timeout) == 0x00fff) 
		{ 
			WRITE_REG32(NFLASH_NFINTP_ADDR,1) ; 
			return  NAND_FAIL ; 
		} 
	} 
 
	WRITE_REG32(NFLASH_NFINTP_ADDR,1) ; 
	return  NAND_PASS; 
} 
 
static NAND_Ret IsReadyToRW1(void) 
{ 
	UINT32 device_status ; 
	UINT32 EventStatus, EventResult; 
	extern void HD_EnableInterrupt(UINT32); 
 
	EventStatus = OS_DRIVER_WaitEventOR(PERIPH_EVENT_ID,PERIPH_NAND_EVTBIT,&EventResult, 
					NAND_DMA_TIMEOUT_VALUE);  
	if (EventStatus == OS_DRIVER_WAIT_EVENT_TIMEOUT) 
	{ 
		return NAND_FAIL ; 
	} 
	else 
	{ 
		WRITE_REG32(NFLASH_NFINTE_ADDR,0) ;/*Disable NAND INT*/ 
		device_status = READ_REG32(NFLASH_NFINTP_ADDR)  ; 
		WRITE_REG32(NFLASH_NFINTP_ADDR,1) ; 
		WRITE_REG32(NFLASH_NFINTE_ADDR,1) ;/*Enable NAND INT*/ 
		HD_EnableInterrupt(INT_NAND_BIT); 
		if ((device_status & 0x1) == 0x01) 
		{ 
			return  NAND_PASS; 
		} 
	} 
	return  NAND_FAIL; 
} 
 
 
/********************************************************************************/ 
/********************************************************************************/ 
/********************************************************************************/ 
 
 
 
 
/********************************************************************************/ 
/********************************Nand Chip Select and Deselect***********************/ 
/********************************************************************************/ 
#ifdef NAND_SPEED_OPTIMISE 
__inline static void NFlashSelect(void) 
#else 
 static void NFlashSelect(void) 
 #endif 
{ 
#if (ASIC_VERSION!=VT3360) 
	UINT16 gpdir; 
	UINT16 gpdr; 
	OS_DRIVER_ObtainSemaphore(GPIO_SEMAPHORE_ID); 
	/*set the direction of gpio8 as output*/ 
	gpdir = (READ_REG(GPIO_GPDIR_ADDR) & 0xFFFF) | (1 << NAND_SEL_GPIO_PIN); /*GPIO10*/ 
	WRITE_REG(GPIO_GPDIR_ADDR,gpdir); 
	/*set gpio 8 low to select nand flash chip*/ 
	//gpdr = (READ_REG(GPIO_GPDR_ADDR) & 0XFBFF);/*GPIO10*/ 
	gpdr = (READ_REG(GPIO_GPDR_ADDR) & 0XFFFF) & (~(1 << NAND_SEL_GPIO_PIN)); 
	WRITE_REG(GPIO_GPDR_ADDR,gpdr); 
	OS_DRIVER_ReleaseSemaphore(GPIO_SEMAPHORE_ID); 
#endif/*(ASIC_VERSION!=VT3363)*/ 
} 
 
#ifdef NAND_SPEED_OPTIMISE 
__inline static void NFlashDeselect(void) 
#else 
 static void NFlashDeselect(void) 
 #endif 
 
{ 
#if (ASIC_VERSION!=VT3360) 
	UINT16 gpdir; 
	UINT16 gpdr; 
	OS_DRIVER_ObtainSemaphore(GPIO_SEMAPHORE_ID); 
	/*set the direction of gpio8 as output*/ 
	gpdir = (READ_REG(GPIO_GPDIR_ADDR) & 0xFFFF) | (1 << NAND_SEL_GPIO_PIN); 
	WRITE_REG(GPIO_GPDIR_ADDR,gpdir); 
	/*set gpio 8 high to deselect nand flash chip*/ 
	gpdr = (READ_REG(GPIO_GPDR_ADDR) & 0XFFFF) | (1 << NAND_SEL_GPIO_PIN); 
	WRITE_REG(GPIO_GPDR_ADDR,gpdr); 
	OS_DRIVER_ReleaseSemaphore(GPIO_SEMAPHORE_ID); 
#endif/*(ASIC_VERSION!=VT3363)*/ 
} 
/********************************************************************************/ 
/********************************************************************************/ 
/********************************************************************************/ 
 
/* 
 * Function:	NFlashDelay( )  
 * DeSCRiption:    This function be used to delay some time  make the hardware steady   					   
 * Input:     UINT32  DelayValue : delay value    
 * Output:    None    
 * Return:    None	    
 * Others:  	    
 */   
static void NFlashDelay(UINT32 DelayValue) 
{ 
	UINT32 i ; 
 
	for (i = 0 ; i < DelayValue+1 ; i++) 
		NULL ; 
 
	return ; 
} 
 
/* 
 * Function:	NFlash_Reset( ) 
 * DeSCRiption:    This function be used to reset Nand Flash controler					   
 * Input:      None	    
 * Output:    None    
 * Return:    None	    
 * Others:  	    
 */   
 void NFlashReset(void) 
{ 
	mNandWrite_SET_CLE(RESET_CMD); 
	NFlashDelay(10) ; 
} 
 
/* 
 * Function:	NFlash_ReadID( ) 
 * DeSCRiption:    This function be used to read the Nand Flash ID (maker_code,device_code etc)					   
 * Input:      None	    
 * Output:    None    
 * Return:    return device code	    
 * Others:  	    
 */   
static NAND_Ret NFlashReadID(void) 
{ 
	/*UINT8 dont_care_code ;*/ 
#if (NFLASH_TYPE == TYPE_IS_K9F1208X0B)  
	UINT32 tmp ; 
#endif/*#if (NFLASH_TYPE == TYPE_IS_K9F1208X0B) */ 
 
	mNandWrite_SET_CLE(READ_ID_CMD); 
	mNandWrite_SET_ALE(0x00) ; 
 
#if (NFLASH_TYPE == TYPE_IS_K9F1208X0B)  
	gNFlashInfo.maker_code = (UINT8) (mNand_Read_Data() & 0xff) ; 
	gNFlashInfo.device_code = (UINT8) (mNand_Read_Data() & 0xff) ; 
	tmp = mNand_Read_Data(); 
	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_ 
		{ 
			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("Woob 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) pWrOobBuf,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("Woob 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_*/ 
	{ 
		UINT16 i = 0 ; 
 
		for (i = 0 ; i < len; i++) 
			mNand_Write_Data(pWrOobBuf[i]) ; 
	} 
#endif  /*_NFLASH_DMA_*/ 
 
	/***this palce need to pull up the  nce**/ 
	mNandWrite_SET_CLE(PAGE_PRO_TRUE_CMD2); 
 
	if (!IsReadyToRW()) 
	{ 
		DEBUG_OUT("Woob NAND_HW_ERR\n\r") ; 
		return NAND_HW_ERR ; 
	} 
 
	/*if failure it need to block placement*/ 
	if (!IsSucessProgram()) 
	{ 
		DEBUG_OUT("Woob NAND_PRG_FAIL\n\r") ; 
		return NAND_FAIL ; 
	} 
 
	return NAND_PASS; 
} 
 
 NAND_Ret NAND_SpareRead(UINT32 udAddress, UINT8 *pOobBuf,UINT32 len) 
{ 
#ifdef _NAND_DEBUG_ 
	DEBUG_OUT("NandReadOOB\n\r") ; 
	if ((pOobBuf == NULL) || (len > 16)) 
	{ 
		DEBUG_OUT("Roob NAND_SW_ERR\n\r") ; 
		return NAND_SW_ERR ; 
	} 
	if (udAddress >= FLASH_SIZE_64MB) 
	{ 
		DEBUG_OUT("Roob 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; 
	} 
#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_ALE(udAddress&0x03ffff0f) ; 
 
	if (!IsReadyToRW()) 
	{ 
		DEBUG_OUT("Roob NAND_HW_ERR\n\r") ; 
		return NAND_FAIL ; 
	} 
 
#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) pOobBuf,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("Roob 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) pOobBuf,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("Roob 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_*/ 
	{ 
		UINT8 *pd = pOobBuf ; 
 
		 	 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 			 
                      *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
	} 
#endif/*_NFLASH_DMA_*/ 
 
	return NAND_PASS; 
} 
 
 
 NAND_Ret NAND_PageReadWithEcc(UINT32 udAddress, dataWidth *pReadBuf,UINT32 len) 
{ 
	UINT8 error_code = NAND_PASS ; 
	UINT8 EccBuf[3]; 
 
#ifdef _NAND_DEBUG_ 
	DEBUG_OUT("NandReadWithEcc\n\r") ; 
 
	if ((pReadBuf == NULL) || (len > PAGE_SIZE)) 
	{ 
		DEBUG_OUT("Read NAND_SW_ERR\n\r") ; 
		return NAND_SW_ERR ; 
	} 
 
	if (udAddress >= FLASH_SIZE_64MB) 
	{ 
		DEBUG_OUT("Read NAND_ADDR_OVERFLOW\n\r") ; 
		return NAND_ADDR_OVERFLOW; 
	} 
#endif /*_NAND_DEBUG_*/ 
 
	//udAddress &= 0x03ffffff ; 
	WRITE_REG32(NFLASH_NFINTP_ADDR,1) ; 
	mNandWrite_SET_CLE(READ1_CMD_00H); 
	mNandWrite_SET_ALE(udAddress&0x03ffffff) ; 
 
	if (!IsReadyToRW()) 
	{ 
		DEBUG_OUT("Read NAND_HW_ERR\n\r") ; 
		return NAND_FAIL ; 
	} 
 
	EccClear(); 
	/**************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) | (SECTOR_SIZE- 1) << 8 | (1 << 20) | (0 << 21) ;  */ 
		temp = 0x11FF01; 
		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("Read 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) | (512 << 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("Roob 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); 
	 
		GenerateEcc(&EccBuf[0]); 
		 
		/*start ,byte width ,length is len, source fix ,dst increment*/ 
		OS_DRIVER_ObtainSemaphore(DMA_SEMAPHORE_ID);   
		/*temp = (1 << 0) | (0 << 4) | (16 - 1) << 8 | (1 << 20) | (0 << 21) ;  */ 
	#if (DMA_TYPE==TYPE_IS_MOSE_DMA) 
		EnablePDClk(PD_CCKEN_DMAC_BIT); 
		temp = 0x100F01;   
		ProgramDMAChannel(NFLASH_NFDIN_ADDR + 1,(UINT32) (pReadBuf + SECTOR_SIZE),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("Read NAND_DMA_TIMEOUT\n\r") ; 
					OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);  
					return NAND_DMA_TIMEOUT; 
				}  
			} 
		#else 
			TimeOut = 0; 
			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) | (16 << 12); 
 
			ProgramDMAChannel(NFLASH_NFDIN_ADDR,(UINT32) (pReadBuf + SECTOR_SIZE), 
				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("Roob 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); 
		error_code = CompareEcc(&EccBuf[0],pReadBuf + SECTOR_SIZE); 
	} 
#else   /*_NFLASH_DMA_*/ 
	{ 
		 
	   	 UINT8  mi,*pd; 
		 UINT16 temp = SECTOR_SIZE>>4 ; 
		 pd=(unsigned char *)pReadBuf; 
		 mi=0; 
		do 
		{ 
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 			 
                      *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 			 	 
		}while((++mi) PAGE_SIZE)) 
	{ 
		DEBUG_OUT("Write NAND_SW_ERR\n\r") ; 
		return NAND_SW_ERR ; 
	} 
	if (udAddress >= FLASH_SIZE_64MB) 
	{ 
		DEBUG_OUT("Write NAND_ADDR_OVERFLOW\n\r") ; 
		return NAND_ADDR_OVERFLOW; 
	} 
	/*if Write protection is valid*/ 
	if (!IsWriteProtect()) 
	{ 
		DEBUG_OUT("Write NAND_WRPRT_ERR\n\r") ; 
		return NAND_WRPRT_ERR; 
	} 
#endif /*_NAND_DEBUG_*/ 
 
	WRITE_REG32(NFLASH_NFINTP_ADDR,1) ; 
	mNandWrite_SET_CLE(READ1_CMD_00H);  /*reset  pointer to 'a' area*/ 
	mNandWrite_SET_CLE(PAGE_PRO_TRUE_CMD1); 
	mNandWrite_SET_ALE(udAddress&0x03ffffff) ; 
 
	EccClear() ; 
 
	/*********Write  the 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 inc ,dst fix*/ 
		/*temp = 1 << 0 | 0 << 4 | (SECTOR_SIZE - 1) << 8 | 0 << 20 | 1 << 21 ; */ 
		temp = 0x21FF01 ; 
		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("Write 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) | (512 << 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("Write 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); 
 
		GenerateEcc(&pWritebuf[SECTOR_SIZE]); 
 
		/*start ,byte width ,length is len, source inc ,dst fix*/ 
 
		OS_DRIVER_ObtainSemaphore(DMA_SEMAPHORE_ID);   
		/*temp = 1 << 0 | 0 << 4 | (16 - 1) << 8 | 0 << 20 | 1 << 21 ; */ 
	#if (DMA_TYPE==TYPE_IS_MOSE_DMA) 
		EnablePDClk(PD_CCKEN_DMAC_BIT); 
		temp = 0x200F01 ;   
		ProgramDMAChannel((UINT32) (pWritebuf + SECTOR_SIZE),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("Write NAND_DMA_TIMEOUT\n\r") ; 
					OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID); 
					return NAND_DMA_TIMEOUT; 
				} 
			} 
		#else 
			TimeOut = 0; 
			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) | (16 << 12); 
			ProgramDMAChannel((UINT32) (pWritebuf + SECTOR_SIZE),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("Write 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_*/ 
	{ 
 
	   	 UINT8  mi,*pd; 
		 UINT16 temp = SECTOR_SIZE>>4 ; 
		 pd=(unsigned char *)pWritebuf; 
		 mi=0; 
		do 
		{ 
			mNand_Write_Data(*pd++) ; 
			mNand_Write_Data(*pd++) ; 
			mNand_Write_Data(*pd++) ;  
			mNand_Write_Data(*pd++) ; 
			mNand_Write_Data(*pd++) ; 
			mNand_Write_Data(*pd++) ; 
			mNand_Write_Data(*pd++) ; 
			mNand_Write_Data(*pd++) ; 
			mNand_Write_Data(*pd++) ; 
			mNand_Write_Data(*pd++) ; 
			mNand_Write_Data(*pd++) ; 
			mNand_Write_Data(*pd++) ; 
			mNand_Write_Data(*pd++) ; 
			mNand_Write_Data(*pd++) ; 
			mNand_Write_Data(*pd++) ; 
			mNand_Write_Data(*pd++) ; 
			  
		}while((++mi) 16)) 
	{ 
		DEBUG_OUT("Roob NAND_SW_ERR\n\r") ; 
		return NAND_SW_ERR ; 
	} 
	if (udAddress >= FLASH_SIZE_64MB) 
	{ 
		DEBUG_OUT("Roob 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; 
	} 
#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_ALE((udAddress &0x03ffff0f)) ; 
 
	if (!IsReadyToRW()) 
	{ 
		DEBUG_OUT("Roob NAND_HW_ERR\n\r") ; 
		return NAND_FAIL ; 
	} 
 
 
	{ 
		UINT8 *pd = pOobBuf ; 
 
		 	 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 			 
                      *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
	} 
 
 
	return NAND_PASS; 
} 
#if 0 
NAND_Ret NAND_SpareReadRandom(UINT32 udAddress, dataWidth *pOobBuf, UINT32 udLenght) 
{ 
	UINT8 ErrorCode ; 
	//EnableNAND(); 
	ErrorCode = NandReadOOBNoDMA(udAddress,udLenght,pOobBuf); 
	//DisableNAND(); 
	return ErrorCode ; 
} 
#endif 
 
 
NAND_Ret NAND_ChipErase(void) 
{ 
	UINT8 ErrorCode ; 
	UINT32 i ; 
 
	NAND_Init(); 
 
	EnableNAND(); 
	for (i=0;i= FLASH_SIZE_64MB) 
	{ 
		DEBUG_OUT("Read NAND_ADDR_OVERFLOW\n\r") ; 
		return NAND_ADDR_OVERFLOW; 
	} 
#endif /*_NAND_DEBUG_*/ 
 
	WRITE_REG32(NFLASH_NFINTP_ADDR,1) ; 
	mNandWrite_SET_CLE(READ1_CMD_00H); 
	mNandWrite_SET_ALE(udAddress&0x03ffffff) ; 
 
	if (!IsReadyToRW()) 
	{ 
		DEBUG_OUT("Read NAND_HW_ERR\n\r") ; 
		return NAND_FAIL ; 
	} 
 
	EccClear(); 
	/**************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) | (SECTOR_SIZE- 1) << 8 | (1 << 20) | (0 << 21) ;  */ 
		temp = 0x11FF01; 
		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("Read 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) | (512 << 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("Roob 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); 
	 
		GenerateEcc(&EccBuf[0]); 
		 
		/*start ,byte width ,length is len, source fix ,dst increment*/ 
		OS_DRIVER_ObtainSemaphore(DMA_SEMAPHORE_ID);   
		/*temp = (1 << 0) | (0 << 4) | (16 - 1) << 8 | (1 << 20) | (0 << 21) ;  */ 
	#if (DMA_TYPE==TYPE_IS_MOSE_DMA) 
		EnablePDClk(PD_CCKEN_DMAC_BIT); 
		temp = 0x100F01;   
		ProgramDMAChannel(NFLASH_NFDIN_ADDR + 1,(UINT32) (&SpareBuf[0]),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("Read NAND_DMA_TIMEOUT\n\r") ; 
					OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);  
					return NAND_DMA_TIMEOUT; 
				}  
			} 
		#else 
			TimeOut = 0; 
			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) | (16 << 12); 
 
			ProgramDMAChannel(NFLASH_NFDIN_ADDR,(&SpareBuf[0]), 
				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("Roob 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); 
		error_code = CompareEcc(&EccBuf[0],&SpareBuf[0]); 
	} 
#else   /*_NFLASH_DMA_*/ 
	{ 
	   	 UINT8  mi,*pd; 
		 UINT16 temp = SECTOR_SIZE>>4 ; 
		 pd=(UINT8 *)pReadBuf; 
		 mi=0; 
		do 
		{ 
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 			 
                      *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 
 			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;  
			 *pd++ = (UINT8) (mNand_Read_Data() & 0xff) ; 			 	 
		}while((++mi)