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

Posted liuyuchun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自己写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:

技术分享图片

技术分享图片

芯片手册关于引脚的定义

技术分享图片

 

 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;
    }
}

 

 
 



以上是关于自己写bootloader——mini2440(初始化NAND FLASH)的主要内容,如果未能解决你的问题,请参考以下文章

[Mini2440 - 009] 如何获取最新的 U-Boot

简易bootloader重定位问题

[Mini2440 - 0xx] 第09课第1节 u-boot 分析之编译体验

u-boot学习:自己写bootloader

mini2440 使用uClibc编译静态程序

基于JZ2440开发板编写bootloader总结