打印
[牛人杂谈]

外部总线接口 (EBI)怎么用

[复制链接]
5721|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
NuMicro M05xxBN/DN/DE 系列配备一个外部总线接口 (EBI) , 用来访问外部设备.
为节省外部设备与芯片的连接引脚数, EBI支持地址总线与数据总线复用模式. 且地址锁存使能 (ALE)信
号支持区分地址与数据周期.

[size=13.3333330154419px]其实其他系列也都有的。
外部总线接口有下列功能:
 支持外部设备最大64K字节 (8位数据宽度)/128K字节(16位数据宽度)
 外部总线基本时钟频率可调 (MCLK)
 支持8位或 16 位数据宽度
 数据访问时间 (tACC), 地址锁存使能时间(tALE) 和地址保持时间(tAHD) 可调
 支持地址总线和数据总线复用以节省地址管脚
 空闲周期可配置用于不同的访问条件: 写命令结束(W2X), 连续读(R2R)
 读/写操作支持0访问保持时间,写操作有写缓冲以增强读/写效率(M051xxDN/DE)

沙发
mintspring|  楼主 | 2016-7-10 15:48 | 只看该作者

我们可以看到EBI跟AHB bus直接的关系

使用特权

评论回复
板凳
mintspring|  楼主 | 2016-7-10 15:51 | 只看该作者
基本配置
EBI基本配置如下:
 EBI 设备时钟在 AHBCLK[3]中使能
 AD[15:0]引脚功能在 P0_MFP 和 P2_MFP 寄存器中配置; nRD、 nWR 和 MCLK 引脚功能在
P4_MFP 寄存器中配置; nWRL 和 nWRH 引脚在 P1_MFP 寄存器中配置

使用特权

评论回复
地板
mintspring|  楼主 | 2016-7-10 15:52 | 只看该作者
EBI 区域和地址命中
EBI地址映射在0x6000_0000 ~ 0x6001_FFFF , 最大存储器空间为128K字节。 当系统请求的地址命中
EBI的存储空间时, 相应的EBI片选信号(nCS)有效, EBI状态机开始工作.
对于8位设备(64Kbyte), EBI把该64K字节的设备同时映射到地址0x6000_0000 ~ 0x6000_FFFF 和
0x6001_0000 ~ 0x6001_FFFF.
对于16位设备(128Kbyte), EBI把该128K字节的设备映射到地址0x6000_0000 ~ 0x6001_FFFF
EBI 数据宽度连接
EBI控制器支持地址总线和数据总线复用的设备。 对于地址总线与数据总线分开的外部设备,与设备的
连接需要额外的逻辑器件来锁存地址. 这种情况下, ALE需要连接到锁存设备(如74HC373) 以锁存地
址。 16位数据宽度引脚AD0 ~ AD15, 8位数据宽度引脚AD0 ~ AD7作为锁存设备的输入引脚,锁存设备
的输出引脚连到外部设备的Addr[15:0]。
对于16位设备, AD[15:0] 由地址线与16位数据线共享. 对于 8位设备, 仅AD[7:0] 由地址线与8位数据线
共享, AD [15:8]则只作为地址线直接与8位设备连接.





使用特权

评论回复
5
mintspring|  楼主 | 2016-7-10 15:53 | 只看该作者


当系统访问数据宽度大于EBI的数据宽度时(8-bit / 16 bit 数据宽度), EBI控制器通过多次执行EBI访问来
完成操作. 例如, 如果系统通过EBI设备请求32位数据, 如果EBI为8位数据宽度, EBI控制器将访问4次来
完成操作.



使用特权

评论回复
6
mintspring|  楼主 | 2016-7-10 15:54 | 只看该作者
EBI 操作控制
MCLK 控制
NuMicro™ M051 系列中, EBI工作时,通过MCLK同步所有EBI信号. 当芯片连接到工作频率较低的外部
设备时, MCLK 可以通过设置寄存器EBICON 中的MCLKDIV[2:0]分频,最小可达HCLK/32. 因此, EBI控
制器 可以适用于宽频率范围的EBI 设备。 如果 MCLK的频率等于HCLK, EBI 信号由MCLK的上升沿同
步, 其他情况下, EBI信号由MCLK的下降沿同步.

