对NandFlash编程实现的代码进行分析
整个程序段分解为四个部分来分析,初始化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 一、初始化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%xfailn",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 failn",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 }? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |