Description
On run of initial program to esp32 i get a crash on lv_helpers cause of
spi_bus_initialize(758): SPI bus already initialized
What MCU/Processor/Board and compiler are you using?
esp32 esp-idf 5.0.1
What LVGL version are you using?
release/8.3
What do you want to achieve?
To run program without crash
What have you tried so far?
I have set screen ili9488 to SPI_2=HSPI and touch to SPI_3=VSPI
Code to reproduce
My main is the next:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_freertos_hooks.h"
#include "freertos/semphr.h"
#include "esp_timer.h"
#include "esp_system.h"
#include "driver/gpio.h"
#include "lvgl/lvgl.h"
#include "lvgl_helpers.h"
SemaphoreHandle_t xGuiSemaphore;
lv_indev_t * touch_indev;
static void guiTask(void *pvParameter);
static void run_application(void);
static void lv_tick_task(void *arg);
static void lv_port_disp_init();
#define MY_DISP_HOR_RES 480
#define MY_DISP_VER_RES 320
static void disp_init(void);
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
static void lv_port_indev_init(void);
static void touchpad_init(void);
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static bool touchpad_is_pressed(void);
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y);
/**********************
* STATIC VARIABLES
**********************/
lv_indev_t * indev_touchpad;
lv_indev_t * indev_mouse;
void app_main(void)
{
xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 0, NULL, 1);
}
static void guiTask(void *pvParameter) {
(void) pvParameter;
xGuiSemaphore = xSemaphoreCreateMutex();
lv_init();
/* Initialize SPI or I2C bus used by the drivers */
lvgl_driver_init();
lv_port_disp_init();
/* Register an input device when enabled on the menuconfig */
#if CONFIG_LV_TOUCH_CONTROLLER != TOUCH_CONTROLLER_NONE
lv_port_indev_init();
#endif
const esp_timer_create_args_t periodic_timer_args = {
.callback = &lv_tick_task,
.name = "periodic_gui"
};
esp_timer_handle_t periodic_timer;
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, portTICK_PERIOD_MS * 1000));
run_application();
while (1) {
/* Delay 1 tick (assumes FreeRTOS tick is 10ms */
vTaskDelay(pdMS_TO_TICKS(10));
/* Try to take the semaphore, call lvgl related function on success */
if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY)) {
lv_task_handler();
xSemaphoreGive(xGuiSemaphore);
}
}
vTaskDelete(NULL);
}
static void run_application(void){
lv_obj_t * scr = lv_disp_get_scr_act(NULL);
/*Create a Label on the currently active screen*/
lv_obj_t * label1 = lv_label_create(scr);
/*Modify the Label's text*/
lv_label_set_text(label1, "Hello\nworld");
/* Align the Label to the center
* NULL means align on parent (which is the screen now)
* 0, 0 at the end means an x, y offset after alignment*/
lv_obj_align(label1, LV_ALIGN_CENTER, 0, 0);
}
static void lv_tick_task(void *arg) {
lv_tick_inc(portTICK_PERIOD_MS);
}
void lv_port_disp_init(void)
{
disp_init();
/* Example for 2) */
static lv_disp_draw_buf_t draw_buf_dsc_2;
static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10]; /*A buffer for 10 rows*/
static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10]; /*An other buffer for 10 rows*/
lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10); /*Initialize the display buffer*/
static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
/*Set the resolution of the display*/
disp_drv.hor_res = MY_DISP_HOR_RES;
disp_drv.ver_res = MY_DISP_VER_RES;
/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = disp_flush;
/*Set a display buffer*/
disp_drv.draw_buf = &draw_buf_dsc_2;
/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);
}
/*Initialize your display and the required peripherals.*/
static void disp_init(void)
{
/*You code here*/
}
volatile bool disp_flush_enabled = true;
/* Enable updating the screen (the flushing process) when disp_flush() is called by LVGL
*/
void disp_enable_update(void)
{
disp_flush_enabled = true;
}
/* Disable updating the screen (the flushing process) when disp_flush() is called by LVGL
*/
void disp_disable_update(void)
{
disp_flush_enabled = false;
}
/*Flush the content of the internal buffer the specific area on the display
*You can use DMA or any hardware acceleration to do this operation in the background but
*'lv_disp_flush_ready()' has to be called when finished.*/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
if(disp_flush_enabled) {
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
int32_t x;
int32_t y;
for(y = area->y1; y <= area->y2; y++) {
for(x = area->x1; x <= area->x2; x++) {
/*Put a pixel to the display. For example:*/
/*put_px(x, y, *color_p)*/
color_p++;
}
}
}
/*IMPORTANT!!!
*Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp_drv);
}
void lv_port_indev_init(void)
{
static lv_indev_drv_t indev_drv;
/*Register a touchpad input device*/
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = touchpad_read;
indev_touchpad = lv_indev_drv_register(&indev_drv);
// /*------------------
// * Mouse
// * -----------------*/
// /*Initialize your mouse if you have*/
// mouse_init();
// /*Register a mouse input device*/
// lv_indev_drv_init(&indev_drv);
// indev_drv.type = LV_INDEV_TYPE_POINTER;
// indev_drv.read_cb = mouse_read;
// indev_mouse = lv_indev_drv_register(&indev_drv);
// /*Set cursor. For simplicity set a HOME symbol now.*/
// lv_obj_t * mouse_cursor = lv_img_create(lv_scr_act());
// lv_img_set_src(mouse_cursor, LV_SYMBOL_HOME);
// lv_indev_set_cursor(indev_mouse, mouse_cursor);
}
/*Will be called by the library to read the touchpad*/
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
static lv_coord_t last_x = 0;
static lv_coord_t last_y = 0;
/*Save the pressed coordinates and the state*/
if(touchpad_is_pressed()) {
touchpad_get_xy(&last_x, &last_y);
data->state = LV_INDEV_STATE_PR;
}
else {
data->state = LV_INDEV_STATE_REL;
}
/*Set the last pressed coordinates*/
data->point.x = last_x;
data->point.y = last_y;
}
/*Return true is the touchpad is pressed*/
static bool touchpad_is_pressed(void)
{
/*Your code comes here*/
return false;
}
/*Get the x and y coordinates if the touchpad is pressed*/
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)
{
/*Your code comes here*/
(*x) = 0;
(*y) = 0;
}
Error is :
I (27) boot: ESP-IDF v5.0.1-dirty 2nd stage bootloader
I (27) boot: compile time 23:28:05
I (27) boot: chip revision: v3.0
I (31) boot.esp32: SPI Speed : 40MHz
I (35) boot.esp32: SPI Mode : DIO
I (40) boot.esp32: SPI Flash Size : 8MB
I (45) boot: Enabling RNG early entropy source...
I (50) boot: Partition Table:
I (53) boot: ## Label Usage Type ST Offset Length
I (61) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (68) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (76) boot: 2 factory factory app 00 00 00010000 00100000
I (83) boot: End of partition table
I (87) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=12374h ( 74612) map
I (123) esp_image: segment 1: paddr=0002239c vaddr=3ffb0000 size=020bch ( 8380) load
I (126) esp_image: segment 2: paddr=00024460 vaddr=40080000 size=0bbb8h ( 48056) load
I (148) esp_image: segment 3: paddr=00030020 vaddr=400d0020 size=48544h (296260) map
I (256) esp_image: segment 4: paddr=0007856c vaddr=4008bbb8 size=01c1ch ( 7196) load
I (266) boot: Loaded app from partition at offset 0x10000
I (266) boot: Disabling RNG early entropy source...
I (279) cpu_start: Pro cpu up.
I (279) cpu_start: Starting app cpu, entry point is 0x400811fc
0x400811fc: call_start_cpu1 at /Users/kyrpav/esp/esp-idf/components/esp_system/port/cpu_start.c:142
I (265) cpu_start: App cpu up.
I (295) cpu_start: Pro cpu start user code
I (295) cpu_start: cpu freq: 160000000 Hz
I (295) cpu_start: Application information:
I (300) cpu_start: Project name: ad_racketier
I (305) cpu_start: App version: bbb12ef-dirty
I (310) cpu_start: Compile time: Mar 8 2023 21:03:21
I (316) cpu_start: ELF file SHA256: f8e15d31f4065cc3...
I (322) cpu_start: ESP-IDF: v5.0.1-dirty
I (328) cpu_start: Min chip rev: v0.0
I (333) cpu_start: Max chip rev: v3.99
I (337) cpu_start: Chip rev: v3.0
I (342) heap_init: Initializing. RAM available for dynamic allocation:
I (349) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (355) heap_init: At 3FFD7A60 len 000085A0 (33 KiB): DRAM
I (362) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (368) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (374) heap_init: At 4008D7D4 len 0001282C (74 KiB): IRAM
I (382) spi_flash: detected chip: generic
I (385) spi_flash: flash io: dio
I (390) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (20) lvgl_helpers: Display buffer size: 0
I (20) lvgl_helpers: Initializing SPI master for display
I (20) lvgl_helpers: Configuring SPI host SPI3_HOST
I (30) lvgl_helpers: MISO pin: 12, MOSI pin: 13, SCLK pin: 14, IO2/WP pin: -1, IO3/HD pin: -1
I (40) lvgl_helpers: Max transfer size: 0 (bytes)
I (40) lvgl_helpers: Initializing SPI bus...
I (50) disp_spi: Adding SPI device
I (60) disp_spi: Clock speed: 10000000Hz, mode: 0, CS pin: 15
I (60) ILI9488: ILI9488 initialization.
I (390) ILI9488: Display orientation: LANDSCAPE
I (390) ILI9488: 0x36 command value: 0x28
I (390) disp_backlight: Setting LCD backlight: 100%
I (390) lvgl_helpers: Initializing SPI master for touch
I (410) lvgl_helpers: Configuring SPI host SPI3_HOST
I (410) lvgl_helpers: MISO pin: 19, MOSI pin: 23, SCLK pin: 18, IO2/WP pin: -1, IO3/HD pin: -1
I (420) lvgl_helpers: Max transfer size: 0 (bytes)
I (430) lvgl_helpers: Initializing SPI bus...
E (430) spi: spi_bus_initialize(758): SPI bus already initialized.
assert failed: lvgl_spi_driver_init lvgl_helpers.c:182 (ret == ESP_OK)
Backtrace: 0x40081cca:0x3ffdc820 0x400868c1:0x3ffdc840 0x4008c39d:0x3ffdc860 0x40101687:0x3ffdc980 0x40101727:0x3ffdca00 0x400d6d40:0x3ffdca30 0x40089461:0x3ffdca70
0x40081cca: panic_abort at /Users/kyrpav/esp/esp-idf/components/esp_system/panic.c:423
0x400868c1: esp_system_abort at /Users/kyrpav/esp/esp-idf/components/esp_system/esp_system.c:153
0x4008c39d: __assert_func at /Users/kyrpav/esp/esp-idf/components/newlib/assert.c:78
0x40101687: lvgl_spi_driver_init at /Users/kyrpav/workspace/esp32/ad_racketier/components/lvgl_esp32_drivers/lvgl_helpers.c:182 (discriminator 1)
0x40101727: lvgl_driver_init at /Users/kyrpav/workspace/esp32/ad_racketier/components/lvgl_esp32_drivers/lvgl_helpers.c:121
0x400d6d40: guiTask at /Users/kyrpav/workspace/esp32/ad_racketier/main/main.c:63
0x40089461: vPortTaskWrapper at /Users/kyrpav/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:154
Screenshot and/or video
If possible, add screenshots and/or videos about the current state.