Skip to main content
Graduate
September 24, 2025
Solved

STM32H743 FMC send only part of the data

  • September 24, 2025
  • 2 replies
  • 504 views

I am using an STM32H743 FMC to connect to the FPGA to do data transfer. (SRAM type with 16-bit data. I tried this on an STM32F429 and the test was successful) 

 

The test is to send some amount of data to the FPGA through FMC.

snkparty1_0-1758736871511.png

snkparty1_1-1758737054591.png

The code is quite simple. Write some data to 0x6000 0000 and check if the FPGA can get the data correctly.

My discovery is that if only a small amount of data has been sent and  chip select signal FMC_NE1 will remain high and no waveform can be observed...

snkparty1_2-1758737708330.png

Send 100 data and FMC_NE1 remains high

 

If I send lots of data(for example, 10000 data) then FPGA can receive data correctly, but the data FPGA receives starts from 2020(this number is also random, some time 1820 some time 3020, etc)

snkparty1_3-1758737921392.png

This phenomenon does not happen on F429... If I send 10 data and the FPGA can receive 10 data correctly...

 

    This topic has been closed for replies.
    Best answer by mƎALLEm

    Hello @snkparty1 ,

    If you need to communicate with a FPGA over FMC you need to configure the region at that address (in your case 0x6xxx xxxx) as Device or Strongly-ordred using the MPU.

    Try this MPU config, just put the size of the FPGA region:

    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);
    
     /* Enable the access to 0x60000000 address keeping the Strongly ordered config */
     MPU_InitStruct.Enable = MPU_REGION_ENABLE;
     MPU_InitStruct.BaseAddress = 0x60000000;
     MPU_InitStruct.Size = MPU_REGION_SIZE_<Size Region>;
     MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
     MPU_InitStruct.Number = MPU_REGION_NUMBER1;
     MPU_InitStruct.SubRegionDisable = 0x0;
     MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
    
     HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
     /* Enable the MPU */
     HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
    }

     

     

    2 replies

    Explorer
    September 24, 2025

    I wonder whether it is related to some sort of cache coherency problem since 0x6000_0000 address is marked as "Normal" and "Write back, write allocate cache attribute". You can try adding an MPU entry for this address range and mark this range as non-cached. If you want this region cached, you can also use the SCB_CleanDCache_by_Addr() to flush the data you wrote from the cache. Size argument to this API which is in bytes should be multiples of cache line size, like multiples of 32 bytes.

    Double check the FMC clock configuration, if you are using two different CubeMX configuration files(.ioc) for STM32F and STM32H. You can also compare the FMC and RCC register setup to make sure both STM32F and STM32H are configured similarly.

    snkparty1Author
    Graduate
    September 25, 2025

    Thank you so much for giving me the idea that this is caused by cache...

    I checked the code, checked the timing, checked the cable connection on the board, checked everything without realizing this was a cache-related issue. After setting MPU and disabling cache, the problem was solved.

    Technical Moderator
    September 25, 2025

    Don't disable the cache (that decreases the perf of your application) but use MPU to disable the cache from that specific region instead, i.e. setting that region as Device or Strongly-ordred (as provided above) .

    mƎALLEmAnswer
    Technical Moderator
    September 24, 2025

    Hello @snkparty1 ,

    If you need to communicate with a FPGA over FMC you need to configure the region at that address (in your case 0x6xxx xxxx) as Device or Strongly-ordred using the MPU.

    Try this MPU config, just put the size of the FPGA region:

    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);
    
     /* Enable the access to 0x60000000 address keeping the Strongly ordered config */
     MPU_InitStruct.Enable = MPU_REGION_ENABLE;
     MPU_InitStruct.BaseAddress = 0x60000000;
     MPU_InitStruct.Size = MPU_REGION_SIZE_<Size Region>;
     MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
     MPU_InitStruct.Number = MPU_REGION_NUMBER1;
     MPU_InitStruct.SubRegionDisable = 0x0;
     MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
    
     HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
     /* Enable the MPU */
     HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
    }

     

     

    snkparty1Author
    Graduate
    September 26, 2025

    I changed MPU config based on your sample code. Now data transferred to FPGA can be received correctly. Thank you for the help.

    There is only one setting I found 

    In your code sample "MPU_InitStruct.Number = MPU_REGION_NUMBER1;"

    Timing issue still remains under this setting. I changed this setting to level0 and the timing issue was solved.

    snkparty1_0-1758855187281.png

    level0(no timing issue)

    snkparty1_1-1758855424884.png

    level1(still timing is strange)

    snkparty1_2-1758855549819.png