对NandFlash编程实现的代码进行分析

来源:互联网 发布:插画需要什么软件 编辑:程序博客网 时间:2024/05/06 17:46

整个程序段分解为四个部分来分析,初始化NandFlash,读取NandFlash的ID号,NandFlash块擦洗,NandFlash的页数据读写;

在对代码进行分析之前需要把代码中的相应常量定义先列出来:

#define   EnNandFlash()  (rNFCONF |= 0x8000) //bit15=1 enable NANDflash controller

#define    NFChipEn()        (rNFCONF &= ~0x800) //bit11=0Nandflash nFCE = L (active)

#define    EnNandFlash()    (rNFCONF |= 0x8000) //bit15=1enable NAND flash controller
#define    DsNandFlash()    (rNFCONF &= ~0x8000) //bit15=1disable NAND flash controller
#define    InitEcc()        (rNFCONF |= 0x1000) //bit12=1initialize ECC
#define    NoEcc()            (rNFCONF &= ~0x1000) //bit12=0initialize ECC
#define    NFChipEn()        (rNFCONF &= ~0x800) //bit11=0NAND flash nFCE = L (active)
#define    NFChipDs()        (rNFCONF |= 0x800) //bit11=1NAND flash nFCE = H (inactive)
#define    WrNFCmd(cmd)    (rNFCMD = (cmd)) //writecommond to nand flash
#define    WrNFAddr(addr)    (rNFADDR = (addr)) //writeaddress to nand flash
#define    WrNFDat(dat)    (rNFDATA = (dat)) //writedata to nand flash
#define    RdNFDat()        (rNFDATA) //readdata from nand flash
#define    RdNFStat()        (rNFSTAT) //readstatus from nand flash
#define    NFIsBusy()        (!(rNFSTAT&1)) //whethernand flash is busy?
#define    NFIsReady()        (rNFSTAT&1) //whethernand flash is ready?
#define    READCMD0    0 //Read0model command == Page addr 0~127
#define    READCMD1    1 //Read1model command == Page addr 128~511
#define    READCMD2    0x50 //Read2model command == Page addr 512~527
#define    ERASECMD0    0x60 //Blockerase command 0
#define    ERASECMD1    0xd0 //Blockerase command 1
#define    PROGCMD0    0x80 //pagewrite command 0
#define    PROGCMD1    0x10 //pagewrite command 1
#define    QUERYCMD    0x70 //querycommand
#define    RdIDCMD        0x90 //readid command

一、初始化NandFlash

初始化部分对NandFlash的控制寄存器进行初始化配置,而rNFCONF是NandFlash的配置寄存器;在初始化部分的代码基本上所以的Flash都可以公用的。

//****   初始化  K9F1208U0M nand flash    ****/

staticvoid InitNandCfg(void)

{

      //enablenand flash control, initilize ecc, chip disable,

rNFCONF =(1<<15)|(1<<12)|(1<<11)|(7<<8)|(7<<4)|(7);

//对NandFlash的控制寄存器进行初始化配置,rNFCONF是NandFlash的配置寄存器

//使用控制器,使用ECC,不激活NandFlash,持续时间都设置为HCLK*8

}

二、读NandFlash的ID号

/****  K9F1208U0M nand flash  的ID  ****/

staticU32 ReadChipId(void)

{

U32 id;

 

NFChipEn();                       //选中NandFlash

WrNFCmd(RdIDCMD);      //写入90h指令,这是读 ID的命令

WrNFAddr(0);                    //写入地址00h

while(NFIsBusy());             //等待前一步完成

id  =RdNFDat()<<8;         //8位的NandFlash,之前定义过RdNFDat()

id |= RdNFDat();               //读DeviceCode

NFChipDs();  

return id;

}

三、NandFlash 块擦除

**  K9F1208U0M nand flash  的块擦除操作  ****/

staticU32 EraseBlock(U32 addr)

{

U8 stat;

 

addr &= ~0x1f;                   //保留9-25位

 

NFChipEn();                   //芯片使能,片选拉低,Nand Flash使能

WrNFCmd(ERASECMD0); //擦出的启动指令为60h

WrNFAddr(addr);             //写入块地址1

WrNFAddr(addr>>8);          //块地址2

if(NandAddr)                      //判断Flash的型号

WrNFAddr(addr>>16);       //后传A17-A24,A25

WrNFCmd(ERASECMD1); //发出擦出命令0Xd0H

stat = WaitNFBusy();         //写完擦除命令后,执行等待过程

NFChipDs();                       //失能

return stat;                         //返回到star

}

四、NandFlash的写、读操作

对于NandFlash而言,地址和命令只能在I/O[7:0]上传递,数据宽度为8位;由于地址只能在I/O[7:0]上传递,因此必须采用移位的方式进行。

写操作的过程为:

/****  K9F1208U0M nand flash  的页数据写  ****/

staticU32 WritePage(U32 addr, U8 *buf)

{

U16 i;

U8 stat, tmp[3];

NFChipEn();                      //使能NandFlash

WrNFCmd(PROGCMD0);    //写入串行数据输入指令(80h)

WrNFAddr(0);                          //写地址,即为第1个cycle

WrNFAddr(addr);               //写地址的第2个cycle

WrNFAddr(addr>>8);           //写地址的第3个cycle

if(NandAddr)

WrNFAddr(addr>>16);        //写地址的第4个cycle

InitEcc();                          //初始化ECC检测

for(i=0; i<512; i++)

WrNFDat(buf[i]);        //循环写入1页数据

 

tmp[0] = rNFECC0;            //产生3位校验码

tmp[1] = rNFECC1;

tmp[2] = rNFECC2;

 

WrNFDat(tmp[0]);              //将校验码写入页面

WrNFDat(tmp[1]);

WrNFDat(tmp[2]);

 

WrNFCmd(PROGCMD1);    //正是开始写入数据

stat = WaitNFBusy();

NFChipDs();

 

if(stat)

printf("Write nand flash 0x%xfail\n", addr);

else {

U8 RdDat[512];

             ReadPage(addr,RdDat);  

             for(i=0;i<512; i++)

                   if(RdDat[i]!=buf[i]){

                      printf("Checkdata at page 0x%x, offset 0x%x fail\n", addr, i);

                         stat= 1;

                         break;

                   }

}

return stat; 

}

读操作的过程为:

/****  K9F1208U0M nand flash  的页数据读  ****/

staticvoid ReadPage(U32 addr, U8 *buf)     //addr= page address 即是Flashd地址

{

U16 i;

NFChipEn();                       //使能NandFlash

 

WrNFCmd(READCMD0);   //发送读指令‘0x00’,整页读取

WrNFAddr(0);                            //读地址的第1个cycle, 读一个Page, addr=0

WrNFAddr(addr);                //读地址的第2个cycle,即A[9:16]

WrNFAddr(addr>>8);          //读地址的第3个cycle,即A[17:24]

if(NandAddr)

WrNFAddr(addr>>16);        //读地址的第4个cycle,即A[25]。

InitEcc();                            //初始化ECC

WaitNFBusy();                    //等待系统不忙

for(i=0; i<512; i++)

buf[i] = RdNFDat();    //循环读出1页数据

NFChipDs();                     //释放NandFlash

0 0
原创粉丝点击