加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

2440nandflash小实验

发布时间:2020-12-15 18:44:36 所属栏目:百科 来源:网络整理
导读:/********************** 按键 实验*********************************/ /***************************************************************/ /* ? ? ? ? 本实验 接口 说明 */ # include ?"include.h" /*-----------------------函数声明------------------
/**********************按键实验*********************************/

/***************************************************************/

/*
? ? ? ? 本实验接口说明
*/
#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)? ? ? ? // 等待nand flash 的操作结束
{
? ? ? ? U8 stat;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //因为nansh flash数据通道只有8bit
? ? ? ??
? ? ? ? WrNFCmd(QUERYCMD);? ? ? ? ? ? ? ? //QUERYCMD=0X70,将0x70写入NFCMD
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //查看nand flash芯片资料中的Command Sets
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //0x70表示读nand flash的状态
? ? ? ? do?
? ? ? ? {
? ? ? ? ? ? ? ? stat = RdNFDat();? ? ? ? //上面命令是读nandflash的状态,因此RdNFDat获得的是nandflash的状态。
? ? ? ? }
? ? ? ? while (!(stat&0x40));? ? ? ? //[6] busy:0??ready:1
? ? ? ? WrNFCmd(READCMD0);? ? ? ? ? ? ? ? //READCMD0=0
? ? ? ? return stat&1;? ? //注意0为操作成功.见datasheet34页表。
}

