十六课(1)Nand Flash的操作原理
1、从Nand原理图上分析
从原理图上看,Nand Flash只有数据线,那么是怎么传输地址的?
DATA0~DATA7既传输数据又传输地址。
当ALE为高电平时传输的是地址;当ALE为低电平传输的是数据。
从Nand Flash芯片手册可知,要操作Nand Flash需要先发出命令。
那么说明数据线也传输命令,那么怎么分辨是命令呢?
当CLE为高电平时传输的是命令;当CLE和ALE为低电平时传输的是数据。
nCE用来干嘛呢?
数据线接到Nand Flash、Nor Flash、SDRAM、DM9000,那么怎么避免干扰?
这些数据被访问时,需要被选中,没有选中的就当没接一样。
假设烧写Nand Flash,把命令、地址、数据发给它之后,Nand Flash不可能瞬间完成。那么怎么判断是烧写完成了呢?
通过状态引脚RnB来判断。
当RnB为高电平表示就绪;当RnB为低电平表示正在忙。
2、怎么操作Nand Flash呢?
根据Nand Flash的芯片手册,一般过程是
- 发出地址
- 发出命令
- 发出/读数据
从读ID时序图看[每个NAND FLASH都内嵌一些ID(譬如:厂家ID,设备ID)]:
对于我们s3c2440来说,内部集成了一个NAND FLASH控制器
NAND FLASH控制器,帮我们简化了对NAND FLASH的操作。
下面来分析一下不使用NAND FLASH控制器和使用NAND FLASH控制器对外设NAND FLASH的操作。
发命令:
Nand Flash | S3C2440(使用Nand Flash 控制器) |
---|---|
nCE选中 | NFCMMD寄存器上写命令值 |
CLE输出高电平 | |
DATA0~DATA7上输出命令值 | |
发出一个写脉冲 |
发地址:
Nand FlashS3C2440 | (使用Nand Flash 控制器) |
---|---|
nCE选中 | NFADDR寄存器上写地址值 |
ALE输出高电平 | |
DATA0~DATA7输出地址值 | |
发出一个写脉冲 |
发数据:
Nand Flash | S3C2440(使用Nand Flash 控制器) |
---|---|
nCE选中 | NFDATA寄存器上写数据值 |
ALE和CLE输出低电平 | |
DATA0~DATA7输出数据值 | |
发出一个写脉冲 |
读数据:
Nand Flash | S3C2440(使用Nand Flash 控制器) |
---|---|
nCE选中 | 从NFDATA寄存器上读出数据 |
发出读脉冲 | |
读DATA0~DATA7上的数据 |
3、从uboot上体验Nand Flash的操作:
在uboot上,查看下命令的作用:help md
help mw
(1)读ID
uboot里的数据都认为是16进制的,所以不加0x也可以。
- | S3C2440 | u-boot |
---|---|---|
选中 | NFCONT的bit1设为0 | md.l 4E000004 1;mw.l 4E000004 1 |
发出命令0x90 | NFCMMD=0x90 | mw.b 0x4E000008 90 |
发出地址0x00 | NFADDR=0x00 | mw.b 0x4E00000C 00 |
读数据得到0xEC | val=NFDATA | md.b 0x4E000010 1(1:表示读1次,如果不屑1的话会一直读下去) |
读数据得到device code | val=NFDATA | md.b 0x4E000010 1 |
退出读ID的状态 | NFCMMD=0xff | mw.b 0x4E000010 0xff |
(2)读0地址的数据
uboot上查看:nand dump 0
从时序图上看:
因为我们要读0地址上的数据,所以写入地址00000。
为什么是5个地址表示地址呢?
我们的Nand Flash是256M(228),至少需要28条数据线。但是我们的Nand数据线有8条,所以至少是需要4个周期,表示地址。为了兼容不同的Nand,用5个周期表示:
- | S3C2440 | u-boot |
---|---|---|
选中 | NFCONT的bit1设为0 | mw.l 4E000004 1 |
发出命令0x00 | NFCMMD=0x00 | mw.b 4E000008 0x00 |
发出地址0x00 | NFADDR=0x00 | mw.b 0x4E00000C 0x00 |
发出地址0x00 | NFADDR=0x00 | mw.b 0x4E00000C 0x00 |
发出地址0x00 | NFADDR=0x00 | mw.b 0x4E00000C 0x00 |
发出地址0x00 | NFADDR=0x00 | mw.b 0x4E00000C 0x00 |
发出地址0x00 | NFADDR=0x00 | mw.b 0x4E00000C 0x00 |
发出命令0x30 | NFCMMD=0x30 | mw.b 0x4E00000C 0x00 |
读数据得到0x17 | val=NFDATA | mr.b 0x4E00000C 1 |
读数据得到0x00 | val=NFDATA | mr.b 0x4E00000C 1 |
读数据得到0x00 | val=NFDATA | mr.b 0x4E00000C 1 |
读数据得到0xea | val=NFDATA | mr.b 0x4E00000C 1 |
退出读状态 | NFCMMD=0xff | mw.b 0x4E000010 0xff |