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

📄 nandflash.c

📁 ucos_ii在mini2440上的移植KEIL编译环境
💻 C
字号:
#include "NandFlash.h"

//Nand Flash复位
void NAND_Reset(void)
{
	volatile int i;
	NF_nFCE_L();
	NF_CLEAR_RB();
	for(i=0; i<10; i++);
	NF_CMD(0XFF);
	NF_DETECT_RB();
	NF_nFCE_H();
}


//Nand初始化
void NAND_Init(void)
{
	NFCONF &= 0;
	NFCONF |= NFCONF_VAL;
	NFCONT &= 0;
	NFCONT |= NFCONT_VAL;
	NFSTAT = 0;
	NAND_Reset();
}

//读取Nand Flash的ID
unsigned int NAND_ReadId(char * th2,char * th3,char * th4,char * th5)
{
	unsigned int nID = 0;
	char cCh;
	NAND_Reset();
	
	NF_nFCE_L();
	NF_CMD(0X90);
	NF_ADDRESS(0X00);   //写入地址
	NF_DETECT_RB();  //等待存储区空间
	
	//读取数据
	
	cCh = NF_RDDATA8();
	cCh = NF_RDDATA8();
	*th2 = cCh;
	nID = ((int)cCh << 24);
	cCh = NF_RDDATA8();
	*th3 = cCh;
	nID |= ((int)cCh << 16);
	cCh = NF_RDDATA8();
	*th4 = cCh;
	nID |= ((int)cCh << 8);
	cCh = NF_RDDATA8();
	*th5 = cCh;
	nID |= ((int)cCh << 0);
	


	NF_nFCE_H();
	return nID;
}

//读取状态
unsigned int NF_ReadStatus(void)
{
	unsigned int nState = 0;
	NF_nFCE_L();
	NF_CMD(0x70);
	nState = NF_RDDATA8();
	NF_nFCE_H();

	return nState;
}

//坏块判断
int NF_CheckBlock(unsigned int nBlock)
{
	char cState = 0;
	int nState = 0;
	
	//读取坏块标志1
	NF_ReadPage((nBlock <<6)+0,NF_INVALIDBLOCK_BYTE,&cState,1);
	if(cState != NF_VALID_BLOCK_SIGN) //坏块
	{
		nState = 1;
	}
	
	//读取坏块标志2
	NF_ReadPage((nBlock <<6)+1,NF_INVALIDBLOCK_BYTE,&cState,1);
	if(cState != NF_VALID_BLOCK_SIGN) //坏块
	{
		nState = 1;
	}
	
	return nState;
}

int NF_write_addr(int nRowAddr,int nColAddr)
{
	int n;
	//写入地址
	NF_ADDRESS(nColAddr & 0xFF);
	for(n = 0; n < 10; n++);
	NF_ADDRESS(((nColAddr >> 8) & 0XF));
	for(n = 0; n < 10; n++);
	NF_ADDRESS(((nRowAddr >> 0) & 0XFF));
	for(n = 0; n < 10; n++);
	NF_ADDRESS(((nRowAddr >> 8) & 0XFF));
	for(n = 0; n < 10; n++);
	NF_ADDRESS(((nRowAddr >> 16) & 0X1));
	for(n = 0; n < 10; n++);

	return 1;
}

//单次读取页数据
int NF_ReadPage(int nRowAddr,int nColAddr,void * pvReadBuff,int nSize)
{
	int nCount;

	NF_nFCE_L(); //芯片片选
	NF_CLEAR_RB();
		
	NF_CMD(0X00);
	NF_write_addr(nRowAddr,nColAddr);
	NF_CMD(0X30);
	NF_DETECT_RB();	//等待存储区空闲
	
	//读取数据
	for(nCount = 0; nCount < nSize; nCount++)
	{
		((char *)pvReadBuff)[nCount] = NF_RDDATA8();
	}

	NF_nFCE_H(); //取消片选

	return nCount;

}

//单次写入页数据
int NAND_WritePage(int nRowAddr,int nColAddr,void *pvWireBuff,int nLeng)
{
	int nState;
	int nCount;

	NF_nFCE_L();     //片选
	NF_CLEAR_RB();
	   
	NF_CMD(0X80);
	NF_write_addr(nRowAddr,nColAddr);

	for(nCount = 0; nCount < nLeng ; nCount++)
	{
		NF_WRDATA8(((char *)pvWireBuff)[nCount]);
	}

	NF_CMD(0X10);
	NF_DETECT_RB();
	nState = NF_ReadStatus();
	NF_nFCE_H();
	if(nState & 0x01)
	{
		GPBDAT &= ~(0x1<<5);
		return -1;
	}
	else
	{
		return nCount;
	}
}

//块擦除
int NF_EreaseBlock(int nBlock)
{
	int nState;
	int n;
	
	if(NF_CheckBlock(nBlock) == 1)//坏块
	{
		return -1;
	}
	
	NF_nFCE_L();
	NF_CLEAR_RB();
	NF_CMD(0X60);
	NF_ADDRESS(((nBlock << 6) >> 0) & 0xFF);
	for(n = 0; n < 10; n++);
	NF_ADDRESS(((nBlock << 6) >> 8) & 0xF);
	for(n = 0; n < 10; n++);
	NF_ADDRESS(((nBlock << 6) >> 16) & 0x1);
	for(n = 0; n < 10; n++);

	NF_CMD(0XD0);
	NF_DETECT_RB();
	NF_nFCE_H();
	nState = NF_ReadStatus();
	

	if(nState & 0x01)
	{
		GPBDAT &= ~(0x1<<6);
		return -1;
	}
	else
	{
		//GPBDAT &= ~(0x1<<6);
		return 1;
	}
}


