ESP32S3 update from esp-idf 4.4.2 to 5.4.1 lcd doesn't display anymore :(

Hi Lvgl Community :slight_smile:

I freshly migrate my esp-idf based project from esp-idf 4.4.2 to v5.4.1.

I’m using lvgl v8.3.6.

After few adjustement ( nothing linked with lvgl), i ran my project and deploy on my st7789 lcd but nothing is displayed.

I debugged to be sure that only the display Task is working to isolate the problem but nothing.
I can only see the backlight, that’s all.
There is no compil or warning error.
I even reduce from 40 t 20Mhz the clock, checked that all the spi line and control define was ok.

lv_timer_handler(); is called in loop in my while(1) task too.
Here a piece of code about the init.

I precise that this code was perfectly working before the esp-idf migration.

   ESP_LOGI(TAG_GUI, "Initialize LCD SPI bus");

    spi_bus_config_t buscfg = {
        .sclk_io_num = EXAMPLE_PIN_NUM_SCLK,
        .mosi_io_num = EXAMPLE_PIN_NUM_MOSI,
        .miso_io_num = EXAMPLE_PIN_NUM_MISO,
        .quadwp_io_num = -1, // Quad SPI LCD driver is not yet supported
        .quadhd_io_num = -1, // Quad SPI LCD driver is not yet supported
        .max_transfer_sz =  EXAMPLE_LCD_H_RES * 80 * sizeof(uint16_t), // transfer 80 lines of pixels (assume pixel is RGB565) at most in one SPI transaction
        .flags=SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_GPIO_PINS,//0,
    };
    ESP_ERROR_CHECK(spi_bus_initialize(LCD_HOST, &buscfg, SPI_DMA_CH_AUTO)); // Enable the DMA feature


    // 2. LCD IO device handle 

    esp_lcd_panel_io_handle_t io_handle = NULL;
    esp_lcd_panel_io_spi_config_t io_config = {
        .dc_gpio_num = EXAMPLE_PIN_NUM_LCD_DC,
        .cs_gpio_num = EXAMPLE_PIN_NUM_CS,
        .pclk_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ,
        .lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS,
        .lcd_param_bits = EXAMPLE_LCD_PARAM_BITS,
        .spi_mode = 0,
        .trans_queue_depth = 10,
    .on_color_trans_done = example_notify_lvgl_flush_ready,
    .user_ctx = &disp_drv,
    .flags.dc_low_on_data = 0,
    };
    // Attach the LCD to the SPI bus
    ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_HOST, &io_config, &io_handle));

    ESP_LOGI(TAG_GUI, "Install LCD driver of st7789");
    esp_lcd_panel_handle_t panel_handle = NULL;
    esp_lcd_panel_dev_config_t panel_config = {
        .reset_gpio_num = EXAMPLE_PIN_NUM_RST,
        .color_space = ESP_LCD_COLOR_SPACE_RGB,
        .bits_per_pixel = 16,
    };

    ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));

    esp_lcd_panel_reset(panel_handle);
    esp_lcd_panel_init(panel_handle);


    esp_lcd_panel_invert_color(panel_handle, true);
    // the gap is LCD panel specific, even panels with the same driver IC, can have different gap value
    esp_lcd_panel_set_gap(panel_handle,0, 0);

    ESP_LOGI(TAG_GUI, "Turn on LCD backlight");
    gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, EXAMPLE_LCD_BK_LIGHT_ON_LEVEL);


    ESP_LOGI(TAG_GUI, "Initialize LVGL library");
    lv_init();
    ESP_LOGI(TAG_GUI, "Initialize LVGL library done");
    // alloc draw buffers used by LVGL
    // it's recommended to choose the size of the draw buffer(s) to be at least 1/10 screen sized
    lv_color_t *buf1 = heap_caps_malloc(EXAMPLE_LCD_H_RES * 40* sizeof(lv_color_t), MALLOC_CAP_DMA /*| MALLOC_CAP_SPIRAM*/);
    assert(buf1);
    lv_color_t *buf2 = heap_caps_malloc(EXAMPLE_LCD_H_RES * 40 * sizeof(lv_color_t), MALLOC_CAP_DMA /*| MALLOC_CAP_SPIRAM*/);
    assert(buf2);
    // initialize LVGL draw buffers
    lv_disp_draw_buf_init(&disp_buf, buf1, buf2, EXAMPLE_LCD_H_RES * 40);

    ESP_LOGI(TAG_GUI, "Register display driver to LVGL");
    lv_disp_drv_init(&disp_drv);
    disp_drv.hor_res = EXAMPLE_LCD_H_RES;
    disp_drv.ver_res = EXAMPLE_LCD_V_RES;
    disp_drv.flush_cb = example_lvgl_flush_cb;
    disp_drv.draw_buf = &disp_buf;
    disp_drv.user_data = panel_handle;
    disp_drv.sw_rotate = 1;
    disp_drv.rotated = 1;

    //flo add pour gerer l'allumage du backlight au demarage et eviter le bruit et l'ecran moche en ram
    disp_drv.monitor_cb = display_fully_draw_cb;

    lv_disp_t *disp = lv_disp_drv_register(&disp_drv);

    ESP_LOGI(TAG_GUI, "Install LVGL tick timer");
    // Tick interface for LVGL (using esp_timer to generate 2ms periodic event)
    const esp_timer_create_args_t lvgl_tick_timer_args = {
        .callback = &example_increase_lvgl_tick,
        .name = "lvgl_tick"
    };
    esp_timer_handle_t lvgl_tick_timer = NULL;
    ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer));
    ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer, EXAMPLE_LVGL_TICK_PERIOD_MS * 1000));

    ui_init();  

    logo_Animation(ui_logo, 1000);

I thought that may be an obvious and popular stuff need to be done that even chat gpt would have skipped :joy:

Thanks a lot for your help, i have the feeling to have tried all and has there is no complain in the log, I really wonder what could be the reason.

I jjust tried with a second new from the box screen and i have the same behavior.

I also checked signals on scope, all looks fine, may be exept the miso line that looks a bit strange , like a kind of discharge signal without a lot of bits on it. I don’t know if read clearly by the lvgl stack and usefull.

I succeed in running the esp-idf lcd spi_master example on my hardware just after configuring properly the pins so no hardware issue.

I will try to create an isolated project, simple, to see …

Hi @Olfox59,

I’ve same issue when using > IDF 5.x.x. I did some testing on the SPI transfer. I noticed that the SPI MOSI is sending out LSB first:

It’s just a simple setup, ESP32-C3 connected to ILI9488 display.

I tried to change the lsb_first flag in the LCD SPI device configuration, but it doesn’t changed anything.

Once I used lower version of ESP-IDF (4.4.7), the SPI transfer is correct (MSB first) and the LCD is displaying again.

My suggestion is to check the SPI transfer using logic analyzer.