/*author----->Armking*/
/*data----->2008年9月2*/
/*ps:本人总结,备于日后查阅,如若转载,请注明出处*/
/*QQ:382750150*/
写于篇头:
终于又开始接着学习了,只是不知道为什么JTAG又连不上目标板了,如果谁不小心看到了此文章,又凑巧知道了是什么原因,请留言赐教,不胜感激。
关于NAND FLASH很详细的内容,肯定无需在此多做说明,只要有电脑,baidu,google一天不垮台,都可以查阅到很多相关的资料。最最最权威的还是官方的手册,比如说我用的就是S3C2440这个板子,而这个板子上配的NAND是K9F1208,三星公司的,可以去它的官网下载即可。
下图为手册上的管脚图和管脚功能表,可能一开始搬这些东西出来觉得很枯涩,我也觉得这样,不过我是总结之用,无所谓了
各位看客的英语肯定比俺好,几个类似于power这样的E文,随便啃肯定没问题!
下面这个图是NAND FLASH的功能图,有点吓人的功能图
下面我先来剖析NAND FLASH的物理结构:
上图就是NAND FLASH的物理层结构,其实上图画的比较形象,比较生动
大致意思是这样的:
一个NAND FLASH存储器是由很多快组成的,很多是多少?4096块(就本人所用而言,K9F1208)
4096块中的1块又由很多页组成,多少页?32页
32页中的1页又由什么组成呢?就是由512+16字节组成(为什么要写成512+16)
其实说白了就是528字节,但是是由512的主数据区和16的额外数据区组成的,所以如是。
那我掰开手指算算容量有多大?
1个NAND FLASH容量=4096(块)*32(页)*528(字节)*8(位)=528Mbit(以位为单位算的)
既然是FLASH肯定要与外界交流,如何交流,看上图,发现有IO 0~IO7,不错,就是用这8位来交流的。
刚才算的容量是528Mbit,也就是有64M的空间了,也就是说需要26位地址传送了,可是只有8根IO怎么办啊
这样就形成了NAND FLASH交流的独特性,不管你要干什么,首先发送命令,当然命令也是通过IO传送的,命令传送完毕了,再发送4个地址序列(为什么是4个?,26位要IO来传,分4次才行啊),最后才是必要的校验。
看到上面图是不是有2个方块,下面那个,用E文写着:page regsiter,这又是干什么的啊?
其实NAND访问并非直接通过里面的存储物理层,而是有一个专门的页寄存器来管理,不管你是读,是写,都要首先通过page regsiter,这回我晕晕的脑袋稍微好些了。
上面讲到过需要26位才能寻址到64M啊,我的妈亚,我的家家亚,这么多,叫IO0~IO7怎么吃得消啊,所以说才有地址序列的说法啊,但是地址序列又是如何对应的呢?由于NAND FLASH的结构分的很细,又有什么块啊,页啊,字节啊,所以说这个26位地址的本质就是如何区分这个的!
因此就有了A0~A7是页内寻址,也叫列寻址,也就是528字节寻址,我寻啊寻啊,不对劲啊,A0~A7才8位,匝地就能寻528啊,不是只能寻256吗?貌似有道理,请往下看.....
A9~A25是用来进行页寻址的,也叫行寻址,刚不是算了,4096块*32页=131072页,用A9~A25就可以搞定这么多页了,不信你算算。
客官看出来了没?发现A8怎么溜了?难道生气不干了?没这回事,它在偷偷的工作,默默无为的那种,象俺。
A8是由里面的某个硬件电路根据相关的命令而置为1或者0,这不用我们操心,但我们要理解
比如说我喊话了说要寻址0~255字节,敢情好啊,这样的话8位IO肯定搞定了,对头!这时候我们聪明的硬件电路就会把A8置为0,不需要它了。
又比如说我喊话了要寻址第484字节啊,这么多啊,8位抗不住啊,对,这时候硬件电路就会把A8叫上,一起协助你,完成所谓的第484个字节寻址.484的二进制是111100100,需要9为才行,其实A8此时就充当第9位,其余8位还是由IO完成的,这样就可以完成528字节内的任何寻址了!
基于以上可知,A9~A25是进行多达上万页寻址的,其实还可以细分的,A9~A13是块内的32页寻址,正好5位,2的5次方=32,一块由32页组成,多好啊。
A14~A25是用于寻块的,前面说了,4096块,自己掰开手指算算吧。
其实A14~A25还可以细分,不过必须先了解个概念才行,知道什么是plane吗?
NO!我说的不是飞机!
其实NAND FLASH还被组织成一种形式,就是把整个NAND FLASH分成四个层(plane),每层1024块,每层里还有个528字节的页寄存器,组织形式看下图:
所以说的话,A14~A15是用于plane寻址的,正好4种情况。其余的用于1024块寻址。
对于基本的物理结构就是如上的,其实是总结之用,请勿嘲笑,欲知详细,请查阅文档,OK?
以下是基于程序分析的
本次实验的思路是将一些启动代码,初始化代码放在NAND 0~4K的空间内,把主函数放在4096字节后,那些启动代码,初始化代码负责将4096后的主函数copy到0x30000000的地址空间,然后跳转执行主函数即可。
程序在此就不必写出来了,重在整理思路
在head.S里主要需要关掉watch_dog,调用sdram初始化函数,调用nand初始化函数,调用nand的复制函数(也就是读函数,复制到0x30000000),最后跳转到0x30000000处
nand在使用前,需要进行简单的配置,比如说设置时序,2440在NFCONF里面设置,ECC初始化,片选,控制器使能,在NFCONT设置,最后再复位下nand flash即可。
nand的读需要注意,只用到了低8位,而且读的时候,需要注意控制字节数,因为如果从A区或者C区读取,它会一直的紧接着从下一页的A区或者C区读取,如果是B区,就会在下一页从A区开始读取了,一定要记得判断是否准备好,检测状态。