NandFlash操作详解(一)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/doccode/article/details/46963855

NandFlash的分类:

         根据物理结构上的区别,NandFlash主要分为以下两种:

                   SLC(SingleLevel Cell):单层式存储

                   MLC(MultiLevel Cell):多层式存储

                   SLC在存储格式上只存一位(bit)数据,而MLC则存放两位数据。

根据NandFlash每页(页的概念在后面有介绍)存储字节数,NandFlash分大页和小页两种,大页就是每一个Page有2k 或4k字节,小页就是一个Page只有512字节。

s3c2410通常使用小页NandFlash,s3c2440通常使用大页NandFlash。s3c2440为了支持大页NandFlash,它的NandFlash控制器相对于s3c2410的NandFlash控制器要多几个寄存器,所以在移植uboot到s3c2440的过程中,基于2410的NandFlash代码改动会涉及到寄存器的修改。

NandFlash的结构:

         手册中有(我的NandFlash芯片为K9F2G08U0C):


Features中讲到Page、Block,这些东西是什么呢?如下:


从上面的图中可以看到:一块NandFlash可以划分为2048个块,一个块分为64个页,一页分为2k+64字节的两个区,2k存放有效数据,64字节保存校验信息等。

这种划分的形式在任何NandFlash中都是一样的。只是说块数、页数、每页大小可能不一样。

Row Address - 行地址可以简单的认为是页号

Column Address - 列地址相当于在一个页内的偏移地址。

有了页号和偏移地址便能正确的访问到每个存储单元。

 

NandFlash的访问:

         观察开发板的原理图:


可以发现NandFlash的接线没有一根是s3c2440的数据总线addr(n),这也就说明了s3c2440不能像操作NorFlash/SDRAM一样直接使用绝对地址访问NandFlash空间。也就是说NandFlash的访问是独立于ARM寻址空间的,NandFlash使用独立编址。

         NandFlash的编程应该严格参照NandFlash数据手册的时序来操作信号线(CLE、ALE、CE、R/B等),操作每个时序信号都是有时序关系的,导致在操作和使用上都不方便,所以三星给s3c2440增加了NandFlash控制器,编程操作NandFlash的时候只需要往几个寄存器(配置NandFlash控制器)中写入特定的值即可控制NandFlash。

         回过头来观察电路图,NandFlash的接线中能传输数据的只有LDATA0~LDATA7这8根数据线,地址和数据都是通过这8根线和s3c2440交互的。地址数据有32位(4字节),在传输地址时是分5次传输的(不是4次)。如下:

第一次传输A0~A7          Column Address

第二次传输A8~A11                   Column Address

第三次传输A12~19                 Row Address

第四次传输A20~A27               Row Address

第五次传输A28                          Row Address

 

NandFlash信号引脚:

CLE(CommandLatch Enale):命令锁存允许

ALE(AddressLatch Enable):地址锁存允许

CE:芯片选择

RE:读允许

WE:写允许

WP:在写或擦除期间,提供写保护

R/B:读/忙

ALE:地址锁存  ALE = 1,data0-data7上传输的是地址

CLE:命令锁存  CLE = 1,data0-data7上传输的是命令

都是0的时候data0-data7上传输的是数据

 

NandFlash初始化:

         在读/写NandFlash前,都需要先对NandFlash初始化,所谓初始化就是配置一些必要的时序,打开s3c2440手册NandFlash Controller可以看到第一个寄存器是NFCONF


可以看到这个寄存器需要配置三个域,TACLS、TWRPH0、TWRPH1,这三个值怎么设置呢?看下面的分析:

在NandFlash的芯片手册中找到如下时序:



其中:t2 = TCLS - twp。要想让NandFlash工作必须给NandFlash给这三个时间提供合理值。取值表在NandFlash芯片手册中有说明:


提供至少最小值以上的值才能正常工作。我们的是3.3V的NandFlash芯片。

所以:

t1(twp)最小12ns

t2 = TCLS – twp= 12-12 = 0ns

         t3(TCLH)最小5ns

确定最小值以后找到2440手册的时序:


对照两张时序图可以发现:t2就是TACLS,t1是TWRPH0,t3是TWRPH1.所以便得到了需要配置的三个域的最小值了。

因为NandFlash使用的是HCLK,而我们使用的HCLK是100MHz,就是说一次时钟脉冲10ns。

TACLS最小0ns

         TWRPH0最小12ns

         TWRPH1最小5ns

根据三个域的说明:

所以:

                   10ns* TACLS > 0ns   所以TACLS取1即可

                   10ns* (TWRPH0+1) >12ns 所以TWRPH0取1或2即可

                   10ns* (TWRPH1+1)>5ns 所以TWRPH1取1即可

         以上三个值再取大一点都是可以的,只要比最小值大就行。

配置寄存器NFCONT

因为在未初始化时,不需要片选,所以需要disable chip Select

         MODE位默认是关闭NandFlash控制器,现在需要打开:


         在对NandFlash控制器做配置后通常需要对控制器做复位操作:

         在NandFlash芯片手册中找到复位操作:

         所以复位操作应有如下步骤:

1、  选择nand(片选),这是每一个NandFlash操作都要做的

2、  清除RnB,因为需要等待RnB信号

3、  发送命令0xff

4、  等待RnB

5、  取消片选

代码实现:

void nand_reset()                                                                                                                                                                                                       

{

    //选中flash、片选

    select_chip();

   

    //清除RnB

    clear_RnB();

   

    //发送0xff命令

    send_cmd(0xff);

   

    //等待RnB

    wait_RnB();

   

    //取消选中flash

    deselect_chip();

}

 

void nand_init()//NandFlash初始化

{

    //初始化NFCONF

    NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);

   

    //初始化NFCONT

    NFCONT = (1<<0) | (1<<1);

   

    //复位

    nand_reset();      

}

 

下一节NandFlash操作详解(二)


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页