Hello,
Some weeks ago I started with ESP-IDF v4.3.1 and LVGL 8.0.2.
At the beginning the code seemed to work. But later it worked any more! And I don’t know why.
I’ve tried everything and tried all possible ways, but nothing helps.
My code looked very simple to start with:
/*
* File: main.c
* Author: Mick P. F.
* Created: 2021-11-06
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "esp_system.h"
#include "esp_err.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#if defined(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488)
#if defined(CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE) || defined(CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
#define DISPLAY_WIDTH 480
#define DISPLAY_HEIGHT 320
#else
#define DISPLAY_WIDTH 320
#define DISPLAY_HEIGHT 480
#endif
#endif
#include "lvgl.h"
#include "lvgl_helpers.h"
#define DEBUG_MODULE
#ifndef DELAY_MS
#define DELAY_MS(ms) vTaskDelay((ms) / portTICK_PERIOD_MS)
#endif
#define LV_TICK_PERIOD_MS 10 // Call every 10 ms the LVGL Ticker
#define SCREEN_BACKGROUND_OPACITY LV_OPA_COVER
#define SCREEN_FOREGROUND_OPACITY LV_OPA_COVER
#define COLOR_BACKGROUND_RED 0x36
#define COLOR_BACKGROUND_GREEN 0x2C
#define COLOR_BACKGROUND_BLUE 0x1C
#define COLOR_FOREGROUND_RED 0xFF
#define COLOR_FOREGROUND_GREEN 0x66
#define COLOR_FOREGROUND_BLUE 0x00
#define COLOR_INDOOR_SENSOR_RED 0x33
#define COLOR_INDOOR_SENSOR_GREEN 0xCC
#define COLOR_INDOOR_SENSOR_BLUE 0x66
#define COLOR_OUTDOOR_SENSOR_RED 0x00
#define COLOR_OUTDOOR_SENSOR_GREEN 0xCC
#define COLOR_OUTDOOR_SENSOR_BLUE 0xFF
static const char *MODULE_TAG = "MAIN";
static int16_t screen_width, screen_height;
static lv_color_t *display_cache;
static lv_disp_draw_buf_t display_buffer;
static lv_disp_drv_t display_driver;
static lv_disp_t *display;
static lv_obj_t *screen;
static lv_color_t color_bg, color_fg;
static void lv_tick_task(void *arg)
{
lv_tick_inc(LV_TICK_PERIOD_MS);
}
void app_main(void)
{
esp_timer_handle_t gui_timer;
esp_timer_create_args_t timer_args;
lv_area_t draw_area, clip_area;
lv_draw_rect_dsc_t frame;
lv_init();
lvgl_driver_init();
color_bg = lv_color_make(COLOR_BACKGROUND_RED, COLOR_BACKGROUND_GREEN, COLOR_BACKGROUND_BLUE);
color_fg = lv_color_make(COLOR_FOREGROUND_RED, COLOR_FOREGROUND_GREEN, COLOR_FOREGROUND_BLUE);
display_cache = (lv_color_t *) heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
if (display_cache == NULL)
{
ESP_LOGE(MODULE_TAG, "Allocating space for display buffer failed!");
abort();
}
lv_disp_draw_buf_init(&display_buffer, display_cache, NULL, DISP_BUF_SIZE);
lv_disp_drv_init(&display_driver);
display_driver.hor_res = DISPLAY_WIDTH;
display_driver.ver_res = DISPLAY_HEIGHT;
display_driver.flush_cb = disp_driver_flush;
display_driver.draw_buf = &display_buffer;
display = lv_disp_drv_register(&display_driver);
if (display == NULL)
{
ESP_LOGE(MODULE_TAG, "Register display driver failed!");
abort();
}
lv_disp_set_default(display);
/* Create and start a periodic timer interrupt to call lv_tick_inc */
timer_args.callback = lv_tick_task;
timer_args.name = "gui_timer";
ESP_ERROR_CHECK(esp_timer_create(&timer_args, &gui_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(gui_timer, LV_TICK_PERIOD_MS * 1000));
display = lv_disp_get_default();
screen = lv_disp_get_scr_act(display);
screen_width = lv_disp_get_hor_res(display);
screen_height = lv_disp_get_ver_res(display);
lv_draw_rect_dsc_init(&frame);
frame.radius = 7;
frame.bg_color = color_bg;
frame.bg_opa = SCREEN_BACKGROUND_OPACITY;
frame.border_color = color_fg;
frame.border_width = 3;
frame.border_opa = SCREEN_FOREGROUND_OPACITY;
draw_area.x1 = 3; draw_area.y1 = 3;
draw_area.x2 = 299; draw_area.y2 = 199;
clip_area.x1 = 0; clip_area.y1 = 0;
clip_area.x2 = DISPLAY_WIDTH - 1; clip_area.y2 = DISPLAY_HEIGHT - 1;
lv_draw_rect(&draw_area, &clip_area, &frame);
while (1)
{
lv_task_handler();
DELAY_MS(2000);
}
}
Running this code resulted in an exception with a crash:
I (911) lvgl_helpers: Display buffer size: 19200
I (911) lvgl_helpers: Initializing SPI master for display
I (921) lvgl_helpers: Configuring SPI host VSPI_HOST (2)
I (931) lvgl_helpers: MISO pin: 19, MOSI pin: 23, SCLK pin: 18, IO2/WP pin: -1, IO3/HD pin: -1
I (941) lvgl_helpers: Max transfer size: 57600 (bytes)
I (941) lvgl_helpers: Initializing SPI bus...
I (951) disp_spi: Adding SPI device
I (951) disp_spi: Clock speed: 20000000Hz, mode: 0, CS pin: 5
I (961) ILI9488: ILI9488 initialization.
I (1261) ILI9488: Display orientation: LANDSCAPE
I (1261) ILI9488: 0x36 command value: 0x28
I (1261) disp_backlight: Setting LCD backlight: 100%
I (1261) FT6X36: Found touch panel controller
I (1261) lvgl_i2c: Starting I2C master at port 0.
I (1271) lvgl_i2c: Initialised port 0 (SDA: 25, SCL: 26, speed: 400000 Hz.)
I (1281) FT6X36: Device ID: 0x11
I (1281) FT6X36: Chip ID: 0x36
I (1291) FT6X36: Device mode: 0x00
I (1291) FT6X36: Firmware ID: 0x03
I (1291) FT6X36: Release code: 0x01
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x4010ea73 PS : 0x00060030 A0 : 0x8008ab3c A1 : 0x3ffbe760
0x4010ea73: lv_disp_get_draw_buf at /home/mick/Projects/ESP32/ESP32/ER-TFTM035/build/../components/lvgl/src/hal/lv_hal_disp.c:503
A2 : 0x00000000 A3 : 0x0000000a A4 : 0x00000005 A5 : 0x3ffb44d4
A6 : 0x3ffb44c0 A7 : 0x00000005 A8 : 0x3ffb3320 A9 : 0x3ffbe740
A10 : 0x00000000 A11 : 0x00000005 A12 : 0x00000000 A13 : 0x3ffb435c
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x00000009 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x4008df32 LEND : 0x4008df3d LCOUNT : 0x00000000
0x4008df32: memset at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/src/newlib/newlib/libc/machine/xtensa/memset.S:150
0x4008df3d: memset at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/src/newlib/newlib/libc/machine/xtensa/memset.S:160
Backtrace:0x4010ea70:0x3ffbe760 0x4008ab39:0x3ffbe780 0x400e2616:0x3ffbe7e0 0x4008a041:0x3ffbe8b0 0x400e2ae0:0x3ffbe8f0 0x400d9e10:0x3ffbe910 0x401104f9:0x3ffbe990 0x40093791:0x3ffbe9b0
0x4010ea70: lv_disp_get_draw_buf at /home/mick/Projects/ESP32/ESP32/ER-TFTM035/build/../components/lvgl/src/hal/lv_hal_disp.c:502
0x4008ab39: _lv_blend_fill at /home/mick/Projects/ESP32/ESP32/ER-TFTM035/build/../components/lvgl/src/draw/lv_draw_blend.c:138
0x400e2616: draw_border_generic at /home/mick/Projects/ESP32/ESP32/ER-TFTM035/build/../components/lvgl/src/draw/lv_draw_rect.c:1171
0x4008a041: draw_border at /home/mick/Projects/ESP32/ESP32/ER-TFTM035/build/../components/lvgl/src/draw/lv_draw_rect.c:406
0x400e2ae0: lv_draw_rect at /home/mick/Projects/ESP32/ESP32/ER-TFTM035/build/../components/lvgl/src/draw/lv_draw_rect.c:111
0x400d9e10: app_main at /home/mick/Projects/ESP32/ESP32/ER-TFTM035/build/../main/main.c:137 (discriminator 2)
0x401104f9: main_task at /opt/ESP32/v4.3.1/esp-idf/components/freertos/port/port_common.c:133
0x40093791: vPortTaskWrapper at /opt/ESP32/v4.3.1/esp-idf/components/freertos/port/xtensa/port.c:168
The cause was quickly found because the variable disp in “lvgl/src/hal/lv_hal_disp.c:503” has the value NULL; the value of NULL is returned in code line 137 of the source file “lv_draw_blend.c” by calling “_lv_refr_get_disp_refreshing()” in the funtion “_lv_blend_fill”. The global variable “disp_ref” is not set anywhere in the source file “lv_refr.c”.
So I built the call of the function “_lv_refr_set_disp_refreshing(display)” into my code after calling “lv_disp_set_default(display)”.
Since then there have been no crashes, but the display stays white and my rectangle is not drawn.
I noticed a few uncomfortable things in the library LVGL:
- There are no calls to erase the whole display or a part of it.
- As a rule, functions in a library that begin with an underscore are only intended for internal use and should therefore not be called from outside.
What am I doing wrong?
Can someone please help me get the code working (again)?
Thanks in advance,
Michael