From 4ffc0764fe376120c5aee9d60569b869c06eac0b Mon Sep 17 00:00:00 2001 From: Vilem Zavodny Date: Thu, 20 Jun 2024 09:04:06 +0200 Subject: [PATCH] feat(lvgl_port): Used added SW rotation to LVGL9 --- .../esp32_p4_function_ev_board.c | 6 +- .../include/bsp/esp32_p4_function_ev_board.h | 2 +- components/esp_lvgl_port/CHANGELOG.md | 7 + components/esp_lvgl_port/README.md | 4 +- components/esp_lvgl_port/idf_component.yml | 2 +- .../include/esp_lvgl_port_disp.h | 4 +- .../esp_lvgl_port/src/lvgl9/esp_lvgl_port.c | 19 +- .../src/lvgl9/esp_lvgl_port_disp.c | 168 ++++++++++++++++-- .../display_lvgl_demos/main/CMakeLists.txt | 18 +- .../sdkconfig.bsp.esp32_p4_function_ev_board | 35 ++++ 10 files changed, 232 insertions(+), 33 deletions(-) create mode 100644 examples/display_rotation/sdkconfig.bsp.esp32_p4_function_ev_board diff --git a/bsp/esp32_p4_function_ev_board/esp32_p4_function_ev_board.c b/bsp/esp32_p4_function_ev_board/esp32_p4_function_ev_board.c index b736089e..342c7b11 100644 --- a/bsp/esp32_p4_function_ev_board/esp32_p4_function_ev_board.c +++ b/bsp/esp32_p4_function_ev_board/esp32_p4_function_ev_board.c @@ -30,7 +30,6 @@ static lv_indev_t *disp_indev = NULL; #endif // (BSP_CONFIG_NO_GRAPHIC_LIB == 0) sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler -static esp_lcd_touch_handle_t tp; // LCD touch handle static bool i2c_initialized = false; static TaskHandle_t usb_host_task; // USB Host Library task @@ -357,15 +356,14 @@ static lv_display_t *bsp_display_lcd_init(const bsp_display_cfg_t *cfg) .mirror_x = true, .mirror_y = true, }, + .color_format = LV_COLOR_FORMAT_RGB565, .flags = { .buff_dma = cfg->flags.buff_dma, .buff_spiram = cfg->flags.buff_spiram, #if LVGL_VERSION_MAJOR >= 9 .swap_bytes = (BSP_LCD_BIGENDIAN ? true : false), #endif -#if LVGL_VERSION_MAJOR == 8 .sw_rotate = cfg->flags.sw_rotate, /* Only SW rotation is supported for 90° and 270° */ -#endif } }; @@ -374,6 +372,7 @@ static lv_display_t *bsp_display_lcd_init(const bsp_display_cfg_t *cfg) static lv_indev_t *bsp_display_indev_init(lv_display_t *disp) { + esp_lcd_touch_handle_t tp; BSP_ERROR_CHECK_RETURN_NULL(bsp_touch_new(NULL, &tp)); assert(tp); @@ -395,6 +394,7 @@ lv_display_t *bsp_display_start(void) .flags = { .buff_dma = true, .buff_spiram = false, + .sw_rotate = true, } }; return bsp_display_start_with_config(&cfg); diff --git a/bsp/esp32_p4_function_ev_board/include/bsp/esp32_p4_function_ev_board.h b/bsp/esp32_p4_function_ev_board/include/bsp/esp32_p4_function_ev_board.h index 238f4870..dbe736a5 100644 --- a/bsp/esp32_p4_function_ev_board/include/bsp/esp32_p4_function_ev_board.h +++ b/bsp/esp32_p4_function_ev_board/include/bsp/esp32_p4_function_ev_board.h @@ -184,7 +184,7 @@ esp_err_t bsp_sdcard_unmount(void); #if (BSP_CONFIG_NO_GRAPHIC_LIB == 0) -#define BSP_LCD_DRAW_BUFF_SIZE (BSP_LCD_H_RES * 100) // Frame buffer size in pixels +#define BSP_LCD_DRAW_BUFF_SIZE (BSP_LCD_H_RES * 50) // Frame buffer size in pixels #define BSP_LCD_DRAW_BUFF_DOUBLE (0) /** diff --git a/components/esp_lvgl_port/CHANGELOG.md b/components/esp_lvgl_port/CHANGELOG.md index 0c3f6938..d0a98894 100644 --- a/components/esp_lvgl_port/CHANGELOG.md +++ b/components/esp_lvgl_port/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 2.3.0 +- Fixed LVGL port for using with LVGL9 OS FreeRTOS enabled +- Fixed bad handled touch due to synchronization timer task + +### Features +- Added support for SW rotation in LVGL9 + ## 2.2.2 ### Fixes diff --git a/components/esp_lvgl_port/README.md b/components/esp_lvgl_port/README.md index 9d6c8a5c..6b90a7e6 100644 --- a/components/esp_lvgl_port/README.md +++ b/components/esp_lvgl_port/README.md @@ -265,8 +265,8 @@ Display rotation can be changed at runtime. lv_disp_set_rotation(disp_handle, LV_DISP_ROT_90); ``` -> [!WARNING] -> Software rotation is available only in LVGL 8. +> [!NOTE] +> This feature consume more RAM. > [!NOTE] > During the hardware rotating, the component call [`esp_lcd`](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/lcd.html) API. When using software rotation, you cannot use neither `direct_mode` nor `full_refresh` in the driver. See [LVGL documentation](https://docs.lvgl.io/8.3/porting/display.html?highlight=sw_rotate) for more info. diff --git a/components/esp_lvgl_port/idf_component.yml b/components/esp_lvgl_port/idf_component.yml index 960b4241..84282afd 100644 --- a/components/esp_lvgl_port/idf_component.yml +++ b/components/esp_lvgl_port/idf_component.yml @@ -1,4 +1,4 @@ -version: "2.2.2" +version: "2.3.0" description: ESP LVGL port url: https://github.com/espressif/esp-bsp/tree/master/components/esp_lvgl_port dependencies: diff --git a/components/esp_lvgl_port/include/esp_lvgl_port_disp.h b/components/esp_lvgl_port/include/esp_lvgl_port_disp.h index f78d70c2..5efbbab2 100644 --- a/components/esp_lvgl_port/include/esp_lvgl_port_disp.h +++ b/components/esp_lvgl_port/include/esp_lvgl_port_disp.h @@ -57,9 +57,7 @@ typedef struct { struct { unsigned int buff_dma: 1; /*!< Allocated LVGL buffer will be DMA capable */ unsigned int buff_spiram: 1; /*!< Allocated LVGL buffer will be in PSRAM */ -#if LVGL_VERSION_MAJOR == 8 - unsigned int sw_rotate: 1; /*!< Use software rotation (slower) */ -#endif + unsigned int sw_rotate: 1; /*!< Use software rotation (slower) or PPA if available */ #if LVGL_VERSION_MAJOR >= 9 unsigned int swap_bytes: 1; /*!< Swap bytes in RGB656 (16-bit) color format before send to LCD driver */ #endif diff --git a/components/esp_lvgl_port/src/lvgl9/esp_lvgl_port.c b/components/esp_lvgl_port/src/lvgl9/esp_lvgl_port.c index 156010fe..87ffb63b 100644 --- a/components/esp_lvgl_port/src/lvgl9/esp_lvgl_port.c +++ b/components/esp_lvgl_port/src/lvgl9/esp_lvgl_port.c @@ -29,6 +29,7 @@ static const char *TAG = "LVGL"; typedef struct lvgl_port_ctx_s { TaskHandle_t lvgl_task; SemaphoreHandle_t lvgl_mux; + SemaphoreHandle_t timer_mux; QueueHandle_t lvgl_queue; SemaphoreHandle_t task_init_mux; esp_timer_handle_t tick_timer; @@ -61,16 +62,16 @@ esp_err_t lvgl_port_init(const lvgl_port_cfg_t *cfg) memset(&lvgl_port_ctx, 0, sizeof(lvgl_port_ctx)); - /* LVGL init */ - lv_init(); /* Tick init */ lvgl_port_ctx.timer_period_ms = cfg->timer_period_ms; - ESP_RETURN_ON_ERROR(lvgl_port_tick_init(), TAG, ""); /* Create task */ lvgl_port_ctx.task_max_sleep_ms = cfg->task_max_sleep_ms; if (lvgl_port_ctx.task_max_sleep_ms == 0) { lvgl_port_ctx.task_max_sleep_ms = 500; } + /* Timer semaphore */ + lvgl_port_ctx.timer_mux = xSemaphoreCreateMutex(); + ESP_GOTO_ON_FALSE(lvgl_port_ctx.timer_mux, ESP_ERR_NO_MEM, err, TAG, "Create timer mutex fail!"); /* LVGL semaphore */ lvgl_port_ctx.lvgl_mux = xSemaphoreCreateRecursiveMutex(); ESP_GOTO_ON_FALSE(lvgl_port_ctx.lvgl_mux, ESP_ERR_NO_MEM, err, TAG, "Create LVGL mutex fail!"); @@ -216,6 +217,11 @@ static void lvgl_port_task(void *arg) vTaskDelete( NULL ); } + /* LVGL init */ + lv_init(); + /* Tick init */ + lvgl_port_tick_init(); + ESP_LOGI(TAG, "Starting LVGL task"); lvgl_port_ctx.running = true; while (lvgl_port_ctx.running) { @@ -227,6 +233,7 @@ static void lvgl_port_task(void *arg) /* Call read input devices */ if (event.type == LVGL_PORT_EVENT_TOUCH) { + xSemaphoreTake(lvgl_port_ctx.timer_mux, portMAX_DELAY); if (event.param != NULL) { lv_indev_read(event.param); } else { @@ -236,6 +243,7 @@ static void lvgl_port_task(void *arg) indev = lv_indev_get_next(indev); } } + xSemaphoreGive(lvgl_port_ctx.timer_mux); } /* Handle LVGL */ @@ -262,6 +270,9 @@ static void lvgl_port_task(void *arg) static void lvgl_port_task_deinit(void) { + if (lvgl_port_ctx.timer_mux) { + vSemaphoreDelete(lvgl_port_ctx.timer_mux); + } if (lvgl_port_ctx.lvgl_mux) { vSemaphoreDelete(lvgl_port_ctx.lvgl_mux); } @@ -280,8 +291,10 @@ static void lvgl_port_task_deinit(void) static void lvgl_port_tick_increment(void *arg) { + xSemaphoreTake(lvgl_port_ctx.timer_mux, portMAX_DELAY); /* Tell LVGL how many milliseconds have elapsed */ lv_tick_inc(lvgl_port_ctx.timer_period_ms); + xSemaphoreGive(lvgl_port_ctx.timer_mux); } static esp_err_t lvgl_port_tick_init(void) diff --git a/components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_disp.c b/components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_disp.c index 0eb6b2b3..99dd2b30 100644 --- a/components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_disp.c +++ b/components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_disp.c @@ -10,6 +10,7 @@ #include "esp_check.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "freertos/semphr.h" #include "esp_heap_caps.h" #include "esp_idf_version.h" #include "esp_lcd_panel_io.h" @@ -43,13 +44,15 @@ typedef struct { esp_lcd_panel_handle_t panel_handle; /* LCD panel handle */ esp_lcd_panel_handle_t control_handle; /* LCD panel control handle */ lvgl_port_rotation_cfg_t rotation; /* Default values of the screen rotation */ - lv_color_t *draw_buffs[2]; /* Display draw buffers */ + lv_color_t *draw_buffs[3]; /* Display draw buffers */ lv_display_t *disp_drv; /* LVGL display driver */ + lv_display_rotation_t current_rotation; struct { unsigned int monochrome: 1; /* True, if display is monochrome and using 1bit for 1px */ unsigned int swap_bytes: 1; /* Swap bytes in RGB656 (16-bit) before send to LCD driver */ unsigned int full_refresh: 1; /* Always make the whole screen redrawn */ unsigned int direct_mode: 1; /* Use screen-sized buffers and draw to absolute coordinates */ + unsigned int sw_rotate: 1; /* Use software rotation (slower) or PPA if available */ } flags; } lvgl_port_display_ctx_t; @@ -122,6 +125,7 @@ lv_display_t *lvgl_port_add_disp_dsi(const lvgl_port_display_cfg_t *disp_cfg, co /* Apply rotation from initial display configuration */ lvgl_port_disp_rotation_update(disp_ctx); + #else ESP_RETURN_ON_FALSE(false, NULL, TAG, "MIPI-DSI is supported only on ESP32P4 and from IDF 5.3!"); #endif @@ -191,6 +195,10 @@ esp_err_t lvgl_port_remove_disp(lv_display_t *disp) free(disp_ctx->draw_buffs[1]); } + if (disp_ctx->draw_buffs[2]) { + free(disp_ctx->draw_buffs[2]); + } + free(disp_ctx); return ESP_OK; @@ -246,6 +254,24 @@ static lv_display_t *lvgl_port_add_disp_priv(const lvgl_port_display_cfg_t *disp disp_ctx->rotation.mirror_x = disp_cfg->rotation.mirror_x; disp_ctx->rotation.mirror_y = disp_cfg->rotation.mirror_y; disp_ctx->flags.swap_bytes = disp_cfg->flags.swap_bytes; + disp_ctx->flags.sw_rotate = disp_cfg->flags.sw_rotate; + disp_ctx->current_rotation = LV_DISPLAY_ROTATION_0; + + uint32_t buff_caps = 0; +#if SOC_PSRAM_DMA_CAPABLE == 0 + if (disp_cfg->flags.buff_dma && disp_cfg->flags.buff_spiram) { + ESP_GOTO_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, err, TAG, "Alloc DMA capable buffer in SPIRAM is not supported!"); + } +#endif + if (disp_cfg->flags.buff_dma) { + buff_caps |= MALLOC_CAP_DMA; + } + if (disp_cfg->flags.buff_spiram) { + buff_caps |= MALLOC_CAP_SPIRAM; + } + if (buff_caps == 0) { + buff_caps |= MALLOC_CAP_DEFAULT; + } /* Use RGB internal buffers for avoid tearing effect */ if (priv_cfg && priv_cfg->avoid_tearing) { @@ -254,15 +280,6 @@ static lv_display_t *lvgl_port_add_disp_priv(const lvgl_port_display_cfg_t *disp ESP_GOTO_ON_ERROR(esp_lcd_rgb_panel_get_frame_buffer(disp_cfg->panel_handle, 2, (void *)&buf1, (void *)&buf2), err, TAG, "Get RGB buffers failed"); #endif } else { - uint32_t buff_caps = MALLOC_CAP_DEFAULT; - if (disp_cfg->flags.buff_dma && disp_cfg->flags.buff_spiram) { - ESP_GOTO_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, err, TAG, "Alloc DMA capable buffer in SPIRAM is not supported!"); - } else if (disp_cfg->flags.buff_dma) { - buff_caps = MALLOC_CAP_DMA; - } else if (disp_cfg->flags.buff_spiram) { - buff_caps = MALLOC_CAP_SPIRAM; - } - /* alloc draw buffers used by LVGL */ /* it's recommended to choose the size of the draw buffer(s) to be at least 1/10 screen sized */ buf1 = heap_caps_malloc(buffer_size * sizeof(lv_color_t), buff_caps); @@ -310,6 +327,13 @@ static lv_display_t *lvgl_port_add_disp_priv(const lvgl_port_display_cfg_t *disp lv_display_set_user_data(disp, disp_ctx); disp_ctx->disp_drv = disp; + /* Use SW rotation */ + if (disp_cfg->flags.sw_rotate) { + disp_ctx->draw_buffs[2] = heap_caps_malloc(buffer_size * sizeof(lv_color_t), buff_caps); + ESP_GOTO_ON_FALSE(disp_ctx->draw_buffs[2], ESP_ERR_NO_MEM, err, TAG, "Not enough memory for LVGL buffer (rotation buffer) allocation!"); + } + + err: if (ret != ESP_OK) { if (buf1) { @@ -318,6 +342,9 @@ static lv_display_t *lvgl_port_add_disp_priv(const lvgl_port_display_cfg_t *disp if (buf2) { free(buf2); } + if (disp_ctx->draw_buffs[2]) { + free(disp_ctx->draw_buffs[2]); + } if (disp_ctx) { free(disp_ctx); } @@ -401,27 +428,127 @@ static void _lvgl_port_transform_monochrome(lv_display_t *display, const lv_area } } +void lv_display_rotate_area(lv_display_t *disp, lv_area_t *area) +{ + lv_display_rotation_t rotation = lv_display_get_rotation(disp); + + int32_t w = lv_area_get_width(area); + int32_t h = lv_area_get_height(area); + + int32_t hres = lv_display_get_horizontal_resolution(disp); + int32_t vres = lv_display_get_vertical_resolution(disp); + + /*int x1 = area->x1; + int x2 = area->x2; + int y1 = area->y1; + int y2 = area->y2;*/ + + /* Rotate coordinates */ + /*switch (rotation) { + case LV_DISPLAY_ROTATION_0: + break; + case LV_DISPLAY_ROTATION_90: + x1 = area->y1; + x2 = area->y2; + y1 = hres - area->x2; + y2 = hres - area->x1; + break; + case LV_DISPLAY_ROTATION_180: + x1 = hres - area->x2 - 1; + x2 = hres - area->x1 - 1; + y1 = vres - area->y2; + y2 = vres - area->y1; + break; + case LV_DISPLAY_ROTATION_270: + x1 = vres - area->y2 - 1; + x2 = vres - area->y1 - 1; + y1 = area->x1; + y2 = area->x2; + break; + }*/ + /* Return new coordinates */ + /*area->x1 = x1; + area->x2 = x2; + area->y1 = y1; + area->y2 = y2;*/ + + + if (rotation == LV_DISPLAY_ROTATION_90 || rotation == LV_DISPLAY_ROTATION_270) { + vres = lv_display_get_horizontal_resolution(disp); + hres = lv_display_get_vertical_resolution(disp); + } + + switch (rotation) { + case LV_DISPLAY_ROTATION_0: + return; + case LV_DISPLAY_ROTATION_90: + area->y2 = vres - area->x1 - 1; + area->x1 = area->y1; + area->x2 = area->x1 + h - 1; + area->y1 = area->y2 - w + 1; + break; + case LV_DISPLAY_ROTATION_180: + area->y2 = vres - area->y1 - 1; + area->y1 = area->y2 - h + 1; + area->x2 = hres - area->x1 - 1; + area->x1 = area->x2 - w + 1; + break; + case LV_DISPLAY_ROTATION_270: + area->x1 = hres - area->y2 - 1; + area->y2 = area->x2; + area->x2 = area->x1 + h - 1; + area->y1 = area->y2 - w + 1; + break; + } +} + static void lvgl_port_flush_callback(lv_display_t *drv, const lv_area_t *area, uint8_t *color_map) { assert(drv != NULL); + assert(area != NULL); + assert(color_map != NULL); lvgl_port_display_ctx_t *disp_ctx = (lvgl_port_display_ctx_t *)lv_display_get_user_data(drv); assert(disp_ctx != NULL); - if (disp_ctx->flags.swap_bytes) { + int offsetx1 = area->x1; + int offsetx2 = area->x2; + int offsety1 = area->y1; + int offsety2 = area->y2; + + /* SW rotation enabled */ + if (disp_ctx->flags.sw_rotate && (disp_ctx->current_rotation > LV_DISPLAY_ROTATION_0 || disp_ctx->flags.swap_bytes)) { + /* SW rotation */ + if (disp_ctx->draw_buffs[2]) { + int32_t ww = lv_area_get_width(area); + int32_t hh = lv_area_get_height(area); + lv_color_format_t cf = lv_display_get_color_format(drv); + uint32_t w_stride = lv_draw_buf_width_to_stride(ww, cf); + uint32_t h_stride = lv_draw_buf_width_to_stride(hh, cf); + if (disp_ctx->current_rotation == LV_DISPLAY_ROTATION_180) { + lv_draw_sw_rotate(color_map, disp_ctx->draw_buffs[2], hh, ww, h_stride, h_stride, LV_DISPLAY_ROTATION_180, cf); + } else if (disp_ctx->current_rotation == LV_DISPLAY_ROTATION_90) { + lv_draw_sw_rotate(color_map, disp_ctx->draw_buffs[2], ww, hh, w_stride, h_stride, LV_DISPLAY_ROTATION_270, cf); + } else if (disp_ctx->current_rotation == LV_DISPLAY_ROTATION_270) { + lv_draw_sw_rotate(color_map, disp_ctx->draw_buffs[2], ww, hh, w_stride, h_stride, LV_DISPLAY_ROTATION_90, cf); + } + color_map = (uint8_t *)disp_ctx->draw_buffs[2]; + lv_display_rotate_area(drv, (lv_area_t *)area); + offsetx1 = area->x1; + offsetx2 = area->x2; + offsety1 = area->y1; + offsety2 = area->y2; + } + } else if (disp_ctx->flags.swap_bytes) { size_t len = lv_area_get_size(area); lv_draw_sw_rgb565_swap(color_map, len); } - /* Transfor data in buffer for monochromatic screen */ + /* Transfer data in buffer for monochromatic screen */ if (disp_ctx->flags.monochrome) { _lvgl_port_transform_monochrome(drv, area, color_map); } - const int offsetx1 = area->x1; - const int offsetx2 = area->x2; - const int offsety1 = area->y1; - const int offsety2 = area->y2; - + /* RGB LCD */ if (disp_ctx->disp_type == LVGL_PORT_DISP_TYPE_RGB && (disp_ctx->flags.full_refresh || disp_ctx->flags.direct_mode)) { if (lv_disp_flush_is_last(drv)) { /* If the interface is I80 or SPI, this step cannot be used for drawing. */ @@ -442,8 +569,13 @@ static void lvgl_port_flush_callback(lv_display_t *drv, const lv_area_t *area, u static void lvgl_port_disp_rotation_update(lvgl_port_display_ctx_t *disp_ctx) { assert(disp_ctx != NULL); - esp_lcd_panel_handle_t control_handle = (disp_ctx->control_handle ? disp_ctx->control_handle : disp_ctx->panel_handle); + disp_ctx->current_rotation = lv_display_get_rotation(disp_ctx->disp_drv); + if (disp_ctx->flags.sw_rotate) { + return; + } + + esp_lcd_panel_handle_t control_handle = (disp_ctx->control_handle ? disp_ctx->control_handle : disp_ctx->panel_handle); /* Solve rotation screen and touch */ switch (lv_display_get_rotation(disp_ctx->disp_drv)) { case LV_DISPLAY_ROTATION_0: diff --git a/examples/display_lvgl_demos/main/CMakeLists.txt b/examples/display_lvgl_demos/main/CMakeLists.txt index 9cbce04f..2b3ee70e 100644 --- a/examples/display_lvgl_demos/main/CMakeLists.txt +++ b/examples/display_lvgl_demos/main/CMakeLists.txt @@ -1,3 +1,17 @@ +set(LV_DEMO_DIR "") +set(LV_DEMOS_SOURCES "") +if(CONFIG_LV_USE_DEMO_BENCHMARK) + list(APPEND LV_DEMO_DIR ../managed_components/lvgl__lvgl/demos) + file(GLOB_RECURSE LV_DEMOS_SOURCES ${LV_DEMO_DIR}/*.c) +endif() + idf_component_register( - SRCS "dispaly_lvgl_demos_main.c" - INCLUDE_DIRS ".") + SRCS "dispaly_lvgl_demos_main.c" ${LV_DEMOS_SOURCES} + INCLUDE_DIRS "." ${LV_DEMO_DIR}) + +if(CONFIG_LV_USE_DEMO_BENCHMARK) +set_source_files_properties( + ${LV_DEMOS_SOURCES} + PROPERTIES COMPILE_OPTIONS + -DLV_LVGL_H_INCLUDE_SIMPLE) +endif() diff --git a/examples/display_rotation/sdkconfig.bsp.esp32_p4_function_ev_board b/examples/display_rotation/sdkconfig.bsp.esp32_p4_function_ev_board new file mode 100644 index 00000000..e3d4fd25 --- /dev/null +++ b/examples/display_rotation/sdkconfig.bsp.esp32_p4_function_ev_board @@ -0,0 +1,35 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_IDF_TARGET="esp32p4" + +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_COMPILER_OPTIMIZATION_PERF=y +CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM=y +CONFIG_FREERTOS_HZ=1000 + +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_HEX=y +CONFIG_SPIRAM_SPEED_200M=y +CONFIG_IDF_EXPERIMENTAL_FEATURES=y + +## LVGL8 ## +CONFIG_LV_MEM_SIZE_KILOBYTES=48 +CONFIG_LV_USE_PERF_MONITOR=y + +## LVGL9 ## +CONFIG_LV_CONF_SKIP=y +CONFIG_LV_DEF_REFR_PERIOD=10 + +#CLIB default +CONFIG_LV_USE_CLIB_MALLOC=y +CONFIG_LV_USE_CLIB_SPRINTF=y +CONFIG_LV_USE_CLIB_STRING=y + +# Performance monitor +CONFIG_LV_USE_OBSERVER=y +CONFIG_LV_USE_SYSMON=y +CONFIG_LV_USE_PERF_MONITOR=y + + +# CONFIG_LV_BUILD_EXAMPLES is not set