AnsweredAssumed Answered

Cant read/write from external sdram stm32f429, AS4C8M16S-6TIN

Question asked by Liatukis.Julius on Oct 19, 2016
Latest reply on Oct 20, 2016 by Liatukis.Julius
Hi everyone,
I got problem, when trying to write read to external SDRAM AS4C8M16S-6TIN using STM32F429 MCU. I created my own board and connected SDRAM as you can see in attach schematic.png (data and address lines are connected correctly, there was only one connection alternative).

Hardware: SDRAM is under MCU (oposite side of MCU). See attach hardware.png

Initialize code for MCU is correct, I have already runing spi, usart, i2c interfaces, using RTC, LCD with FT812 controller and so on.

Here is SDRAM Initialize code:

// USER CODE START


SDRAM_HandleTypeDef g_sdram;
FMC_SDRAM_TimingTypeDef g_sdram_timing;
uint16_t write[100]={0};
uint16_t read[100]={0};
void SDRAM_init(void)
 {
  GPIO_InitTypeDef     sd_gpio;
  __FMC_CLK_ENABLE();




  //Step 1:  Initialize relevant GPIO
  sd_gpio.Pin = GPIO_PIN_5 | GPIO_PIN_6;
  sd_gpio.Mode = GPIO_MODE_AF_PP;
  sd_gpio.Pull = GPIO_PULLUP;
  sd_gpio.Speed = GPIO_SPEED_HIGH;
  sd_gpio.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init(GPIOB, &sd_gpio);


  sd_gpio.Pin = GPIO_PIN_0;
  HAL_GPIO_Init(GPIOC, &sd_gpio);


  sd_gpio.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15;
  HAL_GPIO_Init(GPIOD, &sd_gpio);


  sd_gpio.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
  HAL_GPIO_Init(GPIOE, &sd_gpio);


  sd_gpio.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
  HAL_GPIO_Init(GPIOF, &sd_gpio);


  sd_gpio.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15;
  HAL_GPIO_Init(GPIOG, &sd_gpio);
  
  //Step 2:  Initialize SDRAM parameters
  g_sdram.Instance=FMC_SDRAM_DEVICE;
  g_sdram.Init.SDBank = FMC_SDRAM_BANK2;
  g_sdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
  g_sdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
  g_sdram.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
  g_sdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
  g_sdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
  g_sdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
  g_sdram.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
  g_sdram.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
  g_sdram.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
  
  //Step 3:  Initialize SDRAM timings
  // While HCLK is 180 MHZ and FMC_SDRAM_CLOCK_PERIOD_2, FMC is runnig 90MHz (T=11.11ns)
  g_sdram_timing.LoadToActiveDelay    = 2;   // TMRD: 2 Clock cycles
  g_sdram_timing.ExitSelfRefreshDelay = 6;   // TXSR: min=64.5 ns (6x11.1ns)
  g_sdram_timing.SelfRefreshTime      = 4;   // TRAS: min=42 ns   (4x11.1ns)
  g_sdram_timing.RowCycleDelay        = 6;   // TRC:  min=60 ns   (6x11.1ns)
  g_sdram_timing.WriteRecoveryTime    = 2;   // TWR:  2 Clock cycles
  g_sdram_timing.RPDelay              = 2;   // TRP:  min=18 ns   (2x11.1ns)
  g_sdram_timing.RCDDelay             = 2;   // TRCD: min=18 ns   (2x11.1ns)
  HAL_SDRAM_DeInit(&g_sdram);
  HAL_SDRAM_Init(&g_sdram, &g_sdram_timing);
  
  FMC_SDRAM_CommandTypeDef sdramCommand;


  //Step 4:  Configure a clock configuration enable command
  sdramCommand.CommandMode             = FMC_SDRAM_CMD_CLK_ENABLE;
  sdramCommand.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
  sdramCommand.AutoRefreshNumber       = 1;
  sdramCommand.ModeRegisterDefinition  = 0;
  HAL_SDRAM_SendCommand(&g_sdram, &sdramCommand, 100);


  HAL_Delay(100);
  
  //Step 5: Configure a PALL (precharge all) command
  sdramCommand.CommandMode             = FMC_SDRAM_CMD_PALL;
  sdramCommand.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
  sdramCommand.AutoRefreshNumber       = 1;
  sdramCommand.ModeRegisterDefinition  = 0;
  HAL_SDRAM_SendCommand(&g_sdram, &sdramCommand, 100);


  //Step 6 : Configure a Auto-Refresh command
  sdramCommand.CommandMode             = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
  sdramCommand.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
  sdramCommand.AutoRefreshNumber       = 4;
  sdramCommand.ModeRegisterDefinition  = 0;
  HAL_SDRAM_SendCommand(&g_sdram, &sdramCommand, 100);


  //Step 7: Program the external memory mode register
  sdramCommand.CommandMode            = FMC_SDRAM_CMD_LOAD_MODE;
  sdramCommand.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK2;
  sdramCommand.AutoRefreshNumber      = 1;
  sdramCommand.ModeRegisterDefinition =(uint32_t)  SDRAM_MODEREG_BURST_LENGTH_2             |        
                                                     SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      |
                                                   FMC_SDRAM_CAS_LATENCY_3                  |
                                                   SDRAM_MODEREG_OPERATING_MODE_STANDARD    |
                                                   SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
  HAL_SDRAM_SendCommand(&g_sdram, &sdramCommand, 100);


  // Step 8: Set the refresh rate counter
  HAL_SDRAM_ProgramRefreshRate(&g_sdram, 1404 - 20 );
  
  HAL_Delay(100);


  // Step 8: Clear SDRAM
  int i=0;
  for (i=0; i<100; i++)
   {
    write[i]=i*100;
   }
  uint16_t *p=0xD0000000;   // sdram start address
  memset(p,0,0x800000);     //Clear sdram memory  0x800000 - mem size
 }


// USER CODE END



After that, somwhere in code i run SDRAM read write comand:

          uint32_t readadd =0xD0000000;
          uint32_t writeadd=0xD0000000;
          uint32_t address =0;

           address=writeadd;
           HAL_SDRAM_Write_16b(&g_sdram, address, &write, 100);


           address=readadd;
           HAL_SDRAM_Read_16b(&g_sdram, address, &read, 100);

Rezult is:

write values:      read values
0                         300
100                     300
200                     300
300                     300
400                     700
500                     700
600                     700
700                     700
800                   1100
900                   1100
1000                 1100
1100                 1100
1200                 1500
1300                 1500
1400                 1500
1500                 1500

As you can see, last writted value is in all 4 cells. After that I try write single uint16_t:

           single[0]=writeval;           // write val - value to write
           address=writeadd+writereg*2; //writereg - indicates cell, whre i'm going to write
           HAL_SDRAM_Write_16b(&g_sdram, address, &single, 1);

           address=readadd;
           HAL_SDRAM_Read_16b(&g_sdram, address, &read, 100);


The result is the same. Let's say I want to write in any of 4 repetitive value. After i read the memory, I get that all 4 values are changed. 
The MCU seing the SDRAM, because if I try to write lower than external ram base address (<0xD0000000) or adress, higher than base address + sdram size (0xD0800000) I get Hard fault.

Anyone know what could be wrong? I stuck here for weeks...

Thank you in adwance.

Attachments

Outcomes