新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > s3c2440 nand flash 的操作

        s3c2440 nand flash 的操作

        作者: 時間:2016-11-21 來源:網絡 收藏
        @******************************************************************************

        @ File:head.s
        @ 功能:設置SDRAM,將程序復制到SDRAM,然后跳到SDRAM繼續執行
        @******************************************************************************

        .text
        .global _start
        _start:
        @函數disable_watch_dog, memsetup, init_nand, nand_read_ll在init.c中定義
        ldr sp, =4096 @設置堆棧
        bl disable_watch_dog @關WATCH DOG
        bl memsetup @初始化SDRAM
        bl nand_init @初始化NAND Flash

        本文引用地址:http://www.104case.com/article/201611/319116.htm

        @將NAND Flash中地址4096開始的1024字節代碼(main.c編譯得到)復制到SDRAM中
        @nand_read_ll函數需要3個參數:
        ldr r0, =0x30000000 @1. 目標地址=0x30000000,這是SDRAM的起始地址
        mov r1, #4096 @2. 源地址 = 4096,連接的時候,main.c中的代碼都存在NAND Flash地址4096開始處
        mov r2, #1024 @3. 復制長度= 1024(bytes),對于本實驗的main.c,這是足夠了
        bl nand_read @調用C函數nand_read

        ldr sp, =0x34000000 @設置棧
        ldr lr, =halt_loop @設置返回地址
        ldr pc, =main @b指令和bl指令只能前后跳轉32M的范圍,所以這里使用向pc賦值的方法進行跳轉
        halt_loop:
        b halt_loop


        #define WTCON(*(volatile unsigned long *)0x53000000)


        #define MEM_CTL_BASE0x48000000

        void disable_watch_dog();
        void memsetup();


        void disable_watch_dog()
        {
        WTCON= 0;
        }


        void memsetup()
        {
        int i = 0;
        unsigned long *p = (unsigned long *)MEM_CTL_BASE;


        unsigned long const mem_cfg_val[]={ 0x22011110, //BWSCON
        0x00000700, //BANKCON0
        0x00000700, //BANKCON1
        0x00000700, //BANKCON2
        0x00000700, //BANKCON3
        0x00000700, //BANKCON4
        0x00000700, //BANKCON5
        0x00018005, //BANKCON6
        0x00018005, //BANKCON7
        0x008C07A3, //REFRESH
        0x000000B1, //BANKSIZE
        0x00000030, //MRSRB6
        0x00000030, //MRSRB7
        };

        for(; i < 13; i++)
        p[i] = mem_cfg_val[i];
        }

        nand.c

        #define GSTATUS1 (*(volatile unsigned int *)0x560000B0)
        #define BUSY 1

        typedef unsigned int S3C24X0_REG32;



        typedef struct {
        S3C24X0_REG32 NFCONF;
        S3C24X0_REG32 NFCMD;
        S3C24X0_REG32 NFADDR;
        S3C24X0_REG32 NFDATA;
        S3C24X0_REG32 NFSTAT;
        S3C24X0_REG32 NFECC;
        } S3C2410_NAND;


        typedef struct {
        S3C24X0_REG32 NFCONF;
        S3C24X0_REG32 NFCONT;
        S3C24X0_REG32 NFCMD;
        S3C24X0_REG32 NFADDR;
        S3C24X0_REG32 NFDATA;
        S3C24X0_REG32 NFMECCD0;
        S3C24X0_REG32 NFMECCD1;
        S3C24X0_REG32 NFSECCD;
        S3C24X0_REG32 NFSTAT;
        S3C24X0_REG32 NFESTAT0;
        S3C24X0_REG32 NFESTAT1;
        S3C24X0_REG32 NFMECC0;
        S3C24X0_REG32 NFMECC1;
        S3C24X0_REG32 NFSECC;
        S3C24X0_REG32 NFSBLK;
        S3C24X0_REG32 NFEBLK;
        } S3C2440_NAND;


        typedef struct {
        void (*nand_reset)(void);
        void (*wait_idle)(void);
        void (*nand_select_chip)(void);
        void (*nand_deselect_chip)(void);
        void (*write_cmd)(int cmd);
        void (*write_addr)(unsigned int addr);
        unsigned char (*read_data)(void);
        }t_nand_chip;

        static S3C2410_NAND * s3c2410nand = (S3C2410_NAND *)0x4e000000;
        static S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;

        static t_nand_chip nand_chip;


        void nand_init(void);
        void nand_read(unsigned char *buf, unsigned long start_addr, int size);


        static void nand_reset(void);
        static void wait_idle(void);
        static void nand_select_chip(void);
        static void nand_deselect_chip(void);
        static void write_cmd(int cmd);
        static void write_addr(unsigned int addr);
        static unsigned char read_data(void);


        static void s3c2410_nand_reset(void);
        static void s3c2410_wait_idle(void);
        static void s3c2410_nand_select_chip(void);
        static void s3c2410_nand_deselect_chip(void);
        static void s3c2410_write_cmd(int cmd);
        static void s3c2410_write_addr(unsigned int addr);
        static unsigned char s3c2410_read_data();


        static void s3c2440_nand_reset(void);
        static void s3c2440_wait_idle(void);
        static void s3c2440_nand_select_chip(void);
        static void s3c2440_nand_deselect_chip(void);
        static void s3c2440_write_cmd(int cmd);
        static void s3c2440_write_addr(unsigned int addr);
        static unsigned char s3c2440_read_data(void);


        static void s3c2410_nand_reset(void)
        {
        s3c2410_nand_select_chip();
        s3c2410_write_cmd(0xff); // 復位命令
        s3c2410_wait_idle();
        s3c2410_nand_deselect_chip();
        }


        static void s3c2410_wait_idle(void)
        {
        int i;
        volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFSTAT;
        while(!(*p & BUSY))
        for(i=0; i<10; i++);
        }


        static void s3c2410_nand_select_chip(void)
        {
        int i;
        s3c2410nand->NFCONF &= ~(1<<11);
        for(i=0; i<10; i++);
        }


        static void s3c2410_nand_deselect_chip(void)
        {
        s3c2410nand->NFCONF |= (1<<11);
        }


        static void s3c2410_write_cmd(int cmd)
        {
        volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFCMD;
        *p = cmd;
        }


        static void s3c2410_write_addr(unsigned int addr)
        {
        int i;
        volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFADDR;

        *p = addr & 0xff;
        for(i=0; i<10; i++);
        *p = (addr >> 9) & 0xff;
        for(i=0; i<10; i++);
        *p = (addr >> 17) & 0xff;
        for(i=0; i<10; i++);
        *p = (addr >> 25) & 0xff;
        for(i=0; i<10; i++);
        }


        static unsigned char s3c2410_read_data(void)
        {
        volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFDATA;
        return *p;
        }


        static void s3c2440_nand_reset(void)
        {
        s3c2440_nand_select_chip();
        s3c2440_write_cmd(0xff); // 復位命令
        s3c2440_wait_idle();
        s3c2440_nand_deselect_chip();
        }


        static void s3c2440_wait_idle(void)
        {
        int i;
        volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFSTAT;
        while(!(*p & BUSY))
        for(i=0; i<10; i++);
        }


        static void s3c2440_nand_select_chip(void)
        {
        int i;
        s3c2440nand->NFCONT &= ~(1<<1);
        for(i=0; i<10; i++);
        }


        static void s3c2440_nand_deselect_chip(void)
        {
        s3c2440nand->NFCONT |= (1<<1);
        }


        static void s3c2440_write_cmd(int cmd)
        {
        volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFCMD;
        *p = cmd;
        }


        static void s3c2440_write_addr(unsigned int addr)
        {
        int i;
        volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;

        *p = addr & 0xff;
        for(i=0; i<10; i++);
        *p = (addr >> 9) & 0xff;
        for(i=0; i<10; i++);
        *p = (addr >> 17) & 0xff;
        for(i=0; i<10; i++);
        *p = (addr >> 25) & 0xff;
        for(i=0; i<10; i++);
        }


        static unsigned char s3c2440_read_data(void)
        {
        volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFDATA;
        return *p;
        }



        static void nand_reset(void)
        {
        nand_chip.nand_reset();
        }

        static void wait_idle(void)
        {
        nand_chip.wait_idle();
        }

        static void nand_select_chip(void)
        {
        int i;
        nand_chip.nand_select_chip();
        for(i=0; i<10; i++);
        }

        static void nand_deselect_chip(void)
        {
        nand_chip.nand_deselect_chip();
        }

        static void write_cmd(int cmd)
        {
        nand_chip.write_cmd(cmd);
        }
        static void write_addr(unsigned int addr)
        {
        nand_chip.write_addr(addr);
        }

        static unsigned char read_data(void)
        {
        return nand_chip.read_data();
        }



        void nand_init(void)
        {
        #define TACLS 0
        #define TWRPH0 3
        #define TWRPH1 0


        if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))
        {
        nand_chip.nand_reset = s3c2410_nand_reset;
        nand_chip.wait_idle = s3c2410_wait_idle;
        nand_chip.nand_select_chip = s3c2410_nand_select_chip;
        nand_chip.nand_deselect_chip = s3c2410_nand_deselect_chip;
        nand_chip.write_cmd = s3c2410_write_cmd;
        nand_chip.write_addr = s3c2410_write_addr;
        nand_chip.read_data = s3c2410_read_data;


        s3c2410nand->NFCONF = (1<<15)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
        }
        else
        {
        nand_chip.nand_reset = s3c2440_nand_reset;
        nand_chip.wait_idle = s3c2440_wait_idle;
        nand_chip.nand_select_chip = s3c2440_nand_select_chip;
        nand_chip.nand_deselect_chip = s3c2440_nand_deselect_chip;
        nand_chip.write_cmd = s3c2440_write_cmd;
        nand_chip.write_addr = s3c2440_write_addr;
        nand_chip.read_data = s3c2440_read_data;


        s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);

        s3c2440nand->NFCONT = (1<<4)|(1<<1)|(1<<0);
        }


        nand_reset();
        }


        #define NAND_SECTOR_SIZE 512
        #define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)


        void nand_read(unsigned char *buf, unsigned long start_addr, int size)
        {
        int i, j;

        if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
        return ;
        }


        nand_select_chip();

        for(i=start_addr; i < (start_addr + size);) {

        write_cmd(0);


        write_addr(i);
        wait_idle();

        for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
        *buf = read_data();
        buf++;
        }
        }


        nand_deselect_chip();

        return ;
        }

        main 函數
        #defineGPBCON(*(volatile unsigned long *)0x56000010)
        #defineGPBDAT(*(volatile unsigned long *)0x56000014)

        #defineGPB5_out(1<<(5*2))
        #defineGPB6_out(1<<(6*2))
        #defineGPB7_out(1<<(7*2))
        #defineGPB8_out(1<<(8*2))

        void wait(unsigned long dly)
        {
        for(; dly > 0; dly--);
        }

        int main(void)
        {
        unsigned long i = 0;

        GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out;// 將LED1-4對應的GPB5/6/7/8四個引腳設為輸出

        while(1){
        wait(30000);
        GPBDAT = (~(i<<5)); // 根據i的值,點亮LED1-4
        if(++i == 16)
        i = 0;
        }

        return 0;
        }



        關鍵詞: nandflashs3c244

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 郁南县| 聂荣县| 饶阳县| 郴州市| 江孜县| 灵石县| 龙里县| 武川县| 宜章县| 兴业县| 呼玛县| 洞头县| 竹山县| 保康县| 英山县| 清远市| 望城县| 鄯善县| 涿鹿县| 贵南县| 灵山县| 鹤山市| 梅河口市| 京山县| 石景山区| 乌兰察布市| 定远县| 托克逊县| 麟游县| 郁南县| 博野县| 织金县| 杭锦后旗| 子长县| 沁水县| 红安县| 米易县| 海淀区| 乌兰察布市| 濮阳县| 罗源县|