打印
[新唐博主]

M480 EBI SRAM驱动

[复制链接]
3741|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2021-10-1 18:31 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

M480 驱动SRAM非常容易,但是官方这个开发板有点坑,将最高3位地址线接了IO口,导致只能访问128KB的内存空间,原理图如下:


使用特权

评论回复
沙发
tpgf|  楼主 | 2021-10-1 18:32 | 只看该作者
上代码


/*************************************************************************************************************
* 文件名                :        m48x_ebi.c
* 功能                        :        m48X EBI驱动
* 作者                        :        cp1300@139.com
* 创建时间                :        2021-09-29
* 最后修改时间        :        2021-09-29
* 详细                        :        用于外部SRAM驱动
*************************************************************************************************************/
#include "m48x_map.h"
#include "system.h"
#include "m48x_ebi.h"

/*************************************************************************************************************************
* 函数                        :        void EBI_EnableWriteBuff(bool isEnable)
* 功能                        :        EBI总线写buff使能设置-全局设置
* 参数                        :        isEnable:是否使能
* 返回                        :        无
* 依赖                        :        底层
* 作者                        :        cp1300@139.com
* 时间                        :        2021-09-30
* 最后修改时间         :         2021-09-30
* 说明                        :        
*************************************************************************************************************************/
void EBI_EnableWriteBuff(bool isEnable)
{
    SYS_DeviceClockEnable(DEV_EBI, TRUE);               //使能EBI时钟
    if (isEnable)
    {
        EBI->CTL0 |= 1<<24; //使能
    }
    else
    {
        EBI->CTL0 &= ~(1 << 24);
    }
   
}

/*************************************************************************************************************************
* 函数                        :        void EBI_SetALE(u8 tALE)
* 功能                        :        EBI总线地址锁存周期设置-全局设置
* 参数                        :        tALE:地址锁存周期,0-7
* 返回                        :        无
* 依赖                        :        底层
* 作者                        :        cp1300@139.com
* 时间                        :        2021-09-30
* 最后修改时间         :         2021-09-30
* 说明                        :
*************************************************************************************************************************/
void EBI_SetALE(u8 tALE)
{
    SYS_DeviceClockEnable(DEV_EBI, TRUE);               //使能EBI时钟
    EBI->CTL0 &= ~(7 << 16);
    EBI->CTL0 |= (u32)(tALE & 0x07) << 16;
}


/*************************************************************************************************************************
* 函数                        :        void EBI_Enable(EBI_CH ch, bool isEnable)
* 功能                        :        EBI总线使能
* 参数                        :        ch:EBI通道0-2;isEnable:是否使能
* 返回                        :        无
* 依赖                        :        底层
* 作者                        :        cp1300@139.com
* 时间                        :        2021-09-30
* 最后修改时间         :         2021-09-30
* 说明                        :
*************************************************************************************************************************/
void EBI_Enable(EBI_CH ch, bool isEnable)
{
    SYS_DeviceClockEnable(DEV_EBI, TRUE);               //使能EBI时钟
        switch (ch)
        {
                case EBI_CH0:
                {
            if (isEnable)
            {
                EBI->CTL0 |= (1 << 0);
            }
            else
            {
                EBI->CTL0 &= ~(1 << 0);
            }
                }break;
                case EBI_CH1:
                {
                        if (isEnable)
                        {
                                EBI->CTL1 |= (1 << 0);
                        }
                        else
                        {
                                EBI->CTL1 &= ~(1 << 0);
                        }
                }break;
                case EBI_CH2:
                {
                        if (isEnable)
                        {
                                EBI->CTL2 |= (1 << 0);
                        }
                        else
                        {
                                EBI->CTL2 &= ~(1 << 0);
                        }
                }break;
                default:break;
        }
}

