软件版本:练习程序
例程路径:F:\code\004
硬件平台:JZ2440(S3C2440)
问题1:编写调试了NAND的读程序,可以正常读取数据,写入和擦除操作一直没起作用。检查代码没有发现与例程有大出入,换成例程的NAND_INIT程序后就可以正常写入和擦除。下面是例程代码:
void nand_init(void)
{
#define TACLS 0
#define TWRPH0 1
#define TWRPH1 0
/*设置NAND FLASH的时序*/
NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);
/*使能NAND FLASH控制器,初始化ECC,禁止片选*/
NFCONT = (1<<4) | (1<<1) | (1<<0);
}
下面是我的代码:
void nand_init(void)
{
//initial register
NFCONF &= ~( (3<<12)|(3<<8)|(3<<4) );
NFCONF |= (0<<12)|(1<<8)|(0<<4);
NFCONT &= ~((1<<0)|(1<<1)|(1<<4)|(1<<12) );//00000060
NFCONT |= (1<<0)|(1<<1)|(1<<4); //00000063
printf("%08x\r\n",NFCONT);
//reset
nand_select();
NFCMD = 0xff;
wait_ready();//wait for nand ready
nand_deselect();
}
检查发现NFCONT 寄存器有差异,特别是第12位,如下图
此处没有清零导致NAND不能写和擦除,修改后程序运行正常
问题2:读和写函数添加跳过坏块代码后,读数据错误,写失败
问题定位,调试代码发现只要执行坏块检测代码即不能正常读写
调试发现是读写时序要求造成的,按上图将片选指令调整到箭头位置,就能正常读写。因为坏块检测程序内部先片选再取消片选,最后读指令执行时并没有片选导致读写失败
3:NAND启动代码重定位失败分析
重定位代码只有2行
extern int _code_start,_bss_start;
volatile unsigned int * code_start=(volatile unsigned int *)(&_code_start);
volatile unsigned int * code_end=(volatile unsigned int *)(&_bss_start);
nand_init();
nand_read((unsigned int)src, (unsigned char*)code_start, (unsigned int)(code_end- code_start) );
测试发现是(unsigned int)(code_end- code_start)问题,真是愚蠢,int指针按4步进,nand_read函数第三个参数
要求是读取字节数。改成
(unsigned int)(&_bss_start) - (unsigned int)(&_code_start)后NAND启动运行成功