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

📄 nandflash.c

📁 一个三星S3C2440上面的NANDFLASH芯片K9F1208的代码
💻 C
字号:
#include <S3C2440.H>

#define RnB  	(NFSTAT&0x0001)		//读取RnB状态
#define DectRnB	(NFSTAT&0x0003)

#define NandEnable     NFCONT&=0xfffd; 
#define NandDisable    NFCONT|=0x0002;
#define DATA NFDATA	  //32位
#define COMD NFCMD	  //8位
#define ADDR NFADDR	  //8位



#define SHOW 0
int CheckRnB(void)			   //检查数据线是否忙
{
	#define BUSY  0
	#define	READY 1
	if(DectRnB==0) //没有接收到忙结束信号
		return BUSY;
	if(DectRnB==1)
	{
		NFSTAT=NFSTAT|0x0003;
		return READY;
	}
}
int NandReadID(void)   //度芯片ID
{
	int NAND_DATA;
	COMD=0x90;
	ADDR=0x00; 
    NAND_DATA=DATA;
	SciTx('I'); 
	SciTx('D'); 
	SciTx(':');	
	SciTxHexWord(NAND_DATA);
    SciTx('\n');
	SciTx('\r');
	return NFDATA;	 
}
void CopyNandToSdram(unsigned int Source,unsigned int Destination,unsigned int Lenght)
{
	unsigned int Cntx,Cnty,PageCnt;
	PageCnt=(Lenght/512)+1;
	if(((Source>>8)&0x0001)==0)	//起始地址有奇偶,在这个上我跳了很久才出来
		COMD=0x00;	  
	if(((Source>>8)&0x0001)==1)
		COMD=0x01;
	ADDR=(Source&0x000000ff); 	 
	ADDR=((Source>> 9)&0x000000ff);
	ADDR=((Source>>17)&0x000000ff);
	ADDR=((Source>>25)&0x000000ff);	   //连续读取
	while((CheckRnB())==BUSY);
	for(Cnty=0;Cnty<PageCnt;Cnty++)//需要读取的页数
	{
		for(Cntx=(Source%512)/4;Cntx<(512/4);Cntx++)//从气势除开始,至一页末尾结束
		{
			*(unsigned int *)Destination=DATA;
		    Destination+=4;
		}
		Source=((Source%512)+1)*512;
		Cntx=DATA;
		Cntx=DATA;
		Cntx=DATA;
		Cntx=DATA;
		while((CheckRnB())==BUSY);
	}


}


unsigned int PageData[132];
unsigned int Stat;

unsigned int NandPageRead(int Addr)//读NandFlash,返回Page存储地址,读取线性地址一夜的数据和寄存器数据
{
	int Cnt;
	COMD=0x00;
	ADDR=0; 	 //PageRead是从一页的开始读取的	  ,共512字节
	ADDR=((Addr>>9)&0x000000ff);
	ADDR=((Addr>>17)&0x000000ff);
	ADDR=((Addr>>25)&0x000000ff);
	while((CheckRnB())==BUSY);
	for(Cnt=0;Cnt<132;Cnt++) //Cnt后的数字是Int,1个Page实际上是128*4;也就是128int;
	{
		PageData[Cnt]=DATA;
	}
	for(Cnt=0;Cnt<132;Cnt++)
	{			
		SciTxHexWord(PageData[Cnt]);
		SciTx(' ');
		if(Cnt%8==7) 
		{
			SciTx('\n');
			SciTx('\r');
		}
	}
	SciTx('\n');
	SciTx('\r');
	return (unsigned int)PageData;
}
unsigned int NandWordRead(int Addr)	  //返回独处的数据,读取的是线性地址的数据,程序自动分辨是Section1还是2不能读取标志
{									  //注意:有关地址4Byte对其的问题
	unsigned int Cnt;
	if(((Addr>>8)&0x0001)==0)
		COMD=0x00;	  
	if(((Addr>>8)&0x0001)==1)
		COMD=0x01;
	ADDR=((Addr)&0x000000ff); 
	ADDR=((Addr>>9)&0x000000ff);
	ADDR=((Addr>>17)&0x000000ff);
	ADDR=((Addr>>25)&0x000000ff);
	while((CheckRnB())==BUSY);
	Cnt=DATA;
	return Cnt;
}	
unsigned int RegData[4];
unsigned int NandRegRead(int Addr)//程序自动识别地址所处的页,然后读取他的16Byte寄存器
{
	int Cnt;
    COMD=0x50; 
	ADDR=0; 	  //从0号寄存器开始读取
	ADDR=((Addr>>9)&0x000000ff);
	ADDR=((Addr>>17)&0x000000ff);
	ADDR=((Addr>>25)&0x000000ff); 
	while((CheckRnB())==BUSY);
	for(Cnt=0;Cnt<4;Cnt++)
	{
		RegData[Cnt]=DATA;
	}	
	#if SHOW==1
	for(Cnt=0;Cnt<4;Cnt++)
	{			
		SciTxHexWord(RegData[Cnt]);
		SciTx(' ');
		if(Cnt%8==7) 
		{
			SciTx('\n');
			SciTx('\r');
		}
	}
	#endif
	return (unsigned int)RegData;
}
#define BADBLOCK 	0
#define NORMALBLOCK	1
unsigned int NandBlocStatCheck(int Block) //读取地址所在Block的第一第二页的寄存器的第0个值,用于检测坏块
{
	unsigned int x1,x2;
	//COMD=0xff;	
	//while((CheckRnB())==BUSY);
	COMD=0x50;
	ADDR=5;
	ADDR=(Block<< 5)&0x000000ff;	
	ADDR=(Block>> 3)&0x000000ff;	
	ADDR=(Block>>11)&0x000000ff;
	while((CheckRnB())==BUSY);
	x1=DATA;//Block的第一页第一个寄存器
	if(x1==0xffffffff) return NORMALBLOCK;
	else			   return BADBLOCK;
}

