对S3C2440读取NAND Flash的总结
来源:    发布时间: 2018-12-30 23:38   67 次浏览   大小:  16px  14px  12px
对S3C2440读取NAND Flash的总结

  引脚充当数据、地址、命令的复用端口。地址和命令只能在I/O[7:0]上传递,数据宽度是8

  正如硬盘的盘片被分为磁道,每个磁道又分为若干扇区,一块nandflash也分为若干block,每个block分为如干page。一般而言,block、page之间的关系随着芯片的不同而不同,典型的分配是这样的:

  需要注意的是,对于flash的读写都是以一个page开始的,但是在读写之前必须进行flash的擦写,而擦写则是以一个block为单位的。同时必须提醒的是,512bytes理论上被分为1sthalf和2sdhalf,每个half各占256个字节。

  由上图所示,1个Page总共由528Bytes组成,这528个字节按顺序由上而下以列为单位进行排列(1列代表一个Byte。第0行为第0Byte,第1行为第1Byte,以此类推,每个行又由8个位组成,每个位表示1个Byte里面的1bit)。这528Bytes按功能分为两大部分,分别是DataField和SpareField,其中SpareField占528Bytes里的16Bytes,这16Bytes是用于在读写操作的时候存放校验码用的,一般不用做普通数据的存储区,除去这16Bytes,剩下的512Bytes便是我们用于存放数据用的DataField,所以一个Page上虽然有528个Bytes,但我们只按512Bytes进行容量的计算。

  读命令有两个,分别是Read1,Read2其中Read1用于读取DataField的数据,而Read2则是用于读取SpareField的数据。对于NandFlash来说,读操作的最小操作单位为Page,也就是说当我们给定了读取的起始后,读操作将从该开始,连续读取到本Page的最后一个Byte为止(可以包括SpareField)

  PaageAddress:页地址。由于页地址总是以512Bytes对齐的,所以它的低9位总是0。确定读写操作是在Flash上的哪个页进行的。

  Read1的命令里面出现了两个命令选项,分别是00h和01h。这里出现了两个读命是否令你意识到什么呢?是的,00h是用于读写1sthalf的命令,而01h是用于读取2ndhalf的命令。现在我可以结合上图给你说明为什么K9F1208U0B的DataField被分为2个half了。

  如上文我所提及的,Read1的1st.Cycle是发送ColumnAddress,假设我现在指定的ColumnAddress是0,那么读操作将从此页的第0号Byte开始一直读取到此页的最后一个Byte(包括SpareField),如果我指定的ColumnAddress是127,情况也与前面一样,但不知道你发现没有,用于传递ColumnAddress的数据线]为什么不出现在我们传递的地址位中),也就是说我们能够指定的ColumnAddress范围为0-255,但不要忘了,1个Page的DataField是由512个Byte组成的,假设现在我要指定读命令从第256个字节处开始读取此页,那将会发生什么情景?我必须把ColumnAddress设置为256,但ColumnAddress最大只能是255,这就造成数据溢出。正是因为这个原因我们才把DataField分为两个半区,当要读取的起始地址(ColumnAddress)在0-255内时我们用00h命令,当读取的起始地址是在256-511时,则使用01h命令.假设现在我要指定从第256个byte开始读取此页,那么我将这样发送命令串。

  事实上,当NF_CMD=0x01时,NANDFlash地址寄存器中的第8位(A8)将被设置为1(如上文分析,A8位不在我们传递的地址中,这个位其实就是硬件电根据01h或是00h这两个命令来置高位或是置低位),这样我们传递column_addr的值256随然由于数据溢出变为1,但A8位已经由于NF_CMD=0x01的关系被置为1了。这8个位所表示的正好是256,这样读操作将从此页的第256号byte(2ndhalf的第0号byte)开始读取数据。

  在对NANDFlash进行任何操作之前,NANDFlash必须被初始化。向NandFlash的命令寄存器和地址寄存器发送完以上命令和参数之后,我们就可以从rNFDATA寄存器(NandFlash数据寄存器)读取数据了.

  2.NandFlash芯片每一位(bit)只能从1变为0,而不能从0变为1,所以在对其进行写入操作之前要一定将相应块擦除(擦除即是将相应块得位全部变为1).

  3.OOB部分的第六字节(即517字节)标志是否是坏块,如果不是坏块该值为FF,否则为坏块。

  I/O0-I/O7:复用引脚。可以通过它向nandflash芯片输入数据、地址、nandflash命令以及输出数据和操作状态信息。

  ECC是用于对存储器之间传送数据正确进行校验的一种算法,分硬件ECC和软件ECC算法两种,在S3C2440的NandFlash控制器中实现了由硬件电(ECC生成器)实现的硬件ECC。

  当写入数据到Nandflash存储空间时,ECC生成器会在写入数据完毕后自动生成ECC码,将其放入到ECC0-ECC2。当读出数据时NandFlash同样会在读数据完毕后,自动生成ECC码将其放到ECC0-ECC2当中。

  当写入数据时,可以在每页写完数据后将产生的ECC码放入到OOB指定的(Byte6)去,这样就完成了ECC码的存储。这样当读出该页数据时,将所需数据以及整个OOB读出,然后将指定的ECC码与读出数据后在ECC0-ECC1的实际产生的ECC码进行对比,如果相等则读出正确,若不相等则读取错误需要进行重读。

  操作NANDFLASH时,先传输命令,接着输出地址,最后读/写数据,期间还要检查FLASH的状态。具体的命令字见下表。

  如上图,当发出00h命令后,接着4个字节的地址序列,然后再发出30h命令,接着,就可以读出数据了,当发送完30h后,可以检测R/B引脚看是否准备好了,如果准备好,就可以读出数据。

  当向芯片发送FFh命令时,可以复位芯片,如果芯片正在处于读、写、擦除状态,复位命令会终止这些命令。

  NANDFLASH的写操作一般是以页为单位进行的,因此才会叫Page Program,但是也支持一个字以上的(包括一个字)连续写操作。开始发出80h命令,接着发送5个字节的地址序列,然后向FLASH发送数据,最大为一页大小,最后发送10h命令启动烧写,此时FLASH内部会自动完成写、校验操作。发送10h后,可以通过读状态命令70h(见下文)获知写操作是否完成,是否成功。

  此命令用于将一页复制到同一层的另外一页,它省去了读出数据、将数据重新载入FLASH的过程,使得效率大大提高。

  关于层:NANDFLASH有层的概念,K9F2G08分为两层,每层包括了1024个块,如下图,因此的命令表中才会有two-plane的命令,这些命令可以使得在两个层间完成操作,这样程序员就很方便的使用一个命令完成更多的操作,其命令格式和单层操作的类似,详见手册。但K9F2G08R0A不支持两层命令。

  上图清晰的告诉我们,开始发送00h和源地址,当发送35h之后,芯片将一页大小的数据读入到内部寄存器,接着,我们发送85h和目的地址序列,最后发送10h启动。最后,我们可以使用70h/7Bh检测是否完成,是否成功。

  擦除操作是以块为单位的,也就是128K。开始发出60h,然后发出3个地址序列仅行地址,最好发出D0h。具体操作,如下图。

  读状态命令可以读出芯片的状态寄存器,查看是否读、写操作是否完成、是否成功。具体的状态见下图。

  看了的命令时序图,大家肯定认为对NANDFLASH的操作比较复杂,因此S3C2440为了简化操作,为我们提供了几个寄存器,比如NFCMD寄存器,就是NANDFLASH命令寄存器,如果我们需要读命令,直接向此寄存器写00h、30h即可。

  4.读/写数据,通过NFSTAT检测NANDFLASH的状态,读R/nB信号以确定是否完成操作,是否成功。

  配置寄存器,设置NANDFLASH的时序参考TACLS、TWRPH0、TWRPH1,这三个参数见下面时序图;设置位宽度;还包括一些只读位,用来批示是否支持其它大小的页。

  用来使能/NANDFLASH控制器、使能/控制引脚信号nFCE、初始化ECC。

  NFCONF主要是设置TACLS、TWRPH0、TWRPH1三个时间参数。根据手册的参数表,见下图:

  三个参数只有最小值MIN,没有最大值,因此,只要参数大于表格中的数即可,这里涉及时钟的一些概念,这里直接将参数告诉大家: