Display is Flickering in Single Frame Buffer Configuration

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Display is Flickering in Single Frame Buffer Configuration

3,874 Views
Rudy25
Contributor I

Hi, good day!

We are using the iMXRT1062 and LCDIF to send the graphic data to LCD. We have the EVK1060 demo board and also our own custom board for our project.
In our project, we don't have the external RAM hence we are relying to the internal 1MB RAM of the MCU. Having said that, we have RAM space concern that's why we are planning to use only single frame buffer instead of two. The size of our lcd is 320x480 and pixel format of RGB565.
This configuration will result in having 307,200 Bytes of RAM for single frame buffer alone. The single frame buffer will be stored in the OCRAM2 and the rest of OCRAM2 up to OCRAM will be used for gui library dynamic allocation. ITCM and DTCM will be used for our application.

I tried to play around using the EVK demo board to run some of the available examples that used lcdif.
I tried two examples (evkmimxrt1060_elcdif_rgb and evkmimxrt1060_lvgl_guider) one without using gui library and the other one using the lvgl library.
When I run them out-of-the-box, as it is without modification from my end, both projects were working fine. The display on the screen was smooth.
These projects are running with double frame buffer and since our end goal is to only use single frame buffer, I did an adaptation to run single frame buffer. The display was visible on the screen but with some tearing effect/flickering. The display was really bad.

My question now, how to eliminate this tearing effect/flickering on the display when only single buffer is used? Probably we need to do some kind of synchronization. If yes, can you please let me know on how to achieve this?

Thank you very much.

0 Kudos
Reply
11 Replies

3,649 Views
DanielRuvalcaba
NXP TechSupport
NXP TechSupport

Hi,

Using a single frame buffer means that all the drawings have to be done during the period of VSYNC Pulse Width (VSW).

If the drawings can’t be done before the end of VBP, the tearing will likely be observed on the screen.

Please take a look to the pictures below.

DanielRuvalcaba_0-1697237337535.png

 

DanielRuvalcaba_1-1697237337577.png

I hope this helps.

Regards,

Daniel.

0 Kudos
Reply

3,661 Views
nsi
Contributor III

Hi, I encountered the same issue using LVGL.

Having only one buffer created flickering when changing the displayed contents.

I solved it by using 2 buffers that are half size of the screen. I have yet to run more tests with this configuration but that allowed me to use the memory footprint of a single buffer to save RAM.

According to LVGL documentation, you could even go to lower buffer sizes but I have yet to try it.

NB: although I don't understand why, I still had to give the size of the full screen when calling lv_disp_draw_buf_init which worries me a little bit that lvgl may be writing outside the buffer but for now its working.

 

 

 

0 Kudos
Reply

3,589 Views
Rudy25
Contributor I

Hi nsi,

Thanks for your response.
If possible, can you please provide the following info.
1. Which hardware platform are you using?
2. Which version of LVGL are you using?
3. Size of your LCD
4. Can you please provide a snapshot of you LVGL initialization part (e.g., buffer declaration, partial-mode/full refresh mode, direct/in-direct mode, etc..)?

I believe your display is not giving tearing/flickering effect because you reduced the amount of graphic data(half size of screen as you mentioned) and the overall time needed to do this is within the VSYNC period. If the complexity of your system has increased, probably you might encounter the display problem again.

Probably by synchronizing the amount of graphic data being drawn in accordance to the VSYNC period might solve the problem permanently.
I'm still trying to figure out on how to do it. But given the info from @DanielRuvalcaba and you, I think this is a possible solution moving forward.

Thank you

0 Kudos
Reply

3,581 Views
nsi
Contributor III

Hi,

Sure I can provide those info !

1. I have a custom board that uses the MIMXRT1062DJV6B. We have a slower XIP than the one on the EVK (80MHz Quad spi), no external RAM and our code does a lot of stuff so I will definitely have huge increases in complexity over the next few weeks of development.

2. LVGL version 8.3.2_rev1 (was shipped with SDK 2.13.1 if I remember correctly)

3. width: 240px, height: 320px with 16 bits / px

4. I started with the configuration from the lvgl_demo_widgets example. lv_conf.h was only modified to lower LV_MEM_SIZE to 24 kB (from 48) and to remove the demo. For the actual init, I also started from the example code and only modified what I had to, see attached screenshots.

It might be worth noting that having little experience with displays, I wasn't able to find the right parameters of the elcdif init. Right now I still have a line of pixel that is displayed on the wrong side of the screen (bottom line is on top). Using the parameters from the screen's datasheet wasn't working so i played around with hsw, hfp, hbp etc until it worked.

In the attached code, DEMO_FB_SIZE was divided by 2 compared to what it was originially

#define DEMO_FB_SIZE \
(((LCD_WIDTH * LCD_HEIGHT * LCD_FB_BYTE_PER_PIXEL) + DEMO_FB_ALIGN - 1 / 2) & ~(DEMO_FB_ALIGN - 1))

 

0 Kudos
Reply

3,553 Views
Rudy25
Contributor I

Hi nsi,

Thanks for your response and for answering my questions

