2026-02-15 4:09 AM - edited 2026-02-15 4:14 AM
Hello,
I'm trying to run SDRAM (AS4C4M16SA-5TCN) with FMC. It looks like all connections are correct. When I try to read/write to memory pointer, I got memory management fault handler.
My FMC configuration:
Clock connected to FMC is 275MHz (HCLK3). I've tried also to lower it to ~30MHz, but it didn't help.
Under "USER CODE BEGIN 2" I'm executing FMC_Init() function. This is it:
I tried to write something to memory, but this is the moment when fault handler is activated:
*(__IO uint8_t*) (SDRAM_START_ADDR) = 0x00;
SDRAM_START_ADDR is defined as 0xC0000000.
All FMC's GPIOs are set to Very High speed. What else can I check?
@Tesla DeLorean maybe you could help, please?
Solved! Go to Solution.
2026-02-15 6:33 AM - edited 2026-02-15 6:42 AM
Hello,
Do you have the default MPU configuration activated to prevent the CM7 speculative access in your project? like this:
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x00;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
That MPU configuration prevents any access to any external memory. See this thread for the explanation.
You need to add another MPU region to activate the access to you SDRAM memory region.
This is an example of the FMC_SDRAM provided by the H7 CubeHAL. There is a default MPU config and there is a second one to activate the access to the SDRAM:
static void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the MPU as Strongly ordered for not defined regions */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x00;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the MPU attributes as WB for SDRAM */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = SDRAM_BANK_ADDR;
MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
Hope that helps.
PS: in next time please use </> to share a code instead of providing a screenshot of it.
2026-02-15 6:33 AM - edited 2026-02-15 6:42 AM
Hello,
Do you have the default MPU configuration activated to prevent the CM7 speculative access in your project? like this:
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x00;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
That MPU configuration prevents any access to any external memory. See this thread for the explanation.
You need to add another MPU region to activate the access to you SDRAM memory region.
This is an example of the FMC_SDRAM provided by the H7 CubeHAL. There is a default MPU config and there is a second one to activate the access to the SDRAM:
static void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the MPU as Strongly ordered for not defined regions */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x00;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the MPU attributes as WB for SDRAM */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = SDRAM_BANK_ADDR;
MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
Hope that helps.
PS: in next time please use </> to share a code instead of providing a screenshot of it.
2026-02-15 7:50 AM
Thank you, it seems to be working now. But I noticed, with every code generation, MPU_Config function is overwritten by Cube code. How can I prevent it?
2026-02-15 7:58 AM - edited 2026-02-15 8:00 AM
Use the MPU menu in CubeMx to add the new region for SDRAM:
2026-02-16 8:03 AM
Thank you, now it works, but I have another problem.
Let's start with array declaration:
uint8_t *externalRAM = (uint8_t*)0xC0000000;
/* USER CODE END PV */Then I'm trying to write some bytes to this array, ie:
externalRAM[0] = 0xAA;
externalRAM[1] = 0xAA;
externalRAM[2] = 0xAA;
externalRAM[3] = 0xAA;And to read it:
uint8_t test[4];
test[0] = externalRAM[0];
test[1] = externalRAM[1];
test[2] = externalRAM[2];
test[3] = externalRAM[3];And this is the result:
Sometimes test[1] has 0xAA too, but mostly it's 0. What does this look like?
2026-02-16 8:28 AM
Hello,
Need to open a new thread for that new question.
Thank you.