NANDFLASH控制器实验(一直以为NANDFLASH有这么多寄存器- -!)
主程序:
/*
本实验接口说明
*/
#include "include.h"//这个头文件包含一些宏定义
/*-----------------------函数声明----------------------------*/
void InitNandFlash(int info);
void cpy_bpage(void);
void add_bpage(unsigned int seq);
extern void Uart_Printf(char *fmt,...);
extern void Uart_Init(int baud);
extern void Uart_Select(int ch);
/*------------------------------------------------------------/
函数名称: InitNandCfg
功能描述: 配置flash
传 参: 无
返 回 值: 无
-------------------------------------------------------------*/
static void InitNandCfg(void)
{
rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
}
/*------------------------------------------------------------/
函数名称: WaitNFBusy
功能描述:
传 参: 无
返 回 值: static U32 stat&1
-------------------------------------------------------------*/
static U32 WaitNFBusy(void) // R/B 未接好?
{
U8 stat;
WrNFCmd(QUERYCMD);//向NANDFLASH命令寄存器写入命令,QUERYCMD是70H,是读状态寄存器的命令
do
{
stat = RdNFDat();//RDNFDAT()是从数据寄存器得到数据
}
while (!(stat&0x40));
WrNFCmd(READCMD0);
return stat&1; //注意0为操作成功
}
/*------------------------------------------------------------/
函数名称: ReadChipId
功能描述: 读flash ID
传 参: 无
返 回 值: static U32 id
-------------------------------------------------------------*/
static U32 ReadChipId(void)
{
U32 id,k;
NFChipEn(); //使能
WrNFCmd(RdIDCMD);//读ID命令
WrNFAddr(0);//读ID时,地址设定为0
while(NFIsBusy());// 每写一次命令,都要等它再次准备好- -
id = RdNFDat()<<8;//先取低8位
for(k=0;k<500;k++);//延时
id |= RdNFDat(); // 再取高8位
NFChipDs();
return id;
}
/*------------------------------------------------------------/
函数名称: ReadStatus
功能描述: 读FLASH状态
传 参: 无
返 回 值: static U16 stat
-------------------------------------------------------------*/
static U16 ReadStatus(void)
{
U16 stat;
NFChipEn();
WrNFCmd(QUERYCMD);
stat = RdNFDat();
NFChipDs();
return stat;
}
/*------------------------------------------------------------/
函数名称: EraseBlock
功能描述: 擦除 FLASH
传 参: U32 addr
返 回 值: U32 ~stat
-------------------------------------------------------------*/
U32 EraseBlock(U32 addr)
{
U8 stat;
addr &= ~0x3f;//擦除FLASH只要3个地址序列
NFChipEn();
WrNFCmd(ERASECMD0); 0X60写入擦除命令
WrNFAddr(addr);
WrNFAddr(addr>>8);
WrNFCmd(ERASECMD1); 0XD0启动擦除操作
stat = WaitNFBusy();
NFChipDs();
return ~stat;
}
/*------------------------------------------------------------/
函数名称: ReadPage
功能描述:
传 参: U32 addr, U8 *buf
返 回 值: 无
-------------------------------------------------------------*/
void ReadPage(U32 addr, U8 *buf)
{
U16 i;
NFChipEn();
WrNFCmd(READCMD0);
WrNFAddr(0);
WrNFAddr(0);
WrNFAddr(addr);
WrNFAddr(addr>>8);//32位地址
WrNFCmd(READCMD1);
InitEcc();初始化ECC
WaitNFBusy();
for(i=0; i<2048; i++)
buf[i] = RdNFDat();
NFChipDs();
}
/*------------------------------------------------------------/
函数名称: WritePage
功能描述:
传 参: U32 addr, U8 *buf
返 回 值: U32 ~stat
-------------------------------------------------------------*/
U32 WritePage(U32 addr, U8 *buf)
{
U32 i, mecc;
U8 stat, tmp[7];
NFChipEn();
WrNFCmd(PROGCMD0);
WrNFAddr(0);
WrNFAddr(0);
WrNFAddr(addr);
WrNFAddr(addr>>8);
InitEcc(); //reset mecc and secc
MEccUnlock();//解锁主ECC数据寄存器
for(i=0; i<512; i++)
WrNFDat(buf[i]);//写数据
MEccLock();//锁定
mecc = RdNFMEcc());//
tmp[0] = mecc&0xff;
tmp[1] = (mecc>>8)&0xff;
tmp[2] = (mecc>>16)&0xff;
tmp[3] = (mecc>>24)&0xff;
tmp[5] = 0xff; //mark good block
WrNFDat(0xff);//2048,坏块标志
SEccUnlock();
WrNFDat(tmp[0]);//ECC校验码保存
WrNFDat(tmp[1]);
WrNFDat(tmp[2]);
WrNFDat(tmp[3]);
SEccLock();
WrNFCmd(PROGCMD1);
stat = WaitNFBusy();
NFChipDs();
return ~stat;
}
/*------------------------------------------------------------/
函数名称: nandMain
功能描述: 入口函数
传 参: 无
返 回 值: 无
-------------------------------------------------------------*/
void nandMain(void)
{
U16 ID,i;
U8 buf[512];
U32 NFBlockNO=6;
U32 NFPagesNO = 25;
U32 status;
U32 BlockPages;
BlockPages =(NFBlockNO<<6)+NFPagesNO;
Uart_Init(115200);
Uart_Printf("/nthe main is running/n");
InitNandCfg(); //初始化函数
ID=ReadChipId();//ID=ECf1
Uart_Printf("/nnand flash`s ID is:%x/n",ID);
if(EraseBlock(BlockPages)&0x1==TRUE)
{
Uart_Printf("/nblock %d is erased/n",NFBlockNO);
ReadPage(BlockPages,buf);
Uart_Printf("/n/***********************擦除之后flash中的数据 ****************//n");
for(i=0; i<512; i++)
Uart_Printf("%4x", buf[i]);
Uart_Printf("/n/***********************应写入数据****************//n");
for(i=0; i<512; i++)
{
buf[i] = i;
Uart_Printf("%4x", buf[i]);
}
Uart_Printf("/nWrite data[%d block, %d page]./n", NFBlockNO,NFPagesNO);
status = WritePage(BlockPages,buf);
if(status&0x1==TRUE )
Uart_Printf("/nWrite OK./n");
else
Uart_Printf("/nWrite Error./n");
for(i=0; i<512; i++)
buf[i] = 1; //为验证后边数组中的数据是来自flash
ReadPage(BlockPages,buf);
Uart_Printf("/nRead data[%d block, %d page]./n", NFBlockNO,NFPagesNO);
Uart_Printf("/n/*********************** 读出的数据 ****************//n");
for(i=0; i<512; i++)
Uart_Printf("%4x", buf[i]);
}
else
Uart_Printf("/nblock %4x erased is bad/n",NFBlockNO);
while(1);
}
还是有些地方不太清楚- -!