自己写bootloader——mini2440(四、初始化NAND FLASH)

参考资料:https://blog.csdn.net/qqliyunpeng/article/details/51180276

程序框架

/*定义寄存器*/
#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))

/*nand读数据*/
void nand_read(unsigned int addr, unsigned char *buf, unsigned int len);
/*nand初始化*/
void nand_init(void)
{
/*设置时序*/
}
void nand_read(unsigned int addr, unsigned char *buf, unsigned int len)
{

}

1、NAND FLASH 控制器

Rnb:状态引脚

nFCE:

CLE:
ALE:

nFWE

nFRE:

LDATA0~LDAT7A:

扫描二维码关注公众号,回复: 1446677 查看本文章

芯片手册关于引脚的定义

 2、根据数据手册定义寄存器

/*定义寄存器*/
#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))

3、nand_init()设置正确的时序

  2440端:

 

nand芯片端:

 

NFCONF寄存器:

HCLK:100HZ  10ns

根据上面的时序图设置这三个参数:

TACLS:0

TWRPH0:1

TWRPH1:0

NFCONT寄存器:

MODE:1

Reg_nCE:1

initECC:1

代码

void nand_init(void)
{
    #define TACLS  0
    #define TWRPH0 1
    #define TWRPH1 0
    /*设置时序*/
    NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
    /* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */
    NFCONT = (1<<4)|(1<<1)|(1<<0);    
}

 4、void nand_read(unsigned int addr, unsigned char *buf, unsigned int len); 函数

读数据流程:

读数据流程:

根据上面的框图可以确定读数据的框架:

void nand_read(unsigned int addr, unsigned char *buf, unsigned int len)
{
    int col = addr % 2048;//确定是这一页的哪一个数据
    int i =0;

    /* 1. 选中 */
    nand_select();
    while(i < len)
    {
        /* 2. 发出读命令00h */ nand_cmd(0x00); /* 3. 发出地址(分5步发出) */ nand_addr(addr); /* 4. 发出地址(分5步发出) */ nand_addr(0x30); /* 5. 判断状态 */ nand_wait_ready(); for(;(col < 2048 && i < len); col++) { buf[i] = nand_data();//读数据的地址自动加1 i++; addr++; } col = 0; } }

 nand_cmd();函数

void nand_cmd(unsigned char cmd)
{    
    unsigned char i;
    NFCMMD = cmd;
    for(i = 0;i < 10; i++);
}
nand_addr();函数
void nand_addr(unsigned int addr)
{
    unsigned int col = addr % 2048;
    unsigned int page = addr / 2048;
    volatile int i;
    NFADDR = col & 0xff;
    for(i = 0;i < 10; i++); NFADDR = (col >> 8) & 0xff; for(i = 0;i < 10; i++); NFADDR = page & 0xff; for(i = 0;i < 10; i++); NFADDR = (page >> 8) & 0xff; for(i = 0;i < 10; i++); NFADDR = (page >> 16) & 0xff; for(i = 0;i < 10; i++); }
nand_data();函数
void nand_data(void)
{
    return NFDATA;
}

 isBootFromNorFlash();函数

int isBootFromNorFlash(void)
{
    volatile int *p = (volatile int *)0;
    int val;

    val = *p;
    *p = 0x12345678;
    if (*p == 0x12345678)
    {
        /* 写成功, 是nand启动 */
        *p = val;
        return 0;
    }
    else
    {
        /* NOR不能像内存一样写 */
        return 1;
    }
}
 
 

猜你喜欢

转载自www.cnblogs.com/liuyuchun/p/9131552.html