1. 程式人生 > >自己寫bootloader——mini2440(四、初始化NAND FLASH)

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

nbsp AI fadd lec 內存 hcl orf ready 自己

參考資料: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)