📄 nandflash.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 + -