Why is LVGL v7 working on ESP32 but LVGL v8 falls into error?

Description

Hello,

I am having long time trouble trying to figure out how to start up LVGL v8 on my ESP32 (Platformio - Arduino framework). Down here you can see my code which I use for v8. It is exactly the same code (with some necessary changes like different buffer notation etc.).

When I am using v7 everything works just fine but with v8 at the exact moment I enter the loop task it shows this:

Board: NodeMCU ESP32S (not only one, so HW mistake is not possible)

LVGL version: v7 - working, v8 not working

Platform: PlatformIO - Arduino framework

Goal: I would like to run my code on LVGL v8 so bad… :smiley:

Code to reproduce

Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.

The code block(s) should be formatted like:

#include <Arduino.h>
#include <lvgl.h>
#include <Ticker.h>
#include <TFT_eSPI.h>

#define LVGL_TICK_PERIOD 20
Ticker tick; /* timer for interrupt handler */

TFT_eSPI tft = TFT_eSPI(); /* TFT instance */

static lv_disp_draw_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];

int screenWidth = 240;
int screenHeight = 320;

/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
  uint16_t c;

  tft.startWrite(); /* Start new TFT transaction */
  tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */
  for (int y = area->y1; y <= area->y2; y++) {
    for (int x = area->x1; x <= area->x2; x++) {
      c = color_p->full;
      tft.writeColor(c, 1);
      color_p++;
    }
  }
  tft.endWrite(); /* terminate TFT transaction */
  lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}

/* Interrupt driven periodic handler */
static void lv_tick_handler(void)
{
  lv_tick_inc(LVGL_TICK_PERIOD);
}

void my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
    uint16_t touchX, touchY;

    bool touched = tft.getTouch(&touchX, &touchY, 600);

    if(!touched)
    {
      //return false;
    }

    if(touchX > screenWidth || touchY > screenHeight)
    {
      Serial.println("x or y outside of expected parameters..");
      Serial.print("y:");
      Serial.print(touchX);
      Serial.print(" x:");
      Serial.print(touchY);
    }
    else
    {

      data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; 
  
      /*Save the state and save the pressed coordinate*/
      //if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
     
      /*Set the coordinates (if released use the last pressed coordinates)*/
      data->point.x = touchX;
      data->point.y = touchY;
  
      Serial.print("Data x");
      Serial.println(touchX);
      
      Serial.print("Data y");
      Serial.println(touchY);

    }

    //return false; /*Return `false` because we are not buffering and no more data to read*/
}

void setup()
{
    Serial.begin(115200); /*prepare for possible serial debug*/

    vTaskDelay(1000 / portTICK_PERIOD_MS);

    lv_init();

    tft.begin(); /*TFT init*/
    tft.setRotation(0); /*Landscape orientation*/

    uint16_t calData[5] = {261, 3548, 469, 3453, 6};
    tft.setTouch(calData);

    lv_disp_draw_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);

    /*Initialize the disply*/
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.draw_buf = &disp_buf;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.hor_res = 240;
    disp_drv.ver_res = 320;
    lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/

    /*Initialize the graphics library's tick*/
    tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler);

    /*Initialize the input device driver*/
    lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);             /*Descriptor of a input device driver*/
    indev_drv.type = LV_INDEV_TYPE_POINTER;    /*Touch pad is a pointer-like device*/
    indev_drv.read_cb = my_touchpad_read;      /*Set your driver function*/
    lv_indev_drv_register(&indev_drv);         /*Finally register the driver*/

    /*Create simple label*/
    lv_obj_t *label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, "Hello Arduino!");
    lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
    
}


void loop()
{
    lv_task_handler();
    delay(5);
}

Thank you for all your effort!

disp_drv and indev_drv need to be static in v8+.

I strongly suggest reviewing the changelog when upgrading to a new major release. Sometimes there are API changes which we cannot get the compiler to issue an error on, like this one.

2 Likes