www.pudn.com > nandflash_1G08U0A.rar > drv_nandflash.c


//////////////////////////////////////////////////////////////////////// 
//	ÎļþÃû		£ºdrv_nandflash.c 
//	Îļþ¹¦ÄÜ	£ºÏµÍ³¶ÁÈ¡Nand FlashÇý¶¯ 
//	×÷Õß		£ºcxl 
//	´´½¨Ê±¼ä	£º2005Äê11ÔÂ11ÈÕ 
//      ´¦ÀíÆ÷	        : Epson C33L05 
//	ÏîÄ¿Ãû³Æ	£º 
//	±¸×¢		£º 
//     ¿ÉÒÔÇý¶¯µÄNand FlashÐͺţº K9F1G08U0A  SAMSUNG 
//////////////////////////////////////////////////////////////////////// 
 
 
//Sys include file 
#include "..\include\common.h" 
#include "..\include\8timer.h" 
#include "..\include\16timer.h" 
#include "..\include\io.h" 
#include "..\include\presc.h" 
 
//Nand Flash driver file 
#include "comm_drv.h" 
#include "drv_nandfls.h" 
 
 
//#undef  USE_K9F5616 
//#undef  USE_K9F2808U0M 
//#define USE_K9F1208U0M 
 
t_nand_fls_id this_nand_fls_id,*p_nand_fls_id; 
 
int nand_fls_init(void) 
{ 
	unsigned short i; 
	//read id 
	p_nand_fls_id = &this_nand_fls_id; 
	memset(p_nand_fls_id,0,sizeof(t_nand_fls_id)); 
		 
	 
 
/*select ALE, CLE port as output*/ 
  	SET_ALE_L; 
 	SET_ALE_OUTPUT; 
 	SET_CLE_L; 
 	SET_CLE_OUTPUT; 
 
 	/* select CE15,16 data is high (P51)*/ 
 	SET_NAND_CE_H; 
	 
 	/*select CE/GPIO port function as CE*/ 
 	SET_NAND_CE_CE; 
	 
 	/*select CE as output*/ 
 	SET_NAND_CE_OUTPUT; 
	 
 	/* set flash device mode*/ 
  	SET_DEVICE_8;	 
 	 
 	/*select NAND flashmap to area 15 and boot function*/	 
	SET_NAND_AREA; 
 
 	/*select SMWE,SMRD port function as flash I/F function */ 
 	//CLR_SMIFREG; 
 	SET_SMIF_WE; 
 	SET_SMIF_RD; 
 	 
 	/*set by/ry signal as input*/ 
 	SET_BUSY_INPUT;	 
 	 
 	/*disable write protect*/ 
 	SET_WP_H; 
 	SET_WP_GPIO; 
 	 
 	/*set wp pin as output	*/ 
 	SET_WP_OUTPUT;	 
  
  
       SET_NAND_CE_L; 
   
       asm("nop"); 
   
 	 for(i=0;i<10000;i++){ 
		   asm("nop"); 
	 }	 
     
  
    	//write read ID command 
    	SET_CLE_H; 
    	REG_CHAR(Nand_Fls_COMM_ADD)=0x90; 
	SET_CLE_L; 
    	//write address 0 
    	SET_ALE_H; 
    	REG_CHAR(Nand_Fls_Reg_ADD)=0x00; 
	SET_ALE_L; 
  
    	//read maker id 
    	p_nand_fls_id->maker_code 		= REG_CHAR(Nand_Fls_Data_ADD); 
    	p_nand_fls_id->device_code 		= REG_CHAR(Nand_Fls_Data_ADD); 
    	p_nand_fls_id->rev1        		= REG_CHAR(Nand_Fls_Data_ADD); 
    	p_nand_fls_id->mutiplane_code = REG_CHAR(Nand_Fls_Data_ADD); 
    	 
    	SET_NAND_CE_H; 
    	asm("nop"); 
   	if((p_nand_fls_id->maker_code == 0xEC)&&(p_nand_fls_id->device_code == 0xF1)\ 
   			&&(p_nand_fls_id->mutiplane_code == 0x15)) 
   			return NAND_INIT_OK; 
    	return NAND_INIT_ERROR; 
    	 
 
} 
 
 
void nand_fls_Reset(void){ 
  	 
  	int i; 
 	 
 	SET_CLE_H;		/*set CLE H*/ 
 	 
 	*(volatile unsigned short*)NAND_Flash_BASE_ADDRESS=RESET_CMD;	/*write RESET command*/ 
 
 	SET_CLE_L;		/*set CE L*/ 
 
	/*Wait flash R/#B ready (worst case 500us reset when erase; delay 1ms for safe)*/ 
 	for (i=0; i<800; i++) { 
    		asm("nop"); 
  	}   
   
	return;	 
 } 
 
