NAND Flash驱动程序设计
来源:互联网 发布:布偶猫哪里买 知乎 编辑:程序博客网 时间:2024/05/29 08:39
一 NAND Flash概括
NAND Flash充当硬盘的角色,NAND Flash主要分为以下两类,
SLC(single level cell):单层式存储
MLC(multi level cell):多层式存储
MLC对比SLC
SLC访问速度一般比MLC快三倍以上 SLC可以进行十万次的擦写,MLC可以进行一万次,MLC功耗比SLC高15%左右
访问方式内存采用的是统一编址,NAND Flash采用的是独立编址,第一传地址给CPU控制器,第二传命令给控制器,第三传数据给控制器
二 NAND Flash驱动设计_读
根据NAND Flash的芯片手册,可以看出页读中I/Ox的编码步骤
首先发送命令00h,然后发送地址,发送地址先发送列地址,后发送行地址。其次发送命令0x30,等待RnB信号,最后读取数据。除此之外,还需要加入一些通用步骤,选中NAND Flash芯片,清除RnB信号,在最后需要取消选中NAND Flash芯片。所以基本步骤是
1 选中芯片
2 清除RnB
3 发出命令
4 发出列地址
5 发出行地址
6 发出命令
7 等待RnB信号
8 读数据
9 取消片选
如何选中NAND Flash芯片
选中NAND Flash芯片,就是往NFCONT这个寄存器中第一位写入0。
void select_ship(void){ NFCONT &= ~(1<<1); }
如何发送命令
NFCMMD(八位)寄存器就是存放发送给NAND Flash的命令的,命令本身传进来后送到NFCMMD寄存器中。
void nand_cmd(unsigned char cmd){ NFCMMD = cmd; }
如何发送地址
NFADDR(八位)往这个寄存器中写入地址,按页读没有偏移,所以列地址为0,有两个列地址都为0。有三个行地址。由READ OPERATION时序图中看出有两个列地址和三个行地址。
void nand_addr(unsigned char addr){ NFADDR = addr;}/*********************************/ /* 发出列地址 */ nand_addr(0x00); nand_addr(0x00); /* 发出行地址 */ nand_addr(addr&0xff); nand_addr((addr >>8 ) & (0xff)); nand_addr((addr >>16 ) & (0xff));
如何清除RnB信号
在NFSTAT寄存器中,当RnB信号从低变成高电平的时候,第4位自动设置为1,检查这位有没有变成1,首先要将其擦除清零才能检查。
清零就是要写入这个寄存器的第四位为0, 此时根据To clear this write‘1’,可知不是直接写0,而是写成1。
void clean_RnB(){ NFSTAT |= (1<<4);}
发送完30h 信号后,需要等待RnB信号结束,只要RnB信号没有从低电平到高电平,就需要等。
void wait_RnB(void){ while(!(NFSTAT & 0x1));}
如何取消选中
在NFCONT第一位写入1即可。
void delselect_ship(void){ NFCONT |= (1<<1);}
如何读取数据?
NFDATA是读取数据用到的寄存器,由图可知,一页上有2K的空间所以 读取数据的时候一般大于2048,这里选择为4096。
for(i = 0; i<1024*4; i++) { buff[i] = NFDATA; }
至此,按页读的步骤就结束了。但是,这只是nandflash读功能的实现,初始化工作还没有完成,我们还需要初始化NFCONF,NFCONT和复位。
如何初始化NFCONF
上图可得到三个重要的时间:1 TWP 2 TCLS-TWP 3 TCLH。由下表可知,由于3.3V为工作电压,所以TWP最小时间为12ns,TCLS-TWP是0ns,tclh为5ns,要保证nandflash正常工作,需要将其配置不小于最低时间。
根据上图时序图,可以得出TACLS为TCLS-TWP,TWRPH0为TWP ,TWRPH1为TCLH
由于NandFlash使用的是HCLK,100MHZ,故周期为10ns,在Nand Flash Configuration这个寄存器中去修改相应位的值,由手册可知,TACLS只要大于0即可,根据公式HCLK*TACLS>0,在这里设置TACLS为1,TWRPH0大于12ns,同理这里设置TWRPH0为2(1也可以),TWRPH1要大于5ns,这里设置TWRPH1为1(0也可以)。这样NFCONF寄存器就设置好了。
如何初始化NFCONT
这里只要设置两个位。
#define TACLS 1#define TWRPH0 2#define TWRPH1 1 NFCONF &= ~((7<<12)|(7<<8)|(7<<4)); NFCONF |= (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4); /* 使能 nandflash controller*/ NFCONT = 1 | (1<<1);
如何初始化复位
这里有以下几个步骤,选中flash,清除RnB信号,发送0xff命令,等到RnB,取消选中flash。
NAND Flash驱动设计_写
之前选择的是按页读,所以这里选择的是按页写(还有一种是随机写)
这里还是按照和读方式一样的思路去设计,首先是发送命令0x80,其次是发送列地址,行地址,然后是写入数据,再次发送命令0x10,等待RnB信号发生变化,最后发送命令0x70,读取写入结果。
除此之外,还要加入通用操作,清除RnB,选中Flash芯片,在最后取消flash芯片的选中。
int NF_WritePage(unsigned long addr,unsigned char* buff){ int ret,i; //选中flash芯片 select_ship(); //清除RnB clean_RnB(); //发送命令80 nand_cmd(0x80); //发送列地址(2个周期) nand_addr(0x00); nand_addr(0x00); //发送行地址(3个周期) nand_addr(addr&0xff); nand_addr((addr >>8 ) & (0xff)); nand_addr((addr >>16 ) & (0xff)); //写入数据 for(i=0;i<1024*4;i++) { NFDATA = buff[i]; } //发送命令10 nand_cmd(0x10); //等待RnB wait_RnB(); //发送命令70 nand_cmd(0x70); //读取写入结果 ret = NFDATA; //取消选中flash芯片 delselect_ship(); return ret;}
在写入NAND Flash之前需要做擦除的工作
擦除的时候,不是按照页来擦除,首先发送命令0x60,然后发送三个行地址,发送命令0xd0,等待RnB信号,通过发送命令0x70读取发送结果,同样加入三个通用流程,选中(选中flash芯片),清除(清除RnB信号),取消(取消片选)。
int NF_Erase(unsigned long addr){ int ret; //选中flash芯片 select_ship(); //清除RnB clean_RnB(); //发送命令60 nand_cmd(0x60); //发送行地址(3个周期) nand_addr(addr&0xff); nand_addr((addr >>8 ) & (0xff)); nand_addr((addr >>16 ) & (0xff)); //发送命令D0 nand_cmd(0xD0); //等待RnB wait_RnB(); //发送命令70 nand_cmd(0x70); //读取擦除结果 ret = NFDATA; //取消选中flash芯片 delselect_ship(); return ret;}
- NAND Flash驱动程序设计
- NAND Flash的驱动程序设计
- NAND Flash的驱动程序设计
- NAND Flash的驱动程序设计
- NAND Flash的驱动程序设计
- NAND Flash的驱动程序设计
- Nand Flash驱动程序分析
- Nand Flash的驱动程序
- NAND FLASH驱动程序
- linux之NAND FLASH驱动程序
- Linux NAND FLASH驱动程序框架分析
- Linux NAND FLASH驱动程序分析(mini2440)
- Nand Flash驱动程序编写指南-1
- Nand Flash驱动程序编写指南-2
- Nand Flash驱动程序编写指南-3
- Linux NAND FLASH驱动程序分析(mini2440)
- 2014-04-17 nand flash驱动程序__
- 块设备驱动之NAND FLASH驱动程序
- 杭电acm 1412 {A}+{B}
- 旋转数组中的最小数字
- 网格UV展开
- Unity3D
- C++ 多态
- NAND Flash驱动程序设计
- 关于Nginx
- dedecms有下拉框的二级栏目导航输出模板
- C++之继承与派生、多继承、C++向上转型
- python
- 单链表插入节点、删除节点、倒置、去重
- 安装虚拟机vmware8.0.4版本
- Spark版本说明
- 指针