I think your project is still running in full double frame buffer mode because of the priority of the operator, the compiler will handle the divide by 2 in different way.

To verify this, you can open your .map file and search for the variable "s_frameBuffer". From there, see how much RAM the variable s_frameBuffer is using.

Based on your lcd size and configuration, for full double frame buffer, you will see that variable s_frameBuffer  is consuming around 307200Bytes of RAM.

Thank you.

0 Kudos
Reply

3,534 Views
nsi
Contributor III

You are right, I shouldn't have worked on that so late at night.

After a little bit of experimenting, I haven't been able to have LVGL working with 2 non-screen-sized buffers. I still think it would be a good solution and will keep looking into it.

0 Kudos
Reply

3,811 Views
diego_charles
NXP TechSupport
NXP TechSupport

Hi @Rudy25 

I hope you are doing great!

Can you provide more details regarding the modification? Or, are you okay if I create an internal case so you can add the whole project there? I want to see MPU settings, code changes and map file to begin. 

How bad is the flicklering? Please share a picture here. Does it happen when there is a refresh on the image on the LCD? I have seen this issue related to the cache settings in the MPU configuration area. 

Best regards, 

Diego 

 

 

0 Kudos
Reply

3,807 Views
Rudy25
Contributor I

Hi @diego_charles 

Thanks for your response

I didn't do anything special. The system configuration like clock, mpu setting, etc., I didn't change them. I used the SDK as it is and only did below modification to run in single frame buffer mode.

For the evkmimxrt1060_elcdif_rgb project, I did the following modification to run in single frame buffer mode.
Change the frame buffer size from s_frameBuffer[2] to s_frameBuffer[1].
AT_NONCACHEABLE_SECTION_ALIGN(static uint32_t s_frameBuffer[1][APP_IMG_HEIGHT][APP_IMG_WIDTH], FRAME_BUFFER_ALIGN);

And inside the while(1), I comment out this line /* frameBufferIndex ^= 1U; */ and /* ELCDIF_SetNextBufferAddr(APP_ELCDIF, (uint32_t)s_frameBuffer[frameBufferIndex]); */
The ELCDIF_SetNextBufferAddr() function whether it is comment-out or not, the behavior is the same. I think this is fine as the project is running in single frame buffer.


And for evkmimxrt1060_lvgl_guider_bm project, I did the following modification to run in single frame buffer mode.
Change the frame buffer size from s_frameBuffer[2] to s_frameBuffer[1].
SDK_ALIGN(static uint8_t s_frameBuffer[1][DEMO_FB_SIZE], DEMO_FB_ALIGN);

In the lvgl initialization "lv_port_disp_init()", I set the second frame buffer to NULL as written in LVGL documentation.
lv_disp_draw_buf_init(&disp_buf, s_frameBuffer[0], NULL, LCD_WIDTH * LCD_HEIGHT);


I would say the flickering is bad and I think it is happening even without redrawing/repainting data/image to LCD.

Do you have the EVK1060 demo board on your side? If yes, please take the latest SDK and run it with single frame buffer modification and see if you are also getting the flickering problem.

By the way, I tried to run the examples using the EVK1060 demo board and our own project board (using only internal RAM) and behavior is the same. Display is flickering for single frame buffer mode. Double frame buffer mode, no problem at all regardless of the hardware board.


Thank you very much.

 

 

0 Kudos
Reply

3,794 Views
diego_charles
NXP TechSupport
NXP TechSupport

Hi @Rudy25 

Thank you for your detailed response. 

I will go ahead and try to replicate this  on my own. 

All the best, 

Diego

0 Kudos
Reply

3,774 Views
diego_charles
NXP TechSupport
NXP TechSupport

Hello, 

 

In order for me to have more details, could you please help me clarify the following information? 

Do you see the same behavior with an empty screen/buffer? 

Are you doing some additional buffer flushing ?

Also, could you please help me with the exact version and toolchain of the SDK you are using ? 

 

Regards,

0 Kudos
Reply

3,768 Views
Rudy25
Contributor I

Hi @diego_charles ,

I tried the following for single frame buffer mode.

Test-1:

1.1. Fill the frame buffer to draw small rectangle on screen.

1.2. Wait for the LCDIF interrupt.

1.3. When interrupt is triggered, fill the frame buffer to draw small rectangle on screen.

1.4. Repeat step 1.2 and 1.3

Note: The location/coordinate and the color of the small rectangle is not fixed. It keeps on changing everytime a new rectangle is redrawn on screen.

Observation: Maybe the correct word is not flickering but tearing effect. I can see incomplete rectangle displayed on screen. It was like, sometimes only the middle of rectangle was visible and first few pixels and last were missing in the display. 

 

Test-2:

2.1. Fill the frame buffer to draw small rectangle on screen.

2.2. Wait for the LCDIF interrupt but don't do anything further.

Observation: The small rectangle was visible on screen and in stable state. No flickering/tearing effect.

 

I was using the SDK v2.13.0 and  for Toolchain MCUXpresso v11.5.1 and IAR 9.20.1 (for our custom board). 

Please let me know if you need more info. Thank you very much.

 

0 Kudos
Reply