cancel
Showing results for 
Search instead for 
Did you mean: 

Screen Flickering on Custom HMI with Double Buffer Enabled (STM32H750 + RGB888, 800x480)

Shekhar_Sukhabhogi
Associate III

Hi,

We are encountering a partial screen flickering issue when using a custom HMI with TouchGFX and double buffer enabled. The screen resolution is 800x480, but only the left portion (480x480) displays correctly. The remaining 320x480 area flickers during runtime, especially when updating data on the UI.

Key Observations:
This issue occurs only when double buffering is enabled.

In single buffer mode, minor flickering is still present, but it's significantly better than dual buffer mode.

The issue is isolated to our custom board and BSP configuration.

Cross-Test:
We tested the same TouchGFX button example on two different displays:

Custom Display Board – 800x480 (TFT-LCD, TST070WVBE-31)
→ Flickering observed

Test Board – 1024x600 (other manufacturer)
→ No flickering observed

The main difference:

Custom board: TouchGFX + BSP drivers (manually configured)

Test board: Fully CubeMX-generated configuration

System Configuration:
MCU: STM32H750

Display: TFT-LCD (TST070WVBE-31), 800x480, RGB888

TouchGFX: 4.24.0

STM32CubeIDE: 1.17.0

STM32CubeMX: 6.14.1

Crystal Frequency: 25 MHz

System Clock: 450 MHz

Display Timing Configuration:
Parameter Value
Width (Active) 800
Height (Active) 480
HSYNC 48
HBP 40
HFP 40
VSYNC 1
VBP 31
VFP 13

Horizontal Total = 48 + 40 + 800 + 40 = 928

Vertical Total = 1 + 31 + 480 + 13 = 525

Pixel Clock Calculation:

PLL3M = 5
PLL3N = 40
PLL3R = 6

VCO = (HSE / PLL3M) × PLL3N = (25 MHz / 5) × 40 = 200 MHz
DOTCLK = VCO / PLL3R = 200 MHz / 6 ≈ 33.33 MHz
Frame Rate ≈ 33.33 MHz / (928 × 525) ≈ **68.7 Hz**

Request:
Could anyone suggest what might be causing the flickering on the right side of the screen (320x480) during UI updates with double buffering?

Are there any known limitations with partial redraws or framebuffer alignment for RGB888 mode?

Could manual invalidateRect() or framebuffer region management be affecting this?

Any experience comparing CubeMX vs. custom BSP configurations in such cases?

We’ve attached the relevant configuration files and video evidence for reference.

Please let me know if additional details are required. Any insights or suggestions to help resolve this issue would be greatly appreciated!

Best regards,
Shekhar

14 REPLIES 14

1. "Change framebuffer format, not display format":
Reply:
Could you please clarify what exactly is meant by changing the framebuffer format?

Is there any additional setting required to change the framebuffer format (e.g., in HAL/LTDC/TouchGFX linker or allocation logic)?
If so, where and how should this be applied?


2. "SDRAM over 2MB fail" — we allocated 16MB:
Reply:
As shown in below attachments, our .ld file allocates 16MB for RAM_FB starting from 0xC0000000.
We are using:uint32_t frameBuf[(800 * 480 * 3) / 4 * 2];
This allocates ~2.25MB for double buffer with RGB888 (or ~1.5MB for RGB565).

Do you suspect:

SDRAM hardware reliability?

Cache configuration/misalignment?

Misconfigured MPU settings?

Are there any tools/methods to validate SDRAM beyond 2MB?

 

1_ld_file.png

 

2_ld_file.png

  


3. appnote define max clock for double buff with DMA2D to 36MHz on 24 bit. You use 33,33 , then your memory and MCU config cant differ from optimal max more as 8%:
Reply:
As per the "Table 12. STM32H742/43/45/47/53/55/57 and STM32H750 maximal supported pixel clock" in application note AN4861, page number 29 (see attachment shown below), max pixel clock for STM32H750 with:

LTDC + DMA2D

RGB888 (24-bit)
→ is 38 MHz.

We're currently using 33.33 MHz, which is close but below the threshold.

To be on the safer side:

Would reducing the pixel clock to 20 MHz be a good fallback?

Is there a recommended “safe margin” (%) for SDRAM when nearing LTDC+DMA2D bandwidth limit?

3_LDTC+DMA2D_Clock_Limits.png


4. Secondary switching from single buffer target to double isnt one line change:
Reply:
We have configured double buffering in TouchGFXGeneratedHAL::initialize() and assigned two buffers using setFrameBufferStartAddresses(...).
Please refer to below attachments for the exact configuration.

 

4_SetFrameBuffer_Addr.png

 

5_SetFrameBufferAddr.png

Do you see anything missing in our implementation?

Are there any additional steps in TouchGFX/target/ or HAL/CubeIDE beyond this setup?

 

Looking forward to your suggestions.

 

Thanks & Regards,

Shekhar

Here isnt place to course you. For example TouchGFXConfiguration.cpp in generated target have lines 

#include <platform/driver/lcd/LCD16bpp.hpp>

static LCD16bpp display;

that when you adopt and not change to 24 result is second buffer copied only 800x480x2 instead x3 etc.

 

Hi,

Thank you for your continued support.

As per your suggestion, I made the necessary framebuffer-related changes, detailed below:

 

In TouchGFXGeneratedHAL.cpp:

  • Added memory section directive:

LOCATION_PRAGMA(".bss.TouchGFX_Framebuffer")
uint32_t frameBuf[(800 * 480 * 3 + 3) / 4 * 2] LOCATION_ATTRIBUTE(".bss.TouchGFX_Framebuffer");

setFrameBufferStartAddresses((void*)frameBuf, (void*)(frameBuf + sizeof(frameBuf)), (void*)0);

 

In TouchGFXConfiguration.cpp:

  • Updated include and display type to match 24bpp format:

  • #include <platform/driver/lcd/LCD24bpp.hpp>
    static LCD24bpp display;

 

Despite these updates, the flickering issue remains unresolved.

Additional observations:

  • I ran a simple SDRAM test (write 64MB with 0xA5, then read back) before the main application, and it passed successfully.

  • I also tested with reduced LTDC pixel clocks (20 MHz and 30 MHz), but the issue persists.

Please let me know if you have any further suggestions or areas I should investigate — I’ll be happy to try them out.

Thanks again for your support.

Best regards,
Shekhar

Hi,

Do you have any suggestions for me to try-out?

 

Thanks & Regards,

Shekhar

Your elementary basic mistakes continues

setFrameBufferStartAddresses((void*)frameBuf, (void*)(frameBuf + sizeof(frameBuf)), (void*)0);

little explain you alocate x2 one buff , but here second buff place to address after first x2.... unalocated space

More clean is create fbuf1 and fbuf2 ...

Next in appnote is described , that better is place starts on sdram pages starts. For example if your sdram banks is 2MB size then fist buff is C0000000 and second C0200000, this memories is reserved in linker script and allocated by address, no as your by linker.

And as i say changing 16bit to 24bit isnt simple change. When you adopt project from 16bit leave it 16bit RGB565.