1、nand_flash的初始化
先找到芯片手册nand_flash控制器这一章,我用的是s3c2440的芯片找到的对应章节如下:
由上图可知需要设置TACLS、TWRPH0、TWRPH1,这些怎么设置呢?
需要看我们nand_flash控制器的时序图,如下图所示:
nand_flash用的时钟是HCLK,我设置的芯片时钟F、H、P分别为400MHZ、100MHZ、50MHZ,因此HCLK的一个周期为1/f=1s/(100MHZ)
可以得到周期T=10ns。
得到了nand_flash控制器的时序还不行,还需要得到nand_flash本身的时序图,找到所用nand_flash型号的手册,找到对应的时序:
这是nand的时序,nand_flash控制器必须按照上面的方式来发出信号才行,这上面没有什么限制,那么怎么才能确定发多少时间的数据呢?这就需要继续寻找nand各个周期的限制,如下图:
将twp、tcls等相关的设置与nand_flash控制器进行对应,可以得知
TACLS: 发出CLE/ALE之后多长时间才发出nWE信号,CLE/ALE与nWE可以同时发出,所以TACLS=0
TWRPH0: nWE的脉冲宽度, HCLK x ( TWRPH0 + 1 ), 它要>=12ns, 所以TWRPH0>=1
TWRPH1: nWE变为高电平后多长时间CLE/ALE才能变为低电平, 它要>=5ns, 所以TWRPH1>=0
现在可以写代码了
/* 先将要用到的寄存器定义出来 */
#define NFCONF (*((volatile unsigned long *)0x4E000000))
#define NFCONT (*((volatile unsigned long *)0x4E000004))
#define NFCMMD (*((volatile unsigned char *)0x4E000008))
#define NFADDR (*((volatile unsigned char *)0x4E00000C))
#define NFDATA (*((volatile unsigned char *)0x4E000010))
#define NFSTAT (*((volatile unsigned char *)0x4E000020))
/* 定义TACLS、TWRPH0、TWRPH1 */
#define TACLS 0
#define TWRPH0 0
#define TWRPH1 0
void nand_init(void)
{
/* 设置时序 */
NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
/* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */
NFCONT = (1<<4)|(1<<1)|(1<<0)