打印

GD32F470 EXMC 的映射问题

[复制链接]
1032|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
在GD32F470上的EXMC同时外接了,DM9000A和一块SDRAM。DM9000A使用的是NOR/PSRAM的BANK0 Regions1区域,使用的命令地址是0x64000100区域,数据地址是0x64000108区域。SDRAM使用的是SDRAM device0区域,是0XC000 0000这一地址起始。单独使用都是可以的,同时使用会出现冲突问题。

后来查了手册,DM9000A所使用的区域16位数据传输下,内部的地址线是这样对应的,HADDR[25:1]--->EXMC_A[24:0],根据HADDR[27:26]作为片选线。SDRAM所使用的区域在16位数据传输下,内部的地址线是这样对应的,HADDR[26:25]作为bank选中线,HADDR[24:12]作为行地址线,HADDR[11:1]作为列地址线。

会是这样的内部址线的冲突,让他们没办法同时使用吗?

下面是同时使用时的波形分析

使用特权

评论回复

相关帖子

沙发
caoenq| | 2023-4-18 09:14 | 只看该作者
映射没有关系的,应该是软件上的问题

使用特权

评论回复
评论
lly123456 2023-4-19 16:27 回复TA
是我配置的问题吗? 
板凳
lly123456|  楼主 | 2023-4-19 16:33 | 只看该作者
这是我·关于SDRAM的配置
void exmc_synchronous_dynamic_ram_init(uint32_t sdram_device)
{
    exmc_sdram_parameter_struct        sdram_init_struct; //功能结构体
    exmc_sdram_timing_parameter_struct  sdram_timing_init_struct;
    exmc_sdram_command_parameter_struct     sdram_command_init_struct;

    uint32_t command_content = 0, bank_select;
    uint32_t timeout = SDRAM_TIMEOUT;

                //主要的管脚应用
                // PE1--EXMC_NBL1   PG8--EXMC_SDCLK   PC3--EXMC_SDCKE0 PE0--EXMC_NBL0
                // PC0--EXMC_SDNWE         PG15--EXMC_SDNCAS PF11--EXMC_SDNRAS PC2--EXMC_SDNE0
    /* enable EXMC clock*/
    rcu_periph_clock_enable(RCU_EXMC);
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_GPIOC);
    rcu_periph_clock_enable(RCU_GPIOD);
    rcu_periph_clock_enable(RCU_GPIOE);
    rcu_periph_clock_enable(RCU_GPIOF);
    rcu_periph_clock_enable(RCU_GPIOG);
    rcu_periph_clock_enable(RCU_GPIOH);

    /* common GPIO configuration */
    /* SDNWE(PC0),SDNE0(PC2),SDCKE0(PC3) pin configuration */
    gpio_af_set(GPIOC, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3); //设置复用功能
    gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3); // 设置GPIO口模式
    gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3);//设置引脚输出模式 推挽输出模式

    /* D2(PD0),D3(PD1),D13(PD8),D14(PD9),D15(PD10),D0(PD14),D1(PD15) pin configuration */ //数据线设置
    gpio_af_set(GPIOD, GPIO_AF_12, GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_8 | GPIO_PIN_9 |
                GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);
    gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_8 | GPIO_PIN_9 |
                  GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);
    gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_8 | GPIO_PIN_9 |
                            GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);

    /* NBL0(PE0),NBL1(PE1),D4(PE7),D5(PE8),D6(PE9),D7(PE10),D8(PE11),D9(PE12),D10(PE13),D11(PE14),D12(PE15) pin configuration */ //地址线设置
    gpio_af_set(GPIOE, GPIO_AF_12, GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_7  | GPIO_PIN_8 |
                GPIO_PIN_9  | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 |
                GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
    gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_7  | GPIO_PIN_8 |
                  GPIO_PIN_9  | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 |
                  GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
    gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_7  | GPIO_PIN_8 |
                            GPIO_PIN_9  | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 |
                            GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);

    /* A0(PF0),A1(PF1),A2(PF2),A3(PF3),A4(PF4),A5(PF5),NRAS(PF11),A6(PF12),A7(PF13),A8(PF14),A9(PF15) pin configuration */
    gpio_af_set(GPIOF, GPIO_AF_12, GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_2  | GPIO_PIN_3  |
                GPIO_PIN_4  | GPIO_PIN_5  | GPIO_PIN_11 | GPIO_PIN_12 |
                GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
    gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_2  | GPIO_PIN_3  |
                  GPIO_PIN_4  | GPIO_PIN_5  | GPIO_PIN_11 | GPIO_PIN_12 |
                  GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
    gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_2  | GPIO_PIN_3  |
                            GPIO_PIN_4  | GPIO_PIN_5  | GPIO_PIN_11 | GPIO_PIN_12 |
                            GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);

    /* A10(PG0),A11(PG1),A12(PG2),A14(PG4),A15(PG5),SDCLK(PG8),NCAS(PG15) pin configuration */
    gpio_af_set(GPIOG, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 |
                GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15);
    gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 |
                  GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15);
    gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 |
                            GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15);

        /*EXMC 把SDRAM的存储区域分成了device0 和device01两块*/
        /*device0 0XC000 0000---0XCFFF FFFF*/
        /*device1 0XD000 0000---0XDFFF FFFF*/
    /* specify which SDRAM to read and write */
    if(EXMC_SDRAM_DEVICE0 == sdram_device) {
        bank_select = EXMC_SDRAM_DEVICE0_SELECT;
    } else {
        bank_select = EXMC_SDRAM_DEVICE1_SELECT;
    }

    /* EXMC SDRAM device initialization sequence --------------------------------*/
    /* Step 1 : configure SDRAM timing registers --------------------------------*/
    /* LMRD: 2 clock cycles */
        //EXMC 时间寄存器的配置
                //200M 三分频 67M 时钟周期 15ns左右
                //200M时钟实际上还是2分频 100M 时钟周期10ns左右
                //tMRD : 14ns
    sdram_timing_init_struct.load_mode_register_delay = 2; //加载模式寄存器延迟
    /* XSRD: min = tRC+tIS=64.5 */
    sdram_timing_init_struct.exit_selfrefresh_delay = 7; //退出自刷新的延迟
    /* tRAS: min=42ns , max=120k (ns) */
    sdram_timing_init_struct.row_address_select_delay = 5; //行地址选择延迟
    /* Refresh cycle time: min=63ns */
    sdram_timing_init_struct.auto_refresh_delay = 7; //自动刷新延迟
    /* tWR 14ns */
    sdram_timing_init_struct.write_recovery_delay = 2; //写恢复延迟
    /* RRD:  min=14ns */
    sdram_timing_init_struct.row_precharge_delay = 2; //行预充电延迟
    /* RCD:  min=21ns */
    sdram_timing_init_struct.row_to_column_delay = 3; //行至列的延迟
               
        //SDRAM 结构体
    /* step 2 : configure SDRAM control registers ---------------------------------*/
    sdram_init_struct.sdram_device = sdram_device;  //选择EXMC SDRAM devicex
    sdram_init_struct.column_address_width = EXMC_SDRAM_COW_ADDRESS_10; //列地址位宽
    sdram_init_struct.row_address_width = EXMC_SDRAM_ROW_ADDRESS_13;  //行地址位宽
    sdram_init_struct.data_width = EXMC_SDRAM_DATABUS_WIDTH_16B; //SDRAM数据总线宽度
    sdram_init_struct.internal_bank_number = EXMC_SDRAM_4_INTER_BANK; //内部Bank的个数
    sdram_init_struct.cas_latency = EXMC_CAS_LATENCY_3_SDCLK; //配置CAS延迟
    sdram_init_struct.write_protection = DISABLE; //配置写保护功能
    sdram_init_struct.sdclock_config = EXMC_SDCLK_PERIODS_3_HCLK; //SDRAM时钟配置
    sdram_init_struct.burst_read_switch = ENABLE; //突发读开关
    sdram_init_struct.pipeline_read_delay = EXMC_PIPELINE_DELAY_1_HCLK;//EXMC_PIPELINE_DELAY_2_HCLK; //流水线读数据延迟
    sdram_init_struct.timing  = &sdram_timing_init_struct; //读写时序参数
    /* EXMC SDRAM bank initialization */
    exmc_sdram_init(&sdram_init_struct); //初始化EXMC SDRAM device

    /* step 3 : configure CKE high command---------------------------------------*/
    sdram_command_init_struct.command = EXMC_SDRAM_CLOCK_ENABLE; //指定发送到SDRAM上的命令 时钟使能命令
    sdram_command_init_struct.bank_select = bank_select;  //选择SDRAM devicex
    sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_2_SDCLK; //连续的自动刷新个数
    sdram_command_init_struct.mode_register_content = 0; //指定SDRAM模式寄存器内容
    /* wait until the SDRAM controller is ready */
               
        // exmc_flag_get 获取EXMC状态   EXMC_SDRAM_FLAG_NREADY: not ready status
    while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {
        timeout--;
    }
