cancel
Showing results for 
Search instead for 
Did you mean: 

TouchGFX: Visual artifacts and ghosting on Scroll Wheel (STM32F767)

Trampler
Associate III

Hello everyone,

I am developing a UI using TouchGFX on a custom board based on the STM32F767. I am encountering visual artifacts during screen updates.

As seen in the attached video:

  1. In the date selection wheel, the text overlaps, tears, and leaves ghosting artifacts during scrolling.

  2. The first menu ("Date & Time", "Language" etc.) is inside a ScrollableContainer with a ListLayout. Initially, the text is corrupted. However, as soon as I scroll this container, the artifacts disappear completely and the screen draws correctly.

System Info:

  • MCU: STM32F767

  • GUI: TouchGFX (Version: [Sürüm] )

  • Memory: Framebuffer is located in [SDRAM vb.]

  • Configuration: MPU is ENABLED, D-Cache is ENABLED.

What could be causing this issue? Any suggestions on which configurations or settings I should check?

Thank you!

3 REPLIES 3
Trampler
Associate III

Any suggestions on this? Still looking for a solution. Thanks in advance!

GPT says:

this is a very typical TouchGFX issue, and the symptoms you describe point quite strongly to framebuffer / cache / invalidation problems, not a widget bug.

Let’s decode your two observations:


What your symptoms mean

1. “Text overlaps / tears / ghosting during scrolling”

Classic sign of:

  • framebuffer not being fully updated
  • or DMA / CPU writing out of sync

2. “Artifacts disappear after scrolling once”

This is the big clue.

It usually means:

The screen is not properly initialized or invalidated, and scrolling forces a full redraw → fixing it temporarily.


Most likely causes (ranked)

1. D-Cache issue (VERY common on STM32F767)

The F7 has data cache, and TouchGFX uses DMA.

If you don’t manage cache properly:

  • CPU writes to framebuffer → stays in cache
  • DMA reads old data → artifacts / ghosting

Fix

You must ensure cache clean before DMA reads framebuffer:

Typical places:

SCB_CleanDCache_by_Addr(...)

Or enable TouchGFX cache handling:

#define USE_BPP 16 // example
 

Also check:

  • framebuffer in AXI SRAM (not DTCM!)
  • cache maintenance enabled in BSP

2. Framebuffer location (critical)

If framebuffer is in:

  • DTCM → DMA cannot access it properly
  • wrong SRAM region → corruption

It should be in:

  • AXI SRAM (e.g. 0x20010000 region)

3. Missing / incorrect invalidation

TouchGFX relies on dirty rectangles.

If something isn’t invalidated:

  • old pixels remain → ghosting
  • scrolling forces redraw → fixes it

 Check:

  • custom widgets calling invalidate()
  • dynamic text updates

4. Double buffering not configured properly

If using:

  • single buffer → tearing possible
  • double buffer → must sync correctly

Check:

  • LTDC line event
  • buffer swap timing

5. LTDC / DMA2D sync issue

If LTDC reads while DMA2D writes:
→ tearing / partial updates

Ensure:

  • proper use of:
    • HAL_LTDC_ProgramLineEvent
    • VSYNC synchronization

 Why scrolling “fixes” it

Scrolling a ScrollableContainer:

  • invalidates entire region
  • forces full redraw
  • flushes bad framebuffer state

That’s why it suddenly looks correct


What I would check first (fast checklist)

  1. Framebuffer location
    • NOT in DTCM
    • in AXI SRAM
  2. Cache enabled?
    • If yes → are you cleaning it?
  3. TouchGFX config
    • FrameBufferAllocator
    • HAL::flushFrameBuffer()
  4. Linker script
    • correct memory region

Most likely root cause (based on your exact symptoms)

:warning:D-Cache not cleaned before LTDC/DMA reads framebuffer

This EXACT pattern:

  • corrupted initially
  • fixed after interaction
    → screams cache coherency issue on F7

Typical fix approach

In TouchGFX HAL:

 

void TouchGFXHAL::flushFrameBuffer(const touchgfx::Rect& rect)
{
SCB_CleanDCache();
}

Bottom line

  • This is almost certainly not a UI bug
  • It’s a memory/cache/sync issue
  • On F7, D-cache + framebuffer placement is the #1 suspect
PeterVang
ST Employee

Hello Trampler,

Based on your video, I think it looks like you are missing some screen area validation in you GUI code. When you do standard animations in TouchGFX, like e.g. scrolling a list, the framework knows that it needs to redraw the relevant area in the framebuffer. But when you manually manipulates widgets in GUI code, like changing the color of your text area, you need manually tell the framework to redraw this area. This is normally done by calling the invalidate method for the relevant widget, e.g.: myTextArea.invalidate().

For testing, you can try just directly calling invalidate() every tick or everytime you change something. This will invalidate the entire and thereby quickly reveal if the issue is related to invalidation. This should however only be used for testing, since redrawing the entire screen all the time can slow done performance a lot.

Best regards

Peter