cancel
Showing results for 
Search instead for 
Did you mean: 

Horizontal glitches on LTDC display during I2C/FRAM transfers with DMA

CiuppaPT
Associate III

 

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.

1 ACCEPTED SOLUTION

Accepted Solutions

@CiuppaPT wrote:

Couldn’t this be the cause of our problem? Reference from AN4861.

CiuppaPT_0-1758211241052.png

 


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.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

View solution in original post

21 REPLIES 21
mƎALLEm
ST Employee

Hello,

Did you set the MPU background configuration to prevent speculative access of CM7?

You can refer to this post.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Osman SOYKURT
ST Employee

Hello @CiuppaPT ,

Have you tried to raise LTDC priority? 

Osman SOYKURT
ST Software Developer | TouchGFX

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

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

CiuppaPT
Associate III

My Toolchain :
STM32CubeIDE Version: 1.18.0 Build: 24413_20250227_1633 (UTC)
TouchGFX  "Version": "4.23.2"

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);
}
To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

No! This section is not in my MPU_config. I don't really understand its function. Should I include it ?

 

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.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Unfortunately, the MPU background init did not solve the issue.