//    if(0 == timeout) {
//        return ERROR;
//    }
    /* send the command */
        //配置SDRAM存储器命令参数
    exmc_sdram_command_config(&sdram_command_init_struct);

    /* step 4 : insert 10ms delay----------------------------------------------*/
    delay_1ms(10);

    /* step 5 : configure precharge all command----------------------------------*/
    sdram_command_init_struct.command = EXMC_SDRAM_PRECHARGE_ALL; //所有 BANK 预充电命令
    sdram_command_init_struct.bank_select = bank_select;
    sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_2_SDCLK; //2 auto-refresh cycles
    sdram_command_init_struct.mode_register_content = 0;
    /* wait until the SDRAM controller is ready */
               
    timeout = SDRAM_TIMEOUT;
               
    while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {
        timeout--;
    }
//    if(0 == timeout) {
//        return ERROR;
//    }
    /* send the command */
    exmc_sdram_command_config(&sdram_command_init_struct);

    /* step 6 : configure Auto-Refresh command-----------------------------------*/
        //至少发送八次自动刷新的命令
    sdram_command_init_struct.command = EXMC_SDRAM_AUTO_REFRESH; //自动刷新的命令
    sdram_command_init_struct.bank_select = bank_select;
    sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_9_SDCLK;
    sdram_command_init_struct.mode_register_content = 0;
    /* wait until the SDRAM controller is ready */
    timeout = SDRAM_TIMEOUT;
    while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {
        timeout--;
    }