/*************************************************************************************************************************
* 函数                        :        void EBI_Config(EBI_CH ch, const EBI_CONFIG* pConfig)
* 功能                        :        EBI总线配置(配置完后会自动使能EBI)
* 参数                        :        ch:EBI通道0-2;pConfig:配置结构体
* 返回                        :        无
* 依赖                        :        底层
* 作者                        :        cp1300@139.com
* 时间                        :        2021-09-30
* 最后修改时间         :         2021-09-30
* 说明                        :
*************************************************************************************************************************/
void EBI_Config(EBI_CH ch, const EBI_CONFIG* pConfig)
{
    u32 CTL = 0, TCTL = 0;

    CTL |= (u32)(pConfig->MCLKDIV & 0x07) << 8;    //外部输出时钟分频器
    CTL |= pConfig->isDataAccessEn ? (1 << 4) : 0;  //连续数据访问模式使能
    CTL |= pConfig->isAddDataSeparEn ? (1 << 3) : 0;//EBI地址/数据总线分离模式使能
    CTL |= pConfig->isCS_H_En ? (1 << 2) : 0;       //芯片选择引脚极性反转使能
    CTL |= pConfig->is16bitDataWidth ? (1 << 1) : 0;//16bit数据宽度使能
    TCTL |= (u32)(pConfig->ReadToReadIdle & 0xF) << 24;//读取间隔,插入空闲时间
    TCTL |= pConfig->isDisAccessWrite ? (1 << 23) : 0;//EBI写入期间的数据访问保持时间(tAHD)已禁用。
    TCTL |= pConfig->isDisAccessRead ? (1 << 22) : 0;//EBI读取期间的数据访问保持时间(tAHD)已禁用
    TCTL |= (u32)(pConfig->WriteToWriteIdle & 0xF) << 12;//写入间隔,插入空闲时间
    TCTL |= (u32)(pConfig->tAHD & 0x7) << 8;             //EBI数据访问保持时间
    TCTL |= (u32)(pConfig->tACC & 0x1F) << 3;             //EBI数据访问时间

    SYS_DeviceClockEnable(DEV_EBI, TRUE);               //使能EBI时钟
    EBI_Enable(ch, FALSE);                              //先关闭EBI
    switch(ch)
    {
        case EBI_CH0 :
        {
            CTL |= EBI->CTL0 & 0xFFFF0000;              //CTL0保留高16位设置
            EBI->CTL0 = CTL;
            EBI->TCTL0 = TCTL;
        }break;
        case EBI_CH1 :
        {
                        EBI->CTL1 = CTL;
                        EBI->TCTL1 = TCTL;
        }break;
        case EBI_CH2 :
        {
                        EBI->CTL2 = CTL;
                        EBI->TCTL2 = TCTL;
        }break;
        default:break;
    }

    EBI_Enable(ch, TRUE);                               //使能EBI
}

使用特权

评论回复
板凳
tpgf|  楼主 | 2021-10-1 18:32 | 只看该作者
/*************************************************************************************************************
* 文件名                :        m48x_ebi.h
* 功能                        :        m48X EBI驱动
* 作者                        :        cp1300@139.com
* 创建时间                :        2021-09-29
* 最后修改时间        :        2021-09-29
* 详细                        :        用于外部SRAM驱动
*************************************************************************************************************/
#ifndef _M48X_EBI_H_
#define _M48X_EBI_H_
#include "m48x_system.h"

//FLASH起始地址
#define M48X_EBI_RAM_BASE0                 0x60000000                 //EBI nCS0对应映射内存起始地址
#define M48X_EBI_RAM_BASE1                 0x60100000                 //EBI nCS1对应映射内存起始地址
#define M48X_EBI_RAM_BASE2                 0x60200000                 //EBI nCS2对应映射内存起始地址


//EBI控制器选择
typedef enum
{
        EBI_CH0 = 0,
        EBI_CH1 = 1,
        EBI_CH2 = 2,
}EBI_CH;

//MCLK分频设置(针对HCLK进行分频)
typedef enum
{
        EBI_MCLKDIV_1 = 0,  //HCLK/1
        EBI_MCLKDIV_2 = 1,  //HCLK/2
        EBI_MCLKDIV_4 = 2,  //HCLK/4
        EBI_MCLKDIV_8 = 3,  //HCLK/8
        EBI_MCLKDIV_16 = 4,  //HCLK/16
        EBI_MCLKDIV_32 = 5,  //HCLK/32
        EBI_MCLKDIV_64 = 6,  //HCLK/64
        EBI_MCLKDIV_128 = 7,  //HCLK/128
}EBI_MCLKDIV;


//EBI总线配置
typedef struct
{
        bool isDataAccessEn;    //连续访问模式使能
        bool isAddDataSeparEn;  //地址/数据总线分离模式使能
        bool isCS_H_En;         //片选高有效使能
        bool is16bitDataWidth;  //使能16bit数据宽度
        bool isDisAccessWrite;  //禁用EBI写入期间的数据访问保持时间(tAHD)
        bool isDisAccessRead;   //禁用EBI读取期间的数据访问保持时间(tAHD)
        u8 ReadToReadIdle;      //读取空闲时间,0-0xF
        u8 WriteToWriteIdle;    //写入数据空闲时间,0-15
        u8 tAHD;                //数据访问保持时间0-7 tAHD = (TAHD +1) * EBI_MCLK.
        u8 tACC;                //数据访问时间0-15 tACC = (TACC +1) * EBI_MCLK.
        EBI_MCLKDIV MCLKDIV;    //时钟分频设置
}EBI_CONFIG;