操作与访问时序控制
EBI开始访问时, 片选 (nCS)置低并等待一个MCLK时钟周期等待地址建立时间(tASU)以使地址稳定。然
后地址稳定后地址锁存使能信号ALE置高 并保持一段时间 (tALE) 以用于地址锁存。 地址锁存后, ALE
置低并等待一个MCLK 时钟周期等待地址锁存保持时间(tLHD) 和另一个MCLK 的周期 (tA2D)插在tLHD
后面 用于总线转换(地址到数据)。然后当读操作时nRD 拉低或写操作时nWR拉低。 在访问保持时间
tACC(用于读取输出稳定或者写完成)之后nRD和nWR被拉高。之后, EBI 信号保持数据访问保持时间
(tAHD),然后片选信号置高, 地址由当前访问控制释放.
EBI控制器提供如下表所示的灵活的EBI 时序控制以用于不同的外部设备. 在EBI 的时序控制中, tASU,
tLHD 和 tA2D固定为1个MCLK周期, tAHD 可以通过设置寄存器EXTIME的ExttAHD[2:0]在1~8 个MCLK
周期内调节, M05xxDN/DE中通过设定RAHD_OFF/WAHD_OFF位,读/写时tAHD可以为0个MCLK周
期; tACC可以通过设置寄存器EXTIME的ExttACC[4:0]在1~32 个MCLK周期内调节; tALE可以通过寄
存器EBICON的ExttALE[2:0]在1~8 个MCLK 周期内调节.



使用特权

评论回复
7
mintspring|  楼主 | 2016-7-10 15:55 | 只看该作者
那么到底什么是EBI呢,EBI就是外部总线接口,就是外挂内存用的,通过这个接口就可以弥补内部RAM的不足了。

使用特权

评论回复
8
mintspring|  楼主 | 2016-7-10 15:55 | 只看该作者
我们看个EBI挂SRAM的例子。
/**************************************************************************//**
* [url=home.php?mod=space&uid=288409]@file[/url]     main.c
* [url=home.php?mod=space&uid=895143]@version[/url]  V3.00
* $Revision: 2 $
* $Date: 14/01/28 11:44a $
* [url=home.php?mod=space&uid=247401]@brief[/url]    M051 Series EBI Driver Sample Code
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#include <stdio.h>
#include "M051Series.h"

#define PLLCON_SETTING      CLK_PLLCON_50MHz_HXT
#define PLL_CLOCK           50000000


extern void SRAM_BS616LV4017(void);


void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Enable IRC22M clock */
    CLK->PWRCON |= CLK_PWRCON_IRC22M_EN_Msk;

    /* Waiting for IRC22M clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_IRC22M_STB_Msk);

    /* Switch HCLK clock source to HIRC */
    CLK->CLKSEL0 = CLK_CLKSEL0_HCLK_S_HIRC;

    /* Set PLL to Power-down mode and PLL_STB bit in CLKSTATUS register will be cleared by hardware.*/
    CLK->PLLCON |= CLK_PLLCON_PD_Msk;

    /* Enable external 12MHz XTAL */
    CLK->PWRCON |= CLK_PWRCON_XTL12M_EN_Msk;

    /* Enable PLL and Set PLL frequency */
    CLK->PLLCON = CLK_PLLCON_50MHz_HXT;

    /* Waiting for clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk | CLK_CLKSTATUS_XTL12M_STB_Msk);

    /* Switch HCLK clock source to PLL, STCLK to HCLK/2 */
    CLK->CLKSEL0 = CLK_CLKSEL0_STCLK_S_HCLK_DIV2 | CLK_CLKSEL0_HCLK_S_PLL;

    /* Enable EBI clock */
    CLK->AHBCLK |= CLK_AHBCLK_EBI_EN_Msk;

    /* Enable UART clock */
    CLK->APBCLK = CLK_APBCLK_UART0_EN_Msk;

    /* UART clock source */
    CLK->CLKSEL1 = CLK_CLKSEL1_UART_S_PLL;

    /* Update System Core Clock */
    /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
    SystemCoreClockUpdate();

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Set P3 multi-function pins for UART0 RXD, TXD and EBI MCLK, nWR and nRD */
    SYS->P3_MFP = SYS_MFP_P30_RXD0 | SYS_MFP_P31_TXD0 | SYS_MFP_P33_MCLK | SYS_MFP_P36_nWR | SYS_MFP_P37_nRD;

    /* Set P0 multi-function pins for EBI AD0 ~ AD7 */
    SYS->P0_MFP = SYS_MFP_P00_AD0 | SYS_MFP_P01_AD1 | SYS_MFP_P02_AD2 | SYS_MFP_P03_AD3 |
                  SYS_MFP_P04_AD4 | SYS_MFP_P05_AD5 | SYS_MFP_P06_AD6 | SYS_MFP_P07_AD7;

    /* Set P2 multi-function pins for EBI AD8 ~ AD15 */
    SYS->P2_MFP = SYS_MFP_P20_AD8 | SYS_MFP_P21_AD9 | SYS_MFP_P22_AD10 | SYS_MFP_P23_AD11 |
                  SYS_MFP_P24_AD12 | SYS_MFP_P25_AD13 | SYS_MFP_P26_AD14 | SYS_MFP_P27_AD15;

    /* Set P1 multi-function pins for EBI nWRL and nWRH */
    SYS->P1_MFP = SYS_MFP_P10_nWRL | SYS_MFP_P11_nWRH;

    /* Set P4 multi-function pins for EBI nCS, ALE and ICE CLK and DAT */
    SYS->P4_MFP = SYS_MFP_P44_nCS | SYS_MFP_P45_ALE | SYS_MFP_P46_ICE_CLK | SYS_MFP_P47_ICE_DAT;
}