//    if(0 == timeout) {
//        return ERROR;
//    }
    /* send the command */
    exmc_sdram_command_config(&sdram_command_init_struct);

    /* step 7 : configure load mode register command-----------------------------*/
    /* program mode register */
        //设置LOAD MODE REGISTER 发送模式寄存器的值,配置SDRAM的工作参数。
        //配置完成后,需要等待tMRD(也叫tRSC),使模式寄存器的配置生效,才能发送其他命令。
               
        /*
        模式寄存器配置:模式寄存器通过写寄存器 EXMC_SDCMD 位域 MRC 来设置,其中定义
        了突发长度,突发类型,CAS 延迟和读写模式,这些需要参考 SDRAM 用户手册。CAS 延
        迟必须与寄存器 EXMC_SDCTLx 位域 CL 对应,突发长度设为 1 来保证数据正常传输。
        如果两个 SDRAM 的模式寄存器内容不同,需要通过 DS0 和 DS1 单独选择设备来配置。
        */
        //command_content
    command_content = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_4 | //(uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
                      SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |
                      SDRAM_MODEREG_CAS_LATENCY_3           |
                      SDRAM_MODEREG_OPERATING_MODE_STANDARD |
                      SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;//SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED

    sdram_command_init_struct.command = EXMC_SDRAM_LOAD_MODE_REGISTER;
    sdram_command_init_struct.bank_select = bank_select;
    sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_2_SDCLK;
    sdram_command_init_struct.mode_register_content = command_content;

    /* wait until the SDRAM controller is ready */
                //等待操作完成。SDRAM初始化完成
    timeout = SDRAM_TIMEOUT;
    while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {
        timeout--;
    }
//    if(0 == timeout) {
//        return ERROR;
//    }
    /* send the command */
    exmc_sdram_command_config(&sdram_command_init_struct);

    /* step 8 : set the auto-refresh rate counter--------------------------------*/
    /* 64ms, 8192-cycle refresh, 64ms/8192=7.81us */
    /* SDCLK_Freq = SYS_Freq/2 */
    /* (7.81 us * SDCLK_Freq) - 20 */
        //配置自刷新间隔
                //7.81*67-20=504
   exmc_sdram_refresh_count_set(761);//504//761//636

    /* wait until the SDRAM controller is ready */
    timeout = SDRAM_TIMEOUT;
    while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {
        timeout--;
    }
