How does display flush function works


How the flush function works as process and consept. I am working with esp32 and currently I am an ili9488 controller.

Based what I understand is that the flush cb has to call a function tha sends the data to the screen.

In port examples in v8.3 the relative function does not include the portion that sends the data to the screen using spi etc… so I assume that user has to write it and at the end to mark the ready function to mark the completion.

In lv_port_esp32 example that work fine and it uses v7 this flush function just calls a ili9488_flush function that does the sending to the screen.

I tried in the v8.3 flush function before the flush_ready function to call the same ili9488_flush function of the relative driver that also has the same operants to imitate what happens in version 7.

In my perspective since controller did not change then a working flushing function should be used again in the new lvgl flush function since also the operands are the same.

Reality is that screen did not show anything.

What do I miss? Can someone explain the consept from general to specific?

Did you do the initialization of the ili9488 at startup?

i did lv init
lvgl_drivers init and
lv_display init also

the log shows that spi starts normally and blacklight also opens

just it stays white.

is there something that i missin general?

static void guiTask(void *pvParameter) {

    (void) pvParameter;
    xGuiSemaphore = xSemaphoreCreateMutex();

    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, portTICK_PERIOD_MS * 1000));

    printf("before funct\n");
    while (1) {
        /* Delay 1 tick (assumes FreeRTOS tick is 10ms */

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



//in display init
void lv_port_disp_init(void)
    static lv_disp_draw_buf_t draw_buf_dsc_2;
    static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10];                        /*A buffer for 10 rows*/
    static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10];                        /*An other buffer for 10 rows*/
    lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10);   

     static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
     lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/

     disp_drv.hor_res = MY_DISP_HOR_RES;
     disp_drv.ver_res = MY_DISP_VER_RES;

     disp_drv.flush_cb = disp_flush;

     disp_drv.draw_buf = &draw_buf_dsc_2;

    /*Finally register the driver*/