void UART0_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset IP */
    SYS_ResetModule(UART0_RST);

    /* Configure UART0 and set UART0 Baudrate */
    UART_Open(UART0, 115200);
}

/*---------------------------------------------------------------------------------------------------------*/
/* MAIN function                                                                                           */
/*---------------------------------------------------------------------------------------------------------*/
int main(void)
{
    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, peripheral clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 for printf */
    UART0_Init();

    printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %d Hz\n", SystemCoreClock);
    printf("+----------------------------+\n");
    printf("|    EBI SRAM Sample Code    |\n");
    printf("+----------------------------+\n\n");

    printf("***************************************************************************\n");
    printf("* Please connect BS616LV4017 to M051 Series EBI bus before EBI testing !! *\n");
    printf("***************************************************************************\n\n");

    /* Enable EBI function and bus width to 16-bit */
    EBI_Open(0, EBI_BUSWIDTH_16BIT, EBI_TIMING_NORMAL, 0, 0);

    /* Start SRAM test */
    SRAM_BS616LV4017();

    /* Disable EBI function */
    EBI_Close(0);

    /* Disable EBI clock */
    CLK->AHBCLK &= ~CLK_AHBCLK_EBI_EN_Msk;

    printf("*** SRAM Test OK ***\n");

    while(1);
}

/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/


使用特权

评论回复
9
mintspring|  楼主 | 2016-7-10 15:58 | 只看该作者
我们按顺序看,先看SYS_UnlockRge();
    /* Enable EBI clock */
    CLK->AHBCLK |= CLK_AHBCLK_EBI_EN_Msk;

/* Set P0 multi-function pins for EBI AD0 ~ AD7 */
    SYS->P0_MFP = SYS_MFP_P00_AD0 | SYS_MFP_P01_AD1 | SYS_MFP_P02_AD2 | SYS_MFP_P03_AD3 |
                  SYS_MFP_P04_AD4 | SYS_MFP_P05_AD5 | SYS_MFP_P06_AD6 | SYS_MFP_P07_AD7;

    /* Set P2 multi-function pins for EBI AD8 ~ AD15 */
    SYS->P2_MFP = SYS_MFP_P20_AD8 | SYS_MFP_P21_AD9 | SYS_MFP_P22_AD10 | SYS_MFP_P23_AD11 |
                  SYS_MFP_P24_AD12 | SYS_MFP_P25_AD13 | SYS_MFP_P26_AD14 | SYS_MFP_P27_AD15;

    /* Set P1 multi-function pins for EBI nWRL and nWRH */
    SYS->P1_MFP = SYS_MFP_P10_nWRL | SYS_MFP_P11_nWRH;

    /* Set P4 multi-function pins for EBI nCS, ALE and ICE CLK and DAT */
    SYS->P4_MFP = SYS_MFP_P44_nCS | SYS_MFP_P45_ALE | SYS_MFP_P46_ICE_CLK | SYS_MFP_P47_ICE_DAT;
