Need 60+ Fps on QSPI 500x500 display

,

Seeking Advice: Achieving 60+ FPS on a 500x500 QSPI Display – Microcontroller and Optimization Tips?

Hello everyone,

I’m planning a project that involves using a QSPI display with a resolution of around 500x500 pixels, and my goal is to achieve a smooth frame rate of 60 FPS or higher.

I’ve previously worked with the ESP32-S3 and developed interfaces for 480x272 displays. However, I’ve noticed that when the UI becomes even moderately complex, the ESP32-S3 struggles to maintain performance — rarely reaching 30 FPS, even on simple screens. This makes me wonder if I’m missing some configuration tweaks or if the chip is simply not suited for higher frame rates in such cases.

That brings me to two main questions:

  1. Are there any recommended microcontrollers capable of reliably driving a 500x500 QSPI display at 60+ FPS?
  2. What techniques or best practices should I follow to optimize rendering performance on embedded systems like these?

Any insights, hardware suggestions, or pointers to resources would be greatly appreciated.

Thanks in advance!

1 Like

Basic school match 500x500x16x60 is bps for QSPI . Internal bus too require read this from memory and construct data before send.

1 Like

OK so think about the bandwidth needed to transfer 500 x 500 x 24 * 60…

quad SPI in 1/2 duplex mode at maximum speed on say an ESP32 S3 is going to be 80mhz * 4 lanes. That means you are able to transfer 80,000,000 * 4 bits per second.

Just one frame at 500 x 500 resolution is going to be 6,000,000 bits. and you want to do at least 60 of those a second. You are looking at 360,000,000 bits that need to be sent. If we divide that by 4 which will tell us how many bits need to be sent per lane you end up with 90,000,000. Which is 90mhz. So it’s impossible to achieve. You also have to keep in mind that there is overhead that will reduce the speed in which it is able to send. If the frame buffers are located in SPIRAM the maximum speed you will be able to transfer at is going to be 1/2 the speed that the SPIRAM is running at if the SPIRAM is using a quad SPI. This is because of reading and writing to that memory at the same time. One buffer being transmitted while the other is being written to by LVGL.

The P4 would be able to fair better than the S3 but even then you would still never get to 60FPS. using quad SPI. It cannot be done as you can see by the numbers above. You cannot ram more data down the SPI then it is able to handle. You are better off using a P4 with an MIPI DSI display. That you would be able to get to that kind of a frame rate because the DSI bus is able to transfer at something like 1.2 gHz per lane (2 lanes).

You can squeeze some more performance if you have LVGL running on one core of the ESP32 and on the other core you have the driver that is passing the data to the display. The reason why you get better performance this way is becasue the interrupts that take place to send the next transaction will happen on a different core than LVGL is running on so LVGL will not get interrupted while it is rendering.

3 Likes

you can also trim down the amount of data being sent if you use RGB565 and then you might get really close to the 60FPS. You will probably fall short a couple frames of that target but it will be close.

1 Like

Good day @kdschlosser
Also, as the author of the topic, I am interested in code optimization and speeding up work.
My hardware is esp32s3 + display connected via RGB interface.
I am already looking for attempts to increase the image speed and FPS.
To my regret, I am not an expert in using freeRTOS, and attempts to find working examples for LVGL and freeRTOS have never ended successfully.
Could you show an example of work, as you say - assign LVGL work to one esp32s3 core, and assign the driver work to another esp32s3 core.
Perhaps this is some kind of commercial secret, but most likely it is physically impossible for esp32s3, because as far as I know, on this microcontroller core 1 or core 2 is always used to work with Wi-Fi and therefore it is a super-complex task to simply distribute tasks between cores.
On simple tasks, esp32s3 often went into a cyclic reboot or displayed

brownout detector was triggered

Sorry for my tone, but except for advices to do so, unfortunately I did not find working options to do this.
I think the author of the topic could not find any options either, since the topic died out.
Thank you :slightly_smiling_face:

RGB displays are very tricky to deal with on the ESP32.

Here is an example of how to go about doing it…

1 Like

My device Guition ESP32-4848S040
LVGL simulator gives 26 FPS with this example of a busy animation

Real hardware gives only 8 FPS

The example is really complicated both for understanding and in terms of code.
I don’t know Python, much less micropython.
But a quick look at the code did not show how tasks are assigned to the esp32s3 cores.
Which proves my assertion that there are no real examples of distributing tasks to core1 and core2.
But you advised the author of the topic to do this above :roll_eyes:

Could you point to examples of such solutions or give a simple example of assigning the task of working with LVGL to core1, and working with the display to core2?
At least for simple displays connected via SPI or QSPI.

In any case, thank you for your participation in the discussion, I hope solutions will be found sooner or later :grinning:

You want me to provide links to every single location in the code where the tasks are assigned? Or optionally you can look through the different files and see where the tasks are created…

