cancel
Showing results for 
Search instead for 
Did you mean: 

New SDRAM model does not work with STM32F7 (but old one does)

Lars Beiderbecke
Senior III

I've migrated to a new custom board, which uses a STM32F746IE and a new SDRAM model, NDS36PT5-20ET by Insignis. And although I could make a MT48LC16M16A2 by Micron work in the previous board, I have no luck with the Insignis SDRAM.

The Insignis SDRAM is rated for 200 MHz. I'm using a system clock of 200 MHz, so the SDRAM is clocked at 100 MHz. Based on the timings in the datasheet, I configured CubeMX like this:

0693W000006GvOuQAK.pngEach FMC cycle is 10 ns, so I divided the datasheet time by 10 ns and rounded up. The Write recovery time would be 1 cycle, but CubeMX sets this to 2. I also chose a CL of 3, since the datasheet doesn't list any Clock cycle time for CL 2.

Similarly, I initialize the SDRAM with this function in main():

static void SDRAM_Init()
{
  FMC_SDRAM_CommandTypeDef Command;
 
  __IO uint32_t tmpmrd =0;
  /* Step 3:  Configure a clock configuration enable command */
  Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
  Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  Command.AutoRefreshNumber = 1;
  Command.ModeRegisterDefinition = 0;
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
 
  /* Step 4: Insert 100 us minimum delay */
  /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
  HAL_Delay(1);
 
  /* Step 5: Configure a PALL (precharge all) command */
  Command.CommandMode = FMC_SDRAM_CMD_PALL;
  Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  Command.AutoRefreshNumber = 1;
  Command.ModeRegisterDefinition = 0;
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
 
  /* Step 6 : Configure a Auto-Refresh command */
  Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
  Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  Command.AutoRefreshNumber = 2;  // Insignis SDRAM
  Command.ModeRegisterDefinition = 0;
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
 
  /* Step 7: Program the external memory mode register */
  tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |
                     SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |
                     SDRAM_MODEREG_CAS_LATENCY_3           |
                     //SDRAM_MODEREG_CAS_LATENCY_2           |
                     SDRAM_MODEREG_OPERATING_MODE_STANDARD |
                     SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
 
  Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
  Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  Command.AutoRefreshNumber = 1;
  Command.ModeRegisterDefinition = tmpmrd;
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
 
  /* Step 8: Set the refresh rate counter: (64 ms / 8192 x Freq) - 20 */
  hsdram1.Instance->SDRTR |= ((uint32_t)761);  // 2HCLK, Insignis SDRAM, 100 MHz
}

My quick and dirty test program

uint32_t i;
  for (i = 0; i < 16384; i += 2) {
    *(__IO uint16_t *) (SDRAM_BASE + i) = i & 0xffff;
  }
 
  for (i = 0; i < 16384; i += 2) {
      uint16_t data = *(__IO uint16_t *) (SDRAM_BASE + i);
      if (data != (i & 0xffff)) {
        while (1);  // breakpoint here
      }
  }

shows an error when reading the first value: 0x3ffe instead of 0 (and that consistently).

To rule out any layout errors, I used the Insignis SDRAM in the older board, in which I got the Micron SDRAM to work. The Insignis still would not run with the old board (same error as in the new board).

For either board, what could be wrong with my configuration above?

1 ACCEPTED SOLUTION

Accepted Solutions

Thanks for your info. You were right that something else is amiss.

I created a test project in CubeMX, where I only enabled FMC, in which case FMC_SDNE0 is assigned to PC2. But in my board design, PC2 was already assigned to GPIO_INPUT, so FMC_SDNE0 was assigned to PH3 -- I didn't realize that was even possible.

So the timing et al. is not the problem, but I was missing the enable signal to the SDRAM!

Thanks for your remark, that made me recheck my layout.

View solution in original post

6 REPLIES 6
Lars Beiderbecke
Senior III

Since I still don't know how to deal with the fact that the 200 MHz SDRAM IC is only clocked at 100 MHz, I tried to double all timings and recalculate the clocks needed in CubeMX. I couldn't enter the Write recovery time value of 2, since that violates the internal working of SDRAMs, and had to enter 5 instead.

Alas, my updated values still don't work; again, the 16-bit value at address 0xc0000000 is 0x3ffe instead of 0.

Likely something else amiss.

Make sure the GPIO's are NOT using an overly aggressive slew rate.

At 100 MHz is should take fewer cycles to hit minimum timing windows.

I have no personal experience with Insignis parts, or if this is a suitable drop-in replacement.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thanks for your info. You were right that something else is amiss.

I created a test project in CubeMX, where I only enabled FMC, in which case FMC_SDNE0 is assigned to PC2. But in my board design, PC2 was already assigned to GPIO_INPUT, so FMC_SDNE0 was assigned to PH3 -- I didn't realize that was even possible.

So the timing et al. is not the problem, but I was missing the enable signal to the SDRAM!

Thanks for your remark, that made me recheck my layout.

I guess I was to hasty: While the Insignis SDRAM does work in an old, proven board as described above, the Insignis SDRAM doesn't work in a new board. I checked the new schema and remeasured the trace lengths, and everything looks alright. But the values read at 0xc0000000 are (depending on timings) 0x3ffe, 0x1008, or 0x0050 instead of 0.

This only leaves issues with the layout itself. Now, if other traces are too close to SDRAM traces, I would expect some random results -- not always the same results. Would you agree with that?

Did you manage to solve the issue? I have the same RAM on an H753 and I'm having issues too.

Thanks in advance.

No, I don't really know. I think my layout was bad, e.g., unrelated traces too close to the SDRAM traces (on all layers).

On the other hand, I had bad SDRAM on a board I knew was good, and this SDRAM showed the same symptoms as the other bad SDRAM. But in this case, simply resoldering the SDRAM solved my problems.