跟前面的描素是一样的,说是时钟在AHB,然后是配置使用那些端口的模式。


使用特权

评论回复
10
mintspring|  楼主 | 2016-7-10 16:02 | 只看该作者
配置完后,后面就简单多了。

    /* Enable EBI function and bus width to 16-bit */
    EBI_Open(0, EBI_BUSWIDTH_16BIT, EBI_TIMING_NORMAL, 0, 0);
   /* Start SRAM test */
    SRAM_BS616LV4017();

    /* Disable EBI function */
    EBI_Close(0);

    /* Disable EBI clock */
    CLK->AHBCLK &= ~CLK_AHBCLK_EBI_EN_Msk;

我们看到打开后就可以测试了,最后关闭,关闭后还要关闭时钟,这样就彻底关闭该模块了
测试内容无非就是读和写
附在后面
/* Data Width : 16bits, Data Size : 128K  */
/* 1. One Byte Write                      */
/* 2. Half Word Write                     */
/* 3. One Word Write                      */
void SRAM_BS616LV4017(void)
{
    uint8_t  *pu8DevPtr;
    uint16_t *pu16DevPtr;
    uint32_t *pu32DevPtr;
    uint32_t u32WriteData;
    uint32_t u32Idx, u32DataIdx;
    uint32_t u32EBIsize;

    u32EBIsize = EBI_MAX_SIZE;
    printf("   >> Data Width use 16bits and Data Size is %dKB << \n", (u32EBIsize / 1024));

    /* One Byte Write */
    printf("[[ One Byte Write test ]]\n");
    u32DataIdx = 0;
    while(u32DataIdx < 5)
    {
        if(u32DataIdx < 4)
        {
            // Fixed data pattern
            // Write to SRAM
            u32Idx = 0;
            pu8DevPtr = (uint8_t *)EBI_BASE_ADDR;
            u32WriteData = g_au32DataArrary[u32DataIdx];
            printf("        All 0x%X Access ... ", (uint8_t)u32WriteData);
            while(u32Idx < u32EBIsize)
            {
                *pu8DevPtr++ = (uint8_t)(u32WriteData);
                u32Idx = u32Idx + 1;
            }
            // Read from SRAM and compare data
            SRAM_CompareFunction(u32DataIdx, u32EBIsize, 0, 0); // param3:0, Byte Write
            printf("PASS\n");
        }
        else
        {
            // Unfixed data pattern
            // Write to SRAM
            u32Idx = 0;
            u32WriteData = 0;
            pu8DevPtr = (uint8_t *)EBI_BASE_ADDR;
            printf("        0x0, 0x1, 0x2, 0x3, 0x4 ... Access with offset(0x%X) ... ", (uint32_t)&u32Idx);
            while(u32Idx < u32EBIsize)
            {
                *pu8DevPtr++ = (uint8_t)(u32WriteData + (uint32_t)&u32Idx);
                u32Idx = u32Idx + 1;
                u32WriteData++;
            }
            SRAM_CompareFunction(u32DataIdx, u32EBIsize, (uint32_t)&u32Idx, 0); // param3:0, Byte Write
            printf("PASS\n\n");
        }
        u32DataIdx++;
    }

    /* Half Word Write */
    printf("[[ Half Word Write test]]\n");
    u32DataIdx = 0;
    while(u32DataIdx < 5)
    {
        if(u32DataIdx < 4)
        {
            // Fixed data pattern
            // Write to SRAM
            u32Idx = 0;
            pu16DevPtr = (uint16_t *)EBI_BASE_ADDR;
            u32WriteData = g_au32DataArrary[u32DataIdx];
            printf("        All 0x%X Access ... ", (uint16_t)u32WriteData);
            while(u32Idx < u32EBIsize)
            {
                *pu16DevPtr++ = (uint16_t)(u32WriteData);
                u32Idx = u32Idx + 2;
            }
            // Read from SRAM and compare data
            SRAM_CompareFunction(u32DataIdx, u32EBIsize, 0, 1); // param3:1, Half Word Write
            printf("PASS\n");
        }
        else
        {
            // Unfixed data pattern
            // Write to SRAM
            u32Idx = 0;
            u32WriteData = 0;
            pu16DevPtr = (uint16_t *)EBI_BASE_ADDR;
            printf("        0x0, 0x1, 0x2, 0x3, 0x4 ... Access with offset(0x%X) ... ", (uint32_t)&u32Idx);
            while(u32Idx < u32EBIsize)
            {
                *pu16DevPtr++ = (uint16_t)(u32WriteData + (uint32_t)&u32Idx);
                u32Idx = u32Idx + 2;
                u32WriteData++;
            }
            SRAM_CompareFunction(u32DataIdx, u32EBIsize, (uint32_t)&u32Idx, 1); // param3:1, Half Word Write
            printf("PASS\n\n");
        }
        u32DataIdx++;
    }

    /* One Word Write */
    printf("[[ One Word Write test ]]\n");
    u32DataIdx = 0;
    while(u32DataIdx < 5)
    {
        if(u32DataIdx < 4)
        {
            // Fixed data pattern
            // Write to SRAM
            u32Idx = 0;
            pu32DevPtr = (uint32_t *)EBI_BASE_ADDR;
            u32WriteData = g_au32DataArrary[u32DataIdx];
            printf("        All 0x%X Access ... ", (uint32_t)u32WriteData);
            while(u32Idx < u32EBIsize)
            {
                *pu32DevPtr++ = (uint32_t)(u32WriteData);
                u32Idx = u32Idx + 4;
            }
            // Read from SRAM and compare data
            SRAM_CompareFunction(u32DataIdx, u32EBIsize, 0, 2); // param3:2, Word Write
            printf("PASS\n");
        }
        else
        {
            // Unfixed data pattern
            // Write to SRAM
            u32Idx = 0;
            u32WriteData = 0;
            pu32DevPtr = (uint32_t *)EBI_BASE_ADDR;
            printf("        0x0, 0x1, 0x2, 0x3, 0x4 ... Access with offset(0x%X) ... ", (uint32_t)&u32Idx);
            while(u32Idx < u32EBIsize)
            {
                *pu32DevPtr++ = (uint32_t)(u32WriteData + (uint32_t)&u32Idx);
                u32Idx = u32Idx + 4;
                u32WriteData++;
            }
            SRAM_CompareFunction(u32DataIdx, u32EBIsize, (uint32_t)&u32Idx, 2); // param3:2, Word Write
            printf("PASS\n\n");
        }
        u32DataIdx++;
    }
}


