NAND结构与驱动
NAND特点
1、NAND按页读写,按块擦除,进行NAND写入操作前,必须对NAND进行擦除操作;
2、NAND的命令、地址、数据管脚复用,优点是明显减少NAND FLASH的管脚数目,缺点是不能随机访问数据,无法直接在上面运行程序。
结合三星公司和ST公司的NAND FLASH产品,介绍NAND的结构及使用。
使用芯片的一般步骤
使用一个芯片时,大致有以下步骤。
1、芯片的功能结构
2、理解接口电路
3、理解操作时序
芯片的功能结构
1、按页存储结构:
以K9F1208为例,其大小为512Mbit,即64MByte。共4096块,每块32页,每页512字节。每一页中有16字节为spare区,一般用来标记坏块,和保存对main区数据的ECC校验码。
A7-A0:每一页的512字节寻址,A8由命令控制,00命令时,访问页中的前256字节,01命令时,访问页中的后256字节;
A13-A9:实现块内的页寻址,5bit寻址32页;
A25-A14:实现块寻址,12bit寻址4096块。
因此,可以有:字节地址:A25-A0;页地址:A25-A9;块地址:A25-A14。
2、引脚图与引脚功能:
CE--任何操作之前,片选必须先使能
WE--有效时表示执行写操作 RE--有效时表示执行读操作 CLE--有效时,数据线上的数据代表命令 ALE--有效时,数据线上的数据代表地址 ALE、CLE都无效时,数据线上的数据代表普通数据 RY/BY -- Ready/Busy状态信号,指示当前器件是空闲,还是繁忙3、关于锁存
因为NAND Flash总共只有8根数据线,而NAND flash操作时有命令/地址/数据三类数据需要在数据线上传输,它们的功能是复用的,为了区分这三种类型的数据,就需要锁存,用CLE/ALE(命令/地址锁存信号线)来区分。
锁存原理:如address latch地址锁存器,典型8D锁存器74ls373。每有一个下降沿(也可能上升沿),输出变为输入的状态,一般还带有输出使能控制。地址操作时,控制器产生一个ALE信号,将地址信号锁存;数据操作时,控制器在锁存器选中的地址的基础上进行数据读写。
4、命令与工作原理
控制器通过向NAND FLASH发送命令控制其状态以及传输数据。Read命令00时读取前256字节数据,01时读取后256字节数据,50读取spare区域。页编程和块擦除都需要两个周期命令。
接口电路
NAND FLASH与DSP的接口电路图如下:
CS3控制片选,高电平有效,映射到片内0x62000000开始的地址区域。
同时,由地址线控制CLE,ALE,均是高电平有效。向不同的地址发送数据表示写的是地址还是命令。(EMIFA_A2,EMIFA_A1分别是第四,第五位地址线,低三位是EMIFA_A0,EMIFA_BA1,EMIFA_BA0)。地址分配具体如下:
0000 0000h,CLE低,ALE低,IO上传递的是数据;
0000 0010h,CLE高,ALE低,IO上传递的是命令;
0000 0008h,CLE低,ALE高,IO上传递的事地址。
于是,通过对不同地址操作便可以实现发送数据、命令、地址。代码为:
*(volatile UINT8* ) (0x62000000+0x00000000)=DATA;
*(volatile UINT8* ) (0x62000000+0x00000010)=CMD;
*(volatile UINT8* ) (0x62000000+0x00000008)=ADDR;
操作时序
1、 ID获取
时序分析:
片选CE有效(低电平);写入命令,命令锁存CLE有效(高电平),地址锁存信号ALE无效;写入信号有效WE(低电平),读信号RE无效;IO线上传输命令。
写入地址,地址锁存信号ALE有效(高电平),命令锁存CLE无效(低电平);写入信号有效WE(低电平),读信号RE无效;IO线上传输地址。
读取数据,命令锁存信号CLE无效,地址锁存信号ALE无效;写信号WE无效,读信号RE有效,读取数据。
WE,RE连接芯片的WE,RE,时序由处理器硬件自动调整,不用程序控制。
依据时序,发送命令90,发送地址00,对IO读取,可得Maker Code与Device Code。从上下两个图中可以看出,如果得到Make Code为EC,则为三星公司的NAND;如果Make Code为20,则为ST公司的NAND。
代码实现:
NAND_ADDR( 0 );
mfg_id = NAND_DATA; // Read MFG Id
dev_id = NAND_DATA; // Read Device Id
结果如下图:
mfg_id=0x20,说明为ST公司的NAND FLASH。
2、读卡状态
#define NAND_DATA *( volatile Uint8* )( NAND_BASE + 0x00 );
status=NAND_DATA;
发送70h命令后,从NAND_BASE + 0x00地址得到的数据即为status。最关键的是最低位,0表示操作成功,1表示操作失败。一般每次编程后都会检测NAND状态,确定操作是否成功。
3、块擦除
时序图:
NAND FLASH按块擦除。首先发送擦除扇区命令CMD_ERASE(60h),然后依次发送A9-A16,A17-A24,A25地址,最后发送确认命令CMD_ERASE_CONFIRM(D0h),其中start是NAND FLASH的页地址(A9-A25)。当擦除第n(0-4095)块时,则发送地址n<<5(将块地址扩展为页地址,A25-A14扩展为A25-A9)。
程序实现:
start=start<<5;
NAND_CMD( CMD_ERASE ); // Erase block NAND_ADDR(start&0xff);
NAND_ADDR((start>>8)&0xff);
NAND_ADDR((start>>16)&0xff);
NAND_CMD( CMD_ERASE_CONFIRM ); // Confirm Erase
4、页写(对页编程)
NAND FLASH按页读写,首先发送写命令80h(CMD_PROGRAM),然后发送地址(A25-A0),最后发送写确认命令10h(PROGRAM_CONFIRM)。若擦除第n页,则发送地址n<<9(将页地址扩展为字节地址,A25-A9扩展为A25-A0)。
程序实现:
write_addr=write_addr<<9;
NAND_CMD(CMD_PROGRAM);
NAND_ADDR(write_addr);
NAND_ADDR((write_addr>>8) & 0xff);
NAND_ADDR((write_addr>>16) & 0xff);
NAND_ADDR((write_addr>>24) & 0xff);
for(k=0;k<100000;k++); //延时,等待写完成
//写main区512字节
j=NAND_PAGESIZE;
while(j--) NAND_DATA=*write_data++;
//写spare区,不校验ECC
j=NAND_SPARESIZE;
while(j--) NAND_DATA=0xff;
NAND_CMD( CMD_PROGRAM_CONFIRM );// Confirm Program
5、页读
与写操作相似,变为读命令00h(CMD_READ)。
代码实现:
read_addr=read_addr<<9;
NAND_CMD(CMD_READ);
NAND_ADDR(read_addr & 0xff);
NAND_ADDR((read_addr>>8) & 0xff);
NAND_ADDR((read_addr>>16) & 0xff);
NAND_ADDR((read_addr>>24) & 0xff);
for(k=0;k<100000;k++); //延时,等待读完成
//读main区
j=NAND_PAGESIZE;
while(j--) *read_data++=NAND_DATA;
//读spare区
for(j=0;j<NAND_SPARESIZE;j++) spare[j]=NAND_DATA;