I use esp32s3 and lvgl 8.3.11
The image is successfully drawn on the QSPI display with 360x360 px
I added two tasks to freeRTOS, one controls the backlight, and the other starts Wi-Fi and creates an access point on the device.
The pseudocode is:
#include "Arduino.h"
// setup for QSPI st77916 display
#include "scr_st77916.h"
#include <lvgl.h>
// widget
#include <ui.h>
// Task for initializing and controlling PWM
void pwmTask(void *pvParameters) {
while (true) {
}
backlight->setBrightness(brightness);
vTaskDelay(5 / portTICK_PERIOD_MS);
}
}
// Task for initializing wi-fi
void settingsTask(void *pvParameters) {
while (true) {
sett_loop();
vTaskDelay(5 / portTICK_PERIOD_MS);
}
}
void setup()
{
scr_lvgl_init();
ui_init();
// Task wi-fi
xTaskCreate(settingsTask, "Settings Task", 4096, NULL, 0, NULL);
// Task PWM
xTaskCreatePinnedToCore(pwmTask, "Task", configMINIMAL_STACK_SIZE + 1024, NULL, tskIDLE_PRIORITY, NULL, 0);
}
void loop()
{
// anything
}
The file scr_st77916.h contains display buffer settings for lvgl 8, part of the code is:
#define SCREEN_RES_HOR 280
#define SCREEN_RES_VER 280
// #define SCREEN_RES_HOR 359
// #define SCREEN_RES_VER 359
#define TFT_SPI_FREQ_HZ (30 * 1000 * 1000)
static void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
ESP_PanelLcd *lcd = (ESP_PanelLcd *)disp->user_data;
const int offsetx1 = area->x1;
const int offsetx2 = area->x2;
const int offsety1 = area->y1;
const int offsety2 = area->y2;
// lcd->drawBitmap(offsetx1, offsety1, offsetx2 - offsetx1 + 1, offsety2 - offsety1 + 1, (const uint8_t *)color_p);
lcd->drawBitmap(offsetx1 + RATIO, offsety1 + RATIO, offsetx2 - offsetx1 + 1, offsety2 - offsety1 + 1, (const uint8_t *)color_p);
}
static lv_color_t *disp_draw_buf = NULL;
static lv_color_t *buf1 = NULL;
static lv_color_t *buf2 = NULL;
static lv_disp_draw_buf_t draw_buf;
static lv_disp_drv_t disp_drv;
ESP_PanelBus_QSPI *panel_bus = new ESP_PanelBus_QSPI(TFT_CS, TFT_SCK, TFT_SDA0, TFT_SDA1, TFT_SDA2, TFT_SDA3);
panel_bus->configQspiFreqHz(TFT_SPI_FREQ_HZ);
panel_bus->begin();
lcd = new ESP_PanelLcd_ST77916(panel_bus, 16, TFT_RST);
lcd->init();
lcd->reset();
lcd->begin();
// old setup
size_t lv_cache_rows = 72;
size_t lv_buffer_size = SCREEN_RES_HOR * SCREEN_RES_VER;
disp_draw_buf = (lv_color_t *)heap_caps_malloc(lv_cache_rows * SCREEN_RES_HOR * 2, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
assert(disp_draw_buf);
buf1 = (lv_color_t *)heap_caps_malloc(lv_buffer_size, MALLOC_CAP_SPIRAM);
assert(buf1);
lv_init();
lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, buf1, SCREEN_RES_HOR * lv_cache_rows);
// new setup
drawBufSize = screenWidth * screenHeight;
buf1= (lv_color_t*)heap_caps_malloc(drawBufSize, MALLOC_CAP_SPIRAM);
assert(buf1);
buf2 = (lv_color_t*)heap_caps_malloc(drawBufSize, MALLOC_CAP_SPIRAM);
assert(buf2);
lv_init();
lv_disp_draw_buf_init(&draw_buf, buf1, buf2, SCREEN_RES_HOR * SCREEN_RES_VER);
With the old setup configuration I get this picture, and the pwm backlight works, but in the serial port there is this error:
E (3347) lcd_panel.io.spi: panel_io_spi_tx_color(395): spi transmit (queue) color failed
I tried to set the buffers as I set for the same display in lvgl 9.3 new setup, but in this case the display does not display anything except snow and the esp32s3 constantly reboots.
I managed to select the size 280x280, when the image is loaded and the animation starts working.
But I would like to understand the problem and set the buffers correctly.
In the code, the image is formed as a bitmap
lcd->drawBitmap(offsetx1 + RATIO, offsety1 + RATIO, offsetx2 - offsetx1 + 1, offsety2 - offsety1 + 1, (const uint8_t *)color_p);
I use the Arduino framework
Arduino Core 3.3.0 based on ESP-IDF v5.5.0 for Platformio
And a fairly old library for QSPI panels
Dependency Graph
|-- ESP32_IO_Expander @ 0.0.2
|-- ESP32_Display_Panel @ 0.1.4
For example, for lvgl 9.3 for the same device I use this display update function
void my_disp_flush(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) // LVGL 9.3
{
uint32_t w = lv_area_get_width(area);
uint32_t h = lv_area_get_height(area);
gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)px_map, w, h); // LVGL 9.3
lv_disp_flush_ready(disp);
}
But in version 8.3.11 it doesn’t work.






