硬件:
SOC: SAMSUNG三星S3C2440A
NAND FLASH: K9F2G08U0C
在裸板编程驱动NAND FLASH时对nand flash的数据读取一切正常,但是在擦除(已确认是块的起始地址)的时候怎么都不成功,但是用别人的代码能够成功,我怀疑我的代码有错误,然后反复比对我的擦除代码,甚至直接复制采用别人成功的擦除代码到我的工程,但是依然失败,这就很奇怪了。后来我想起来的nand flash控制器的初始化代码和别人成功案例的代码有点不一样。我将别人成功案例替换到我的工程里面,这时候能够成功擦除了。
分析对比了一下我的nand 控制器初始化代码个别人成功案例的初始化代码:
我的代码:
/*设置nand_flash控制器的时序*/
NFCONF &= ~(3<<12); /*清位*/
NFCONF |= ((1<<8)|(0<<4)); /*设置时序*/
/*使能nand_flash*/
NFCONT |= ((1<<0) | (1<<1) | (1<<4)); /*使能nand_flash控制器、关闭片选使能、初始化ECC*/
别人成功案例代码:
#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);
表面看上去似乎一样,但是仔细观察会发现我的代码是用的按位或,除了上面显示的那几位(NFCONT 寄存器的0位、1位、14位),寄存器上的其他寄存器位我是没有改动的,都是保持默认值的。而别人成功案例的代码是用的直接赋值而不是按位或,所以会把NFCONT 寄存器中除了操作了0位、1位、4位这三个位之外还对其他位全部清0;
到了这里我想肯定是这两个寄存器中的某个或某些位控制着擦除相关的功能,于是仔细查看S3C2440的NAND FLASH控制器中的NFCONT 寄存器和NFCONF 寄存器,问题终于被我找到了。
NFCONT 寄存器的第12位,如果该位置1会使NAND FLASH只能读不能擦除和写入,这位默认是为1。
在我的nand flash控制器初始化里我使这一位保持了默认,而别人成功案例的代码则使者位清了0。
解决办法,将这一位清0就行了,或者直接使用别人成功案例的代码。
我修改成功后的代码:
增加 NFCONT &= ~(1<<12); /Soft Lock Disable lock/
/*设置nand_flash控制器的时序*/
NFCONF &= ~(3<<12); /*清位*/
NFCONF |= ((1<<8)|(0<<4)); /*设置时序*/
NFCONT &= ~(1<<12); /*Soft Lock Disable lock*/
/*使能nand_flash*/
NFCONT |= ((1<<0) | (1<<1) | (1<<4)); /*使能nand_flash控制器、关闭片选使能、初始化ECC*/
。
这只是一个小细节,所以拿出来分享,以免一些小伙伴一直不知道是什么问题。
个人推荐再修改寄存器位的时候还是用按位或、按位与的方式,不要直接赋值,不然某些位可能不修改造成麻烦。