//    if(0 == timeout) {
//        return ERROR;
//    }
//    return SUCCESS;
}
//这是关于DM9000A所使用的EXMC的配置

void EXMC_Init(void)
{
exmc_norsram_parameter_struct hsram0;
exmc_norsram_parameter_struct hsram1;
exmc_norsram_parameter_struct hsram2;
exmc_norsram_parameter_struct hsram3;
exmc_norsram_timing_parameter_struct Timing ={0};
exmc_norsram_timing_parameter_struct ExtTiming ={0};
    rcu_periph_clock_enable(RCU_EXMC);
exmc_norsram_deinit(EXMC_BANK0_NORSRAM_REGION1);
Timing.asyn_access_mode = EXMC_ACCESS_MODE_A; //异步访问模式
Timing.asyn_address_setuptime = 15;           //地址建立时间
Timing.asyn_address_holdtime = 15;            //地址保持时间
Timing.asyn_data_setuptime = 10;              //数据建立时间
Timing.bus_latency = 0;                       //总线延迟
Timing.syn_clk_division = EXMC_SYN_CLOCK_RATIO_2_CLK;     //同步时钟分频比
Timing.syn_data_latency = EXMC_DATALAT_2_CLK;             //数据延迟
//写时序 无用 /* ExtTiming */
ExtTiming.asyn_access_mode = EXMC_ACCESS_MODE_A;
ExtTiming.asyn_address_setuptime = 15;
ExtTiming.asyn_address_holdtime = 15;
ExtTiming.asyn_data_setuptime = 10;
ExtTiming.bus_latency = 0;
ExtTiming.syn_clk_division = EXMC_SYN_CLOCK_RATIO_2_CLK;
ExtTiming.syn_data_latency = EXMC_DATALAT_2_CLK;
//执行SRAM 初始化序列
hsram1.norsram_region = EXMC_BANK0_NORSRAM_REGION1;
hsram1.write_mode = EXMC_ASYN_WRITE;
hsram1.extended_mode = ENABLE;
hsram1.asyn_wait = DISABLE;
hsram1.nwait_signal = DISABLE;
hsram1.memory_write = ENABLE;
hsram1.nwait_config = EXMC_NWAIT_CONFIG_BEFORE;
hsram1.wrap_burst_mode = DISABLE;
hsram1.nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
hsram1.burst_mode = DISABLE;
hsram1.databus_width = EXMC_NOR_DATABUS_WIDTH_16B;
hsram1.memory_type = EXMC_MEMORY_TYPE_SRAM;
hsram1.address_data_mux = DISABLE;
hsram1.read_write_timing = &Timing;
hsram1.write_timing = &ExtTiming;
exmc_norsram_init(&hsram1); //初始化NOR/SRAM region
exmc_norsram_enable(EXMC_BANK0_NORSRAM_REGION1);
}

使用特权

评论回复
地板
sagade| | 2023-4-19 17:26 | 只看该作者
看下470的勘误,可能是影响到了。

使用特权

评论回复
评论
lly123456 2023-4-21 08:51 回复TA
这个手册的意思是说SDRAM控制器的自动刷新功能受到其他EXMC控制器的影响。当SDRAM控制器执行自动刷新命令时,如果SDRAM组处于活动状态,则 应生成预充电命令,该命令需要EXMC_A10端口为1。此时,EXMC_A10端口在其他EXMC控制器中使用,则SDRAM自动刷新命令执行异常,导致SDRAM数据错误。就是说不能和其他接EXMC的共用地址线A10吗? 
sagade 2023-4-20 09:15 回复TA
@lly123456 :https://www.gd32mcu.com/cn/download/11?kw=GD32F4 
lly123456 2023-4-20 09:02 回复TA
这个资料是哪个手册啊?可以给一下连接吗? 
5
lly123456|  楼主 | 2023-4-27 09:06 | 只看该作者
问题已经解决了,是勘误手册上所说的,SDRAM和其他外设同时使用EXMC会有冲突的问题。建议分时复用,在操作SDRAM时,不操作其他的EXMC外设。

使用特权

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

本版积分规则

2

主题

14

帖子

0

粉丝