加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

JZ2440的NandFlash控制器

发布时间:2020-12-15 19:54:14 所属栏目:百科 来源:网络整理
导读:【点此回顾上课学习内容] 芯片的型号: K9F2G08U0C 摘要: 本文以S3C2440为例来讲解NAND FLASH控制器的使用方法. 例程中故意将一部分代码放置到 nand 的4k 字节之后,因无法自动拷贝到steppingstone,所以需要读取nand中的内容到sdram,本例程重点关注nand的初始

【点此回顾上课学习内容]

芯片的型号:K9F2G08U0C

摘要: 本文以S3C2440为例来讲解NAND FLASH控制器的使用方法. 例程中故意将一部分代码放置到 nand 的4k 字节之后,因无法自动拷贝到steppingstone,所以需要读取nand中的内容到sdram,本例程重点关注nand的初始化和读取.

1. 硬件部分:


1.1 简介

  • 芯片大小:256M Byte
  • 记忆单元阵列:(256M + 8,192K)bit x 8bit
  • 擦写次数比较少:10 万次?
  • 数据保留时间:10 年
  • 8个IO 口进行数据和地址的复用,因此,读写的时候要用到多个周期
?引脚定义及接法



1.2 内部存储单元的组织结构:



K9F2G08U0C共有2048个Block(块),每个Block含有64 Page(页),每个Page含有2k byte的正常存储空间以及64 byte的校验空间 .

总空间 = 2048 * 64 * (2 * 1024 + 64) ?byte = 264MB

实际存储空间 = 2048 * 64 * 2 * 1024 byte = 256MB

对 nandflash 的结构的几点说明:

  1. ?一页中?1k 表示的是main 区(用于存储用户数据)容量,32 表示的是 spare 区(用于在读写操作的时候存放校验码)容量
  2. 块的大小一般是 128kb、256kb、512kb,貌似这里更小,是64kb
  3. 每个块里边包含很多页,老的 nandflash ,页大小是 256 Bytes、512Bytes,这类被称作 small block,地址周期只有 4 个。常见的nandflash,页大小多数是 2k?Bytes,被称作 big block,地址周期 5 个,更新的 nandflash 页大小是 4k?Bytes,这里的这个芯片,页大小是 2k Bytes,属于 big block。
  4. 这个芯片的写操作是以页为单位的擦除是以块为单位的
  5. 在一个块中,对每一页的编程必须是顺序的,比如,一个块中有128个页,那么你只能先对 Page0 编程,再对 Page1 编程 ...
  6. 为了能让 nandflash 作为启动介质,s3c2440 内部集成了4k 的 sram ,当从 nand 启动的时候,nandflash 代码的前 4k 空间会被赋值到 s3c2440 内部,然后从内部的 sram 开始启动。
  7. s3c2440 硬件产生 ECC 校验码。

1.3寻址方式

???NAND的读写的最小单位为Page:
小页:



大页:(K9F2G08U0C共有2048个Block(块),每个Block含有?64 Page(页),所以我们这款芯片为大页读写)


列地址: 进行 Block 和 Page 寻址

行地址: 进行 Page 内寻址

如何区分Nandflash读写是大页还是小页点我!


2. 软件部分:


由于 s3c2440 内部有nand 的控制器,去查看2440的数据手册,自己编写时序操作程序不是明智的选择,正确的方式是一步一步配置好 s3c2440 的 nandflash 控制器,然后对应查看K9F2G08U0C的芯片手册看是否符合要求!
在此以读Nandflash为例子来配置寄存器。

2.1 初始化部分:

设置好时序中的几个间隔时间:
从 s3c2440 芯片手册上可以知道:
? ??图1


对于 CLE/ALE 上的时序,我们需要设置 TACLS,TWRPH0,TWRPH1,这几个都在 NFCONF 寄存器里。

寄存器

地址

R/W

描述

复位值

NFCONF

0x4E000000

Nandflash?的配置寄存器

0x0000100X

?

Bit

初始值

Reserved

[15:14]

保留

-

TACLS

[13:12]

CLE & ALE duration setting value (0~3)

Duration = ?HCLK x TACLS

