cancel
Showing results for 
Search instead for 
Did you mean: 

Diagonal tearing on LCD_DSI_VideoMode_DoubleBuffering on STM32F469I-DISCO DK32F469I$AU

Richard-CRT
Associate III

[If this would be better off in one of the other STM32 MCUs sub-forums, please feel free to move it admins]

I have spent a very long time removing the BSP initialisation calls from the LCD_DSI_VideoMode_DoubleBuffering example on STM32F469I-DISCO, however it behaves exactly the same using the "stock" example and with my modifications. I am not using TouchGFX.

The symptom is a consistent diagonal tear in a fixed location on my landscape configured display regardless of where the region of the screen I am editing is. Naturally, if the region I'm editing doesn't cross the diagonal, the tear isn't visible. Slow mo video of issue is attached.

In both the example and my modified code, the screen is waiting on HAL_LTDC_LineEventCallback to switch to a new buffer like so:

RichardCRT_0-1714667465849.png

In my modified code as shown above, Buffers[front_buffer] is written to (using DMA2D) while the state machine is at the state before BufferPrepared, and then the state machine moves on to BufferPrepared 200ms later (same behaviour when this is much higher). 200ms allows the DMA2D plenty of time to complete, so when the interrupt above fires with the buffer state correctly set the data should be stable and unchanging.

So in summary, I have 2 buffers in SDRAM. The DMA2D is only ever writing to the one that the LTDC is not reading. And there's a significant enough delay between the DMA2D operation and the LTDC swapping buffers that the DMA2D must have completed in time. So why does the display end up displaying half (not exactly half, but whatever) of the old buffer and half of the new buffer, split by a diagonal line?

The first of the previous tickets below indicates that this is caused by the screen updating in a 'portrait' manner while the LTDC is updating in a 'landscape' manner, but I don't fully understand this, and neither did the OP of that question (@S.K.Matters), but they never received any further explanation. What's more, even if that is an explanation of the issue, why has the LCD_DSI_VideoMode_DoubleBuffering example got this issue?

The second of the previous tickets below has the same issue, complete with a similar video, but received no reply. I'm hoping someone will be able to reply to this one.

The last ticket I have linked from just a few days ago refers to the same exact issue on a different DISCO board (STM32H747I-DISCO) and the ST employee there said he has reported it internally.

 

Previous tickets going back 5 years ago with seemingly the same issue but no solution:

https://community.st.com/t5/stm32-mcus-touchgfx-and-gui/some-kind-of-tearing-effect-with-lcd-dsi-videomode/td-p/398477

https://community.st.com/t5/stm32-mcus-touchgfx-and-gui/stm32f469i-disco-screen-tearing-on-double-buffer-example/m-p/668979#M37372

Previous ticket with seemingly the same issue on a different dev board and a ST employee saying the issue was "reported":

https://community.st.com/t5/stm32-mcus-products/stm32h747i-disco-tearing-in-double-buffering/m-p/647508#M237425

 

23 REPLIES 23

This was my finding too. In landscape mode, I was able to minimise the porch values as follows, which is slightly lower than the values given in the example (I was trying to get a higher refresh rate at all costs):

  • HSYNC 2
  • HBP 10
  • HFP 10
  • VSYNC 120
  • VBP 140
  • VFP 100

Interestingly, the portrait mode is able to handle lower porch values, despite what the nt35510.h BSP file in the example claims.


* @brief NT35510_800X480 Timing parameters for Landscape orientation mode

* Same values as for Portrait mode in fact.


I don't have exact values for this, but I know that portrait mode still functions when VSYNC VBP and VFP are all 100, whereas in landscape mode, as you say, the display simply doesn't show anything. It breaks again when VSYNC VBP and VFP are all 50, so it's still not nearly as good as the Linux configuration, despite them both being portrait.

I won't post pictures as the driver datasheet is plastered with "confidential" but page 68 of the easily google-able NT35510 datasheet also gives some constraints for the porch values, and they (especially the Vxx values) are much lower than the values in the STM example. It's interesting that the Linux configuration is able to use values much more similar to those given in the datasheet.

 

  The lane byte clock is set 62500 Khz
  The pixel clock is set to 27429 Khz
  */
  if(Lcd_Driver_Type == LCD_CTRL_NT35510)
  {
    VidCfg.HorizontalSyncActive = (NT35510_480X800_HSYNC * 62500U)/27429U;
    VidCfg.HorizontalBackPorch = (NT35510_480X800_HBP * 62500U)/27429U;
    VidCfg.HorizontalLine = ((Width + NT35510_480X800_HSYNC + NT35510_480X800_HBP + NT35510_480X800_HFP) * 62500U)/27429U;

 

in debuger check values calculated here , too clock ltdc is real 27.429MHz ? And is max DSI speed required?

 

@Alekseusis correct that the pixel clock has to be provided to the peripheral initialisation as an integer number of KHz. 27429 KHz is the value used in the example provided by STM, but I have also been able to get it to work at a lower speed, and as high as 35000 KHz.

For completeness: the limiting factor of the pixel clock on this dev board seems to the FMC/SDRAM bandwidth - page 26 of AN4861 has some good recommendations on that topic.

I ask if in clock config you have this numbers as in code

MM1_0-1715367060296.png

but we can end this conversation with explain. This display work ok with portrait refresh because controller NT reads GRAM and shows data on display filled in memory from video mode traffic. Tearing here may occur but is line type on place where data is read and writed same time (protected with some buffer or GRAM bidi). But when GRAM is filled in landscape order and read in portrait tearing is angle line type diagonal and visible (protect rw not work here)