全部博文(11)
分类: LINUX
2009-08-12 13:17:56
1 要写某个块时,先要擦除这个块。
2 Nand Flash 一般以512字节为单位进行读写
3 Nand flash上发生位反转,推荐使用EDC/ECC进行错误检测和恢复
4 Nor Flash上常使用jffs2文件系统,在Nand Flash上常用yaffs文件系统,在更底层,有MTD驱动程序实现对它们的读、写、擦除操作,它也实现了EDC/ECC校验
5 当读、写某页时会先将数据读入\写入页寄存器,大小为528字节
6 NAND Flash K
(1)1页=(512+16)字节
16字节额外空间的列地址为512---527
(2)1块=32页=(512+16)字节*32=(16K+512)字节
(3)1个器件=4096块=4096*(16K+512)字节=
7地址分析
(1)行地址即页地址:A9---A25
列地址用来在半页(256字节)中寻址:A0---A7
(2)读命令00:列地址将在上半部分寻址 A8=0,A0---A7
读命令01:列地址将在下半部分寻址 A8=1,A0---A7
读命令50:寻址列地址为512---527的16字节 A0---A3
8 命令介绍
(1)Read 1
00h:从A区开始读
01h:从B区开始读
命令字--->4个地址序列--->检测R/nB引脚以确实Flash是否准备好
具体用法看下面实验
(2)Read 2
50h:读C区数据
命令字--->4个地址序列--->检测R/nB引脚以确实Flash是否准备好
(3)Read ID
90h--->4个地址序列(都为0)--->连续读5个数据
(4)复位
FFh
(5)写页
80h--->4个地址序列--->发送数据--->10h--->70h(检测是否成功,是否完成)
(6)写多页
|
528字节寄存器 |
|
|
|
|
|
|
|
|
第一层:80h--->4个地址序列--->数据(最多528字节)--->11h--->71h( 检测写操作是否完成,是否成功)
第二层:80h--->4个地址序列--->数据(最多528字节)--->11h--->71h( 检测写操作是否完成,是否成功)
第三层:80h--->4个地址序列--->数据(最多528字节)--->11h--->71h( 检测写操作是否完成,是否成功)
第三层:80h--->4个地址序列--->数据(最多528字节)--->11h--->71h( 检测写操作是否完成,是否成功)
第四层:80h--->4个地址序列--->数据(最多528字节)--->11h--->71h( 检测写操作是否完成,是否成功)
(7)将一页复制到同一层的另一页
源地址、目的地址A14、A15必须相同
00--->4个源地地址序列--->
(8)同时进行多个层的复制操作
00h(读操作)--->源地址--->03h--->源地址--->03h--->源地址--->03h--->8Ah---->目的地址--->11h--->8Ah---->目的地址--->11h--->8Ah---->目的地址--->10h
(9)块擦除
60h--->3个地址序列(2、3、
(10)同时擦除不同层中的块
--->60h--->地址--->60h--->地址--->60h--->地址--->60h--->地址--->D0h--->71h(检查擦除操作是否成功)
(11)读状态(读入状态寄存器)
70h:一层时用
71h:多层时用
9读NAND Flash
(1)NFCONF=0x300
0 |
0 |
00 |
0 |
011 |
0 |
000 |
0000 |
|
|
[13:12] TACLS=0 |
|
[10:8] TWRPH0=3 |
|
[6:4] TWRPH1=0 |
|
|
|
|
|
|
|
|
|
(2)NFCONT= (1<<4) | (1<<1) | (1<<0)
初始化ECC 禁止控制引脚信号 使能Nand Flash控制器
(3)第一次操作NAND Flash前,通常复位一下NAND flash
NFCONF&=~(1<<1) 发出片选信号
NFCOM=0xff 复位命令
然后循环查询NFSTAT位0,直到它等于1
最后禁止片选信号,在实际使用时再使能
NFCONF|=0x2 禁止NAND Flash
(4) 先使能NAND Flash,然后发出读命令
NFCONT&=~(1<<1) 发出片选信号
NFCMD=0 读命令 此时A8=0
(5) 发出地止信号
NFADRR=addr&0xff A0---A7
NFADRR=(addr>>9)&0xff A9---A16
NFADRR=(addr>>17)&0xff A17---A24
NFADRR=(addr>>25)&0xff A25
(6) 循环查询NFSTAT位0,直到它等于1,这时就可以读取数据了
(7)连续读NFDATA寄存器512次,得到一页数据(循环执行4,5,6,7)
(8)最后禁止NAND lash片选信号
NFCONT|=(1<<1)
10关键部分代码详解 完整代码:nandflash.tar.gz
这个实验源码文件较多,可用source insight来分析
(1)/* 初始化NAND Flash */
void nand_init(void)
{
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0
/* 判断是S
if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))
{
nand_chip.nand_reset = s
nand_chip.wait_idle = s
nand_chip.nand_select_chip = s
nand_chip.nand_deselect_chip = s
nand_chip.write_cmd = s
nand_chip.write_addr = s
nand_chip.read_data = s
/* 使能NAND Flash控制器, 初始化ECC, 禁止片选, 设置时序 */
s
}
else
{
nand_chip.nand_reset = s
nand_chip.wait_idle = s
nand_chip.nand_select_chip = s
nand_chip.nand_deselect_chip = s
nand_chip.write_cmd = s
nand_chip.write_addr = s
nand_chip.read_data = s
/* 设置时序 */
s
/* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */
s
}
/* 复位NAND Flash */
nand_reset();
}
(2)/* 读函数 */
void nand_read(unsigned char *buf, unsigned long start_addr, int size)
{
int i, j;
if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
return ; /* 地址或长度不对齐 */
}
/* 选中芯片 */
nand_select_chip();
for(i=start_addr; i < (start_addr + size);) {
/* 发出READ0命令 */
write_cmd(0);
/* Write Address */
write_addr(i);
wait_idle();
for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
*buf = read_data();
buf++;
}
}
/* 取消片选信号 */
nand_deselect_chip();
return ;
}