int nand_read(int nRowAddr,int nColAddr,char * pvReadBuff,int nBuffSize)
{
	int n;
	int ntemp;	
	
	ntemp = (pagesize - nColAddr);

	if((nBuffSize - ntemp) <= 0)
	{
		NF_ReadPage(nRowAddr,nColAddr,pvReadBuff,nBuffSize);	
	} 	
	else
	{
		NF_ReadPage(nRowAddr,nColAddr,pvReadBuff,ntemp);
		nRowAddr++;
		nColAddr = 0;
		if((nBuffSize - ntemp) / pagesize == 0)
		{
			NF_ReadPage(nRowAddr,nColAddr,pvReadBuff + ntemp,nBuffSize - ntemp);	
		}
		else
		{
			
			for(n = 0; n < ((nBuffSize - ntemp) / pagesize) ; n++)
			{
				NF_ReadPage(nRowAddr,nColAddr,pvReadBuff + ntemp + n * pagesize,pagesize);
				nRowAddr++;	
			}
			if( ((nBuffSize - ntemp) % pagesize) != 0)
			{
				NF_ReadPage(nRowAddr,nColAddr,pvReadBuff + ntemp + n * pagesize,((nBuffSize - ntemp) % pagesize));	
			}
		}	
	}

	return 1;
}

int nand_write(int nRowAddr,int nColAddr,char *pvWireBuff,int nBuffSize)
{
	int n;
	int ntemp;	
	
	ntemp = (pagesize - nColAddr);

	if((nBuffSize - ntemp) <= 0)
	{
		if(NAND_WritePage(nRowAddr,nColAddr,pvWireBuff,nBuffSize) == -1)
			return -1;
	} 	
	else
	{
		if(NAND_WritePage(nRowAddr,nColAddr,pvWireBuff,ntemp) == -1)
			return -1;
		nRowAddr++;
		nColAddr = 0;
		if((nBuffSize - ntemp) / pagesize == 0)
		{
			if(NAND_WritePage(nRowAddr,nColAddr,pvWireBuff + ntemp,nBuffSize - ntemp) == -1)
				return -1;	
		}
		else
		{
			for(n = 0; n < ((nBuffSize - ntemp) / pagesize) ; n++)
			{
				if(NAND_WritePage(nRowAddr,nColAddr,pvWireBuff + ntemp + n * pagesize,pagesize) == -1)
					return -1;
				nRowAddr++;	
			}
			if( ((nBuffSize - ntemp) % pagesize) != 0)
			{
				if(NAND_WritePage(nRowAddr,nColAddr,pvWireBuff + ntemp + n * pagesize,((nBuffSize - ntemp) % pagesize)) == -1)
					return -1;	
			}
		}	
	}

	return 1;
}

/*
void write_addr(unsigned int addr)
{
    int i;

    NFADDR = addr & 0xFF;         //先发低八位,从0-7,
    for(i=0; i<10; i++);      //延时
    NFADDR = (addr >> 8) & 0xFF;//再发从8位开始的8.9,10,11,共4位,这样把列地址发完,共12位,可寻址2^12=4096bytes
    for(i=0; i<10; i++);
    NFADDR = (addr >> 11) & 0xFF;
    for(i=0; i<10; i++);
    NFADDR = (addr >> 19) & 0xFF;
    for(i=0; i<10; i++);
    NFADDR = (addr >> 27) & 0xff;//最后发送页地址的高2位。
    for(i=0; i<10; i++);
}


void nand_read(unsigned char *buf, unsigned long start_addr, int len)
{
    unsigned long i,j;
    unsigned char * des_addr=buf;

    NF_nFCE_L();
    NF_CLEAR_RB();   //清除等待位

    for(i=start_addr;i<(start_addr+len);)
    {    
		//发出页读命令
        NF_CMD(0x00);
        write_addr(i);
        NF_CMD(0x30);
        NF_DETECT_RB();

        for(j=0; j < pagesize; j++, i++) 
        {
            *des_addr= NF_RDDATA8();
            des_addr++;
        }
    }
    NF_nFCE_H();
}


int nand_write(unsigned char *buf, unsigned long start_addr, int len)
{
    int nState;
	int ncount=0;
	unsigned long i,j;
    unsigned char *des_addr=buf;

    NF_nFCE_L();
    NF_CLEAR_RB();    //清除等待位

    for(i = start_addr;i < (start_addr+len);)
    {    
		//发出页读命令
		NF_nFCE_L();
		NF_CLEAR_RB();    //清除等待位
        NF_CMD(0x80);
        write_addr(i);
        
        for(j=0; j < pagesize; j++, i++) 
        {
            NF_WRDATA8(*des_addr);
            des_addr++;
			ncount++;
        }
		NF_CMD(0x10);
		NF_DETECT_RB();

		nState = NF_ReadStatus();
		if(nState & 0x01)
		{
			NF_nFCE_H();
			GPBDAT &= ~(0x1<<7);
			return -1;	
		}
    }
    NF_nFCE_H();
	return ncount;
}
*/


⌨️ 快捷键说明

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