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 and SDRAM( MT48LC4M16A2P-6A)

Expert 2590 points
Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: TM4C129XNCZAD

So I'm having problem with the MT48LC4M16A2P-6A connected to EPI.

I have been writing to SDRAM one byte at the time but the read value is not always the same as was written. I have made a for loop to write a bate at the time to EPI address:

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

With the debugger I can see that with a index 1, 3, 9, 11, 17, 19 ...

1 becomes to 5

3 becomes to 7

9 becomes to 13

11 becomes to 15

So the 3bit is always one in these cases. The memory is 16-bit with 1 Meg x 16 x 4 banks and it needs 12-bit for the row access and 8 bits for the column. Is there a problem with a EPI and how the memory is organized in this SDRAM?

Here is the configuration (GPIO peripherals are already all enabled):

//
    // 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

  • So I'm having problem with the MT48LC4M16A2P-6A connected to EPI.

    Can you show the schematic for how the MT48LC4M16A2P-6A is connected to the EPI pins?

  • Hello JHi,

    It looks like you have DRM calls intermixed with DriverLib calls here and its not clear to me how this is setup. My guess right now is that perhaps you don't have a GPIO set up correctly or as Chester alluded to, have a schematic error with the connections. 

    Looking at the general configuration vs the SDRAM you selected, I don't see any issues there at first review.

    You may want to scope the lower lines to see if they are changing as you expect when writing.

  • It looks like you have DRM calls intermixed with DriverLib calls here and its not clear to me how this is setup.

    To be fair, I found a TivaWare example did that - see TM4C129XNCZAD: Use of DRM in TivaWare_C_Series-2.2.0.295 examples for setting pin mux. A series of GPIOPinConfigure() calls would be clearer.

    I agree the general configuration of the SDRAM looks correct, which is why suggested checking the pin muxes against the schematic.

  • Hi Chester,

    Thanks for pointing this out... I found the example now. That's very useful because I could compare the example to their code. I would say the GPIO configuration is correct then unless the example itself has an error with it that I didn't pick up on.

    Given that, yeah I think the schematic may be the key here too.

  • As you said the code is just copied from the example, because I just wanted to fast test the hardware, so this is not the production code. The calls are making the same job as the driverlib, this was the first thing I checked.

    Here is the schematic

    And here is a pic from the memory browser

      

    Schematic is taken directly from the TM4C1294 data sheet.

    JHi

    Edit: I just made a test with 32-bit access:

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

    And 16-bit access

  • Here is the schematic

    The EPI0S0, EPI0S1, EPI0S2, EPI0S3, EPI0S29 and EPI0S30 signals each have two possible pins they can be muxed to. The schematic doesn't show which of the pins the listed signals are connected so unable to verify the pin muxes in your code. Apart from that, can't see any incorrect connections in the schematic.

    I have been writing to SDRAM one byte at the time but the read value is not always the same as was written.

    Not sure if the problem is stuck address or data bit. In the past have created memory test patterns which look for stuck address / data bits, but don't have an example for SDRAM devices.

    In case it helps, https://github.com/Chester-Gillon/mikromedia5_tivaware_examples/blob/master/mikromedia5_sdram/sdram.c contains some test code for a 8 Mbyte SDRAM connected to a tm4c129xnczad, which wrote a test pattern and then read it back.

  • Hi Chester,

    I agree with the memory test pattern. That would be the most insightful diagnostic to run right now. Let's see if it's just one pin that is an issue. If so... perhaps a cold solder joint? I have fallen victim to that with memory before and it's one of the more baffling problems to debug until your realize that!

  • I'm not really sure what this test should help, but here are the results:

    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

    I also did data bus test (Software based memory testing) and of course it will stop on a first try because the first write will be 0x04000401. Is I'm not sure if this will help me any further. 

    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 are connected to PH0 - PH3

    * EPI0S29 and EPI0S30 are connected to PN2 and PN3.

    I already checked the pins under microscope, but I guess I will have to do it again. What I can't understand is, if the problem were a stuck bit on a hardware, shouldn't it also write to wrong address? The Data and address lines are the same.

     And thanks for your suggestions this far!

    EDIT:

    I found the problem. There was a tin whisker between EPI0S10 and VDD on processor I must have overlooked it last time.