zoukankan      html  css  js  c++  java
  • LPC1788的EMC驱动norflash

     Norflash型号为sst39vf32

     

    #ifndef __NORFLASH_H_

    #define __NORFLASH_H_

     

    #include "common.h"

    #include "delay.h"

    #include "debugserial.h"

     

    #define NOR_FLASH_BASE      0x80000000

    #define NOR_FLASH_SIZE      0x00100000

     

    #define GET_ADDR(addr)  (volatile uint16_t *)(NOR_FLASH_BASE | (addr<<1))

     

    #define SECTOR_SIZE     0x800   /* Must be 2048 words for 39VF160 */

    #define BLOCK_SIZE      0x8000  /* Must be 32K words for 39VF160  */

     

    #define SST_ID          0xBF    /* SST Manufacturer's ID code   */

    #define SST_39VF160     0x235D  /* SST 39VF160 device code      */

     

    #define PROGRAM_TIMEOUT 0x00008000

     

    //norflash 初始化必须在sram初始化之前

    void norflash_init(void);

     

    void norflash_erase(void);

     

    u32 norflash_check_id(void);

     

    u32 norflash_write_word(u32 add, u16 data);

     

    u32 norflash_toggle_bit_check(u32 addr,u16 data);

     

     

    #endif

     

     

     

     

     

     

     

     

     

    #include "norflash.h"

     

     

    static void norflash_io_init(void)

    {

        //a0-a22

        /* init EMC_A1 */

        LPC_IOCON->P4_1 = 0x21;

        /* init EMC_A2 */

        LPC_IOCON->P4_2 = 0x21;

        /* init EMC_A3 */

        LPC_IOCON->P4_3 = 0x21;

        /* init EMC_A4 */

        LPC_IOCON->P4_4 = 0x21;

        /* init EMC_A5 */

        LPC_IOCON->P4_5 = 0x21;

        /* init EMC_A6 */

        LPC_IOCON->P4_6 = 0x21;

        /* init EMC_A7 */

        LPC_IOCON->P4_7 = 0x21;

        /* init EMC_A8 */

        LPC_IOCON->P4_8 = 0x21;

        /* init EMC_A9 */

        LPC_IOCON->P4_9 = 0x21;

        /* init EMC_A10 */

        LPC_IOCON->P4_10 = 0x21;

        /* init EMC_A11 */

        LPC_IOCON->P4_11 = 0x21;

        /* init EMC_A12 */

        LPC_IOCON->P4_12 = 0x21;

        /* init EMC_A13 */

        LPC_IOCON->P4_13 = 0x21;

        /* init EMC_A14 */

        LPC_IOCON->P4_14 = 0x21;

        /* init EMC_A15 */

        LPC_IOCON->P4_15 = 0x21;

        /* init EMC_A16 */

        LPC_IOCON->P4_16 = 0x21;

        /* init EMC_A17 */

        LPC_IOCON->P4_17 = 0x21;

        /* init EMC_A18 */

        LPC_IOCON->P4_18 = 0x21;

        /* init EMC_A19 */

        LPC_IOCON->P4_19 = 0x21;

        /* init EMC_A20 */

        LPC_IOCON->P4_20 = 0x21;

        /* init EMC_A21 */

        LPC_IOCON->P4_21 = 0x21;

        /* init EMC_A22 */

        LPC_IOCON->P4_22 = 0x21;

       

        //d0-d15

        /* init EMC_D0 */

        LPC_IOCON->P3_0 = 0x21;

        /* init EMC_D1 */

        LPC_IOCON->P3_1 = 0x21;

        /* init EMC_D2 */

        LPC_IOCON->P3_2 = 0x21;

        /* init EMC_D3 */

        LPC_IOCON->P3_3 = 0x21;

        /* init EMC_D4 */

        LPC_IOCON->P3_4 = 0x21;

        /* init EMC_D5 */

        LPC_IOCON->P3_5 = 0x21;

        /* init EMC_D6 */

        LPC_IOCON->P3_6 = 0x21;

        /* init EMC_D7 */

        LPC_IOCON->P3_7 = 0x21;

        /* init EMC_D8 */

        LPC_IOCON->P3_8 = 0x21;

        /* init EMC_D9 */

        LPC_IOCON->P3_9 = 0x21;

        /* init EMC_D10 */

        LPC_IOCON->P3_10 = 0x21;

      /* init EMC_D11 */

        LPC_IOCON->P3_11 = 0x21;

        /* init EMC_D12 */

        LPC_IOCON->P3_12 = 0x21;

        /* init EMC_D13 */

        LPC_IOCON->P3_13 = 0x21;

        /* init EMC_D14 */

        LPC_IOCON->P3_14 = 0x21;

        /* init EMC_D15 */

        LPC_IOCON->P3_15 = 0x21;

       

        /* init EMC_WE */

        LPC_IOCON->P4_25 = 0x21;

        /* init EMC_oe */

        LPC_IOCON->P4_24 = 0x21;

        /* init EMC_cs0 */

        LPC_IOCON->P4_30 = 0x21;

       

       

    }

     

    void norflash_init(void)

    {

        LPC_SC->SCS |= (1<<0);//emc地址不移位

        //打开emc时钟与端口时钟

        LPC_SC->PCONP |= (1<<15)|(1<<11);//打开时钟

        LPC_SC->EMCDLYCTL = 0x00001010;//延时时间初始化

        LPC_EMC->Control  = 0x00000001;//emc使能

        LPC_EMC->Config  = 0x00000000;//emc配置清零,小端模式

       

        norflash_io_init();

        DelayMs(100);

     

        LPC_EMC->StaticConfig0 &= ~(3<<0);  //

        LPC_EMC->StaticConfig0 |= (1<<0);   //设置总线宽度16位

        LPC_EMC->StaticConfig0 |= (1<<7);   //设置读写有效电平,读为低电平

        LPC_EMC->StaticWaitWen0 &= ~(7<<0);

        LPC_EMC->StaticWaitWen0 |= (2<<0);//设置片选到写使能的延时时间

        LPC_EMC->StaticWaitOen0 &= ~(7<<0);

        LPC_EMC->StaticWaitOen0 |= (2<<0);//设置片选到输出使能的延时

        LPC_EMC->StaticWaitWr0 &= ~(0x1f<<0);

        LPC_EMC->StaticWaitWr0 |= (0x1f<<0);//设置片选到写入的延时

        LPC_EMC->StaticWaitPage0 &= ~(0x1f<<0);

        LPC_EMC->StaticWaitPage0 |= (0x1f<<0);//设置读模式顺序存取延时

        LPC_EMC->StaticWaitRd0 &= ~(0x1f<<0);

        LPC_EMC->StaticWaitRd0 |= (0x1f<<0);//设置片选到读取的延时

        LPC_EMC->StaticWaitTurn0 &= ~(0x1f<<0);

        LPC_EMC->StaticWaitTurn0 |= (0x1f<<0);//设置总线周转周期

       

        DelayMs(100);

       

    }

     

    void norflash_erase(void)

    {

        volatile uint16_t *ip;

     

        ip  = GET_ADDR(0x5555);

        *ip = 0x00AA;

        ip  = GET_ADDR(0x2AAA);

        *ip = 0x0055;

        ip  = GET_ADDR(0x5555);

        *ip = 0x0080;

        ip  = GET_ADDR(0x5555);

        *ip = 0x00AA;

        ip  = GET_ADDR(0x2AAA);

        *ip = 0x0055;

        ip  = GET_ADDR(0x5555);

        *ip = 0x0010;

        DelayMs(10);                /* Use timer 1 */

        return;

    }

     

    //检查nand id

    u32 norflash_check_id(void)

    {

        volatile uint16_t *ip;

        uint16_t SST_id1, SST_id2;

        /*  Issue the Software Product ID code to 39VF160   */

        ip  = GET_ADDR(0x5555);

        *ip = 0x00AA;

        ip  = GET_ADDR(0x2AAA);

        *ip = 0x0055;

        ip  = GET_ADDR(0x5555);

        *ip = 0x0090;

        DelayMs(10);

     

        /* Read the product ID from 39VF160 */

        ip  = GET_ADDR(0x0000);

        SST_id1 = *ip & 0x00FF;

        ip  = GET_ADDR(0x0001);

        SST_id2 = *ip;

     

        /* Issue the Soffware Product ID Exit code thus returning the 39VF160 */

        /* to the read operating mode */

        ip  = GET_ADDR(0x5555);

        *ip = 0x00AA;

        ip  = GET_ADDR(0x2AAA);

        *ip = 0x0055;

        ip  = GET_ADDR(0x5555);

        *ip = 0x00F0;

        DelayMs(10);

     

        /* Check ID */

        if ((SST_id1 == SST_ID) && (SST_id2 ==SST_39VF160))

        {

            return( 0 );

        }  

        else

        {

            printf("SST_id1 = %x ",SST_id1);

            printf("SST_id2 = %x ",SST_id2);

            return( 1 );

        }

           

    }

     

    //写入数据,只能16位写入

    u32 norflash_write_word(u32 add, u16 data)

    {

         volatile uint16_t *ip;

     

      ip  = GET_ADDR(0x5555);

      *ip = 0x00AA;

      ip  = GET_ADDR(0x2aaa);

      *ip = 0x0055;

      ip  = GET_ADDR(0x5555);

      *ip = 0x00A0;

     

      ip = GET_ADDR(add);       /* Program 16-bit word */

      *ip = data;

      return ( norflash_toggle_bit_check( add, data ) );

    }

     

    //数据写入检查

    u32 norflash_toggle_bit_check(u32 addr,u16 data)

    {

        volatile u16 *ip;

        u16 temp1, temp2;

        u32 TimeOut = PROGRAM_TIMEOUT;

     

        while( TimeOut > 0 )

        {

            ip = GET_ADDR(addr);

            temp1 = *ip;

            ip = GET_ADDR(addr);

            temp2 = *ip;

     

            if ( (temp1 == temp2) && (temp1 == data) )

            {

                return( 0 );

            }

            TimeOut--;

        }

        printf("temp1 = %x ",temp1);

        printf("temp2 = %x ",temp2);

        return ( 1 );

    }

  • 相关阅读:
    tab
    js大牛
    Codeforces 559B Equivalent Strings 等价串
    Java (JDK7)中的String常量和String.intern的实现
    js控制textarea输入字符串的个数,鼠标按下抬起推断输入字符数
    用LogParser分析Windows日志
    oracle 11g RAC手动卸载grid,no deinstall
    硬件的魅力
    精益敏捷外包开发--- 思维篇
    MFC中CFileDialog使用方法
  • 原文地址:https://www.cnblogs.com/dengxiaojun/p/4338704.html
Copyright © 2011-2022 走看看