/*------------------------------------------------------------/
函数名称:? ? ? ? ReadChipId
功能描述:? ? ? ? 读flash ID
传? ? 参:? ? ? ? 无
返 回 值:? ? ? ? static U32 id
-------------------------------------------------------------*/
// 读ID过程的时序图在K9F1G08U0A的datasheet中,第28和35页//
static U32 ReadChipId(void)
{? ? ? ??
? ? ? ? U32 id,k;
? ? ? ??
? ? ? ? NFChipEn();? ? ? ? //选中nandflash
? ? ? ? WrNFCmd(RdIDCMD);//读ID命令
? ? ? ? WrNFAddr(0);? ? ? ? //写入00h(根据datasheet)
? ? ? ? while(NFIsBusy());? ? ? ? //等待前一步完成
? ? ? ? id??= RdNFDat()<<8;? ? ? ? //define中规定:RdNFDat8(); for 8 bit nand flash,use byt access
? ? ? ? for(k=0;k<500;k++);? ? ? ? //
? ? ? ? id |= RdNFDat();? ? ? ? //从运行结果ID:ecda来看,可能是这边程序有点问题(ID指什么不明确)
? ? ? ? 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
-------------------------------------------------------------*/
//? ?? ?? ?地址输入(两个周期) datasheet第27页? ?? ? //
U32 EraseBlock(U32 addr)
{
? ? ? ? U8 stat;

? ? ? ? addr &= ~0x3f;? ? ? ? ? ? ? ? ? ? ? ? //addr=0000 0001 1000 0000
? ? ? ? ? ? ? ??
? ? ? ? NFChipEn();? ? ? ??
? ? ? ? WrNFCmd(ERASECMD0);? ? ? ? ? ? ? ? //ERASECMD0=0X60
? ? ? ? WrNFAddr(addr);? ? ? ? ? ? ? ? ? ? ? ? //cycle1:8bit?address=1000 0000
? ? ? ? WrNFAddr(addr>>8);? ? ? ? ? ? ? ? //cycle2:8bit address=0000 0001
? ? ? ? WrNFCmd(ERASECMD1);? ? ? ? ? ? ? ? //ERASE confirm cmd
? ? ? ? stat = WaitNFBusy();? ? ? ? //等待擦除完成
? ? ? ? NFChipDs();
? ? ? ??
? ? ? ? return ~stat;
}

/*------------------------------------------------------------/
函数名称:? ? ? ? ReadPage
功能描述:? ? ? ??
传? ? 参:? ? ? ? U32 addr,U8 *buf
返 回 值:? ? ? ? 无
-------------------------------------------------------------*/
//? ? ? ? ? ? ? ? 读取block6中的page25? ?参考datasheet30页? ? ? ???? ? ? ? //
void ReadPage(U32 addr,U8 *buf)
{
? ? ? ? U16 i;
? ? ? ??
? ? ? ? NFChipEn();
? ? ? ? WrNFCmd(READCMD0);? ? ? ? ? ? ? ? //READCMD0=0
? ? ? ? WrNFAddr(0);? ? ? ? ? ? ? ? ? ? ? ? //
? ? ? ? WrNFAddr(0);? ? ? ? ? ? ? ? ? ? ? ? //因为读的是一个page,所以col addr=0
? ? ? ? WrNFAddr(addr);? ? ? ? ? ? ? ? ? ? ? ? //
? ? ? ? WrNFAddr(addr>>8);? ? ? ? ? ? ? ? //block6,page25的地址
? ? ? ? WrNFCmd(READCMD1);? ? ? ? ? ? ? ? //READCMD1=0X30
? ? ? ? InitEcc();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //初始化ECC
? ? ? ? WaitNFBusy();? ? ? ? ? ? ? ? ? ? ? ? //
? ? ? ? for(i=0; i<2048; i++)
? ? ? ? ? ? ? ? buf?= RdNFDat();? ? ? ? //将2k的内容读出
? ? ? ? NFChipDs();
}

/*------------------------------------------------------------/
函数名称:? ? ? ? WritePage
功能描述:? ? ? ??
传? ? 参:? ? ? ? U32 addr,U8 *buf
返 回 值:? ? ? ? U32 ~stat
-------------------------------------------------------------*/
/*【Nand Flash中的特殊硬件结构】
1.页寄存器(Page Register):由于Nand Flash读取和编程操作
来说,一般最小单位是页,所以,nand flash在硬件设计时候,就考虑到
这一特性,对于每一片,都有一个对应的区域,专门用于存放,将要写入
到物理存储单元中去的或者刚从存储单元中读取出来的,一页的数据,这
个数据缓存区,本质上就是一个buffer,但是只是名字叫法不同,datasheet
里面叫做data Register,实际理解为页缓存,大小应该是等于1个page
恰当些。而正是因为有些人不了解此内部结构,才容易产生之前遇到的某人
的误解,以为内存里面的数据,通过Nand Flash的FIFO,写入到Nand Flash
里面去,就以为立刻实现了实际数据写入到物理存储单元中了。而实际上,
只是写到了这个页缓存中,只有等你发了对应的编程第二阶段的确认命令0x10
之后,实际的编程动作才开始,才开始把页缓存中的数据,一点点写到物理存
储单元中去。*/
//? ? ? ? ? ? ? ? ? ? ? ? 参考datasheet的第23页? ? ? ? ? ? ? ? ? ? ? ? //
U32 WritePage(U32 addr,U8 *buf)
{
? ? ? ? U32 i,mecc;
? ? ? ? U8 stat,tmp[7];
? ? ? ??
? ? ? ??
? ? ? ? NFChipEn();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //
? ? ? ? WrNFCmd(PROGCMD0);? ? ? ? ? ? ? ? //page program 命令? ? ? ??
? ? ? ? WrNFAddr(0);? ? ? ? ? ? ? ? ? ? ? ? //? ? ? ??
? ? ? ? WrNFAddr(0);? ? ? ? ? ? ? ? ? ? ? ? //? ? ? ??
? ? ? ? WrNFAddr(addr);? ? ? ? ? ? ? ? ? ? ? ? //
? ? ? ? WrNFAddr(addr>>8);? ? ? ? ? ? ? ? //要写入的page地址? ? ? ??

? ? ? ? InitEcc();? ? ? ? //reset mecc and secc
? ? ? ? MEccUnlock();? ? ? ? ? ? ? ? ? ? ? ? //unlock main data area ecc generation
? ? ? ? for(i=0; i<512; i++)? ? ? ? //具体要写入页的数据写入main data area
? ? ? ? ? ? ? ? WrNFDat(buf);? ? ? ? //将数据输入NAND FLASH的data register中
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //或者可以理解为写入page的缓冲区
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //只有在发送确认命令0x10之后,该内容才被写入物理存储单元。
? ? ? ? MEccLock();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //unlock it
? ? ? ? mecc = RdNFMEcc();? ? ? ? ? ? ? ? //mecc赋值等于MAIN DATA AREA ECC0 STATUS ERGISTER的内容? ? ? ??
? ? ? ? ? ? ? ??
? ? ? ? tmp[0] = mecc&0xff;? ? ? ? ? ? ? ? //[7:0]
? ? tmp[1] = (mecc>>8)&0xff;//[15:8]
? ? tmp[2] = (mecc>>16)&0xff;//[23:16]
? ? tmp[3] = (mecc>>24)&0xff;//[31:24]
? ? tmp[5] = 0xff;? ? ? ? //mark good block

? ? ? ??
? ? ? ???? ? ? ??
? ? ? ? ? ? ? ? //WrNFDat(0xff);? ? ? ? //2048,坏块标志//此时主数据区已经lock了。如果不等于0xff就说明是坏块
? ? ? ?? ???? ? ? ? ? ? ? ? ? ? ? ?? ?? ? ? ? //sumsung规定在block第一和第二个page的spare area的第一个字节,如果不等于0xff就说明是坏块。
? ? ? ?? ???SEccUnlock();? ? ? ? //校验码写入spare data area
? ? ? ? ? ? ? ? WrNFDat(0xff);? ? ? ? //改到这里来运行也一样,应该是没做坏块的判断吧?
? ? ? ? ? ? ? ? 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; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //block6,page25
? ? ? ? U32 status;?
? ? ? ? U32 BlockPages;

? ? ? ? BlockPages =(NFBlockNO<<6)+NFPagesNO; ? ? ? ? //BlockPages=000110011001
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //左移6位是因为1Block=64Page
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //因此block6的起始地址位:6*64=6<<6

? ? ? ? Uart_Init(115200);?
? ? ? ? Uart_Printf("nthe main is runningn");?

? ? ? ? InitNandCfg();? ?? ?? ?? ?? ? ? ? //初始化函数
? ? ? ? ID=ReadChipId();? ? ? ? ? ? ? ? ? ? ? ? //ID=ECf1 ;;ID=ecda
? ? ? ? Uart_Printf("nnand flash`s ID is:%xn",ID);?
??

? ? if(EraseBlock(BlockPages)&0x1==TRUE)?
? ? {? ?
? ? ? ? ? ? ? ? Uart_Printf("nblock %d is erasedn",NFBlockNO);?

? ? ? ? ? ? ? ? ReadPage(BlockPages,buf); //读page中的内容

? ? ? ? ? ? ? ? Uart_Printf("n/***********************擦除之后flash中的数据****************/n");?
? ? ? ? ? ? ? ? for(i=0; i<512; i++)?
? ?? ???? ? ? ? Uart_Printf("%4x",buf);? ? ?? ??? ? ? ? ? ? ? ? ? Uart_Printf("n/***********************应写入数据****************/n");?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读