//ÕâÀïÓõ½µÄµØÖ·Èë¿Ú²ÎÊý¶¼ÊÇ×Ö½ÚµØÖ·£¬·¶Î§ÊÇ0--->128MB+4MB-1. 
//µØÖ·µÄ¸ñʽÊÇ:A7--A0,0000+A11---A8,A19--A12,A27--A20. 
//ÉÏÃæÕâÖÖÀí½âÊÇ´íÎóµÄ¡ 
//retÓÃÀ´¼ì²â²Á³ýÊÇ·ñÕýÈ·£¬ÔÚÄÚ´æÖÐ 
unsigned char ret; 
int nand_fls_erase_block(unsigned int Block_Number) 
{ 
	//unsigned char tmp_char; 
	int i; 
	 
 	SET_NAND_CE_L; 
 	asm("nop"); 
  
  //Step 1 Write auto block erase setup command 
       SET_CLE_H; 
 	REG_CHAR(Nand_Fls_COMM_ADD) = BLOCK_Er_SETUP_COMMAND; 
 	SET_CLE_L;	 
 	 
 	//Step 2 Write address  
 	SET_ALE_H; 
 
	//row address 1 
	REG_SHORT(Nand_Fls_Reg_ADD) = 0xff&(Block_Number<<6); 
 
	//row address 2 
	REG_SHORT(Nand_Fls_Reg_ADD) = (0xff00&(Block_Number<<6))>>8; 
	 
	SET_ALE_L; 
 	 	 
 	//Step 3 Write erase command 
 	SET_CLE_H; 
 	REG_CHAR(Nand_Fls_COMM_ADD) = Er_COMMAND; 
	SET_CLE_L; 
  
       asm("nop"); 
 	asm("nop"); 
 	asm("nop"); 
 	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
 
       do{}	 
 	while (!CHECK_BUSY);		/*wait R/#B to high*/ 
   
 	//Step 4 Write read status command 
 	SET_CLE_H; 
 	REG_CHAR(Nand_Fls_COMM_ADD) = READ_St_COMMAND; 
       SET_CLE_L; 
 	if(REG_CHAR(Nand_Fls_Data_ADD) & ERASE_ERROR_FLAG) 
 	{ 
 		SET_NAND_CE_H; 
		ret = 1; 
 	 	return -1; 
 	} 
 	else 
 	{ 
 		SET_NAND_CE_H; 
		ret = 0; 
 	 	return 0; 
 	} 
 
} 
 
//ÕâÀï°ÑÕâ¸öµØÖ·²ÎÊýpage_num¿´³ÉÊÇÈÎÒâÒ»¸ö×ֽڵĵØÖ·¡£ 
//ÉÏÃæµÄ¿´·¨ÊÇ´íÎóµÄ 
int nand_fls_write_page(unsigned char *data,unsigned int page_num,unsigned int block_num) 
{ 
	unsigned short sWriteCount; 
	int i; 
	 
 	SET_NAND_CE_L; 
 	asm("nop"); 
 	 
 	//write page program command 
 	SET_CLE_H; 
 	REG_CHAR(Nand_Fls_COMM_ADD) = SEQ_DATA_IN_COMMAND; 
 	SET_CLE_L; 
	 
 	//write column address  
 	SET_ALE_H; 
 	 
 	//column address 1 
 	REG_SHORT(Nand_Fls_Reg_ADD) =  0; 
 
	//colunm addr 2 
      REG_SHORT(Nand_Fls_Reg_ADD) =  0; 
	 
 	//row addr 1 
 	REG_SHORT(Nand_Fls_Reg_ADD) = 0xff&((block_num<<6)+page_num); 
	 
	//row addr 2 
 	REG_SHORT(Nand_Fls_Reg_ADD) = (0xff00&((block_num<<6)+page_num))>>8; 
	 
       SET_ALE_L; 
	 
 	//write data to nandflash 
 	for(sWriteCount = 0; sWriteCount < NAND_FLS_ALL; sWriteCount++) 
 	{         
		   	 
		      REG_CHAR(Nand_Fls_Data_ADD) = REG_CHAR(data + sWriteCount); 
 	} 
 	 
 	//write program command 0x10 
 	SET_CLE_H; 
  REG_CHAR(Nand_Fls_COMM_ADD)  = PROG_COMMAND;	 
      SET_CLE_L; 
 
      asm("nop"); 
 	asm("nop"); 
 	asm("nop"); 
 	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
 
	 do{}	 
 	while (!CHECK_BUSY);		/*wait R/#B to high*/ 
 	//write read status command 
 	SET_CLE_H; 
 	REG_CHAR(Nand_Fls_COMM_ADD)  = READ_St_COMMAND;  
       SET_CLE_L; 
 	if(REG_CHAR(Nand_Fls_Data_ADD) & PROG_ERROR) 
 	{ 
 		SET_NAND_CE_H; 
 		return -1; 
 	} else { 
 		SET_NAND_CE_H; 
 		return 0; 
 	} 
	 
 
} 
 
 
int nand_fls_read_page(unsigned char *data,unsigned int page_num,unsigned int block_num) 
{ 
  unsigned short sReadCount; 
  unsigned short i; 
   
  SET_NAND_CE_L; 
  asm("nop"); 
  
 	//write read command 
 	SET_CLE_H; 
 	REG_CHAR(Nand_Fls_COMM_ADD) = 0x00; 
 	SET_CLE_L; 
	 
 	//write column address  
 	SET_ALE_H; 
	 
 	REG_SHORT(Nand_Fls_Reg_ADD) =  0; 
	 
	REG_SHORT(Nand_Fls_Reg_ADD) =  0; 
	 
	REG_SHORT(Nand_Fls_Reg_ADD) = 0xff&((block_num<<6)+page_num); 
	 
 	REG_SHORT(Nand_Fls_Reg_ADD) = (0xff00&((block_num<<6)+page_num))>>8; 
 
 	SET_ALE_L; 
 
      //write read command 2 
      SET_CLE_H; 
 	REG_CHAR(Nand_Fls_COMM_ADD) = 0x30; 
 	SET_CLE_L; 
	asm("nop"); 
 	asm("nop"); 
 	asm("nop"); 
 	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
      do{}	 
 	while (!CHECK_BUSY);		/*wait R/#B to high*/ 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	asm("nop"); 
	for(i=0;i