LVGL lv_display_t() causing Arduino Giga crash on upload - how to set up TFT_eSPI?

I’ve been trying to figure out how to create a display with LVGL using my Arduino Giga Display, and I am using LVGL v9.2.2 and Arduino_H7_Video. Does anyone know how to do this?

LVGL recommends using the TFT_eSPI library for using for the display, but as far as I know, TFT_eSPI isn’t supported with the Giga Display (Arduino Docs lists only Arduino_GigaDisplay_GFX, LVGL, and ArduinoGraphics as supported for the Giga Display). The LVGL example uses Arduino_H7_Video, and the Arduino_H7_Video repository says that it can be used with LVGL.

As part of setting up LVGL for Arduino, I also tried the LVGL_Arduino.ino file that came with the LVGL library, but it doesn’t do anything on it’s own. I’m trying to figure out how to configure the drivers in User_Setup.h file or find a suitable one in the User_Select_Setup.h file to setup the drivers, but I don’t know what to do in there and I am hesitant that I might do something that wrecks the Arduino board or display. Looking at the TFT_eSPI repository, they do list a TFT_eSPR_STM32.h file in the Processors folder, but I really don’t understand what all is in that file.

I can get my Arduino to create objects using lv_scr_act(), and they work. When I use lv_obj_t * screen = lv_obj_create(NULL); (the syntax provided in the LVGL documentation for creating screens) to try to create a screen, the screen is blank and nothing shows up.

I would like to create screens on the display (I have been having some strange crashing issues with progressing through a series of menus, and I am hoping that this can solve them). However, whenever I use the command lv_display_t * display = lv_display_create(800, 480); (which is the syntax provided in the LVGL documentation on creating displays), my Arduino crashes immediately as soon as the download hits 100%.

I have also tried creating one and two buffers at the same time as creating the display, as well as creating a callback to flush the screen, but it doesn’t seem to have any effect on the crashing. I haven’t been able to figure out a buffer flush code that works for Arduino_H7_Video either.

Does anyone have any experience with this?

Description

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

Arduino Giga R1 WiFi with a Arduino Giga Display Shield

What do you want to achieve?

Get display, screens, and buffers working

What have you tried so far?

Arduino_H7_video.h and using LVGL without creating a display

I tried a different tactic. I changed some of the code around for use with Arduino_H7_Video.h, and I got it to stop crashing (I’ve included the code below). I wasn’t able to get TFT_eSPI set up, as I didn’t know the driver for the display, though it looked like the processor for the Arduino Giga might have been supported.

I am having a different issue now with the screen turning white and the display buffer having some strange behaviour. But because it is a different problem, I am going to put it into a separate post to not mix topics.

Description

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

Arduino Giga with an Arduino Giga Display Shield

Code to reproduce

#include <Arduino_H7_Video.h>
#include <Arduino_GigaDisplay.h> // v1.0.2
#include <Arduino_GigaDisplayTouch.h> // v1.0.1
#include <lvgl.h> // LVGL v9.2.2
#include <ArduinoGraphics.h>

Arduino_H7_Video          Display(800, 480, GigaDisplayShield); /* Arduino_H7_Video Display(1024, 768, USBCVideo); */
Arduino_GigaDisplayTouch  TouchDetector;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  
  Display.begin();

  lv_init();

  lv_display_t * display = lv_display_create(800, 480); 

  static uint8_t buf1[800 * 480 / 10];
  lv_display_set_buffers(display, buf1, NULL, sizeof(buf1), LV_DISPLAY_RENDER_MODE_PARTIAL);
  lv_display_set_flush_cb(display, my_disp_flush); 
  lv_disp_set_default(display);

  lv_obj_t * screen_black = lv_obj_create(NULL);
  lv_obj_set_size(screen_black, 800, 480);
  lv_obj_set_style_bg_color(screen_black, lv_color_black(), LV_PART_MAIN);
  lv_obj_set_style_bg_opa(screen_black, LV_OPA_COVER, LV_PART_MAIN);

}

void loop() {
  // put your main code here, to run repeatedly:
  lv_timer_handler();
}

void my_disp_flush(lv_display_t *disp, const lv_area_t *area, uint8_t *color_p) {
  
    // Cast the buffer to lv_color_t for proper interpretation
    lv_color_t *color_map = (lv_color_t *)color_p;

    // Start drawing to the framebuffer
    Display.beginDraw();

    // Loop through the area and set pixels
    for (int32_t y = area->y1; y <= area->y2; y++) {
        for (int32_t x = area->x1; x <= area->x2; x++) {
            // Extract RGB565 from lv_color_t
            uint16_t color = *((uint16_t *)color_map);

            // Convert RGB565 to R, G, B components
            uint8_t r = (color >> 11) & 0x1F;  // Extract 5 bits for red
            uint8_t g = (color >> 5) & 0x3F;   // Extract 6 bits for green
            uint8_t b = color & 0x1F;          // Extract 5 bits for blue

            // Scale to 8-bit values (0-255)
            r = (r * 255) / 31;
            g = (g * 255) / 63;
            b = (b * 255) / 31;

            // Set the pixel color
            Display.set(x, y, r, g, b);

            // Advance to the next color in the buffer
            color_map++;
        }
    }

    // End drawing operation
    Display.endDraw();

    lv_display_flush_ready(disp);
}