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.

[参考译文] TM4C1294NCPDT:EPI 和 SDRAM (MT48LC4M16A2P-6A)

Guru**** 2418170 points
Other Parts Discussed in Thread: TM4C129XNCZAD

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/996724/tm4c1294ncpdt-epi-and-sdram-mt48lc4m16a2p-6a

器件型号:TM4C1294NCPDT
主题中讨论的其他器件:TM4C129XNCZAD

因此、连接 到 EPI 的 MT48LC4M16A2P-6A 存在问题。

我一直在向 SDRAM 写入一个字节、但读取的值并不总是与写入的值相同。 我已经创建了一个 for 循环、以便在时将一个数据写入到 EPI 地址:

for (uint_fast32_t i = 0; i < SDRAM_END_ADDRESS;++i)
{
    base[i] = (uint8_t)i;
}

使用调试器、我可以看到、对于索引1、3、9、11、17、 19...

1变为5

3变为7

9变为13

11变为15

因此、在这些 情况下、3位始终为1。 存储器为16位、具有1Meg x 16 x 4组、行访问需要12位、列需要8位。 EPI 是否存在问题、以及该 SDRAM 中的存储器是如何组织的?

下面是配置(GPIO 外设已全部启用):

//
    // The EPI0 peripheral must be enabled for use.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_EPI0);


    //
    // This step configures the internal pin muxes to set the EPI pins for use
    // with EPI.  Please refer to the datasheet for more information about pin
    // muxing.  Note that EPI0S27:20 are not used for the EPI SDRAM
    // implementation.
    // TODO: Update this section based upon the EPI pin assignment on your
    // target part.
    //

    //
    // EPI0S00 ~ EPI0S03 : H0 ~ 3
    //
    ui32Val = HWREG(GPIO_PORTH_BASE + GPIO_O_PCTL);
    ui32Val &= 0xFFFF0000;
    ui32Val |= 0x0000FFFF;
    HWREG(GPIO_PORTH_BASE + GPIO_O_PCTL) = ui32Val;

    //
    // EPI0S4 ~ EPI0S7: C4 ~ 7
    //
    ui32Val = HWREG(GPIO_PORTC_BASE + GPIO_O_PCTL);
    ui32Val &= 0x0000FFFF;
    ui32Val |= 0xFFFF0000;
    HWREG(GPIO_PORTC_BASE + GPIO_O_PCTL) = ui32Val;

    //
    // EPI0S8 ~ EPI0S9: A6 ~ 7
    //
    ui32Val = HWREG(GPIO_PORTA_BASE + GPIO_O_PCTL);
    ui32Val &= 0x00FFFFFF;
    ui32Val |= 0xFF000000;
    HWREG(GPIO_PORTA_BASE + GPIO_O_PCTL) = ui32Val;

    //
    // EPI0S10 ~ EPI0S11: G0 ~ 1
    //
    ui32Val = HWREG(GPIO_PORTG_BASE + GPIO_O_PCTL);
    ui32Val &= 0xFFFFFF00;
    ui32Val |= 0x000000FF;
    HWREG(GPIO_PORTG_BASE + GPIO_O_PCTL) = ui32Val;

    //
    // EPI0S12 ~ EPI0S15: M0 ~ 3
    //
    ui32Val = HWREG(GPIO_PORTM_BASE + GPIO_O_PCTL);
    ui32Val &= 0xFFFF0000;
    ui32Val |= 0x0000FFFF;
    HWREG(GPIO_PORTM_BASE + GPIO_O_PCTL) = ui32Val;

    //
    // EPI0S16 ~ EPI0S19: L0 ~ 3
    //
    ui32Val = HWREG(GPIO_PORTL_BASE + GPIO_O_PCTL);
    ui32Val &= 0xFFFF0000;
    ui32Val |= 0x0000FFFF;
    HWREG(GPIO_PORTL_BASE + GPIO_O_PCTL) = ui32Val;

    //
    // EPI0S28 : B3
    //
    ui32Val = HWREG(GPIO_PORTB_BASE + GPIO_O_PCTL);
    ui32Val &= 0xFFFF0FFF;
    ui32Val |= 0x0000F000;
    HWREG(GPIO_PORTB_BASE + GPIO_O_PCTL) = ui32Val;

    //
    // EPI0S29 ~ EPI0S30: N2 ~ 3
    //
    ui32Val = HWREG(GPIO_PORTN_BASE + GPIO_O_PCTL);
    ui32Val &= 0xFFFF00FF;
    ui32Val |= 0x0000FF00;
    HWREG(GPIO_PORTN_BASE + GPIO_O_PCTL) = ui32Val;

    //
    // EPI0S31 : K5
    //
    ui32Val = HWREG(GPIO_PORTK_BASE + GPIO_O_PCTL);
    ui32Val &= 0xFF0FFFFF;
    ui32Val |= 0x00F00000;
    HWREG(GPIO_PORTK_BASE + GPIO_O_PCTL) = ui32Val;


    //
    // Configure the GPIO pins for EPI mode.  All the EPI pins require 8mA
    // drive strength in push-pull operation.  This step also gives control of
    // pins to the EPI module.
    //
    GPIOPinTypeEPI(GPIO_PORTA_BASE, EPI_PORTA_PINS);
    GPIOPinTypeEPI(GPIO_PORTB_BASE, EPI_PORTB_PINS);
    GPIOPinTypeEPI(GPIO_PORTC_BASE, EPI_PORTC_PINS);
    GPIOPinTypeEPI(GPIO_PORTG_BASE, EPI_PORTG_PINS);
    GPIOPinTypeEPI(GPIO_PORTH_BASE, EPI_PORTH_PINS);
    GPIOPinTypeEPI(GPIO_PORTK_BASE, EPI_PORTK_PINS);
    GPIOPinTypeEPI(GPIO_PORTL_BASE, EPI_PORTL_PINS);
    GPIOPinTypeEPI(GPIO_PORTM_BASE, EPI_PORTM_PINS);
    GPIOPinTypeEPI(GPIO_PORTN_BASE, EPI_PORTN_PINS);


    // Our current system clock faster than we can drive the SDRAM clock
    EPIDividerSet(EPI0_BASE, 1);


    //
    // Sets the usage mode of the EPI module.  For this example we will use
    // the SDRAM mode to talk to the external 16MB SDRAM module.
    //
    EPIModeSet(EPI0_BASE, EPI_MODE_SDRAM);


    //
    // Configure the SDRAM mode.  We configure the SDRAM according to our core
    // clock frequency.  We will use the normal (or full power) operating
    // state which means we will not use the low power self-refresh state.
    // Set the SDRAM size to 8MB with a refresh interval of 900 clock ticks.
    //
    EPIConfigSDRAMSet(EPI0_BASE, (EPI_SDRAM_CORE_FREQ_50_100 | EPI_SDRAM_FULL_POWER |
                      EPI_SDRAM_SIZE_64MBIT), 900);

    //
    // Set the address map.  The EPI0 is mapped from 0x60000000 to 0x01000000.
    // For this example, we will start from a base address of 0x60000000 with
    // a size of 256MB.  Although our SDRAM is only 64MB, there is no 64MB
    // aperture option so we pick the next larger size.
    //
    EPIAddressMapSet(EPI0_BASE, EPI_ADDR_RAM_SIZE_16MB | EPI_ADDR_RAM_BASE_6);

    //
    // Wait for the SDRAM wake-up to complete by polling the SDRAM
    // initialization sequence bit.  This bit is true when the SDRAM interface
    // is going through the initialization and false when the SDRAM interface
    // it is not in a wake-up period.
    //
    while(HWREG(EPI0_BASE + EPI_O_STAT) &  EPI_STAT_INITSEQ)
    {
    }

