Lvgl with monochrome display

Description

I’m driving a monochrome display (e-ink) with lvgl and esp32. After first initialisation it displays stuff exactly how I want to, but it does not want to fully refresh afterwards. When I update anything in LVGL after the first image has been drawn, it starts to do something - it will partially draw a random noise to a part of the screen, but it will never affect the overall image, so it will mostly stay the same and never update.

What MCU/Processor/Board and compiler are you using?

ESP32s3, esp-idf v5.0

What LVGL version are you using?

8.3.0

My code is fairly long, but I don’t really suspect the code being at fault here (if I change a display to a standard LCD + different drivers it works exactly how I want to). I think it has to something with updating lv_tick_task() or lv_task_handler(), but I cannot really find any clear explanation if I for example have to set a longer update period to accommodate the e-ink (with SSD1680 display driver), or something like that. My code that does that is here: (it is a mashup of a code from GitHub - AramVartanyan/lvgl_test: Test the lvgl_esp32_drivers)

static const char *LVGL_TAG = "LVGL Handler";

#define LV_TICK_PERIOD_MS 1

static void lv_tick_task(void *arg);
static void _lvg_init(void *pvParameter);

SemaphoreHandle_t xGuiSemaphore;


void lvgl_init()
{
    xTaskCreatePinnedToCore(_lvg_init, "lvgl_init_task", 4096*2, NULL, 0, NULL, 1);
}


static void _lvg_init(void *pvParameter) {

    (void) pvParameter;
    xGuiSemaphore = xSemaphoreCreateMutex();

    lv_init();

    /* Initialize SPI or I2C bus used by the drivers */
    lvgl_driver_init();

    lv_color_t* buf1 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
    assert(buf1 != NULL);


    static lv_color_t *buf2 = NULL;

    static lv_disp_draw_buf_t disp_buf;

    uint32_t size_in_px = DISP_BUF_SIZE;

    #if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820         \
        || defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A    \
        || defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D     \
        || defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1680     \
        || defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306

        /* Actual size in pixels, not bytes. */
        size_in_px *= 8;
    #endif

    /* Initialize the working buffer depending on the selected display.
     * NOTE: buf2 == NULL when using monochrome displays. */
    lv_disp_draw_buf_init(&disp_buf, buf1, buf2, size_in_px);

    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.ver_res = 128;
    disp_drv.hor_res = 296;
    disp_drv.flush_cb = disp_driver_flush;

    /* When using a monochrome display we need to register the callbacks:
     * - rounder_cb
     * - set_px_cb */
    #ifdef CONFIG_LV_TFT_DISPLAY_MONOCHROME
        disp_drv.rounder_cb = disp_driver_rounder;
        disp_drv.set_px_cb = disp_driver_set_px;
    #endif

    disp_drv.draw_buf = &disp_buf;
    // lv_disp_drv_register(&disp_drv);
    lv_disp_t *disp = lv_disp_drv_register(&disp_drv); //lvgl v8+

    /* 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_timer_handle_t periodic_timer = NULL; //lvgl v8+
    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));
    // ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LV_TICK_PERIOD_MS * 200));
    

    xSemaphoreGive(guiTaskSemaphore);

    while (1) {
        /* Delay 1 tick (assumes FreeRTOS tick is 10ms */
        vTaskDelay(pdMS_TO_TICKS(10));

        /* Try to take the semaphore, call lvgl related function on success */
        if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY)) {
            lv_task_handler();
            xSemaphoreGive(xGuiSemaphore);
       }
    }

    /* A task should NEVER return */
    free(buf1);
    #ifndef CONFIG_LV_TFT_DISPLAY_MONOCHROME
        free(buf2);
    #endif
        vTaskDelete(NULL);
}

static void lv_tick_task(void *arg) {
    (void) arg;
    // ESP_LOGI(LVGL_TAG, "tick inc");
    lv_tick_inc(LV_TICK_PERIOD_MS);
}

thank you very much, I can add anything if it will help to solve this

I had the same static image on the right of my SSD1603 display. It was because the maximum horizontal resoluation/ maximum vertical resolution was configured too high for SSD1603. once I set the config parameters using idf.py menuconfig to those that matched my screen it displayed the image successfully.