Skip to main content
Graduate
June 13, 2025
Solved

Hardfault after acessing FMC intyerface on STM32H753

  • June 13, 2025
  • 2 replies
  • 461 views

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!

 

 

    This topic has been closed for replies.
    Best answer by Hal56-GCI

    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!

     

    2 replies

    Hal56-GCIAuthor
    Graduate
    June 13, 2025

    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.

    Hal56-GCIAuthorAnswer
    Graduate
    June 13, 2025

    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!

     

    Graduate II
    June 13, 2025

    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.