LVGL9.1 on Arduino Due w PlatformIO

Description

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

I am using a Arduino Due with PlatformIO.

What do you want to achieve?

I am trying to setup a very simple and basic test project running LVGL on Arduino Due.

What have you tried so far?

I am using ILI9341_due library with some adaptions to the initialisation to make it work with ST7789.
This is working. I am able to draw the display without lvgl.
I tried to activate logging, but I do not get any output. I think the crash happens, before the serial monitor has connected.

Code to reproduce

#define TFT_RST 51
#define TFT_DC 11
#define TFT_CS 10
#define PIN_DISPLAY_BACKLIGHT 9

#define TFT_HOR_RES 320
#define TFT_VER_RES 240
#define DRAW_BUF_SIZE (TFT_HOR_RES * TFT_VER_RES / 10 * (LV_COLOR_DEPTH / 8))

void log(lv_log_level_t level, const char *buf)
{
  Serial.print(level);
  Serial.print(": ");
  Serial.println(buf);
}

static void flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map)
{
  ILI9341_due *tft = (ILI9341_due *)lv_display_get_driver_data(disp);

  uint32_t w = (area->x2 - area->x1 + 1);
  uint32_t h = (area->y2 - area->y1 + 1);

  tft->setAddrWindow(area->x1, area->y1, w, h);
  tft->pushColors((uint16_t *)px_map, w * h, true);

  lv_display_flush_ready(disp);
}

uint32_t draw_buf[DRAW_BUF_SIZE / 4];

void setup()
{
  pinMode(PIN_DISPLAY_BACKLIGHT, OUTPUT);
  digitalWrite(PIN_DISPLAY_BACKLIGHT, HIGH);

  ILI9341_due *tft = new ILI9341_due(TFT_CS, TFT_DC, TFT_RST);
  tft->begin();
  tft->fillScreen(ILI9341_RED);

  lv_init();
  lv_log_register_print_cb(log);
  lv_display_t *display = lv_display_create(TFT_HOR_RES, TFT_VER_RES);
  lv_display_set_driver_data(display, (void *)tft);
  lv_display_set_flush_cb(display, flush_cb);
  lv_display_set_buffers(display, (void *)draw_buf, NULL, sizeof(draw_buf), LV_DISPLAY_RENDER_MODE_PARTIAL);

  lv_obj_t *_label = lv_label_create(lv_scr_act());
  lv_label_set_text(_label, "This is a test");
  lv_obj_align(_label, LV_ALIGN_LEFT_MID, 5, 0);
  lv_obj_set_width(_label, 100);
}

void loop()
{
  lv_timer_handler();
  lv_tick_inc(3);
}

When commenting all lv_ lines, the displays is drawn red.
When only lv_init() is un-commented, I see a red display with some artefacts on the right hand side and the Arduino hangs as it immediately powers off.

I am using pretty much the lv_conf_template. I’ve copied it under /src and set the following build_flags

build_flags = 
	-D LV_CONF_INCLUDE_SIMPLE
	-I src

I’ve made 2 changes to the lv_conf.h file:

  1. #define LV_USE_DEMO_WIDGETS 0
  2. #define LV_USE_ST7789 1

I’ve made some progress.
I reduced the mem size #define LV_MEM_SIZE (32 * 1024U) to 32KB.
Now, at least something is drawing.

But for some reason not the whole screen is drawn, but only stripes.
I set the original background color (with the display driver, not lvgl) to red. And only the white stripes are drawn by lvgl.

This is probably not related to lvgl, right?
It feels like a problem in the drawing method.

static void flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map)
{
    ILI9341_due *tft = (ILI9341_due *)lv_display_get_driver_data(disp);

    uint32_t w = (area->x2 - area->x1 + 1);
    uint32_t h = (area->y2 - area->y1 + 1);

    tft->setAddrWindowRect(area->x1, area->y1, w, h);
    tft->pushColors((uint16_t *)px_map, 0, w * h);

    lv_display_flush_ready(disp);
}

Would you mind having a look, even if it’s not related to lvgl?
This is the documentation.

I found out that it is working properly, when I halve the buff size uint32_t draw_buf[DRAW_BUF_SIZE / 8];

I absolutely do not understand this behaviour.
Can somebody with more experience and knowledge explain what’s going on? :slight_smile:

dont like this in function chaos… normal is init class before setup

ILI9341_due tft = ILI9341_due(TFT_CS, TFT_DC, TFT_RST);

and your loop code tick_inc is next nonsense

Thanks for your reply, @Marian_M.
Though, I am not sure, if I understand your point.

I moved lv_init() to the very beginning of the method.

void setup()
{
  lv_init();

  pinMode(PIN_DISPLAY_BACKLIGHT, OUTPUT);
  digitalWrite(PIN_DISPLAY_BACKLIGHT, HIGH);

  ILI9341_due *tft = new ILI9341_due(TFT_CS, TFT_DC, TFT_RST);
  tft->begin();
  tft->fillScreen(ILI9341_RED);

  lv_log_register_print_cb(log);
  lv_display_t *display = lv_display_create(TFT_HOR_RES, TFT_VER_RES);
  lv_display_set_driver_data(display, (void *)tft);
  lv_display_set_flush_cb(display, flush_cb);
  lv_display_set_buffers(display, (void *)draw_buf, NULL, sizeof(draw_buf), LV_DISPLAY_RENDER_MODE_PARTIAL);

  lv_obj_t *_label = lv_label_create(lv_scr_act());
  lv_label_set_text(_label, "This is a test");
  lv_obj_align(_label, LV_ALIGN_LEFT_MID, 5, 0);
  lv_obj_set_width(_label, 100);
}

Is this what you were talking about? Or do you recommend moving the instantiation of the ILI9341_due class out of the function to a global context?

Can you please explain why the tick_inc is not making sense in the loop?
I know that using a timer would be the better option, but as first prototype it seemed sufficient to put it in the main loop. But based on your answer it seems useless…

None of these changes had influence on the drawing problem.
Can you imagine what causes these stripes?

Thanks for your help.

tick_inc is for lvgl handle realtime. Your code speed world up around 20000x

Understood, thanks for explanation :slight_smile:
Do you have an idea, why it is drawing these stripes, when the buffer size is too big?

After added delay ? And change tft to global not pointer alias class?

Yes, same behaviour even with these two changes.
tft is now global and not a pointer, but I am passing the address to the `lv_display_set_driver_data´ function.

lv_display_set_driver_data(display, (void *)&tft);

And the delay(3) is added to the main loop.

When tft is global dont require send as user data use it direct in flushcb, but problem is inside tft class or flush cb. Try other lib or correct this setup. I never preff convert ILI to ST etc. Are you sure LV_COLOR_DEPTH is ok with ST config?

Yes, I am very sure. I am using this library adapted for ST7789 for years …
I can try using another one, but I decided to use this one as I know it was working …

Anyhow, if I got you right, then this problem should not be related to lvgl, but to the driver, right?

Hard to say for 9.1 i still use 8.3 , but with any version with trouble you need check step by step sw and hw