0 前言
参考资料[1]p125-137分析了Nand Flash的原理、读写方法、S3C2410/S3C2440的Nand Flash控制器,并且在随书光盘中提供了关于Nand Flash裸板代码。该代码的主要功能是:将Nand Flash的代码复制到SDRAM中运行,然后点亮LED等。
该代码简单明了,思路清晰,采用了良好的设计模式,因此我个人非常推崇。然而当我将其编译,然后下载到Mini2440的Nand Flash中运行时,却失败了。因此,对代码做了详细分析与修改,使其能在Mini2440中跑起来。
1 硬件分析
参考资料[1]所使用的S3C2440开发板的Nand Flash型号是K9F1G08,大小为128 MB,页大小为512 + 16 Bytes,读取数据需要4个地址周期;Mini2440开发板的Nand Flash型号为K9F2G08,大小为256 MB,页大小为2k + 64 Bytes,读取数据需要5个地址周期,如下图所示(截自K9F2G08手册):
2 修改代码
2.1 nand.c
(1)s3c2440_write_addr()
将下述代码:
static void s3c2440_write_addr(unsigned int addr)
{
int i;
volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
*p = addr & 0xff;
for(i=0; i<10; i++);
*p = (addr >> 9) & 0xff;
for(i=0; i<10; i++);
*p = (addr >> 17) & 0xff;
for(i=0; i<10; i++);
*p = (addr >> 25) & 0xff;
for(i=0; i<10; i++);
}
改为:
static void s3c2440_write_addr(unsigned int addr)
{
int i;
volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
*p = addr & 0xff;
for(i=0; i<10; i++);
*p = (addr >> 8) & 0x0f;
for(i=0; i<10; i++);
*p = (addr >> 11) & 0xff;
for(i=0; i<10; i++);
*p = (addr >> 19) & 0xff;
for(i=0; i<10; i++);
*p = (addr >> 26) & 0x01;
for(i=0; i<10; i++);
}
(2)修改页大小
将:
#define NAND_SECTOR_SIZE 512
改为:
#define NAND_SECTOR_SIZE 2048
(3)nand_read()
下图是K9F2G08的读流程图(截自K9F2G08手册):
由上图可见,读取数据的操作顺序为:发送0x00命令-->发送地址-->发送0x30命令-->...。
在参考资料[1]所提供的源码的nand_read()函数中只是发送了0x00命令,并没有发送地址之后再发送0x30命令,这里需要加上,如下所示:
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);
/* 新增:发出READ1命令 */
write_cmd(0x30);
wait_idle();
for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
*buf = read_data();
buf++;
}
}
/* 取消片选信号 */
nand_deselect_chip();
return ;
}
2.2 head.S
将:
mov r2, #1024
改为:
mov r2, #2048
3 编译&下载&运行&源码
经过上述修改后,可以编译然后下载到MIni2440中运行。Nand Flash启动,LED灯会跑起来。
修改后的源码可以点击这里下载。
4 补充说明
参考资料[2][3]提供了另外一种修改方式,最大的差异在于修改了系统时钟(本文方法使用默认时钟12MHz)。经过运行测试,可以顺利通过,只是LED灯闪得更快。
参考资料
[1]韦东山. 嵌入式Linux应用开发完全手册,人民邮电出版社,2012
[2]根据韦东山修改的mini2440 nand flash裸机程序