BR JHi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="51904" URL"~/support/microcontrollers/other/f/other-microcontrollers-forum/996724/tm4c1294ncpdt-epi-and-sdram-mt48lc4m16a2p-6a "]因此我遇到 了连接到 EPI 的 MT48LC4M16A2P-6A 的问题。

     您能否展示 MT48LC4M16A2P-6A 如何连接到 EPI 引脚的原理图?

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

    您好、JHi、

    您在这里似乎有 DRM 调用与 DriverLib 调用混合、我不清楚这是如何设置的。 我现在的猜测是、您可能没有正确设置 GPIO、或者正如切斯特所提到的、连接出现原理图错误。  

    查看常规配置与您选择的 SDRAM、我在第一次审阅时没有发现任何问题。

    您可能希望对较低的行进行范围调整、以查看它们是否如编写时所期望的那样发生变化。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="189615" URL"~/support/microcontrollers/other/f/other-microcontrollers-forum/996724/tm4c1294ncpdt-epi-and-sdram-mt48lc4m16a2p-6a/3682196 #3682196"]此处看起来您的 DRM 调用与 DriverLib 调用混合、但我不清楚这是如何设置的。

    公平地说、我发现一个 TivaWare 示例执行了该操作-请参阅 TM4C129XNCZAD:TivaWare_C_Series-2.2.0.295示例中的使用 DRM 来设置引脚多路复用器。 一系列 GPIOPinConfigure()调用会更清晰。

    我同意 SDRAM 的一般配置是正确的、因此建议对照原理图检查引脚多路复用器。

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

    切斯特、您好!

    感谢您指出这一点... 我现在找到了示例。 这非常有用、因为我可以将示例与其代码进行比较。 我会说 GPIO 配置是正确的、除非示例本身有一个错误、但我没有收到该错误。

    考虑到这一点、是的、我认为原理图也可能是这里的关键。

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

    正如您所说的、代码只是从示例中复制的、因为我只是想快速测试硬件、所以这不是生产代码。 这些调用正在进行与 driverlib 相同的工作、这是我检查的第一件事。

    这是原理图

    这里是存储器浏览器中的图片

      

    原理图直接取自 TM4C1294数据表。

    JHi

    编辑:我刚刚使用32位访问进行了测试:

    uint32_t *base2 = (uint32_t*)0x60000000;
    
    for (uint_fast32_t i = 0; i < SDRAM_END_ADDRESS/2;++i)
    {
        base2[i] = (uint32_t)i;
    }

    和16位访问

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="51904" URL"~/support/microcontrollers/other/f/other-microcontrollers-forum/996724/tm4c1294ncpdt-epi-and-sdram-mt48lc4m16a2p-6a/3682705 #3682705"]此处是原理图

     EPI0S0、 EPI0S1、 EPI0S2、 EPI0S3、 EPI0S29 和 EPI0S30信号各有两个可复用的管脚。 该原理图未显示所列出信号连接的引脚、因此无法验证代码中的引脚多路复用器。 除此之外、在原理图中看不到任何不正确的连接。

    [引用 userid="51904" URL"~/support/microcontrollers/other/f/other-microcontrollers-forum/996724/tm4c1294ncpdt-epi-and-sdram-mt48lc4m16a2p-6a。]我一直在向 SDRAM 写入一个字节、但读取的值并不总是与写入的值相同。 [/报价]

    不确定问题是地址还是数据位卡住。 过去创建了存储器测试模式、该模式查找卡滞的地址/数据位、但没有 SDRAM 器件的示例。

     如果有用、https://github.com/Chester-Gillon/mikromedia5_tivaware_examples/blob/master/mikromedia5_sdram/sdram.c 包含一些连接到 tm4c129xnczad 的8 MB SDRAM 的测试代码、该测试代码编写了测试模式、然后将其读回。

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

    切斯特、您好!

    我同意内存测试模式。 这将是目前运行的最有洞察力的诊断。 让我们看看它是否只是一个引脚存在问题。 如果是... 也许是冷焊点? 我以前就已经成为这种情况的受害者、这是调试中更令人困惑的问题之一、直到您意识到这一点!

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

    我不确定该测试应该帮助什么、但结果如下:

    Write test starting with offset 0
    After index write num_errors=2097152
    After ~index write num_errors=3670016
    Write test starting with offset 1
    After index write num_errors=5767168
    After ~index write num_errors=7340032
    Write test starting with offset 2
    After index write num_errors=9437184
    After ~index write num_errors=11010048
    Write test starting with offset 3
    After index write num_errors=13107200
    After ~index write num_errors=14680064

    我还进行了数据总线测试(基于软件的内存测试)、当然、第一次写入时它将停止、因为第一次写入将为0x04000401。 我不确定这是否会进一步帮助我。  

    uint32_t memTestDataBus(volatile uint32_t * address)
    {
        uint32_t pattern;
        /*
         * Perform a walking 1's test at the given address.
         */
        for (pattern = 1; pattern != 0; pattern <<= 1)
        {
            /*
             * Write the test pattern.
             */
            *address = pattern;
            /*
             * Read it back (immediately is okay for this test).
             */
            if (*address != pattern)
            {
                return (pattern);
            }
        }
        return (0);
    }
    
    #define SDRAM_MAPPING_ADDRESS 0x60000000
    #define SDRAM_SIZE_BYTES    0x00800000
    #define SDRAM_SIZE_WORDS   (SDRAM_SIZE_BYTES / sizeof (uint32_t))
    static uint32_t *const sdram_base = (uint32_t *) SDRAM_MAPPING_ADDRESS;
        
    uint32_t test = memTestDataBus(sdram_base);
    printf("Data bus test: %u\n", test); -> Data bus test: 1

    * PI0S0、 EPI0S1、 EPI0S2、 EPI0S3连接到 PH0 - PH3

    * EPI0S29和 EPI0S30连接到 PN2和 PN3。

    我已经检查了显微镜下的引脚、但我想我必须再次检查。 我无法理解的是、如果问题是硬件上的卡位、它是否也应该写入错误的地址? 数据和地址行 是相同的。

     感谢您到目前为止提出的建议!

    编辑:

    我找到了问题。  EPI0S10和处理器上的 VDD 之间有一个锡须、我上一次一定会忽略它。