u-boot分析(九)
上篇博文我们按照210的启动流程,分析到了初始化串口,由于接下来的取消存储保护不是很重要,所以我们今天按照u-boot的启动流程对nand flash初始化进行分析。
今天我们会用到的文档:
1. 2440芯片手册:http://download.csdn.net/detail/wrjvszq/8358949
2. 6410芯片手册:http://download.csdn.net/detail/wrjvszq/8358965
3. 210芯片手册:S5PV210_UM_REV1.1(我的不知道为什么传不上去大家去百度搜吧)
4. Nand flash芯片手册:大家根据自己的nand flash芯片型号,找到对应的手册
我们今天会通过以下几点,对nand flash的初始化进行介绍:
1. Nand flash简介
2. Nand flash初始化
3. Nand flash读写操作
l Nand flash简介
1. 分类
Nand flash闪存芯片又分为
1) SLC(单层单元,每个存储格上存一个)
2) MLC(多层单元,每个存储格上存两个)
3) TLC(三层单元,每个存储格上存三个)
2. 访问方式
类似与我们单片机里面的外设,其有自己的控制器,可以对数据解析,我们要按照固定的格式和协议进行访问。
3. 地址构成
在Nand flash芯片手册中我们很容易找到其构成图,我们结合下图对其进行简单分析
1) device:一个Nand flash可以分为多个block
2) block:一个block可以分为多个pages
3) page:一个page可以分为两个区,分别为数据区和信息区(包括校验码等内容)
其地址构成分为:
行地址:表示要访问的页在块中的页编号
列地址:表示要访问的地址在该页中的偏移
l Nand flash初始化
通过上面的分析我们对nand的基本信息有了了解,下面我们来分析其初始化,同样我们可以参考u-boot给出的代码得出其初始化流程:
1) 设置管脚
2) 初始化NFCONF寄存器
3) 初始化NFCONT寄存器
1. 初始化NFCONF寄存器
在初始化NFCONF寄存器的时候我们要特别注意下面几个值(这三个值是将nand flash和我们芯片自有的nand flash控制器的时序相匹配的重要值):TACLS、TWRPH0、TWRPH1。
我们可以在我们的芯片手册中找到nand flash控制器所提供的时序图,其中TACLS、TWRPH0、TWRPH1是我们自己可以配置的。
同时可以在nand flash芯片手册中找到其所需要的时序图,如下
简单通过时序比较我们就可以清楚的知道,TACLS、TWRPH0、TWRPH1分别对应tCLS、twp、tCLH
那么其所需要的这些值的大小到底是多少呢?我们通过nand的芯片手册就可以找到下表,其中的值是该时序所需的最小值。
通过以上分析,我们再结合在http://www.cnblogs.com/wrjvszq/p/4227435.html一文中设置的系统时钟,就可以轻松的设置我们的NFCONF寄存器了,NFCONT寄存器设置比较简单,按照寄存器说明即可,在此也就不过多分析了。
/*
* Nand Interface Init for SMDKC110
*/
nand_asm_init: /* Setting GPIO for NAND */
/* This setting is NAND initialze code at booting time in iROM. */ ldr r0, =ELFIN_GPIO_BASE ldr r1, [r0, #MP01CON_OFFSET]
bic r1, r1, #(0xf<<)
orr r1, r1, #(0x3<<)
str r1, [r0, #MP01CON_OFFSET] ldr r1, [r0, #MP01PUD_OFFSET]
bic r1, r1, #(0x3<<)
str r1, [r0, #MP01PUD_OFFSET] ldr r1, [r0, #MP03CON_OFFSET]
bic r1, r1, #0xFFFFFF
ldr r2, =0x22222222
orr r1, r1, r2
str r1, [r0, #MP03CON_OFFSET] ldr r1, [r0, #MP03PUD_OFFSET]
ldr r2, =0x3fff
bic r1, r1, r2
str r1, [r0, #MP03PUD_OFFSET] ldr r0, =ELFIN_NAND_BASE ldr r1, [r0, #NFCONF_OFFSET]
ldr r2, =0x777F
bic r1, r1, r2
ldr r2, =NFCONF_VAL
orr r1, r1, r2
str r1, [r0, #NFCONF_OFFSET] ldr r1, [r0, #NFCONT_OFFSET]
ldr r2, =0x707C7
bic r1, r1, r2
ldr r2, =NFCONT_VAL
orr r1, r1, r2
str r1, [r0, #NFCONT_OFFSET] ldr r1, [r0, #NFCONF_OFFSET]
orr r1, r1, #0x70
orr r1, r1, #0x7700
str r1, [r0, #NFCONF_OFFSET] ldr r1, [r0, #NFCONT_OFFSET]
orr r1, r1, #0x03
str r1, [r0, #NFCONT_OFFSET] mov pc, lr
经过上述内容我们对nand的初始化有了一定的了解,u-boot在此阶段做的内容也就完成了,但是为了不在以后返回来分析nand,我们今天趁热打铁,将其的读写操作一同分析。
l Nand flash读写操作
1. 读操作
我们的nand flash支持两种读操作,一种是页读(整页读取,只需用行地址),一种是随机读(随机读取,需要行列地址),今天我们重点分析页读,随机读取跟其类似。
按照以前自己在做单片机时候的经验,我们既然要和外设通信,那么就必须按照外设自身所规定的时序发送内容,所以自己在nand芯片手册中找到了读操作的时序图(如下),根据此时序图我们可以很容易总结出读操作的流程,有了流程我们的代码实现起来就比较简单了。
1. 选中nand芯片
2. 清除rb
3. 发送0x00
4. 发送列地址
5. 发送行地址
6. 发送0x30
7. 等待R/B
8. 读数据
9. 取消选中
2. 写操作
我们的nand flash同样支持两种写操作,一种是页写(整页写入,只需用行地址),一种是随机写(随机写入,需要行列地址),今天我们重点分析页写,随机写入跟其类似。
同样我们可以在nand芯片手册中找到写操作的时序图(如下),根据此时序图我们可以很容易总结出写操作的流程,有了流程我们的代码实现起来就比较简单了。
1. 选中nand芯片
2. 清除rb
3. 发送0x80命令
4. 发送列地址
5. 发送行地址
6. 写入数据
7. 发送0x10命令
8. 等待R/B
9. 发送0x70命令
10. 读取写入结果
11. 取消选中
经过上述内容我们对nand的读写操作进行了简单的流程分析,对于nand还有其他操作,比如复位,擦除等操作,其实其实现都可以仿照我们实现读写的思路,进行实现。