www.pudn.com > flashfat16.rar > FLASH.C


#include  
#include  
#include  
#include "flash.h" 
#include "44b.h" 
#include "def.h" 
#include "44blib.h" 
	/*  PC7		6		5		4		3		2		1		0	*/ 
	/*   I		I		I		I		I		I		I		I	*/ 
	/*   NC		NC		NC		NC		SMCALE	SMCCLE	SMCCE	SMCRB*/ 
	/*   00		00		00		00		01		01		01		00	*/ 
 
extern void __RdPage528(U8 *);	/*these two function are writed in ASM*/ 
extern void __WrPage528(U8 *); 
U8 Verify_Buf[528]; 
unsigned int Check_Flash_Id(void) 
{ 
	int i; 
	unsigned int id; 
 
	FC_CMD; 
	Nand_IO = 0x90; 
 
	FC_ADDR; 
	Nand_IO = 0; 
	FC_DATA; 
 
	for(i=0;i<10;i++);	//wait 100ns 
	id = Nand_IO<<8; 
	id += Nand_IO; 
	FC_INACTIVE; 
	return id; 
} 
 
void Flash_Reset()		//flash reset 
{  
	int i; 
	//  rPDATC = rPDATC | WP;	//write unprotect 
	FC_CMD; 
	Nand_IO = 0xff;	//reset command 
	for (i=0;i<3000;i++);	//delay 	 
} 
/********************************************************/ 
/*功能:擦除FLASH的1Block(对应文件系统为1Cluster)          */ 
/*     每一个簇为16KB,因此KM29U128共有1024个簇            */ 
/*输入:unsigned int cluster/block(需要擦除的Block Number)*/ 
/*返回:OK或FAIL                                         */ 
/********************************************************/ 
unsigned char Erase_Cluster(unsigned int cluster)  
{ 
	unsigned int blockPage = (cluster<<5); 
	int i; 
 
	FC_CMD; 
	Nand_IO = 0x60; 
 
	FC_ADDR;	      
	Nand_IO = blockPage & 0xff;   
	Nand_IO = (blockPage>>8) & 0xff; 
 
	for(i=0;i<2;i++);		//tWC  50ns 
     
	FC_CMD; 
	Nand_IO = 0xd0; 
     
	for(i=0;i<3;i++); 
     
	FC_DATA; 
	WAITRB;					//wait max 3ms 
 
	FC_CMD; 
	Nand_IO = 0x70; 
	FC_DATA; 
	if (Nand_IO & 0x1) //erase error 
	{ 
		FC_INACTIVE; 
		return FAIL; 
	} 
	else  
	{ 
		FC_INACTIVE;    
		return OK; 
	} 
} 
/********************************************************/ 
int VerifyPage(unsigned int block,unsigned int page,U8 *buffer) 
{ 
	ReadPage(block,page,Verify_Buf); 
	if(strncmp((char *)Verify_Buf,(char *)buffer,528)==0) 
		return 1; 
	else 
		return 0; 
} 
/*****************************************************************/ 
/*功能:读取FLASH的某个Block中的1page数据                           */ 
/*     在文件系统中,有如下对应关系:Block=Cluster                   */ 
/*                               Page =Sector                    */ 
/*输入:unsigned int block,page,unsigned char *pPage(存放数据的地址)*/ 
/*****************************************************************/ 
void ReadPage(unsigned int block,unsigned int page,unsigned char *pPage) 
{ 
	int i; 
	unsigned int blockPage = (block<<5) + page; 
 
	FC_CMD;                
	Nand_IO = 0x00; 
	FC_ADDR; 
	Nand_IO = 0; 
	Nand_IO = blockPage & 0xff; 
	Nand_IO = (blockPage>>8) & 0xff; 
	for(i=0;i<3;i++); 
	FC_DATA; 
	WAITRB;	//random access ,wait max. 10us  
	for(i=0;i<528;i++) 
		{*pPage++=Nand_IO;}         //data input->as the same as _WrPage528() 
//	__RdPage528(pPage);		//which is written with assemble in flash.s 
	FC_INACTIVE; 
} 
/*****************************************************************/ 
/*功能:向FLASH的某个Block中的1page写入数据                         */ 
/*     在文件系统中,有如下对应关系:Block=Cluster                   */ 
/*                               Page =Sector                    */ 
/*输入:unsigned int block,page,unsigned char *pPage(存放数据的地址)*/ 
/*输出:0:Fail;1:OK                                               */ 
/*****************************************************************/ 
int WritePage(unsigned int block,unsigned int page,unsigned char *pPage)   
{ 
	unsigned int blockPage = (block<<5) + page; 
	int i; 
	U8 *Source;                                      //the begin addr of data to write 
	Source=pPage; 
	FC_CMD; 
	Nand_IO = 0x80; 
	FC_ADDR; 
	Nand_IO = 0; 
	Nand_IO = blockPage & 0xff; 
	Nand_IO = (blockPage>>8) & 0xff; 
	FC_DATA; 
	for(i=0;i<528;i++) 
		{Nand_IO=*pPage++;}         //data input->as the same as _WrPage528() 
//	__WrPage528(pPage); //which is written with assemble in flash.s 
 
	FC_CMD; 
	Nand_IO = 0x10; 
	for(i=0;i<10;i++);  //twb=100ns. why is it 10? spec is false?   
                        //No. It's because of LED of PE1. 
	WAITRB;	//wait max 500us; 
	Nand_IO = 0x70; 
	FC_DATA; 
	for(i=0;i<3;i++);  //twhr=60ns 
	if((Nand_IO & 0x1))	//	 
	{ 
		FC_INACTIVE;	 
		return 0; 
	} 
	else 
	{ 
		FC_INACTIVE;	 
		pPage = Source;     
		#if (WRITEVERIFY==1) 
			return VerifyPage(block,page,pPage);	 
		#else 
			return 1; 
		#endif 
	} 
} 
/*******************************************************************/ 
/*功能:显示FLASH的数据                                              */ 
/*     整个16MBFLASH空间的划分如下:                                  */ 
/*     Root:Cluster0                                               */ 
/*     Application:Cluster1~1023                                   */ 
/********************************************************************/ 
void Flash_Tools(void) 
{ 
	unsigned char bbb[528]; 
	unsigned int i,sector,cluster; 
	Flash_Reset(); 
	if(Check_Flash_Id()==KM29U128_ID) 
	{ 
		i = 0; 
		sector = 0; 
		cluster = 0; 
		Uart_Printf("\n*                     R(r)>>Point to Root zone(Cluster0)                *"); 
		Uart_Printf("\n*                     A(a)>>Point to Application zone(Cluster1~1023)    *"); 
		Uart_Printf("\n*                     C(c)>>Point to Next Cluster                       *"); 
		Uart_Printf("\n*                     S(s)>>Point to Next Sector                        *"); 
		Uart_Printf("\n*                     Q(q)>>Quit                                        *"); 
		Uart_Printf("\n*-----------------------------------------------------------------------*"); 
 
		//Uart_Printf("\n*---------------------Boot Zone at Cluster %4d, Sector %2d--------------*",cluster,sector); 
		while(1) 
		{ 
			char aa;	 
			 
			aa = Uart_Getch(); 
			if (aa == 'q' || aa=='Q') break; 
			/***** 
			ReadPage(cluster,sector,&(bbb[0])); 
			Uart_Printf("\n*---------------------Cluster %4d, Sector %2d---------------------------*",cluster,sector); 
			for(i=0;i<528;i=i+16) 
			{ 
				Uart_Printf("\nBYTE%4x:%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x",\ 
				i,bbb[i],bbb[i+1],bbb[i+2],bbb[i+3],bbb[i+4],bbb[i+5],bbb[i+6],bbb[i+7],\ 
				bbb[i+8],bbb[i+9],bbb[i+10],bbb[i+11],bbb[i+12],bbb[i+13],bbb[i+14],bbb[i+15]); 
			}	****/ 
			//sector++; 
			if (sector>=32)//goto next cluster 
			{ 
				cluster++; 
				sector = 0; 
		   	} 
			//aa = Uart_Getch(); 
			//if (aa == 'q' || aa=='Q') break; 
			switch(aa) 
			{ 
			case 'r': 
			case 'R': 
				cluster = 0; 
				sector = 0; 
				Uart_Printf("\n*---------------------Root Zone at Cluster %4d, Sector %2d--------------*",cluster,sector); 
				ReadPage(cluster,sector,&(bbb[0])); 
				for(i=0;i<528;i=i+16) 
				{ 
					Uart_Printf("\nBYTE%4x:%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x",\ 
					i,bbb[i],bbb[i+1],bbb[i+2],bbb[i+3],bbb[i+4],bbb[i+5],bbb[i+6],bbb[i+7],\ 
					bbb[i+8],bbb[i+9],bbb[i+10],bbb[i+11],bbb[i+12],bbb[i+13],bbb[i+14],bbb[i+15]); 
				} 
				Uart_Printf("\n*---------------------Cluster %4d, Sector %2d---------------------------*",cluster,sector); 
				break; 
 
			case 'a': 
			case 'A': 
				cluster = 1; 
				sector = 0; 
				Uart_Printf("\n*---------------------Application Zone at Cluster %4d, Sector %2d-------*",cluster,sector); 
				ReadPage(cluster,sector,&(bbb[0])); 
				for(i=0;i<528;i=i+16) 
				{ 
					Uart_Printf("\nBYTE%4x:%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x",\ 
					i,bbb[i],bbb[i+1],bbb[i+2],bbb[i+3],bbb[i+4],bbb[i+5],bbb[i+6],bbb[i+7],\ 
					bbb[i+8],bbb[i+9],bbb[i+10],bbb[i+11],bbb[i+12],bbb[i+13],bbb[i+14],bbb[i+15]); 
				} 
				Uart_Printf("\n*---------------------Cluster %4d, Sector %2d---------------------------*",cluster,sector); 
				break; 
		 
			case 'c': 
			case 'C': 
				cluster ++; 
				if (cluster>=1024)  
					cluster = 0; 
				sector = 0; 
				Uart_Printf("\n*---------------------Cluster %4d, Sector %2d---------------------------*",cluster,sector); 
				ReadPage(cluster,sector,&(bbb[0])); 
				for(i=0;i<528;i=i+16) 
				{ 
					Uart_Printf("\nBYTE%4x:%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x",\ 
					i,bbb[i],bbb[i+1],bbb[i+2],bbb[i+3],bbb[i+4],bbb[i+5],bbb[i+6],bbb[i+7],\ 
					bbb[i+8],bbb[i+9],bbb[i+10],bbb[i+11],bbb[i+12],bbb[i+13],bbb[i+14],bbb[i+15]); 
				} 
				Uart_Printf("\n*---------------------Cluster %4d, Sector %2d---------------------------*",cluster,sector); 
				break; 
				 
			case 's': 
			case 'S': 
				sector++; 
				if (sector>=32)  
				{ 
					sector = 0; 
					cluster ++; 
					if (cluster>=1024) sector = 0; 
				} 
				Uart_Printf("\n*---------------------Cluster %4d, Sector %2d---------------------------*",cluster,sector); 
				ReadPage(cluster,sector,&(bbb[0])); 
				for(i=0;i<528;i=i+16) 
				{ 
					Uart_Printf("\nBYTE%4x:%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x",\ 
					i,bbb[i],bbb[i+1],bbb[i+2],bbb[i+3],bbb[i+4],bbb[i+5],bbb[i+6],bbb[i+7],\ 
					bbb[i+8],bbb[i+9],bbb[i+10],bbb[i+11],bbb[i+12],bbb[i+13],bbb[i+14],bbb[i+15]); 
				} 
				Uart_Printf("\n*---------------------Cluster %4d, Sector %2d---------------------------*",cluster,sector); 
				break; 
					 
			default: 
				Uart_Printf("\n*                     R(r)>>Point to Root zone(Cluster0)                *"); 
				Uart_Printf("\n*                     A(a)>>Point to Application zone(Cluster1~1023)    *"); 
				Uart_Printf("\n*                     C(c)>>Point to Next Cluster                       *"); 
				Uart_Printf("\n*                     S(s)>>Point to Next Sector                        *"); 
				Uart_Printf("\n*                     Q(q)>>Quit                                        *"); 
				Uart_Printf("\n*-----------------------------------------------------------------------*"); 
 
				//Uart_Printf("\n*---------------------Boot Zone at Cluster %4d, Sector %2d--------------*",cluster,sector); 
				break; 
			} 
		} 
	} 
	else 
	{ 
			Uart_Printf("\n*                K9F2808 No Found.Please check your hardware!         *"); 
			Uart_Printf("\n*-----------------------------------------------------------------------*"); 
	} 
}