使用特权

评论回复
11
gaoyang9992006| | 2016-7-11 16:28 | 只看该作者
官方的例程其实还有8bit接口的操作。
/**************************************************************************//**
* [url=home.php?mod=space&uid=288409]@file[/url]     main.c
* [url=home.php?mod=space&uid=895143]@version[/url]  V3.00
* $Revision: 4 $
* $Date: 15/05/22 2:26p $
* [url=home.php?mod=space&uid=247401]@brief[/url]    Configure EBI interface to access W39L040P (NOR Flash) on EBI interface.
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#include <stdio.h>
#include "M051Series.h"
#include "ebi_nor.h"

#define PLLCON_SETTING      CLK_PLLCON_50MHz_HXT
#define PLL_CLOCK           50000000


/*---------------------------------------------------------------------------------------------------------*/
/* Program Continue Data to NOR Flash                                                                      */
/*---------------------------------------------------------------------------------------------------------*/
uint8_t ProgramContinueDataTest(void)
{
    uint8_t u8DataIn, u8DataOut;
    uint32_t u32NORAddr;

    printf("    >> Start to program flash ... \n");

    /* Write */
    for(u32NORAddr = 0; u32NORAddr < EBI_MAX_SIZE; u32NORAddr++)
    {
        u8DataIn = (u32NORAddr % 256) + u32NORAddr;
        if(NOR_WriteData(u32NORAddr, u8DataIn) == FALSE)
        {
            printf("Program [0x%05X]:[0x%02X] FAIL !!! \n\n", u32NORAddr, u8DataIn);
            return FALSE;
        }
    }

    /* Read */
    for(u32NORAddr = 0; u32NORAddr < EBI_MAX_SIZE; u32NORAddr++)
    {
        u8DataIn = (u32NORAddr % 256) + u32NORAddr;
        u8DataOut = NOR_ReadData(u32NORAddr);
        if(u8DataOut != u8DataIn)
        {
            printf("Read [0x%05X]:[0x%02X] FAIL !!! (Got [0x%02X]) \n\n", u32NORAddr, u8DataIn, u8DataOut);
            printf("Program flash FAIL !!! \n\n");
            return FALSE;
        }
    }
    printf("    >> Continue Data Program OK !!! \n\n");

    return TRUE;
}

