2025-02-13 9:42 PM - edited 2025-02-13 9:59 PM
Hi all,
Board: STM32H745I-DISCO
IDE: 1.16.1
I am facing some issues with trying to execute code on the SDRAM. I have a 2nd stage bootloader that loads the user application onto QSPI located at 0x9000 0000. After that, I copy the user application code to the SDRAM 0xD0000000. This part works as verified in the debugger.
However when I try to jump to the SDRAM address, my program is not executing. And it seems like the SDRAM has lost connection? Attached below is the image(sdram_becomes_unreadable.PNG) where my bootloader jumped to the SDRAM address but unable to read from the SDRAM. There is no hard fault..
Background:
I have tried to load the user application onto QSPI and jump to the QSPI address, my program executes successfully.
I have checked my MPU configuration to make sure that SDRAM is MPU_INSTRUCTION_ACCESS_ENABLE.
Below is my MPU configuration
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_128MB;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.BaseAddress = 0xD0000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_64MB;
MPU_InitStruct.SubRegionDisable = 0x0;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
Lastly, I tried to bank swap the SDRAM to 0x70000000, and execute from there incase the SDRAM is still in Execute Never(XN) mode. But this doesn't work too as the SDRAM is unreadable after the jump.
What am I missing? Do I need to initialize the SDRAM for my user application? How come this is not needed for QSPI in such a scenario?
Regards,
Reuben Goh
2025-02-17 1:35 AM
Hi SofLit,
I have found that before and after the jump, the SDRAM_SDCLK is changed from 100MHz to 33MHz as shown in the attached screenshots. My user application might have changed the clock setting that was set by the bootloader.
Regards,
Reuben Goh
2025-02-17 1:41 AM
Ok. If you fix that redo the test and get back with your results.
2025-02-18 12:34 AM
Hi,
I have resolved the issue and found the root cause.. I had to do 2 things to make code execution work for STM32H745 on SDRAM.
1. Remap the SDRAM by executing this command below in stm32h745i_discovery_sdram.c, MX_SDRAM_BANK2_init function
/* SDRAM bank swap 0xD0000000 to 0x70000000*/
HAL_SetFMCMemorySwappingConfig(FMC_SWAPBMAP_SDRAM_SRAM);
2. Disable the configuration that disables FMC bank1 in system_stm32h7xx_dualcore_boot_cm4_cm7.c, SystemInit function
/*
* Disable the FMC bank1 (enabled after reset).
* This, prevents CPU speculation access on this bank which blocks the use of FMC during
* 24us. During this time the others FMC master (such as LTDC) cannot use it!
*/
//FMC_Bank1_R->BTCR[0] = 0x000030D2;
For point 1, I am not too sure why my MPU configuration does not allow 0xD0000000 to execute. But changing it works for me since 0x70000000 allows code execution. For point 2, this is crucial step. Previously when I did bank swapping I did not disable this, that's why it did not work.
I also realize the 100MHz clock drop to 33MHz was normal since the processor is reading from the SDRAM, hence there is some difference in the SDRAM_CLK. I know this because when I copy the code from QSPI to SDRAM, the SDRAM_CLK changes as well.
Thank you all for your help.
Regards,
Reuben Goh