Question
STM32F429 two SDRAMs problem
Posted on December 07, 2014 at 21:12
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){&sharpdefine SDRAM_TIMEOUT ((uint32_t)0xFFFF)&sharpdefine REFRESH_COUNT ((uint32_t)0x050C) /* SDRAM refresh counter (84MHz SD clock) */&sharpdefine SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)&sharpdefine SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)&sharpdefine SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)&sharpdefine SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)&sharpdefine SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)&sharpdefine SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)&sharpdefine SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)&sharpdefine SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)&sharpdefine SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)&sharpdefine SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)&sharpdefine 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 #stm32f429 #sdram #stm32 #cubemx