void EBI_EnableWriteBuff(bool isEnable);//EBI总线写buff使能设置-全局设置
void EBI_SetALE(u8 tALE);//EBI总线地址锁存周期设置-全局设置
void EBI_Enable(EBI_CH ch, bool isEnable);//EBI总线使能
void EBI_Config(EBI_CH ch, const EBI_CONFIG* pConfig);//EBI总线配置(配置完后会自动使能EBI)

#endif //_M48X_EBI_H_


使用特权

评论回复
地板
tpgf|  楼主 | 2021-10-1 18:32 | 只看该作者
/*************************************************************************************************************
* 文件名                :        m48x_sram.c
* 功能                        :        m48X 外部SRAM驱动
* 作者                        :        cp1300@139.com
* 创建时间                :        2021-09-30
* 最后修改时间        :        2021-09-30
* 详细                        :        用于外部SRAM驱动
*************************************************************************************************************/
#include "m48x_map.h"
#include "system.h"
#include "m48x_ebi.h"
#include "m48x_sram.h"

#define SRAM_EBI_CH                        EBI_CH1

//配置
static const EBI_CONFIG scg_SRAM_CONFIG =
{
        FALSE,    //连续访问模式不要开启
        FALSE,  //地址/数据总线分离模式使能
        FALSE,    //片选高有效使能
        TRUE,  //使能16bit数据宽度
        FALSE, //禁用EBI写入期间的数据访问保持时间(tAHD)
        FALSE,   //禁用EBI读取期间的数据访问保持时间(tAHD)
        3,      //读取空闲时间,0-0xF
        3,    //写入数据空闲时间,0-15
        3,               //数据访问保持时间0-7 tAHD = (TAHD +1) * EBI_MCLK.
        3,                //数据访问时间0-15 tACC = (TACC +1) * EBI_MCLK.
        EBI_MCLKDIV_2    //时钟分频设置
};


/*************************************************************************************************************************
* 函数                        :        static void EBI_SRAM_IO_Init(void)
* 功能                        :        外部SRAM所需IO初始化
* 参数                        :        无
* 返回                        :        无
* 依赖                        :        底层
* 作者                        :        cp1300@139.com
* 时间                        :        2021-09-30
* 最后修改时间         :         2021-09-30
* 说明                        :
*************************************************************************************************************************/
static void EBI_SRAM_IO_Init(void)
{
        //AD0-AD7
        SYS_GPIOx_SetAF(GPIO_PG9_EBI_AD0);
        SYS_GPIOx_SetAF(GPIO_PG10_EBI_AD1);
        SYS_GPIOx_SetAF(GPIO_PG11_EBI_AD2);
        SYS_GPIOx_SetAF(GPIO_PG12_EBI_AD3);
        SYS_GPIOx_SetAF(GPIO_PG13_EBI_AD4);
        SYS_GPIOx_SetAF(GPIO_PG14_EBI_AD5);
        SYS_GPIOx_SetAF(GPIO_PD8_EBI_AD6);
        SYS_GPIOx_SetAF(GPIO_PD9_EBI_AD7);
        //AD8-AD15
        SYS_GPIOx_SetAF(GPIO_PE14_EBI_AD8);
        SYS_GPIOx_SetAF(GPIO_PE15_EBI_AD9);
        SYS_GPIOx_SetAF(GPIO_PE1_EBI_AD10);
        SYS_GPIOx_SetAF(GPIO_PE0_EBI_AD11);
        SYS_GPIOx_SetAF(GPIO_PH8_EBI_AD12);
        SYS_GPIOx_SetAF(GPIO_PH9_EBI_AD13);
        SYS_GPIOx_SetAF(GPIO_PH10_EBI_AD14);
        SYS_GPIOx_SetAF(GPIO_PH11_EBI_AD15);
        //A16-A18

        //ALE,nCS1,nWR,nRD,nWRH,nWRL
        SYS_GPIOx_SetAF(GPIO_PA8_EBI_ALE);
        SYS_GPIOx_SetAF(GPIO_PD11_EBI_nCS1);
        SYS_GPIOx_SetAF(GPIO_PE4_EBI_nWR);
        SYS_GPIOx_SetAF(GPIO_PE5_EBI_nRD);
        SYS_GPIOx_SetAF(GPIO_PG8_EBI_nWRH);
        SYS_GPIOx_SetAF(GPIO_PG7_EBI_nWRL);

       
}

