DISCO-F746NG LCD rapid draw to screen location causes a visible glitch

Hi All,

I’ve run into a LCD glitch that’s completely stumped me:
I’ve made a custom board based on the STM32F746ZG, a IS42S16400 SDRAM and RK043HR005-CTG (Same supplier as used on DISCO-F746NG, but 800x480. Similar timings, but obviously a much larger active area and clock).
Drawing to the screen is done via double buffering, using the first two banks of the SDRAM, and everything appears fine when drawing simple objects to the screen.
However when drawing to the same part of the screen (all draws done to back buffer) more than once per screen refresh a visible glitch is observed, where part of the previous draws will be visible for a very short duration before disappearing. The size of the glitch appears to be directly proportional to the size of the area being drawn to.

I was able to replicate the issue on my DISCO-F746NG boards, except with the size of the glitch being far smaller, I’m assuming due to the same LTDC/SDRAM clock rates being used to draw on a far slower pixel clock. I’m using solid RG&B shapes for the replication, but it is just as, if not more obvious when drawing more complex objects, many of which are 4-5 individual props blended on top of each other directly into the back buffer.

Code published here for easy replication.

This is what it looks like if the code draws directly to the front buffer, and is also the exact same size and pattern as the glitch when double buffering (Just that the screen is predominantly blue with the coloured glitches visible). The color is also solid red (on a more expensive camera, the pink is just my phone not being ideal.

If anyone’s run into something similar and has an idea of what could be causing this I’d be glad to hear it. I’ve managed to make some improvements by enabling burst read/write SDRAM transfers (although this seems to create some “ghost” pixel glitches in addition to the (now) smaller block glitch) and really slowing down the LCD’s pixel clock. Similarly using a for loop to manually draw the pixels in creates a lot of noise in the glitch size, which was otherwise rock solid, which may be useful info. I’m suspecting the FMC/SDRAM being the primary culprit, but it’s by far the part of the STM32 I know least about, so I’m at a loss of what to try.

Regards,
Tom

Stupid question: have you tried using TouchGFX to see if the issue persist with their implementation?

It looks like tearing effect, but I’m not an expert.

Maybe it has a common root with this issue. I don’t have such board to test but Wim’s thoughts seem reasonable.

A quick description of the program which replicates the issue (which I forgot to add to original post):
The program in question waits for the screen to exit the active area (via line interrupt) and quickly draws a full screen Red, Green then blue box over the entire screen into the back buffer. This finishes before the next line interrupt (although the draws are happening while the LTDC fetches the front buffer). Once the draws are completed the frame buffer is swapped, to take effect on next vsync, which then triggers a restoration of the new back buffer, by copying 1:1 the front buffer into it, before triggering the cycle to repeat.
This should result in a purely blue screen, but doesn’t…

Hi Ladislas,

TouchGFX doesn’t seem to have the same issue. Although I’m not sure how they assemble the “widgets” they use. It’s entirely possible they assemble them in a separate part of memory and copy to back buffer in 1 go (which I’m about to try). A quick screen-swap application didn’t show it up, although I suspect they’re forcing sync to screen refresh with screen change.
The only difference I can see at the DMA2D level is they’re performing D cache maintenance, which isn’t the issue here:
I’ve previously tried both disabling and liberally placed flush/clean/invalidates and it doesn’t seems to make a difference.

I’ll have a deeper look at their code when I’ve got the chance.
Unfortunately using their setup isn’t really an option here as I can’t create some of the objects I’m after (might be possible, I’ve only had a cursory look).

Cheers for the suggestion though,
Tom

PS,
Hi Zoltan,
It looks like the code in question causes its own issues by only mallocing 1/4 a bmp file size then copying the entire file in… Good 'ol seg-fault inducing buffer overflows without the seg-fault to protect the system.
Not really relevant here, especially since I can replicate it purely with R2M DMA2D calls. We’re only dropping values in, not copying or moving (apart from the back buffer restore which is always between two fixed points and of a fixed size).
Cheers,
Tom

Quick update: Using a 3rd buffer to assemble the props and swapping into the back in a single go appears to be a viable work-around for the issue. I don’t really regard it as an ideal solution, so I’ll leave the question open in case anyone has any ideas what’s causing the issue with the double buffered case.

(Code in previously linked example has been updated to be able to switch between single/double and triple buffering)

Regards,
Tom

The problem turned out to be a simple mistake…
After being used to the CMIS 1-referenced LTDC_Layer1 & 2 address, I mistakenly assumed the HAL_LTDC_ConfigLayer function was 1-referenced (I don’t use HAL all that much)…
It isn’t and what I though was double buffering was double-buffering an inactive layer…

The glitch was caused by every second frame drawing to the front buffer. Apparently most screen updates were quick enough that I never previously noticed any glitching in single draws. At least it proved the draw sync to exiting the active area was working well…

The simplest mistakes are always the most frustrating…

hi, I’m a beginner. May I have a question? how to integrate mbed-os with touchgfx ? I’ve researched the integrated way between mbed-os and touchgfx since 8 days ago, but the result is zero.

Hi @ruem11,

It is probably possible but may be complicated, you need a knowledge and understanding the structure of theTouchGFX I think. I also tried to find a guide in the past but with no luck.
If you still want to spend a time for it, I think better is visit the ST’s forum about TouchGFX also TouchGFX documentation and find how to start.

However the LVGL seems be more achievable. Although they do not have a gui editor and objects must be created via coding but have easy to use simulator in the Visual Studio.
Also in their documentation you can found a Porting section, which will help you. I also made a simple porting guide for Mbed but I am not sure how much up to date it is at the moment.

BR, Jan

1 Like

It also depends if you just want to display content or also react to touch events.

TouchGFX is good for the later but, depending on the content, to just display things on the LCD, you can manage to do that by hand.

Using ST’s BSP, you can find a lot of examples here: GitHub - STMicroelectronics/STM32CubeF7: STM32Cube MCU Full Package for the STM32F7 series - (HAL + LL Drivers, CMSIS Core, CMSIS Device, MW libraries plus a set of Projects running on all boards provided by ST (Nucleo, Evaluation and Discovery Kits))

It’s then a lot easier to integrate them with you mbed project (that’s what we did).

1 Like