int BadBlocks[10];
int BadCnt;
void NandCheckBadBlocks(void)
{
	int Cnt;
	BadCnt=0;
	for(Cnt=1;Cnt<4096;Cnt++)
	{
		if(NandBlocStatCheck(Cnt)==BADBLOCK)
		{
			BadBlocks[BadCnt]=Cnt;
			#if SHOW==1
			SciTxData(4,Cnt);SciTx('\n');SciTx('\r');
			#endif
			BadCnt++; 
			//NandPageRead(Cnt<<13);
			//SciTxHexWord(NandWordRead((Cnt<<14)+516));
			//SciTx('\n');SciTx('\r');
		}
	}		
}
int NandPageProgram(int Addr,int *Data)	 //对一块没有擦除过的Flash编程会出错
{
	int Cnt;
	COMD=0x80;
	//ADDR=((Addr)&0x000000ff); 
	ADDR=0;
	ADDR=((Addr>>9)&0x000000ff);
	ADDR=((Addr>>17)&0x000000ff);
	ADDR=((Addr>>25)&0x000000ff);
	for(Cnt=0;Cnt<132;Cnt++)
	{
		DATA=Data[Cnt];
	} 
	COMD=0x10;
	while((CheckRnB())==BUSY);
	COMD=0x70;
	Stat=DATA; 	
	#if SHOW==1	
	SciTxHexWord(Stat);
	SciTx('\n');
	SciTx('\r');
	#endif
	return Stat;
}
void NandBlockErase(int Block)
{
	COMD=0x60;
	ADDR=((Block<<5)&0x000000ff); 
	ADDR=((Block>>3)&0x000000ff);
	ADDR=((Block>>11)&0x000000ff);
	COMD=0xD0;
	while((CheckRnB())==BUSY);
}

void NandFlash(void)
{	
	int Cnt;
	int x,y; 
	UartInit();
	NFCONF  = (2 << 12) | (7 << 8) | (4 << 4);	 //时间可以打不可以小
  	NFCONT  = (1 << 6) | (1 << 5) | (1 << 4) | (1 << 0);
	NandEnable;
	COMD=0xff;	
	while((CheckRnB())==BUSY);
    NandReadID(); 
	for(Cnt=0;Cnt<10;Cnt++)
	{		   
		SciTxData(2,Cnt);SciTx(':');SciTx('\n');SciTx('\r');
		NandPageRead(512*Cnt);  
	}  

	//while(1)
	//{
	//	SciTx('A');
	//}
}	
/*
				IMPORT  |Load$$StartSram$$Base|	 
                IMPORT  |Image$$StartSram$$Base|	
                IMPORT  |Image$$StartSram$$Length|	;初始化代码区

				IMPORT  |Load$$CodeSdram$$Base|	  
                IMPORT  |Image$$CodeSdram$$Base|
                IMPORT  |Image$$CodeSdram$$Length|	;其他的RO段

				IMPORT  |Load$$DataSdram$$Base|	  
                IMPORT  |Image$$DataSdram$$Base|
                IMPORT  |Image$$DataSdram$$Length|	;其他的RW,ZI段

StartSramBase     DCD  |Load$$StartSram$$Base|
StartSramLength   DCD  |Image$$StartSram$$Length|
StartSramRun   DCD  |Image$$StartSram$$Base|

	
CodeSdramBase     DCD  |Load$$CodeSdram$$Base|	 
CodeSdramLength   DCD  |Image$$CodeSdram$$Length|
CodeSdramRun   DCD  |Image$$CodeSdram$$Base|
	
DataSdramBase     DCD  |Load$$DataSdram$$Base|   
DataSdramLength   DCD  |Image$$DataSdram$$Length|
DataSdramRun   DCD  |Image$$DataSdram$$Base|	
*/

⌨️ 快捷键说明

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