/*************************************************************************************************************************
* 函数                        :        bool EBI_SRAM_Init(void)
* 功能                        :        外部SRAM初始化
* 参数                        :        无
* 返回                        :        无
* 依赖                        :        底层
* 作者                        :        cp1300@139.com
* 时间                        :        2021-09-30
* 最后修改时间         :         2021-09-30
* 说明                        :
*************************************************************************************************************************/
bool EBI_SRAM_Init(void)
{
        EBI_SRAM_IO_Init();

        EBI_EnableWriteBuff(FALSE);//EBI总线写buff使能设置-全局设置
        EBI_SetALE(4);//EBI总线地址锁存周期设置-全局设置
        EBI_Config(SRAM_EBI_CH, &scg_SRAM_CONFIG);//EBI总线配置(配置完后会自动使能EBI)

        return TRUE;
}

使用特权

评论回复
5
tpgf|  楼主 | 2021-10-1 18:32 | 只看该作者
/*************************************************************************************************************
* 文件名                :        m48x_sram.h
* 功能                        :        m48X 外部SRAM驱动
* 作者                        :        cp1300@139.com
* 创建时间                :        2021-09-30
* 最后修改时间        :        2021-09-30
* 详细                        :        用于外部SRAM驱动
*************************************************************************************************************/
#ifndef _M48X_SRAM_H_
#define _M48X_SRAM_H_
#include "m48x_system.h"


bool EBI_SRAM_Init(void);   //外部SRAM初始化


#endif //_M48X_SRAM_H_


使用特权

评论回复
6
tpgf|  楼主 | 2021-10-1 18:32 | 只看该作者
//测试代码


/*************************************************************************************************************
* 文件名:                        ebi_sram_test.c
* 功能:                        外部sram测试
* 作者:                        cp1300@139.com
* 创建时间:                2021-09-30
* 最后修改时间:        2021-09-30
* 详细:                       
*************************************************************************************************************/
#include "system.h"
#include "m48x_system.h"
#include "test.h"
#include "m48x_sram.h"

#define EBI_SRAM_BASE                 0x60100000                 //EBI nCS1对应映射内存起始地址

       
//外部sram测试
void ebi_sram_test(void)
{
    u32* p = (u32*)EBI_SRAM_BASE;
    u32 i;

    SYS_GPIOx_OneInit(GPIOA, 9, OUT_PP, SPEED_40M);
    SYS_GPIOx_OneInit(GPIOA, 10, OUT_PP, SPEED_40M);
    SYS_GPIOx_OneInit(GPIOA, 11, OUT_PP, SPEED_40M);
    PAout(9) = 0;
    PAout(10) = 0;
    PAout(11) = 0;  //由于开发板高3位地址接的IO口,此处测只能都给低电平,只有128KB的内存访问空间


        SYS_DelayMS(1000);
        uart_printf("开始EBI SRAM测试\r\n");
    EBI_SRAM_Init();
    SYS_DelayMS(100);
       
         uart_printf("开始EBI SRAM读取测试\r\n");
    for (i = 0; i < 32; i++)
    {
        uart_printf("%d ", p);
    }
        uart_printf("\r\n");
    uart_printf("开始EBI SRAM写入测试\r\n");
    for (i = 0; i < 32; i++)
    {
        p = i;
    }
    uart_printf("开始EBI SRAM读取测试\r\n");
    for (i = 0; i < 32; i++)
    {
        uart_printf("%d ", p);
    }
        uart_printf("\r\n");
    uart_printf("EBI SRAM测试结束\r\n");

    SYS_DelayMS(1000*1000);
}



使用特权

评论回复
7
tpgf|  楼主 | 2021-10-1 18:33 | 只看该作者
测试结果:
开始EBI SRAM测试
开始EBI SRAM读取测试
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
开始EBI SRAM写入测试
开始EBI SRAM读取测试
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
EBI SRAM测试结束

使用特权

评论回复
8
sadicy| | 2021-10-14 17:13 | 只看该作者
EBI是一种总线协议么?
专门针对SRAM的?

使用特权

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

本版积分规则

1536

主题

14520

帖子

9

粉丝