LV_COLOR_DEPTH=32 Never Works

Hi,

I am running a squareline exported lvgl code on ESP IDE for WT32-SC01 Plus Touch LCD which has a ESP32 S3 MCU.
If I set the color depth of squreline to 32 and export a single page and No image (Basically the simplest and lightest export from squreline) it crashes when I try to flash due to D/IRAM overflow.

Obviously I am doing something wrong because, I am running the most basic UI exported from squreline.
Does anyone have an idea why this is happening.

here is the error:
app-template.elf section .dram0.bss’ will not fit in region dram0_0_seg’
DRAM segment data does not fit.

Used stat D/IRAM: 400622 bytes ( -54766 remain, 115.8% used) Overflow detected! You can run idf.py size-files for more information.
.data size: 10736 bytes
.bss size: 321096 bytes
.text size: 67763 bytes
.vectors size: 1027 bytes

Here is the code:


#include <lvgl.h>
#include <demos/lv_demos.h>
#include "ui.h"
#include "LGFX_MakerFabs_Parallel_S3.hpp"


/ these do not have to be the same, not sure what is optimal
#define TASK_SLEEP_PERIOD_MS 1
#define LV_TICK_PERIOD_MS 1
#define LGFX_USE_V1
#define LV_DOUBLE_BUFFER
#define LANDSCAPE // if changing this, make sure to uncheck landscape in menuconfig -> components -> lvgl -> demos -> music
  // if you get "will not fit, dram segment overflow" reduce this
  #define LV_BUFFER_SIZE 80 /* if not double buffering, then buf will be 2x this */



static LGFX lcd;



/*** Setup screen resolution for LVGL ***/
static const uint16_t screenWidth = 480;
static const uint16_t screenHeight = 320;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[screenWidth * LV_BUFFER_SIZE];
static lv_color_t buf2[screenWidth * LV_BUFFER_SIZE];




/*** Function declaration ***/
static void display_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p);
static void touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data);
static void lv_tick_task(void *arg);


static void init_lvgl_lgfx()
{
    lcd.init();
    lv_init();
    lcd.setRotation(1);
    lcd.setBrightness(255);
    lcd.fillScreen(TFT_BLACK);

    lv_disp_draw_buf_init(&draw_buf, buf, buf2, screenWidth * LV_BUFFER_SIZE);

    /*** LVGL : Setup & Initialize the display device driver ***/
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.hor_res = screenWidth;
    disp_drv.ver_res = screenHeight;
    disp_drv.flush_cb = display_flush;
    disp_drv.draw_buf = &draw_buf;
    lv_disp_drv_register(&disp_drv);

    /*** LVGL : Setup & Initialize the input device driver ***/
    static lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = touchpad_read;
    lv_indev_drv_register(&indev_drv);

    /* Create and start a periodic timer interrupt to call lv_tick_inc */
    const esp_timer_create_args_t periodic_timer_args = {
        .callback = &lv_tick_task,
        .name = "periodic_gui"};
    esp_timer_handle_t periodic_timer;
    ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
    ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LV_TICK_PERIOD_MS * 1000));
}

/*** Display callback to flush the buffer to screen ***/
static void display_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{

    uint32_t w = (area->x2 - area->x1 + 1);
    uint32_t h = (area->y2 - area->y1 + 1);

    lcd.startWrite();
    lcd.setAddrWindow(area->x1, area->y1, w, h);
    lcd.writePixels((uint16_t *)&color_p->full, w * h, true);
    lcd.endWrite();

    lv_disp_flush_ready(disp);
}

/*** Touchpad callback to read the touchpad ***/
static void touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
    uint16_t touchX, touchY;
    bool touched = lcd.getTouch(&touchX, &touchY);

    if (!touched)
    {
        data->state = LV_INDEV_STATE_REL;
    }
    else
    {
        data->state = LV_INDEV_STATE_PR;

        /*Set the coordinates*/
        data->point.x = touchX;
        data->point.y = touchY;
    }
}

/* Setting up tick task for lvgl */
static void lv_tick_task(void *arg)
{
    (void)arg;
    lv_tick_inc(LV_TICK_PERIOD_MS);
}

void SW_initialize(void)
{
	init_lvgl_lgfx();
	ui_init();
}



void Rate_0(void *pvParameter) /* Sample time: [0.1s, 0.0s] */
{
	        TickType_t xLastWakeTime;
		    const TickType_t xFrequency = 1 / portTICK_PERIOD_MS; // 5 Hz
		    xLastWakeTime = xTaskGetTickCount();

	 while (1) {

	       lv_timer_handler();
	     vTaskDelayUntil(&xLastWakeTime, xFrequency);
	            

	    }

}


extern "C" void app_main(void)
{
	  /* Initialize model */

		SW_initialize();

		xTaskCreatePinnedToCore(Rate_0, "Rate_0", STACK_SIZE, NULL, configMAX_PRIORITIES-


               }


little calc use and buf + buf2 uses full iram in 32 mode…

Thanks for the response.
I am still new to this and could not understand your comment. Do you mean I should increase LV_BUFFER_SIZE ?

No you need know how much memory your MCU have , then all need arange inside. If you go over error as you see is result.
For try 32 bit you need go down with size . When on 16 bit gui work 80 lines buf , for 32 is logic use half 40 or maybe 32 (320/10) usw.

1 Like

I see, that makes sense now.
I tried 40 and it flashes with no error. Thank you so much

However, The colors on LCD is all messed up now, did not use to be like this when using 16bit. Does that mean my LCD does not support 32bit? or this is fixable in software?

You configure lvgl to 32 , but too lcd code and drivers require support it. Check .
But you need understand , that use 32 slow down refresh your display to half.
Plus into display is sended only 24bit not 32

1 Like

that display doesn’t support 24 bit color. you have to use 16 bit color.

Here is it working properly using the exact same display.

1 Like