AnsweredAssumed Answered

STM32F429 two SDRAMs problem

Question asked by novak.marek on Dec 7, 2014
Latest reply on Dec 9, 2014 by waclawek.jan
Hello everyone,
 I have used STM32F429 device along with two SDRAMs AS4C16M16S mapped to the two available banks. When the FMC controller was initialized using the generated code from STM32CubeMX with BANK1 initialized before BANK2, I got an error when reading from the BANK1 device (starting at address 0xC0000000) - it was returning only 2 times the LSB instead of MSB:LSB (e.g. I wrote 0x1234 and I read back 0x3434). I was inspecting my PCB many times, looking at the signals with my scope (unfortunately I do not have a logical analyzer), but everything seemed ok to me.

When I was only using the BANK1 device or only BANK2 device (the other one was left uninitialized), everything worked properly, but when I wanted to use both devices, I had to initialize first the BANK2 and then the BANK1 device. Here is my code:



/* FMC initialization function */
void MX_FMC_Init(void)
{
  FMC_SDRAM_TimingTypeDef SdramTiming;


  /** Perform the SDRAM2 memory initialization sequence
  */
  hsdram2.Instance = FMC_SDRAM_DEVICE;
  /* hsdram2.Init */
  hsdram2.Init.SDBank = FMC_SDRAM_BANK2;
  hsdram2.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
  hsdram2.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;
  hsdram2.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
  hsdram2.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
  hsdram2.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
  hsdram2.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
  hsdram2.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
  hsdram2.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
  hsdram2.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
  /* SdramTiming */
  SdramTiming.LoadToActiveDelay = 3;
  SdramTiming.ExitSelfRefreshDelay = 8;
  SdramTiming.SelfRefreshTime = 4;
  SdramTiming.RowCycleDelay = 7;
  SdramTiming.WriteRecoveryTime = 4;
  SdramTiming.RPDelay = 3;
  SdramTiming.RCDDelay = 3;

  HAL_SDRAM_Init(&hsdram2, &SdramTiming);


  /** Perform the SDRAM1 memory initialization sequence
  */
  hsdram1.Instance = FMC_SDRAM_DEVICE;
  /* hsdram1.Init */
  hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
  hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
  hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;
  hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
  hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
  hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
  hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
  hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
  hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
  hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
  /* SdramTiming */
  SdramTiming.LoadToActiveDelay = 3;
  SdramTiming.ExitSelfRefreshDelay = 8;
  SdramTiming.SelfRefreshTime = 4;
  SdramTiming.RowCycleDelay = 7;
  SdramTiming.WriteRecoveryTime = 4;
  SdramTiming.RPDelay = 3;
  SdramTiming.RCDDelay = 3;

  HAL_SDRAM_Init(&hsdram1, &SdramTiming);

  SDRAM_Initialization_Sequence();
}


void SDRAM_Initialization_Sequence(void)
{

#define SDRAM_TIMEOUT       ((uint32_t)0xFFFF)
#define REFRESH_COUNT       ((uint32_t)0x050C)   /* SDRAM refresh counter (84MHz SD clock) */
#define SDRAM_MODEREG_BURST_LENGTH_1             ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2             ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4             ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8             ((uint16_t)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED     ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2              ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3              ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD    ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE     ((uint16_t)0x0200)




  __IO uint32_t tmpmrd =0;
  FMC_SDRAM_CommandTypeDef cmd;





  /* Step 3:  Configure a clock configuration enable command */
  cmd.CommandMode                 = FMC_SDRAM_CMD_CLK_ENABLE;
  cmd.CommandTarget            = FMC_SDRAM_CMD_TARGET_BANK1_2;
  cmd.AutoRefreshNumber       = 1; 
  cmd.ModeRegisterDefinition = 0;


  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &cmd, 0x1000);


  /* Step 4: Insert 100 ms delay */
  HAL_Delay(100);


  /* Step 5: Configure a PALL (precharge all) command */
  cmd.CommandMode                 = FMC_SDRAM_CMD_PALL;
  cmd.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK1_2;
  cmd.AutoRefreshNumber       = 1;
  cmd.ModeRegisterDefinition = 0;


  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &cmd, 0x1000);


  /* Step 6 : Configure a Auto-Refresh command */
  cmd.CommandMode                 = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
  cmd.CommandTarget            = FMC_SDRAM_CMD_TARGET_BANK1_2;
  cmd.AutoRefreshNumber       = 1; 
  cmd.ModeRegisterDefinition = 0;


  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &cmd, 0x1000);


  /* 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_OPERATING_MODE_STANDARD |
                     SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;


  cmd.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
  cmd.CommandTarget            = FMC_SDRAM_CMD_TARGET_BANK1_2;
  cmd.AutoRefreshNumber       = 4; 
  cmd.ModeRegisterDefinition = tmpmrd;


  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &cmd, 0x1000);


  /* Step 8: Set the refresh rate counter */
  /* (15.62 us x Freq) - 20 */
  /* Set the device refresh counter */
  HAL_SDRAM_ProgramRefreshRate(&hsdram1, REFRESH_COUNT);
}

I hope it helps somebody, I will be happy for any feedback.
The probem is solved for my, but I would like to help others, since the ST forum has helped me a lot of times.

Have a nice day,
 OK2NMZ

Outcomes