Glitches during bmp or jpg image display from SD

Environment

  • What MCU/Processor/Board are you using?
    Waveshare esp32-s3-touch-lcd-7

  • What compiler are you using?
    compiler: xtensa-gcc-esp32se-elf-g++
    framwork: arduino
    ide: platformio on visual studio code

Description

  • What version of LittlevGL are you using?
    9.2.0

  • What do you want to achieve?
    I want to load and view bmp or jpg images from SD

  • What have you tried so far?
    I’m able to achieve the goal but during the loading and decondig bmp/jpg, I see glitches. When the image is displayed, the problem ceases.

Code to reproduce

The code block(s) should be formatted like:

#include <Arduino.h>

#include <lvgl.h>
#include <ESP_IOExpander_Library.h>
#include <CH422G.h>
#include <FS.h>
#include <SD.h>
#include <SPI.h>
#include "ui/ui.h"
#include "ui/ui_event.h"
#include "ui/screens.h"
#include <ST7262.h>
#include "sd_helper.h"

// Extend IO Pin define
#define TP_RST 1
#define LCD_BL 2
#define LCD_RST 3
#define SD_CS 4
#define USB_SEL 5

// I2C Pin define
#define I2C_MASTER_NUM 0
#define I2C_MASTER_SDA_IO 8
#define I2C_MASTER_SCL_IO 9

#define SD_MOSI 11
#define SD_CLK  12
#define SD_MISO 13
#define SD_SS -1

// Dichiarazione pannello RGB
LGFX *panel = NULL;

/* Crea buffer per LVGL*/
#define ESP_PANEL_LCD_H_RES 800
#define ESP_PANEL_LCD_V_RES 480
#define DRAW_BUF_SIZE (ESP_PANEL_LCD_H_RES * ESP_PANEL_LCD_V_RES / 10 * (LV_COLOR_DEPTH / 8))
uint32_t draw_buf[DRAW_BUF_SIZE / 4];

/* Invia buffer a LVGL */
static void lvgl_port_disp_flush(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
{
    if (panel->getStartCount() == 0) panel->startWrite();

    panel->pushImageDMA( area->x1
                    , area->y1
                    , area->x2 - area->x1 + 1
                    , area->y2 - area->y1 + 1
                    , ( lgfx::rgb565_t* )px_map);
    
    lv_display_flush_ready(disp);
}

/* Legge il touchpad */
static void lvgl_port_tp_read(lv_indev_t * indev, lv_indev_data_t * data)
{

   uint16_t touchX, touchY;
   bool touched = panel->getTouch( &touchX, &touchY);
   if( !touched )
   {
      data->state = LV_INDEV_STATE_REL;
   }
   else
   {
      data->state = LV_INDEV_STATE_PR;
      data->point.x = touchY;
      data->point.y = ESP_PANEL_LCD_V_RES-touchX;
   }
}

/* Tick custom per LVGL */
static uint32_t my_tick(void)
{
    return millis();
}

/* Inizializza le periferiche */
void setup()
{
    Serial.begin(115200);

    /* Crea pannello RGB */
    panel = new LGFX();

    /* Inizializza LVGL core */
    lv_init();
    lv_tick_set_cb(my_tick);

    /* Inizializza diaplay */
    lv_display_t * disp = lv_display_create(ESP_PANEL_LCD_H_RES, ESP_PANEL_LCD_V_RES);
    lv_display_set_flush_cb(disp, lvgl_port_disp_flush);
    lv_display_set_buffers(disp, (void *)draw_buf, NULL, sizeof(draw_buf), LV_DISPLAY_RENDER_MODE_PARTIAL);  
    lv_display_set_rotation(disp, LV_DISP_ROTATION_90);

    /* Inizializza touchscreen */
    lv_indev_t * indev = lv_indev_create();
    lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
    lv_indev_set_read_cb(indev, lvgl_port_tp_read);

    /* Inizializza bus e il device del pannello */    
    panel->init();   
    panel->setRotation(1);      

    /* Inizializza IO expander */
    ESP_IOExpander *expander = new ESP_IOExpander_CH422G(I2C_MASTER_NUM, ESP_IO_EXPANDER_I2C_CH422G_ADDRESS_000);
    expander->init();
    expander->begin();
    expander->multiPinMode(TP_RST | LCD_BL | LCD_RST | SD_CS | USB_SEL, OUTPUT);
    expander->multiDigitalWrite(TP_RST | LCD_BL | LCD_RST | SD_CS, HIGH);

    // Turn off backlight
    expander->digitalWrite(USB_SEL, LOW);


    /* Inizializza SD card */

    // Configura Expander per la SD card
    expander->digitalWrite(SD_CS, LOW);

    SPI.setHwCs(false);    
    SPI.begin(SD_CLK,SD_MISO,SD_MOSI,SD_SS);
    if(!SD.begin()){
        Serial.println("Card Mount Failed");
        return;
    }
    uint8_t cardType = SD.cardType();

    if(cardType == CARD_NONE){
        Serial.println("No SD card attached");
        return;
    }

    Serial.print("SD Card Type: ");
    if(cardType == CARD_MMC){
        Serial.println("MMC");
    } else if(cardType == CARD_SD){
        Serial.println("SDSC");
    } else if(cardType == CARD_SDHC){
        Serial.println("SDHC");
    } else {
        Serial.println("UNKNOWN");
    }
    
    lv_fs_arduino_sd_init();
    lv_tjpgd_init();


    /* Crea UI */
    ui_init();

}

/* MAIN LOOP */
uint32_t time_till_next = lv_timer_handler();
unsigned long timeout = millis();

void loop()
{
    
    if(ui_event.available){        
        ui_event.available = false;
        if(ui_event.target == objects.btn_load_img){
            lv_img_set_src(objects.img_loaded, "S:/002.jpg");
        }
    }


    if((millis() - timeout) >= time_till_next){
        time_till_next = lv_timer_handler();
        timeout = millis();
        ui_tick();
    }

}

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.
WhatsApp Video 2024-09-19 at 15.55.20.mp4.zip (1.7 MB)

Thanks in advance for any help.

SOLVED:
I made further analyst and I was wrong. The problem isn’t in SPI library directly, but in SD library. Even if I disable CS in SPI library, the SD library redefine a CS (pin 10 default in ESP32) and uses it without any possibility to disable. So I’ve tu pass an unused pin as parameter because I’ve the CS handled by an io expander chip.

I got stuck with the same issue. Can you please share with me your init code for the expander, panel and SD card and in what order do you init them?