// the flush function

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
    if(disp_flush_enabled) {
    	ili9488_flush(disp_drv, area, color_p);// this was the first position tried. 

    	int32_t x;
        int32_t y;
        for(y = area->y1; y <= area->y2; y++) {
            for(x = area->x1; x <= area->x2; x++) {
                /*Put a pixel to the display. For example:*/
             //    ili9488_flush(disp_drv, area, color_p);// this was the second position tried.


     *Inform the graphics library that you are ready with the flushing*/
// the first test was to place it here
//    ili9488_flush(disp_drv, area, color_p); //This was the third position the screen


is is almost obvious that i do not understand something properly

You are sure that disp_flush is called?
Everything after your printf("update); can be removed.
Just calling the ili9488_flush(disp_drv, area, color_p); is ok.
What is the disp_flush_enabled good for? Your are sure disp_flush_enabled is set != 0?

Yes all the printf it is not needed it was the default from the template and since the driver’s flush does this for loop on x and y i agree it is not needed.

volatile bool disp_flush_enabled = true;
is the what the file has

Hmm, I don’t see any obvious problem.

Flush function is called.
The array/buffer color_p should contain something valid (not all pixels white).
On startup the display changes from black (LCD off) to white (LCD is on with backlight on).
This would mean the ili9488 is initialized (means SPI communication is also ok).

This is the log. SPI is initialised and update is called is printed

I (27) boot: ESP-IDF v5.0.1-dirty 2nd stage bootloader
I (27) boot: compile time 23:56:56
I (27) boot: chip revision: v3.0
I (31) boot.esp32: SPI Speed      : 40MHz
I (36) boot.esp32: SPI Mode       : DIO
I (40) boot.esp32: SPI Flash Size : 8MB
I (45) boot: Enabling RNG early entropy source...
I (50) boot: Partition Table:
I (54) boot: ## Label            Usage          Type ST Offset   Length
I (61) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (68) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (76) boot:  2 factory          factory app      00 00 00010000 00100000
I (83) boot: End of partition table
I (87) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=0ff24h ( 65316) map
I (120) esp_image: segment 1: paddr=0001ff4c vaddr=3ffb0000 size=000cch (   204) load
I (120) esp_image: segment 2: paddr=00020020 vaddr=400d0020 size=470dch (291036) map
I (230) esp_image: segment 3: paddr=00067104 vaddr=3ffb00cc size=01ff0h (  8176) load
I (234) esp_image: segment 4: paddr=000690fc vaddr=40080000 size=0d7d4h ( 55252) load
I (266) boot: Loaded app from partition at offset 0x10000
I (266) boot: Disabling RNG early entropy source...
I (278) cpu_start: Pro cpu up.
I (278) cpu_start: Starting app cpu, entry point is 0x400811fc
0x400811fc: call_start_cpu1 at /Users/kyrpav/esp/esp-idf/components/esp_system/port/cpu_start.c:142

I (0) cpu_start: App cpu up.
I (294) cpu_start: Pro cpu start user code
I (294) cpu_start: cpu freq: 160000000 Hz
I (294) cpu_start: Application information:
I (299) cpu_start: Project name:     app-template
I (304) cpu_start: App version:      1
I (309) cpu_start: Compile time:     Mar 19 2023 04:54:29
I (315) cpu_start: ELF file SHA256:  de1d8ee6b3b0b16b...
I (321) cpu_start: ESP-IDF:          v5.0.1-dirty
I (326) cpu_start: Min chip rev:     v0.0
I (331) cpu_start: Max chip rev:     v3.99 
I (336) cpu_start: Chip rev:         v3.0
I (340) heap_init: Initializing. RAM available for dynamic allocation:
I (348) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (354) heap_init: At 3FFC3A78 len 0001C588 (113 KiB): DRAM
I (360) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (366) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (373) heap_init: At 4008D7D4 len 0001282C (74 KiB): IRAM
I (380) spi_flash: detected chip: generic
I (383) spi_flash: flash io: dio
I (388) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (20) lvgl_helpers: Display buffer size: 19200
I (20) lvgl_helpers: Initializing SPI master for display
I (20) lvgl_helpers: Configuring SPI host HSPI_HOST (1)
I (30) lvgl_helpers: MISO pin: 12, MOSI pin: 13, SCLK pin: 14, IO2/WP pin: -1, IO3/HD pin: -1
I (40) lvgl_helpers: Max transfer size: 57600 (bytes)
I (40) lvgl_helpers: Initializing SPI bus...
I (50) disp_spi: Adding SPI device
I (60) disp_spi: Clock speed: 80000000Hz, mode: 0, CS pin: 15
I (60) ILI9488: ILI9488 initialization.
I (390) ILI9488: Display orientation: LANDSCAPE
I (390) ILI9488: 0x36 command value: 0x28
I (390) disp_backlight: Setting LCD backlight : 100%
I (390) lvgl_helpers: Initializing SPI master for touch
I (410) lvgl_helpers: Configuring SPI host VSPI_HOST (2)
I (410) lvgl_helpers: MISO pin: 19, MOSI pin: 23, SCLK pin: 18, IO2/WP pin: -1, IO3/HD pin: -1
I (420) lvgl_helpers: Max transfer size: 0 (bytes)
I (430) lvgl_helpers: Initializing SPI bus...
I (430) XPT2046: XPT2046 Initialization
I (430) gpio: GPIO[21]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
in funct
before funct
update called
size of buffer is: 4800update called
size of buffer is: 4800update called
// this is printed infinitely 

i have updated the printf to say “update called” and i removed the for loops so inside the if condition only the flush is there. So if is true and flush is called.

I have placed also the function that i am running in the v7 port example and see the screen showing one label saying Hello World so the function that i am running is valid in the lv_port_esp32 example

Yes the screen backlight is on,

// the function in version v8.3 is 
static void run_application(void){
  lv_obj_t * scr =  lv_obj_create(NULL);

  /*Create a Label on the currently active screen*/
  lv_obj_t * label1 =  lv_label_create(scr);
  printf("in funct\n");
  /*Modify the Label's text*/
  lv_label_set_text(label1, "Hello\nworld");

  lv_obj_align(label1, LV_ALIGN_CENTER, 0, 0);

is there anything more that i can provide to explain more the issue?