01

...

...

TWRPH0

[10:8]

TWRPH0 duration setting value (0~7)

Duration = ?HCLK x ( TWRPH0 + 1 )

000

TWRPH1

[6:4]

TWRPH1 duration setting value (0~7)

Duration = ?HCLK x ( TWRPH1 + 1 )

000

从这里之后的几个都是由硬件决定(就是上下拉)的不需要软件来管。


?原理图中的这个地方设置的是上表中 TWRPH1 之后的位:


CCON = 1; // 支持 1k 字节或 2k 字字节每页的NAND flash存储器
GPG13 = 1; // 每页 2k 字节
GPG14 = 1; // 5个地址周期
GPG15 = 0; // 8位总线

要 求上边的 TACLS、TWRPH0、TWRPH1 的值:
  1. 我们假设 HCLK 为 最大值 136MHz?,稍作分析可得,我们实际的HCLK肯定要小很多,但是如果最大值满足那么小一点的HCLK肯定满足条件!则 HCLK 的周期是 1/136MHz = 7.4ns<flash时钟来自于HCLK后面讲时钟会提到>
  2. 查看 nandflash 的数据手册,找到跟时间相关的时序图和时间:
? ? ? ??时间表


? ? ? ? 时序:
找一个跟上边红色数字 图1 中都有的一张时序图:


我们把图一也拿过来
图1


则?
TACLS 时间是 tCLS -tWP,查 时间表 得到 12ns -12ns = 0ns
? ? 根据寄存器中描述的计算公式:Duration = ?HCLK x TACLS => ?0ns = 7.4ns x TACLS ?=> TACLS = 0

TWRPH0 的时间是 tWP ,查 时间表 得到 12ns?
? ??根据寄存器中描述的计算公式:Duration = ?HCLK x ( TWRPH0 + 1 ) ?=> ?12ns = 7.4ns x (TWRPH0 + 1) ?=> TWRPH0 = 1.6,由于他的取值范围是 (0~7),并且,时间表中的时间是最小能识别的时间,那我们取TWRPH0 =3
TWRPH1 的时间是 tclh = 5ns
? ??根据寄存器中描述的计算公式:Duration = ?HCLK x ( TWRPH1 + 1 ) => 5ns = 7.4ns x (TWRPH1 + 1) => TWRPH1 = 0 即定能满足
[cpp]?view plain?copy
?print?
  1. #define?NFCONF??(*((volatile?unsigned?long?*)0x4E000000))??
  2. ??
  3. void?nand_init(void?)??
  4. {??
  5. ????#define?TACLS???0??
  6. ????#define?TWRPH0 ?3??
  7. ????#define?TWRPH1??0??
  8. ????/*?设置时序?*/??
  9. ????NFCONF?=?(TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);??
  10. /*?使能?nandflash?控制器,初始化ECC,关片选?*/??
  11. ????NFCONT?=?(1<<4)|(1<<1)|(1<<0);??
  12. }??

2.2 芯片的选择和禁止(让芯片操作 CE 引脚):

copy
?
    #define?NFCONT??(*((volatile?unsigned?long?*)0x4E000004))??
  1. ??
  2. void?nand_select(void?)??
  3. {??
  4. ????NFCONT?&=?~(1<<1);??
  5. }??
  6. ??
  7. void?nand_deselect(void?)??
  8. {??
  9. ????NFCONT?|=?(1<<1);??
  10. }??

2.3 写命令和写地址