void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Enable IRC22M clock */
    CLK->PWRCON |= CLK_PWRCON_IRC22M_EN_Msk;

    /* Waiting for IRC22M clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_IRC22M_STB_Msk);

    /* Switch HCLK clock source to HIRC */
    CLK->CLKSEL0 = CLK_CLKSEL0_HCLK_S_HIRC;

    /* Set PLL to Power-down mode and PLL_STB bit in CLKSTATUS register will be cleared by hardware.*/
    CLK->PLLCON |= CLK_PLLCON_PD_Msk;

    /* Enable external 12MHz XTAL */
    CLK->PWRCON |= CLK_PWRCON_XTL12M_EN_Msk;

    /* Enable PLL and Set PLL frequency */
    CLK->PLLCON = PLLCON_SETTING;

    /* Waiting for clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk | CLK_CLKSTATUS_XTL12M_STB_Msk);

    /* Switch HCLK clock source to PLL, STCLK to HCLK/2 */
    CLK->CLKSEL0 = CLK_CLKSEL0_STCLK_S_HCLK_DIV2 | CLK_CLKSEL0_HCLK_S_PLL;

    /* Enable EBI clock */
    CLK->AHBCLK |= CLK_AHBCLK_EBI_EN_Msk;

    /* Enable UART clock */
    CLK->APBCLK = CLK_APBCLK_UART0_EN_Msk;

    /* UART clock source */
    CLK->CLKSEL1 = CLK_CLKSEL1_UART_S_PLL;

    /* Update System Core Clock */
    /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
    SystemCoreClockUpdate();

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Set P3 multi-function pins for UART0 RXD, TXD and EBI MCLK, nWR and nRD */
    SYS->P3_MFP = SYS_MFP_P30_RXD0 | SYS_MFP_P31_TXD0 | SYS_MFP_P33_MCLK | SYS_MFP_P36_nWR | SYS_MFP_P37_nRD;

    /* Set P0 multi-function pins for EBI AD0 ~ AD7 */
    SYS->P0_MFP = SYS_MFP_P00_AD0 | SYS_MFP_P01_AD1 | SYS_MFP_P02_AD2 | SYS_MFP_P03_AD3 |
                  SYS_MFP_P04_AD4 | SYS_MFP_P05_AD5 | SYS_MFP_P06_AD6 | SYS_MFP_P07_AD7;

    /* Set P2 multi-function pins for EBI AD8 ~ AD15 */
    SYS->P2_MFP = SYS_MFP_P20_AD8 | SYS_MFP_P21_AD9 | SYS_MFP_P22_AD10 | SYS_MFP_P23_AD11 |
                  SYS_MFP_P24_AD12 | SYS_MFP_P25_AD13 | SYS_MFP_P26_AD14 | SYS_MFP_P27_AD15;

    /* Set P1 multi-function pins for EBI nWRL and nWRH */
    SYS->P1_MFP = SYS_MFP_P10_nWRL | SYS_MFP_P11_nWRH;

    /* Set P4 multi-function pins for EBI nCS, ALE and ICE CLK and DAT */
    SYS->P4_MFP = SYS_MFP_P44_nCS | SYS_MFP_P45_ALE | SYS_MFP_P46_ICE_CLK | SYS_MFP_P47_ICE_DAT;
}

