diff --git a/components/platform/CMakeLists.txt b/components/platform/CMakeLists.txt index 6ab6cf3..9ee12af 100644 --- a/components/platform/CMakeLists.txt +++ b/components/platform/CMakeLists.txt @@ -15,6 +15,8 @@ idf_component_register( "include" PRIV_INCLUDE_DIRS "internal" + PRIV_REQUIRES + esp_timer REQUIRES esp_wifi esp_netif @@ -25,7 +27,6 @@ idf_component_register( esp_adc esp_driver_gpio esp_driver_spi - lvgl espressif__libpng espressif__button esp_codec_dev diff --git a/components/platform/src/display_lcd_decode_image.c b/components/platform/src/display_lcd_decode_image.c index ac559ca..a6620b6 100644 --- a/components/platform/src/display_lcd_decode_image.c +++ b/components/platform/src/display_lcd_decode_image.c @@ -8,7 +8,6 @@ #include "esp_check.h" #include "esp_heap_caps.h" #include "esp_log.h" -#include "lvgl.h" #include "png.h" static const char *TAG = "lcd_png_dec"; @@ -23,6 +22,13 @@ static void lcd_fill_err(char *err, size_t err_len, const char *msg) } } +static inline uint16_t lcd_rgb888_to_rgb565(uint8_t r, uint8_t g, uint8_t b) +{ + return (uint16_t)((((uint16_t)r & 0xF8u) << 8) | + (((uint16_t)g & 0xFCu) << 3) | + (((uint16_t)b & 0xF8u) >> 3)); +} + esp_err_t platform_lcd_decode_png_rgb565(const uint8_t *png, size_t png_len, uint16_t **out_pixels, @@ -102,8 +108,7 @@ esp_err_t platform_lcd_decode_png_rgb565(const uint8_t *png, g = (uint8_t)((((uint32_t)g * (uint32_t)a) + (255u * (255u - (uint32_t)a)) + 127u) / 255u); b = (uint8_t)((((uint32_t)b * (uint32_t)a) + (255u * (255u - (uint32_t)a)) + 127u) / 255u); } - lv_color_t color = lv_color_make(r, g, b); - pixels[i] = (uint16_t)color.full; + pixels[i] = lcd_rgb888_to_rgb565(r, g, b); } heap_caps_free(rgba); diff --git a/components/platform/src/display_lcd_module.c b/components/platform/src/display_lcd_module.c index b106f52..0212193 100644 --- a/components/platform/src/display_lcd_module.c +++ b/components/platform/src/display_lcd_module.c @@ -11,7 +11,6 @@ #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" -#include "lvgl.h" #include "sdkconfig.h" #include "display_lcd_decode_image.h" #include "display_st7789p3.h" @@ -24,6 +23,8 @@ static const char *TAG = "lcd_module"; #define LCD_DEFAULT_DRAW_LINES 20 #define LCD_PREVIEW_FADE_DURATION_MS 150 #define LCD_PREVIEW_FADE_STEPS 3 +#define LCD_RGB565_BLACK 0x0000u +#define LCD_RGB565_WHITE 0xFFFFu #ifndef CONFIG_TQ_SCREEN_PIXEL_CLOCK_HZ #define CONFIG_TQ_SCREEN_PIXEL_CLOCK_HZ (10 * 1000 * 1000) @@ -101,16 +102,9 @@ static const char *TAG = "lcd_module"; typedef struct { st7789p3_handle_t panel; SemaphoreHandle_t lock; - lv_disp_draw_buf_t lv_draw_buf; - lv_disp_drv_t lv_drv; - lv_disp_t *lv_disp; - lv_obj_t *preview_img; - lv_color_t *draw_buf_1; - lv_color_t *draw_buf_2; uint16_t *preview_pixels; - lv_img_dsc_t preview_dsc; - bool lvgl_inited; - bool lvgl_ready; + uint16_t preview_w; + uint16_t preview_h; bool initialized; bool shared_spi_dirty; } lcd_state_t; @@ -174,27 +168,6 @@ static void lcd_lock_give(void) } } -static void *lcd_alloc_fb(size_t bytes) -{ - void *buf = heap_caps_malloc(bytes, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); - if (buf == NULL) { - buf = heap_caps_malloc(bytes, MALLOC_CAP_8BIT); - } - return buf; -} - -static void lcd_free_lvgl_buffers(void) -{ - if (s_lcd.draw_buf_1 != NULL) { - heap_caps_free(s_lcd.draw_buf_1); - s_lcd.draw_buf_1 = NULL; - } - if (s_lcd.draw_buf_2 != NULL) { - heap_caps_free(s_lcd.draw_buf_2); - s_lcd.draw_buf_2 = NULL; - } -} - static esp_err_t lcd_recover_panel_for_shared_spi(void) { if (!s_lcd.initialized || s_lcd.panel == NULL) { @@ -223,82 +196,6 @@ static esp_err_t lcd_recover_panel_for_shared_spi(void) return lcd_module_init(); } -static void lcd_lvgl_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_map) -{ - st7789p3_handle_t panel = (st7789p3_handle_t)disp_drv->user_data; - if (panel == NULL || area == NULL || color_map == NULL) { - lv_disp_flush_ready(disp_drv); - return; - } - if (area->x1 < 0 || area->y1 < 0 || area->x2 < area->x1 || area->y2 < area->y1) { - lv_disp_flush_ready(disp_drv); - return; - } - - esp_err_t err = st7789p3_draw_bitmap(panel, - (uint16_t)area->x1, - (uint16_t)area->y1, - (uint16_t)(area->x2 + 1), - (uint16_t)(area->y2 + 1), - (const uint16_t *)color_map); - if (err != ESP_OK) { - ESP_LOGW(TAG, "lvgl flush failed: %s", esp_err_to_name(err)); - } - lv_disp_flush_ready(disp_drv); -} - -static esp_err_t lcd_lvgl_init_locked(void) -{ - if (s_lcd.lvgl_ready) { - return ESP_OK; - } - - if (!s_lcd.lvgl_inited) { - lv_init(); - s_lcd.lvgl_inited = true; - } - - const size_t draw_buf_pixels = LCD_PANEL_H_RES * CONFIG_TQ_SCREEN_DRAW_LINES; - const size_t draw_buf_bytes = draw_buf_pixels * sizeof(lv_color_t); - s_lcd.draw_buf_1 = (lv_color_t *)lcd_alloc_fb(draw_buf_bytes); - if (s_lcd.draw_buf_1 == NULL) { - return ESP_ERR_NO_MEM; - } - s_lcd.draw_buf_2 = (lv_color_t *)lcd_alloc_fb(draw_buf_bytes); - if (s_lcd.draw_buf_2 == NULL) { - lcd_free_lvgl_buffers(); - return ESP_ERR_NO_MEM; - } - - lv_disp_draw_buf_init(&s_lcd.lv_draw_buf, s_lcd.draw_buf_1, s_lcd.draw_buf_2, draw_buf_pixels); - - lv_disp_drv_init(&s_lcd.lv_drv); - s_lcd.lv_drv.hor_res = LCD_PANEL_H_RES; - s_lcd.lv_drv.ver_res = LCD_PANEL_V_RES; - s_lcd.lv_drv.flush_cb = lcd_lvgl_flush_cb; - s_lcd.lv_drv.draw_buf = &s_lcd.lv_draw_buf; - s_lcd.lv_drv.user_data = s_lcd.panel; - s_lcd.lv_disp = lv_disp_drv_register(&s_lcd.lv_drv); - if (s_lcd.lv_disp == NULL) { - lcd_free_lvgl_buffers(); - ESP_LOGE(TAG, "lvgl display register failed"); - return ESP_FAIL; - } - - lv_obj_t *screen = lv_scr_act(); - lv_obj_set_style_bg_color(screen, lv_color_black(), LV_PART_MAIN); - lv_obj_set_style_bg_opa(screen, LV_OPA_COVER, LV_PART_MAIN); - lv_obj_clear_flag(screen, LV_OBJ_FLAG_SCROLLABLE); - - s_lcd.preview_img = lv_img_create(screen); - lv_obj_add_flag(s_lcd.preview_img, LV_OBJ_FLAG_HIDDEN); - lv_obj_center(s_lcd.preview_img); - - s_lcd.lvgl_ready = true; - lv_refr_now(s_lcd.lv_disp); - return ESP_OK; -} - static void lcd_calc_preview_size(uint16_t src_w, uint16_t src_h, uint16_t *out_w, uint16_t *out_h) { if (src_w == 0 || src_h == 0 || out_w == NULL || out_h == NULL) { @@ -489,7 +386,7 @@ static esp_err_t lcd_apply_preview_locked(const uint16_t *prev_pixels, uint16_t prev_w, uint16_t prev_h, bool clear_before_draw, - lv_color_t bg_color, + uint16_t bg_color, char *err, size_t err_len) { @@ -498,15 +395,15 @@ static esp_err_t lcd_apply_preview_locked(const uint16_t *prev_pixels, return ESP_ERR_INVALID_STATE; } - uint16_t preview_w = s_lcd.preview_dsc.header.w; - uint16_t preview_h = s_lcd.preview_dsc.header.h; + uint16_t preview_w = s_lcd.preview_w; + uint16_t preview_h = s_lcd.preview_h; if (preview_w == 0 || preview_h == 0 || preview_w > LCD_PANEL_H_RES || preview_h > LCD_PANEL_V_RES) { lcd_fill_err(err, err_len, "invalid preview size"); return ESP_ERR_INVALID_SIZE; } if (clear_before_draw) { - esp_err_t clear_rc = st7789p3_fill_color(s_lcd.panel, (uint16_t)bg_color.full); + esp_err_t clear_rc = st7789p3_fill_color(s_lcd.panel, bg_color); if (clear_rc != ESP_OK) { lcd_fill_err(err, err_len, "display clear failed"); return clear_rc; @@ -582,17 +479,12 @@ void lcd_module_deinit(void) } } - if (s_lcd.lv_disp != NULL) { - lv_disp_remove(s_lcd.lv_disp); - s_lcd.lv_disp = NULL; - } if (s_lcd.preview_pixels != NULL) { heap_caps_free(s_lcd.preview_pixels); s_lcd.preview_pixels = NULL; } - lcd_free_lvgl_buffers(); - s_lcd.preview_img = NULL; - s_lcd.lvgl_ready = false; + s_lcd.preview_w = 0; + s_lcd.preview_h = 0; if (s_lcd.lock != NULL) { xSemaphoreGive(s_lcd.lock); @@ -655,17 +547,6 @@ esp_err_t lcd_module_init(void) return ESP_ERR_NO_MEM; } - if (!lcd_lock_take(LCD_LOCK_TIMEOUT_MS)) { - lcd_module_deinit(); - return ESP_ERR_TIMEOUT; - } - err = lcd_lvgl_init_locked(); - lcd_lock_give(); - if (err != ESP_OK) { - lcd_module_deinit(); - return err; - } - s_lcd.initialized = true; s_lcd.shared_spi_dirty = false; ESP_LOGI(TAG, @@ -731,26 +612,20 @@ esp_err_t lcd_module_show_raster_1bpp(const uint8_t *raster, } uint16_t *prev_pixels = s_lcd.preview_pixels; - uint16_t prev_w = s_lcd.preview_dsc.header.w; - uint16_t prev_h = s_lcd.preview_dsc.header.h; + uint16_t prev_w = s_lcd.preview_w; + uint16_t prev_h = s_lcd.preview_h; bool clear_before_draw = (s_lcd.preview_pixels == NULL || - s_lcd.preview_dsc.header.w != preview_w || - s_lcd.preview_dsc.header.h != preview_h); + s_lcd.preview_w != preview_w || + s_lcd.preview_h != preview_h); s_lcd.preview_pixels = preview_pixels; - - memset(&s_lcd.preview_dsc, 0, sizeof(s_lcd.preview_dsc)); - s_lcd.preview_dsc.header.always_zero = 0; - s_lcd.preview_dsc.header.w = preview_w; - s_lcd.preview_dsc.header.h = preview_h; - s_lcd.preview_dsc.header.cf = LV_IMG_CF_TRUE_COLOR; - s_lcd.preview_dsc.data_size = (uint32_t)((size_t)preview_w * preview_h * sizeof(uint16_t)); - s_lcd.preview_dsc.data = (const uint8_t *)s_lcd.preview_pixels; + s_lcd.preview_w = preview_w; + s_lcd.preview_h = preview_h; esp_err_t draw_err = lcd_apply_preview_locked(prev_pixels, prev_w, prev_h, clear_before_draw, - lv_color_white(), + LCD_RGB565_WHITE, err, err_len); if (prev_pixels != NULL) { @@ -813,26 +688,20 @@ esp_err_t lcd_module_show_png(const uint8_t *png, } uint16_t *prev_pixels = s_lcd.preview_pixels; - uint16_t prev_w = s_lcd.preview_dsc.header.w; - uint16_t prev_h = s_lcd.preview_dsc.header.h; + uint16_t prev_w = s_lcd.preview_w; + uint16_t prev_h = s_lcd.preview_h; bool clear_before_draw = (s_lcd.preview_pixels == NULL || - s_lcd.preview_dsc.header.w != preview_w || - s_lcd.preview_dsc.header.h != preview_h); + s_lcd.preview_w != preview_w || + s_lcd.preview_h != preview_h); s_lcd.preview_pixels = preview_pixels; - - memset(&s_lcd.preview_dsc, 0, sizeof(s_lcd.preview_dsc)); - s_lcd.preview_dsc.header.always_zero = 0; - s_lcd.preview_dsc.header.w = preview_w; - s_lcd.preview_dsc.header.h = preview_h; - s_lcd.preview_dsc.header.cf = LV_IMG_CF_TRUE_COLOR; - s_lcd.preview_dsc.data_size = (uint32_t)((size_t)preview_w * preview_h * sizeof(uint16_t)); - s_lcd.preview_dsc.data = (const uint8_t *)s_lcd.preview_pixels; + s_lcd.preview_w = preview_w; + s_lcd.preview_h = preview_h; esp_err_t draw_err = lcd_apply_preview_locked(prev_pixels, prev_w, prev_h, clear_before_draw, - lv_color_white(), + LCD_RGB565_WHITE, err, err_len); if (prev_pixels != NULL) { @@ -869,26 +738,20 @@ esp_err_t lcd_module_start_demo(void) } uint16_t *prev_pixels = s_lcd.preview_pixels; - uint16_t prev_w = s_lcd.preview_dsc.header.w; - uint16_t prev_h = s_lcd.preview_dsc.header.h; + uint16_t prev_w = s_lcd.preview_w; + uint16_t prev_h = s_lcd.preview_h; bool clear_before_draw = (s_lcd.preview_pixels == NULL || - s_lcd.preview_dsc.header.w != demo_w || - s_lcd.preview_dsc.header.h != demo_h); + s_lcd.preview_w != demo_w || + s_lcd.preview_h != demo_h); s_lcd.preview_pixels = demo_pixels; - - memset(&s_lcd.preview_dsc, 0, sizeof(s_lcd.preview_dsc)); - s_lcd.preview_dsc.header.always_zero = 0; - s_lcd.preview_dsc.header.w = demo_w; - s_lcd.preview_dsc.header.h = demo_h; - s_lcd.preview_dsc.header.cf = LV_IMG_CF_TRUE_COLOR; - s_lcd.preview_dsc.data_size = (uint32_t)((size_t)demo_w * demo_h * sizeof(uint16_t)); - s_lcd.preview_dsc.data = (const uint8_t *)s_lcd.preview_pixels; + s_lcd.preview_w = demo_w; + s_lcd.preview_h = demo_h; esp_err_t draw_err = lcd_apply_preview_locked(prev_pixels, prev_w, prev_h, clear_before_draw, - lv_color_black(), + LCD_RGB565_BLACK, decode_err, sizeof(decode_err)); if (prev_pixels != NULL) { diff --git a/dependencies.lock b/dependencies.lock index 2513ebf..b17029a 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -81,13 +81,6 @@ dependencies: source: type: idf version: 5.5.2 - lvgl/lvgl: - component_hash: d7c1ac037ae6e85d94897f807d6e7ba0946a83e720074fc95a4f6241da9f9f53 - dependencies: [] - source: - registry_url: https://components.espressif.com/ - type: service - version: 8.4.0 direct_dependencies: - espressif/button - espressif/esp_audio_codec @@ -95,7 +88,6 @@ direct_dependencies: - espressif/esp_websocket_client - espressif/libpng - idf -- lvgl/lvgl -manifest_hash: 5b79c550c80a326ef9d785d7e8e10bbcc72576af958820e86c1740fad847ebab +manifest_hash: f2ca0e74532324c207c6e8a99582179a9b654e68175e1c46107837b09547e31a target: esp32s3 version: 2.0.0 diff --git a/main/idf_component.yml b/main/idf_component.yml index 640ff98..c378ddc 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -18,5 +18,4 @@ dependencies: espressif/esp_codec_dev: ^1.5.4 espressif/esp_audio_codec: ^2.4.1 espressif/libpng: ^1.6.55 - lvgl/lvgl: ^8.3.11 espressif/button: ^4.1.5