This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28388D:f28388d 上的 EMIF 和 SDRAM

Guru**** 2331900 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1507935/tms320f28388d-emif-and-sdram-on-f28388d

器件型号:TMS320F28388D

工具/软件:

我设计了一个包含 EMIF2上外部存储器 的电路板、复制了 F28379D_EMIF_DC 参考设计。  

使用以下代码配置 SDRAM:

void configure_sdram() {

    // Do not synchronize the EMIF2 pins
    for (unsigned i = 53; i <= 68; i++) {
        GPIO_setPadConfig(i, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(i, GPIO_QUAL_ASYNC);
    }

    GPIO_setPinConfig(GPIO_68_EMIF2_D0);
    GPIO_setPinConfig(GPIO_67_EMIF2_D1);
    GPIO_setPinConfig(GPIO_66_EMIF2_D2);
    GPIO_setPinConfig(GPIO_65_EMIF2_D3);
    GPIO_setPinConfig(GPIO_64_EMIF2_D4);
    GPIO_setPinConfig(GPIO_63_EMIF2_D5);
    GPIO_setPinConfig(GPIO_62_EMIF2_D6);
    GPIO_setPinConfig(GPIO_61_EMIF2_D7);
    GPIO_setPinConfig(GPIO_60_EMIF2_D8);
    GPIO_setPinConfig(GPIO_59_EMIF2_D9);
    GPIO_setPinConfig(GPIO_58_EMIF2_D10);
    GPIO_setPinConfig(GPIO_57_EMIF2_D11);
    GPIO_setPinConfig(GPIO_56_EMIF2_D12);
    GPIO_setPinConfig(GPIO_55_EMIF2_D13);
    GPIO_setPinConfig(GPIO_54_EMIF2_D14);
    GPIO_setPinConfig(GPIO_53_EMIF2_D15);

    GPIO_setPinConfig(GPIO_97_EMIF2_DQM0);
    GPIO_setPinConfig(GPIO_96_EMIF2_DQM1);

    GPIO_setPinConfig(GPIO_98_EMIF2_A0);
    GPIO_setPinConfig(GPIO_99_EMIF2_A1);
    GPIO_setPinConfig(GPIO_100_EMIF2_A2);
    GPIO_setPinConfig(GPIO_101_EMIF2_A3);
    GPIO_setPinConfig(GPIO_102_EMIF2_A4);
    GPIO_setPinConfig(GPIO_103_EMIF2_A5);
    GPIO_setPinConfig(GPIO_104_EMIF2_A6);
    GPIO_setPinConfig(GPIO_105_EMIF2_A7);
    GPIO_setPinConfig(GPIO_106_EMIF2_A8);
    GPIO_setPinConfig(GPIO_107_EMIF2_A9);
    GPIO_setPinConfig(GPIO_108_EMIF2_A10);
    GPIO_setPinConfig(GPIO_109_EMIF2_A11);
    GPIO_setPinConfig(GPIO_95_EMIF2_A12);

    GPIO_setPinConfig(GPIO_111_EMIF2_BA0);
    GPIO_setPinConfig(GPIO_112_EMIF2_BA1);
    GPIO_setPinConfig(GPIO_113_EMIF2_CAS);
    GPIO_setPinConfig(GPIO_114_EMIF2_RAS);
    GPIO_setPinConfig(GPIO_115_EMIF2_CS0N);
    //GPIO_setPinConfig(GPIO_110_EMIF2_WAIT);
    //GPIO_setPinConfig(GPIO_116_EMIF2_CS2N);
    GPIO_setPinConfig(GPIO_117_EMIF2_SDCKE);
    GPIO_setPinConfig(GPIO_118_EMIF2_CLK);
    //GPIO_setPinConfig(GPIO_119_EMIF2_RNW);
    GPIO_setPinConfig(GPIO_120_EMIF2_WEN);
    //GPIO_setPinConfig(GPIO_121_EMIF2_OEN);

    SysCtl_setEMIF2ClockDivider(SYSCTL_EMIF2CLK_DIV_2);
    SysCtl_configureType(SYSCTL_MEMMAPTYPE, 0x1U, 0x1U);

    // Allow CPU and DMA access to EMIF2
    EMIF_setAccessProtection(EMIF2CONFIG_BASE, 0x0);
    EMIF_commitAccessConfig(EMIF2CONFIG_BASE);
    EMIF_lockAccessConfig(EMIF2CONFIG_BASE);

    // Apply timing parameters
    EMIF_SyncTimingParams syncTimingParams;
    syncTimingParams.tRfc = 6; // Refresh to Active/Refresh command delay
    syncTimingParams.tRp  = 1; // Precharge to Activate delay
    syncTimingParams.tRcd = 1; // Activate to Read/Write delay
    syncTimingParams.tWr  = 2; // Write recovery time
    syncTimingParams.tRas = 4; // Active to Precharge delay
    syncTimingParams.tRc  = 6; // Active to Active/Auto Refresh delay
    syncTimingParams.tRrd = 1; // Activate to Activate delay (different banks)
    EMIF_setSyncTimingParams(EMIF2_BASE, &syncTimingParams);

    // Set the self-refresh timing (often 64 ms, but here 7.8 us)
    EMIF_setSyncSelfRefreshExitTmng(EMIF2_BASE, 0x7U);
    EMIF_setSyncRefreshRate(EMIF2_BASE, 781); // 7.81 us

    // Configure structure for EMIF2
    EMIF_SyncConfig syncConfig;
    syncConfig.casLatency = EMIF_SYNC_CAS_LAT_2;
    syncConfig.iBank = EMIF_SYNC_BANK_4;
    syncConfig.narrowMode = EMIF_SYNC_NARROW_MODE_TRUE; // 16-bit mode
    syncConfig.pageSize = EMIF_SYNC_COLUMN_WIDTH_9;

    EMIF_setSyncMemoryConfig(EMIF2_BASE, &syncConfig);
}

使用这个测试功能,我注意到一个奇怪的行为:

__attribute__((far)) volatile uint16_t sdram_buffer[8];

volatile uint16_t buffer[8] = {0};
volatile bool error_sdram = 0;

void test_sdram() {
    for (unsigned i = 0; i < 8; ++i) {
        sdram_buffer[i] = i;
    }

    for (unsigned i = 0; i < 8; ++i)
        error_sdram |= sdram_buffer[i] != i;

    for (unsigned i = 0; i < 8; ++i) {
        buffer[i] = sdram_buffer[i];
    }
}

`缓冲器`中的值为:

1, 1, 3, 3, 5, 5, 7, 7

我注意到从 SPRAC96A :

其中我们对16位存储器移位。

正确的方法是什么?  具有16位 SDRAM 的 F28379D_EMIF_DC 或者 SPRAC96A 的表4。

我想找到修复我的设计或代码的最佳方法。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yves:

    表4用于异步存储器(CS2/3/4)。

    EMIF 地址引脚 EMIF_A[0]始终提供32位字地址的最低有效位。 因此、当连接到16位或8位异步器件时、EMIF_BA[1]和 EMIF_BA[0]引脚分别提供半字或字节地址的最低有效位。

    为了连接 SDRAM、EMIF_A[0]始终连接到 SDRAM 器件的 A[0]。  

    我在 LaunchPad 上运行 test_SDRAM 功能、工作正常。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我看到、我的问题出在其他地方。  

    您能否确认 LDQM 和 UDQM 可以绑定并且未在 MCU 上配置?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、可以将 LDQM 和 UDQM 连接到低电平。  当 LDQM 或 UDQM 为低电平时、启用缓冲区字节。