Hardfault after acessing FMC intyerface on STM32H753
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-06-13 12:47 PM - last edited on ‎2025-06-13 1:09 PM by mƎALLEm
MCU: STM32H753XIH
Tool: STM32CubeIDE v1.18.1
FW Pkg: FW_H7_V1.12.1
I have an in-house designed board that has an FPGA connected to the FMC bus. The FPGA uses a simple SRAM interface with Address (7:0), Data (31:0), Chip Select, Read and Write signals. The FPGA has 8 internal 32 bit registers with an address decoder and provides the 8 internal chip selects for these registers from the address bus.
I hard Fault every time I attempt to access the FPGA registers.
FMC Setup:
hsram1.Instance = FMC_NORSRAM_DEVICE;
hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
/* hsram1.Init */
hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
hsram1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_32;
hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
hsram1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
/* Timing */
Timing.AddressSetupTime = 4;
Timing.AddressHoldTime = 15;
Timing.DataSetupTime = 2;
Timing.BusTurnAroundDuration = 1;
Timing.CLKDivision = 16;
Timing.DataLatency = 17;
Timing.AccessMode = FMC_ACCESS_MODE_A;
MPU Setup:
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x60000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32B;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
Access Line of Code:
halStat = HAL_SRAM_Write_32b(&hsram1, (uint32_t *)(SRAM_BANK_ADDR + addr), (uint32_t *) vctBuf.vb85[vbi][vni][0], VECT_LEN);
Stepping into this function call shows me that I hard fault on the very first 32b write from my buffer.
Hoping someone can help.
Thank you!
Solved! Go to Solution.
- Labels:
-
FMC-FSMC
-
STM32H7 Series
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-06-13 1:48 PM
Well.......... I have fixed my problem. it wasn't in the FMC setup or the memory region setup. It was an error in my access code. I forgat an '&'. I actually saw this while posting my last message : )
My original code:
halStat = HAL_SRAM_Write_32b(&hsram1, (uint32_t *)(SRAM_BANK_ADDR + addr), (uint32_t *) vctBuf.vb85[vbi][vni][0], VECT_LEN);
My fixed code: ( (uint32_t *) &vctBuf )
halStat = HAL_SRAM_Write_32b(&hsram1, (uint32_t *)(SRAM_BANK_ADDR + addr), (uint32_t *) &vctBuf.vb85[vbi][vni][vi], VECT_LEN);
Old dogs make mistakes too!
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-06-13 1:25 PM
Here is the code generated from the .ioc file.
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.BaseAddress = 0x60000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32B;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
I changed it to the following in an attempt to get it to work.
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x60000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32B;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
I have also attached a picture of the Memory Management tool from the .ioc file.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-06-13 1:48 PM
Well.......... I have fixed my problem. it wasn't in the FMC setup or the memory region setup. It was an error in my access code. I forgat an '&'. I actually saw this while posting my last message : )
My original code:
halStat = HAL_SRAM_Write_32b(&hsram1, (uint32_t *)(SRAM_BANK_ADDR + addr), (uint32_t *) vctBuf.vb85[vbi][vni][0], VECT_LEN);
My fixed code: ( (uint32_t *) &vctBuf )
halStat = HAL_SRAM_Write_32b(&hsram1, (uint32_t *)(SRAM_BANK_ADDR + addr), (uint32_t *) &vctBuf.vb85[vbi][vni][vi], VECT_LEN);
Old dogs make mistakes too!
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-06-13 1:49 PM
MPU failures would typically go to MemManage_Handler first.
Unpack the actual HardFault failure address, confirm it's on 0x60000000
If it is you'll need to unpack the RCC (clocks) and FMC registers, making sure that's all started up as expected. Dump registers and share.
Up vote any posts that you find helpful, it shows what's working..
