跟着韦老师学Linux学习笔记(四)-Nand Flash

之前我们学习涉及的外设,一般都是有数据总线、地址总线以及便旋信号,但是今天我们使用的Nand Flash是只有数据总线和控制信号,没有地址总线,那我们该如何使用它呢?

(1)、硬件部分

首先我们先了解一下,Nand Flash的存储结构,如下图:

 

NandFlash在存储时,最小单位是一页(2k存储空间+64Bytes的OOB空间),64页组成一块(128K存储空间+4k的OOB空间),设备总共有2048个块,总容量是(128K+4K)*2048=2112Mbits。并且,我们在对Nand进行寻址时,一般情况下,我们只对每一页的前2k进行连续寻址,而忽略OOB的寻址空间。

正如开始时说的Nand Flash是没有地址总线,但是,他是有很多条控制信号线的如下图。

 

其中:       RnB:检测当前设备是否忙的信号,如果不忙则我们可以使用它。

                 CLE:命令信号控制线,表示我们发出的是命令。

                   nFCE: 片选信号线。

                   ALE:地址信号线,表示我们发出的信号是地址。

                   nFEW:写使能信号,表示我们要对Nand进行写数据、地址或命令。

                   NFRE:读使能信号,表示我们要对Nand进行读数据

因此,我们只要控制上述信号线,通过I/o0~I/O7,进行命令、地址和数据的读写,就可以操作Nand Flash了。

那么如何对Nand Flash进行寻址呢?如下图:

 

我们要想访问一个地址,需要连续5个地址信号给Nand Flash,其中两个列信号,三个行信号。*L:低电平。

控制信号有了,地址也有了,我们还需要发送命令,才能设置进行操作。如下图:

 

操作Nand Flash时,我们首先需要传输命令(读、写、擦除或者其他),然后发送相应的地址,最后是数据的读写,中间还要检查Flash的状态是否繁忙。

相应的控制寄存器介绍:

a、  NFCONF:Nand Flash的配置寄存器

主要用来设置Nand Flash的时序参数TACLS、TWRPH0、TWRPH1,设置数据位宽,还有一些只读位,用来指示是否支持其他大小的页。

b、  NFCONT:Nand Flash控制寄存器

用于使能/禁止Nand Flash,使能/禁止控制引脚信号nFCE、初始化ECC。

c、  NFCMD:Nand Flash命令寄存器

d、  NFADDR:Nand Flash地址寄存器

e、  NFDATA:Nand Flash数据寄存器

f、   NFSTAT:Nand Flash状态寄存器

(二)程序设计:

本节程序只是对Nand Flash进行数据的读操作。流程图如下:

 

 

程序代码:

1   firtst      0x00000000 : { head.o init.o nand.o}
2   second     0x30000000 : AT(4096) { main.o }

首先为了方便测试程序,我们把要执行的主函数放在了地址空间4096以后了,程序的运行地址在0x30000000。

基于本节内容,主要对Nand Flash部分的程序进行分析:

首先我们要初始化Nand Flash,

 1         nand_chip.nand_reset         = s3c2440_nand_reset;
 2         nand_chip.wait_idle          = s3c2440_wait_idle;
 3         nand_chip.nand_select_chip   = s3c2440_nand_select_chip;
 4         nand_chip.nand_deselect_chip = s3c2440_nand_deselect_chip;
 5         nand_chip.write_cmd          = s3c2440_write_cmd;
 6         nand_chip.write_addr         = s3c2440_write_addr;
 7         nand_chip.read_data          = s3c2440_read_data;
 8         /* 设置时序 */
 9         s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
10         /* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */
11         s3c2440nand->NFCONT = (1<<4)|(1<<1)|(1<<0);

主要实现了Nand Flash的片选、复位、等待、读写的操作。

然后就是按照流程图进行多Nand Flash的读操作了

 1 /* 读函数 */
 2 void nand_read(unsigned char *buf, unsigned long start_addr, int size)
 3 {
 4     int i, j;
 5 
 6 #ifdef LARGER_NAND_PAGE
 7     if ((start_addr & NAND_BLOCK_MASK_LP) || (size & NAND_BLOCK_MASK_LP)) {
 8         return ;    /* 地址或长度不对齐 */
 9     }
10 #else
11     if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
12         return ;    /* 地址或长度不对齐 */
13     }
14 #endif    
15 
16     /* 选中芯片 */
17     nand_select_chip();
18 
19     for(i=start_addr; i < (start_addr + size);) {
20       /* 发出READ0命令 */
21       write_cmd(0);
22 
23       /* Write Address */
24       write_addr(i);
25 #ifdef LARGER_NAND_PAGE
26       write_cmd(0x30);        
27 #endif
28       wait_idle();
29 
30 #ifdef LARGER_NAND_PAGE
31       for(j=0; j < NAND_SECTOR_SIZE_LP; j++, i++) {
32 #else
33       for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
34 #endif
35           *buf = read_data();
36           buf++;
37       }
38     }
39 
40     /* 取消片选信号 */
41     nand_deselect_chip();
42     
43     return ;
44 }

最后,下载调试。

 

posted @ 2017-03-03 12:01  miyazono  阅读(661)  评论(0编辑  收藏  举报