That code works, it’s all right there… That is C code not Python code.

2 Likes

Yes, what can we say about the work of LVGL and distribution of tasks among cores?
On this forum I came across a description of how to enable the work of LVGL in conjunction with freeRTOS, again everything is at the level of recommendations

disable lv_timer_handler();

and enable the freeRTOS ticker.
Code, especially working, especially for LVGL 9.3 is definitely not to be found.
Yes, everyone just does not care about this.
LVGL does its job, if the hardware is not powerful enough, then you just need to choose more powerful.
Each has its own developer, LVGL has its own development team, freeRTOS has its own, esp-idf has its own and each other does not care about the others.
Until recently, freeRTOS experienced problems with the transition to ESP-IDF version 3.
Therefore, regarding ordinary developers (not professional programmers), the only place to get information and experience is forums like this one.
And the only help is documentation and people like you @kdschlosser :grinning:

As far as I know freeRTOS, there is a function for assigning a task to a core

https://docs.espressif.com/projects/esp-idf/en/v4.3/esp32/api-reference/system/freertos.html#_CPPv429xTaskCreateStaticPinnedToCore14TaskFunction_tPCKcK8uint32_tPCv11UBaseType_tPC11StackType_tPC12StaticTask_tK10BaseType_t

I did not see this in the code you provided :roll_eyes:

I really appreciated your detailed response — it helped a lot.

Based on your explanation, I’ve decided to switch to using the ESP32-P4 for this project. I’ll also look into displays that use MIPI DSI, as you suggested, to achieve the required bandwidth and performance.

However, I know it might be challenging to find a capacitive touch AMOLED/OLED display with specs close to 500x500 resolution, under 2 inches, and MIPI interface.

If you happen to know any specific display models or suppliers that fit this criteria, I’d love to hear your recommendations.

Thanks again for the insights!

1 Like

@Yuri_Alves_Bordin

does the display need to have a 1:1 aspect ratio. That is what will make it a challenge to locate. If you could use a display that had an aspect ratio that was not 1:1 it would make it easier. typically displays that are a 1:1 ratio are round displays.

I will see what I am able to locate. If the resolution is higher is that an issue? The 2" size I would assume is what the real boundary is and not so much the resolution so long as it is a minimum of 500 x 500

Lets say it can be around 400x400 to 500x500 and the ratio dont need to be 1:1 but at least close its not suposed to be a rectangle, rounded displays are fine one thing did not mention is that i also need a capacitive touchscreen also i am looking to be around 1.5 to 2 inches its a wearable device

as an example… here is an MIPI DSI display that is 480 x 480. it is a tad over 2" but it is round…

1 Like

That’s actually not a bad one might use it, thanks!

With that display (ignore the displayed description and actually click on the link) it should plug right into this board…

Now you would need to get a ZIF breakout for the touch IC so you can connect to the GPIO’s on that board. Not a big deal to do.

Have found this one as well, what u think about it?

BuyDisplay.com is a legit company and they will ship you what you are ordering and it’s of a decent quality. Their example code is only geared to the STM line of MCU’s which doesn’t offer huge amount of help in the code example department but the documentation for most of their displays is pretty good. They do have tech support and they do respond to e-mails tho it is hard to understand what they are saying due to language differences.

IDK what I did to that last post. It is showing up as red. I accidentally clicked on something and don’t know how to undo it.

IDK if the last post is even showing up to other users so I will repeat what I had said…

You have to be careful with how displays are advertised. MIPI is not a DSI connection. MIPI is a standard and that standard covers I8080, SPI and DSI connections. so it stating that it is MIPI/QSPI leads me to believe that the display is MIPI DBI Type C compliant

Here are the common MIPI specification types.

MIPI DPI: RGB bus type
MIPI DBI Type A: Motorola 6800 bus type
MIPI DBI Type B: Intel I8080 bus type
MIPI DBI Type C: SPI bus type
MIPI DSI: Display Serial Interface bus type

Unless it specifically says “DSI” the display might not support the high speed serial bus type.

EDIT

Apparently I accidentally deleted the last post.

2 Likes

Thanks a lot for the clarification.
I wasn’t aware that MIPI includes DBI types as well, and that just labeling something “MIPI” doesn’t guarantee it’s using the high-speed DSI interface. That really helps me avoid making a bad hardware choice early on.

And no worries about the deleted post

I am not sure as to why it has become a thing to label displays as being “MIPI” when they are actually DSI displays. the 2 are not interchangeable but it appears that the display manufacturers have not figure that out. King of like what a panel’s native resolution is. Too many times I have seen displays labeled as something like 480 x 320 when the display is actually 320 x 480. This is even more frustrating when dealing with something like a DSI display or an RGB display that doesn’t have internal GRAM and would require software rotation to make it 480 x 320. That can make or break a project because of the processor time involved in handling the rotation.

1 Like