|
s3c2440内部集成有内部SRAM(steppingstone),当选择从nand flash启动的时候,nand flash的前4k代码将会自动copy到内部SRAM中后运行。
一、nand flash控制器的特性
1、支持读/写/编程NAND FLASH内存。
2、系统复位后nand flash的前4k代码自动copy到内部SRAM,copy完成后从SRAM启动,此时内部sram被映射为nGCS0。(当OM[1:0]=00时,使能NAND FLASH 启动模式)
3、支持硬件ECC校验。
4、系统启动后内部SRAM可以用做其他的用途。
二、操作nand flash的方法
1、设置nand flash配置寄存器NFCONF;
2、向命令寄存器NFCMMD写入操作命令;
3、向地址寄存器NFADDR写入地址;
4、读/写数据前要读取状态寄存器NFSTAT来判断nand flash是否处于忙状态。
三、ECC(错误纠错码)
nand flash控制器包括4个ECC模块,两个模块(一个用于data[7:0],一个用于data[15:8])可以被用于2048bytes为上限的ECC检验码的生成,另外两个模块(一个用于data[7:0],一个用于data[15:8])可以被用于16bytes为上限的ECC检验码的生成。
四、NAND FLASH特殊功能寄存器的详细说明----见手册
NFCONF 0x4E000000 NAND flash configuration
NFCONT 0x4E000004 NAND flash control
NFCMD 0x4E000008 NAND flash command
NFADDR 0x4E00000C NAND flash address
NFDATA 0x4E000010 NAND flash data
NFMECC0 0x4E000014 NAND flash main area ECC0/1
NFMECC1 0x4E000018 NAND flash main area ECC2/3
NFSECC 0x4E00001C NAND flash spare area ECC
NFSTAT 0x4E000020 NAND flash operation status
NFESTAT0 0x4E000024 NAND flash ECC status for I/O[7:0]
NFESTAT1 0x4E000028 NAND flash ECC status for I/O[15:8]
NFMECC0 0x4E00002C NAND flash main area ECC0 status
NFMECC1 0x4E000030 NAND flash main area ECC1 status
NFSECC 0x4E000034 NAND flash spare area ECC status
NFSBLK 0x4E000038 NAND flash start block address
NFEBLK 0x4E00003C NAND flash end block address
五、读nand flash一般步骤
1.设置NFCONF和NFCONT
NFCONF = 0x300 ;设置时序
NFCONT = (1<<4)|(1<<1)|(1<<0)
2.发出片选信号.
NFCONT&= ~(1<<11)
NFCMMD = 0xff; reset命令,第一次操作nand flash前,通常复位nand flash
3.发出读命令
NFCMMD = 0 (读命令)
4.发出地址信号
volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
*p = addr & 0xff;
*p = (addr>>9) & 0xff;
*p = (addr>>17) & 0xff;
*p = (addr>>25) & 0xff;
5.循环查询NFSTAT位0,直到它等于1。
6.连续读NFDATA寄存器512次,得到一页数据(512字节)
7.禁止nand flash的片选信号
NFCONT|= (1<<1)
例子:
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_addr(i); /* Write Address */
wait_idle();
for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
*buf = read_data();
buf++;
}
}
nand_deselect_chip(); /* 取消片选信号 */
return ;
}
|
|