S3C2440-裸机篇-10 | 使用S3C2440操作Nand Flash

1. Nor Flash与Nand Flash

Nor Nand
接口 引脚多,类似于RAM 引脚较少
容量 小(1-32MB) 大(128-512MB)
读操作 简单,和RAM相同 简单,和RAM相同
写操作 发出特定命令才能写入 发出特定命令才能写入
价格 便宜
比较 无坏块 有坏块
XIP 可以 不可以
应用场合 存储关键性代码(比如uboot,kernel) 存储海量数据(允许错误)

2. JZ2440开发板上的Nand Flash

JZ2440开发板上板载了一个Nand Flash,型号为K9F2G08U0C,大小为256MB,连接在S3C2440的nand控制器上,原理图如下:

3. Nand Flash的控制原理

3.1. 控制信号

Nand Flash相较于Nor Flash,引脚比较少,它是如何做到的呢?

Nand Flash将地址数据,读写数据,命令数据全部放在了8条数据线上(上图中的LDATA0-7),然后使用控制信号CLE、ALE、WE、RE来区分数据线上的数据,具体如下:

数据线上的数据含义 ALE(地址/数据) CLE(命令/数据) WE(写使能) RE(读使能)
地址
命令数据
写入数据
读出数据

除此之外,还有三个控制引脚,它们的意义如下:

  • CE:片选引脚(LDATA0-7总线复用,用片选信号防止互相干扰)
  • WP:写保护引脚
  • R/B:Flash当前状态引脚(高 -> 空闲或者就绪,低 -> 忙)

3.2. 操作命令

Nand Flash的本质还是Flash,所以操作流程和Nor Flash基本相同,都是:发命令 -> 发地址 - >发数据的流程。

这款Nand Flash的命令列表如下:

3.3. Nand Flash控制器

S3C2440内部有一个Nand Flash控制器,与板载Nand Flash相连,专门负责接收发出Nand Flash的控制信号脉冲,其结构如下:

Nand Flash大大简化了我们的编程工作,在操作之前首先按照这款Nand Flash的性能配置Nand Flash控制器的时序参数,然后只要操作Nand Flash控制器即可。

本文中利用uboot已经配置好Nand Flash控制器中的时序参数这一条件,直接借助uboot读写内存的能力来操作Nand Flash控制器的寄存器,来测试Nand Flash的读写。

因为数据线是共用的,uboot启动之后不会一直将Nand Flash使能,首先需要设置NFCONT寄存器,将片选信号使能:


要发送给Nand Flash的命令需要写入到Nand 控制器的 NFCMMD 寄存器中:

要发送给Nand Flash的地址需要写入到Nand 控制器的 NFADDR 寄存器中:

要发送给Nand Flash的数据需要写入到Nand 控制器的 NFDATA 寄存器中,从 Nand Flash 中读取出的数据也保存在 NFDATA 寄存器中:

4. 使用uboot命令直接读写内存操作Nand Flash

实验前提:烧录uboot.bin到Nor Flash,并且板子设置为Nor Flash启动方式。

知识准备:uboot | uboot内存操作指令mw和md详解

4.1. 读取ID值(ManufacturerID和DeviceID)

查看Nand FLash芯片数据手册,可知读ID的时序如下:

图中表示的读取ID流程如下:

  • ① 写命令90h
  • ② 写地址00h
  • ③ 读数据得到manufacturer code为ECH
  • ④ 读数据得到device code为DAh、10h、15h、44h

设置 Nand Flash 寄存器 NFCONT,首先使能Nand Flash片选信号:

md.l 0x4E000004 1		//先将NFCONT中的值读出来
mw.l 0x4E000004 1		//写入0x01,bit2设置为0,开启片选信号
md.l 0x4E000004 1		//再次读出,检查是否设置成功


发出读ID的一系列流程:

mw.b 0x4E000008 0x90		//写命令90h
mw.b 0x4E00000C 0x00		//写地址00h

md.b 0x4E000010 1	//读取数据

复位,退出该模式:

mw.b 0x4E000008 0xff	//写入命令ff


这5个ID每个都有含义,如下:

读出的第三个ID是0x10,对应信息如下:

读出的第四个ID是0x95,其含义如下:

读出的第五个ID是0x44,其含义如下:

4.2. 读某个地址处的数据

查看芯片手册,时序图如图:

图中表示的读取某个地址处数据的流程如下:

  • ① 写命令00h
  • ② 写Col地址1
  • ③ 写Col地址2
  • ④ 写Row地址1
  • ⑤ 写Row地址2
  • ⑥ 写Row地址3
  • ⑦ 写命令30h
  • ⑧ 读数据

因为Nand Flash的容量有256MB,但是数据线只有8条,所以地址要分为5次来发送,如图:

(暂定)

首先使用uboot命令将0地址处的数据读出,方便后续检验读取的是否正确:

设置 Nand Flash 寄存器 NFCONT,首先使能Nand Flash片选信号:

md.l 0x4E000004 1		//先将NFCONT中的值读出来
mw.l 0x4E000004 1		//写入0x01,bit2设置为0,开启片选信号
md.l 0x4E000004 1		//再次读出,检查是否设置成功

发出读0地址处数据的一系列流程:

mw.b 0x4E000008 0x00		//写命令00h
mw.b 0x4E00000C 0x00		//写地址00h
mw.b 0x4E00000C 0x00
mw.b 0x4E00000C 0x00
mw.b 0x4E00000C 0x00
mw.b 0x4E00000C 0x00
mw.b 0x4E000008 0x30		//写命令00h

md.b 0x4E000010 1	//读取数据

复位,退出该模式:

mw.b 0x4E000008 0xff	//写入命令ff

5. Nand Flash操作代码

上述uboot的操作中,发命令、发地址、发数据、读数据只需要访问Nand Flash控制器的三个寄存器即可,非常简单,在程序中操作nand flash也是访问这三个寄存器即可。

但是在uboot中,nand flash控制器已经被初始化好了,所以在自己编写程序时,需要根据nand flsh的时序参数来初始化nand flash控制器。

5.1. 时序参数初始化

在S3C2440的芯片手册中,首先是CLE(命令/数据)控制信号和ALE控制信号(地址/数据)的时序,如图:

再查找nand flash芯片手册中相对应的时序参数:

所以,从CLE信号发出之后,经过tCLS - tWP时间之后,才能发出WE信号,在芯片手册中查找具体的值:

从时序的具体值中得出,tCLS - tWP = 0,也就是Nand Flash控制器的TACLS参数可以设置为0,设置对应的寄存器,该值可以设置为0

同样的方法,nand flash控制器中的参数TWRPH0对应着nand flash中的tWP参数(min = 12ns),HCLK=100Mhz,周期为10ns,则TWRPH0的寄存器要设置为1(20ns)

同样的方法,nand flash控制器中的参数TWRPH1对应着nand flash中的tCLH参数(min = 5ns),HCLK=100Mhz,周期为10ns,则TWRPH1的寄存器要设置为0(10ns)

5.2. nand flash控制器使能

在nand flash 控制器的控制寄存器中:

nand flash控制器使能设置如下(其中片选信号在操作时再打开):

5.3. 编写nand flash控制器初始化代码

//nand flash控制器初始化
void nand_init(void)
{
    //时序参数初始化
    NFCONF = (0<<12)|(1<<8)|(0<<4);

    //nand flash控制器使能
    //禁止片选,片选信号在操作时再打开
    //初始化ECC
    NFCONT = (1<<4)|(1<<1)|(1<<0);
}
发布了227 篇原创文章 · 获赞 590 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/Mculover666/article/details/104516688