2025-09-16 1:44 AM - last edited on 2025-09-16 1:50 AM by Andrew Neil
Hi,
I am working with an STM32F769 MCU driving a 480×272 RGB565 TFT display through LTDC.
Architecture:
Framebuffer in external SDRAM (IS42S16800F-7TL, 16 MB) connected via FMC.
LTDC + DMA2D used for graphics update (TouchGFX).
I²C + DMA used to read/write parameters on an external FRAM.
System managed with FreeRTOS.
Problem:
When a long I²C DMA transfer is running (FRAM read/write for parameter storage), I see horizontal glitches on the display: objects temporarily shift to the right (as if some pixels were missing).
The curious part is that the phenomenon only happens if I change the initialization sequence in main() from this:
MX_LTDC_Init();
HAL_Delay(1000); // avoid flickering on display
MX_TouchGFX_Init();
HAL_Delay(200); // avoid flickering on display
osKernelInitialize();
…to this:
MX_LTDC_Init();
HAL_Delay(1000); // avoid flickering on display
MX_TouchGFX_Init();
HAL_Delay(200); // avoid flickering on display
__NOP(); // added
__NOP(); // added
osKernelInitialize();
adding only 2 _NOP();
really can’t explain why just adding, in this init sequence, two NOP instructions makes the glitch appear.
Solved! Go to Solution.
2025-09-18 9:24 AM - edited 2025-09-18 9:24 AM
@CiuppaPT wrote:
Couldn’t this be the cause of our problem? Reference from AN4861.
The first MPU config, I provided to you (the background config) prevents that issue to occur. Moreover, the workaround of that limitation was already implemented in the system_stm32f7xx.c file / line 632:
/*
* Disable the FMC bank1 (enabled after reset).
* This, prevents CPU speculation access on this bank which blocks the use of FMC during
* 24us. During this time the others FMC master (such as LTDC) cannot use it!
*/
FMC_Bank1->BTCR[0] = 0x000030d2;
(void)(tmp);
}
Now, as I said, try to reorganize your MPU config.
2025-09-18 3:49 AM
Hello,
Did you set the MPU background configuration to prevent speculative access of CM7?
You can refer to this post.
2025-09-18 6:37 AM
Hello @CiuppaPT ,
Have you tried to raise LTDC priority?
2025-09-18 7:50 AM
I tried everything, but none of the things I tried worked; I list them below. The only one that had any effect was commenting out the call in main()
/* Enable D-Cache--------------------------------------------------- ----- -*/
SCB_EnableDCache();
1) Raised the priority of the LTDC and DMA2D over the I2C DMA (failed)
2) Moved the buffer accessed by the I2C before DMA transfers from the external SDRAM to the internal SRAM1 (failed)
3) Set the property in MPU_Config to NON_CAHABLE for the FRAME_BUFFER of the display located at address 0xC0000000 (failed)
4) Inserted the InvalidateCache() method in both of the following...
TouchGFXGeneratedHAL::beginFrame()
TouchGFXGeneratedHAL::endFrame()
(failed)
At this point, I would be satisfied to understand why only disabling the D-CACHE seems to have a definitive effect on the problem.
Thank you
2025-09-18 7:50 AM
I tried everything, but none of the things I tried worked; I list them below. The only one that had any effect was commenting out the call in main()
/* Enable D-Cache--------------------------------------------------- ----- -*/
SCB_EnableDCache();
1) Raised the priority of the LTDC and DMA2D over the I2C DMA (failed)
2) Moved the buffer accessed by the I2C before DMA transfers from the external SDRAM to the internal SRAM1 (failed)
3) Set the property in MPU_Config to NON_CAHABLE for the FRAME_BUFFER of the display located at address 0xC0000000 (failed)
4) Inserted the InvalidateCache() method in both of the following...
TouchGFXGeneratedHAL::beginFrame()
TouchGFXGeneratedHAL::endFrame()
(failed)
At this point, I would be satisfied to understand why only disabling the D-CACHE seems to have a definitive effect on the problem.
Thank you
2025-09-18 7:52 AM
My Toolchain :
STM32CubeIDE Version: 1.18.0 Build: 24413_20250227_1633 (UTC)
TouchGFX "Version": "4.23.2"
2025-09-18 7:53 AM
You didn't confirm if you enabled the MPU background configuration:
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 MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
2025-09-18 8:05 AM
No! This section is not in my MPU_config. I don't really understand its function. Should I include it ?
2025-09-18 8:08 AM - edited 2025-09-18 8:10 AM
Yes, it's quite recommended in STM32 with CM7 core to prevent the speculative access. Even (maybe) it doesn't solve your issue, you should do it. It should be the first call in your MPU config, then you need to open region by region what you are using in your application: SDRAM, QSPI following their sizes.
2025-09-18 8:13 AM
Unfortunately, the MPU background init did not solve the issue.