2024-08-27 12:00 PM
I have a STM32H7 with it's FMC signals hooked up to an FPGA in order to allow the microcontroller to peak/poke into FPGA registers. I had a FIFO in this address space that, if read, would automatically increment to the next value. I was noticing on occasion having two read requests for what should be only a single read in the code (causing data loss on the FIFO). I found this old post: https://community.st.com/t5/stm32-mcus-products/stm32f7-fmc-dummy-read/td-p/419015 in which someone saw the same issue and found out that interrupts were coming in causing the FMC to repeat the read once returning from the interrupt handler. I tried disabling interrupts and saw my problem go away.
What's odd is that I saw this happening very frequently on reads (occurring anywhere from a couple hundred to a few thousand reads in) but when stressing the writes at the same level, I never saw this occur. The difference in time to finish a read/write doesn't seem to be different enough to explain the disparity. Is there something I'm missing internally that may explain this difference?
Solved! Go to Solution.
2024-08-28 06:17 AM - edited 2024-08-28 06:35 AM
Try to configure FPGA memory region as Strongly-Ordered.
Declare this function and call it first one in your main():
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the FPGA memory regionas Strongly ordered */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x60000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256MB;
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_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
2024-08-27 01:04 PM
Hello,
Did you set the memory region of your FPGA as Device or Strongly-Ordred using MPU?
2024-08-28 05:49 AM
To be honest I'm still new with the STM32. I don't believe I changed anything in regards to the MPU settings. Doing some googling, it seems like the memory range that I'm using for it (0x60000000-0x6FFFFFFF) defaults to Normal instead of Device or Strongly-Ordered.
2024-08-28 06:17 AM - edited 2024-08-28 06:35 AM
Try to configure FPGA memory region as Strongly-Ordered.
Declare this function and call it first one in your main():
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the FPGA memory regionas Strongly ordered */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x60000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256MB;
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_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
2024-08-28 06:35 AM
Just set this up and ran it and it also solved my problem (so that I don't have to disable IRQs). Thank you! Definitely a cleaner solution.
I'm still wondering though. Do you know why, pre MPU change, I was seeing this issue on reads but not writes?
2024-08-28 07:02 AM
Due to complex Core pipelines, Cache + AXI transaction and its internal buffers and data/instruction fetches are not timely ordered in the sequence of the generated assembly when the memory region is set as Normal.
Configuring it as Strongly-Ordered forces all data/instructions to be fetched in order.
This applies also when a LCD is driven with FMC.