6410所使用的NANDFLASH的原理图如下所示:
发现此NANDFLASH的传输数据信号只有9根线(DATA0 - DATA7),那么如何进行寻址,读/写数据呢?
1.命令(cmd),地址(addr),数据(data)复用,cmd,data,addr的识别通过CLE,ALE来决定,读还是写又WE,RE决定,是否处于busy状态由RnB决定
2.地址:多次发出(这个nandflash是256MByte,至少需要28条地址线,所以需要多次发出)
如上图所示,需要发送5个周期的地址才可以访问到寻找的地址。
读操作:
过程如下:
1.ALE为0,CLE为1,发出00h
2.ALE为1,CLE为0,发出5个周期的地址信号。
3.ALE为0,CLE为1,发出30h
4.等待一段时间,判断NANDFLASH是否处于busy状态。
5.NANDFLASH空闲后,ALE,CLE都为0,即可读出数据。
注:
发出的写脉冲,在读操作中主要为写命令,地址。
开始为1,无效,命令和地址写完后,就发出读脉冲了。
怎么读nand flash?
1,初始化nandflash控制器:时间参数,使能片选引脚等
2.发送命令,地址,读数据
具体操作如下:
1. 发出片选信号: CSn2_NAND
2. 发出命令: 把命令写到NFCMD寄存器
3. 发出地址: 把地址写到NFADDR寄存器(总共写5个周期)
4. 发出数据 把数据写到NFDATA寄存器
5. 读数据 读NFDATA寄存器
使用openjtag进行实验:
一、读ID:
1.mdw 0x7E00F120 :显示 0x7E00F120地址的内容
mdw : display memory word:显示一个字长的内容
2.mww 0x7E00F120 0 //初始化
mww:memory write word:写一个字的内存的意思。
3.mww 0x70200000 0x8000777e //时间参数设置
4. mww 0x70200004 0xc5 //发出使能信号
5.mwb 0x70200008 0xff //发出复位命令(可选)
nwb:向内存上写一个字节的内容
6.mwb 0x70200008 0x90 //发出读ID命令
7.mwb 0x7020000C 0 //写0地址
8.mdb 0x70200010 //读数据
mdb : 以一个字节的形式显示内存内容
最后读出的内容会和Datasheet所示一样:
我的NANDFLASH芯片是K9F2G08U0A,所以依次读出的内容为:ec,da,10,95,44
判断二进制文件是否已经烧写到nandflash上的一个方法可以通过openocd查看nandflash地址上内容是否和烧写的二进制内容一致即可。
方法:
二进制使用UE打开,即可查看对应地址上的内容。如下所示:
该二进制文件的0地址就是07 02 A0 。。。。。
假如该二进制文件也是烧写到nandflash上的0地址,就可以通过下面的方法进行读取来查看是否已经烧写进去(6410为例):
a. 初始化
mww 0x7E00F120 0 /* 把xm0csn[2]配置为nand flash的片选信号 */
mww 0x70200000 0x8000777e /* 设置时间参数 */
b. 发出片选信号
mww 0x70200004 0xc5
c. 发出复位信号
mwb 0x70200008 0xff
d. 发出读命令
mwb 0x70200008 0
e. 发出地址
mwb 0x7020000C 0
mwb 0x7020000C 0
mwb 0x7020000C 0
mwb 0x7020000C 0
mwb 0x7020000C 0
f. 发出0x30命令
mwb 0x70200008 0x30
g. 读数据
mdb 0x70200010
从上面的寻址图上可以看到,nandflash的寻址有列地址,行地址。
所谓的列地址:页内地址,0 到 (2048 + 64 - 1)即 0 到 2111字节(加上oob)
所谓的行地址: 表示哪一页。
但是程序是不会操作oob的,假如要访问地址为8000字节的地址:
哪一页: 8000 / 2048 = 3.9 即第3页(从第0页开始)
访问第3页的那个地址:8000 - 3*2048 = 1856 = 0x740
所以
第一周期:发出: 0x40
第二周期:发出: 0x7
第三周期:发出: 0x3
第四周期:发出: 0x0
第五周期:发出: 0x0