copy
?
    //?写命令?注意是八位的命令??
  1. #define?NFCMMD?(*((volatile?unsigned?char?*)0x4E000008))??
  2. ??
  3. void?nand_cmd(unsigned?char?cmd)??
  4. {??
  5. ?volatile?int?i;??
  6. ?NFCMMD?=?cmd;??
  7. for?(i?=?0;?i<10;?i++);?//?延时一段时间??
  8. } ?

  1. //?写地址?? (大页)
  2. #define?NFADDR?(*((volatile?unsigned?char?*)0x4E00000C))??
  3. #define?NAND_SECTOR_SIZE????2048??
  4. #define?NAND_BLOCK_MASK?????(NAND_SECTOR_SIZE_LP?-?1)??
  5. ??
  6. void?nand_addr(unsigned?int?addr)??
  7. {??
  8. //?unsigned?int?col?=?addr?%?2048;??
  9. //?unsigned?int?page?=?addr?/?2048;??
  10. ?col?=?addr?&?NAND_BLOCK_MASK;??
  11. ?page?=?addr?/?NAND_SECTOR_SIZE;??
  12. ?volatile?int?i;??
  13. ?NFADDR?=?col?&?0xff;????????????????/*?Column?Address?A0~A7?*/??
  14. for?(i?=?0;?i<10;?i++);??
  15. ?NFADDR?=?(col>>8)?&?0x0f;???????/*?Column?Address?A8~A11?*/??
  16. ?NFADDR?=?page?&?0xff;????????????/*?Row?Address?A12~A19?*/??
  17. ?NFADDR?=?(page>>8)?&?0xff;???/*?Row?Address?A20~A27?*/??
  18. ?NFADDR?=?(page>>16)?&?0x03;??/*?Row?Address?A28~A29?*/??
  19. } ?



对程序的解释:
?flash芯片的手册上有对于大页 flash 的访问 各个周期传递的位:

因此上边的命令 NFADDR = ... 就不难理解了。
至于,各个周期间的延时:
从flash芯片的数据手册上知道:


对于 I/O 引脚上的数据进行采集是在 WE 的上升沿进行的,因此, 每两个周期的间隔至少应该大于一个 tDS = 12ns,而对 flash 他的时钟来自 HCLK =136MHz,即使是单周期指令,也要 1/136MHz=7.4ns,因此,要延时一段时间。

2.4 读数据:

flash 芯片上:


flash 芯片上:


copy
?
  1. #define?NFSTAT?(*((volatile?unsigned?char?*)0x4E000020))??
  2. #define?NFDATA?(*((volatile?unsigned?char?*)0x4E000010))??
  3. void?nand_wait_teady(void)??
  4. {??
  5. ????while(!(NFSTAT?&?1))??
  6. ?????????for(i?=?0;?i?<?10;?i++);??
  7. }??
  8. ??
  9. unsigned?char?nand_data(return?NFDATA;??
  10. }??
  11. /*?
  12. *?参数的含义: 从NAND Flash位置start_addr开始,将数据复制到SDRAM地址buf处,共复制size字节
  13. */??
  14. void?nand_read(unsignedchar*?buf,?unsignedlong start_addr,int size)
  15. {??
  16. ????int?i,j;??
  17. ? if((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)){
  18. return;
  19. ? ?}
  20. ????
  21. ? ?nand_select_chip(); //选中芯片??
  22. ???
  23. ? ?for(i=start_addr; i < (start_addr + size);)?
  24. ????{??
  25. ? ? ? ? write_cmd(0x00);?//?发出读命令?00h??
  26. ? ? ? ? write_addr(i);?//?发送读的地址??
  27. ? ? ? ? write_cmd(0x30);?//?发出读命令?30h??
  28. ? ? ? ? nand_wait_ready();?//?等待不忙??
  29. ????????for(j=0; j < NAND_SECTOR_SIZE; j++,i++)??
  30. ????????{??
  31. ? ? ? ? ? ? *buf = read_data();?//?读数据????
  32. ? ? ? ? ? ? buf++;??
  33. ????????} ???
  34. ????}??
  35. ????nand_deselect_ship();?//?取消片选
  36. ? ? return ; ?
  37. }??

总结一下:

(1)选中芯片

(2)发送00h

(3)发出地址

(4)发30h

(5)等待就绪

(6)读一页数据

2.5 复位 flash 芯片:

知道了上边的命令的表格,那 复位的实现也就简单了:
copy
void?nand_reset(void)??
  • ????nand_select_chip();?//?选中芯片??
  • ? ? write_cmd(0xff);??
  • ????nand_wait_ready();??
  • ????nand_deselect_chip();??
  • }??
  • 3.NandFlash操作实例

    ?

    篇幅有限,点击跳转NandFlash 控制器操作实例:读Flash

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读