void UART0_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset IP */
    SYS_ResetModule(UART0_RST);

    /* Configure UART0 and set UART0 Baudrate */
    UART_Open(UART0, 115200);
}

/*---------------------------------------------------------------------------------------------------------*/
/* MAIN function                                                                                           */
/*---------------------------------------------------------------------------------------------------------*/
int main(void)
{
    uint32_t u32i;
    uint32_t u32NORIDInfo;
    uint8_t u8ReadOutData;

    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, peripheral clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 for printf */
    UART0_Init();

    printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %d Hz\n", SystemCoreClock);
    printf("+---------------------------------+\n");
    printf("|    EBI NOR Flash Sample Code    |\n");
    printf("+---------------------------------+\n\n");

    printf("************************************************************************\n");
    printf("* Please connect W39L040P to M051 Series EBI bus before EBI testing !! *\n");
    printf("************************************************************************\n\n");

    /* Enable EBI function and bus width to 8-bit */
    EBI_Open(0, EBI_BUSWIDTH_8BIT, EBI_TIMING_NORMAL, 0, 0);

    /* Initial NOR flash and check ID */
    NOR_Init();
    u32NORIDInfo = NOR_GetID();
    if(u32NORIDInfo == 0xDAB6)
    {
        printf("NOR W39L040P initial OK ! Manufacture ID:0x%X, Device ID:0x%X.\n", (u32NORIDInfo >> 8), (u32NORIDInfo & 0xFF));
    }
    else
    {
        printf("NOR W39L040P initial fail ! (ID:0x%X)\n\n", u32NORIDInfo);
        while(1);
    }

    /* Erase flash */
    NOR_Erase();
    for(u32i = 0; u32i < EBI_MAX_SIZE; u32i++)
    {
        u8ReadOutData = NOR_ReadData(u32i);
        if(u8ReadOutData != 0xFF)
        {
            printf("    >> Chip Erase Fail !! Addr:0x%X, Data:0x%X.\n\n", u32i, u8ReadOutData);
            while(1);
        }
    }
    printf("    >> Chip Erase OK !!!\n");

    /* Start to program NOR flash test */
    ProgramContinueDataTest();

    /* Disable EBI function */
    EBI_Close(0);

    /* Disable EBI clock */
    CLK->AHBCLK &= ~CLK_AHBCLK_EBI_EN_Msk;

    printf("*** NOR Flash Test OK ***\n");

    while(1);
}

/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/


使用特权

评论回复
12
gaoyang9992006| | 2016-7-11 16:29 | 只看该作者
理解能力好的,可以参考手册的结构图配置,理解不好,直接复制对应的例程配置

使用特权

评论回复
13
Thethree| | 2016-7-12 21:26 | 只看该作者
这个EBI的访问速度有多快?

使用特权

评论回复
14
yiyigirl2014| | 2016-7-14 07:08 | 只看该作者
EBI地址映射在0x6000_0000 ~ 0x6001_FFFF , 最大存储器空间为128K字节。 当系统请求的地址命中
EBI的存储空间时, 相应的EBI片选信号(nCS)有效, EBI状态机开始工作.

使用特权

评论回复
15
yiyigirl2014| | 2016-7-14 07:09 | 只看该作者
Thethree 发表于 2016-7-12 21:26
这个EBI的访问速度有多快?

/* Enable EBI clock */
    CLK->AHBCLK |= CLK_AHBCLK_EBI_EN_Msk;
这貌似由这个EBI时钟控制吧

使用特权

评论回复
16
夏满竹| | 2020-3-29 13:20 | 只看该作者
mark

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

296

主题

4894

帖子

24

粉丝