From c36e25ce3f728dd79fec9f560a53930fa699f3c6 Mon Sep 17 00:00:00 2001 From: Terrence Date: Mon, 3 Feb 2025 23:43:07 +0800 Subject: [PATCH] upgrade to LVGL 9 --- CMakeLists.txt | 2 +- main/application.cc | 11 +- .../atk-dnesp32s3-box/atk_dnesp32s3_box.cc | 2 +- main/boards/atk-dnesp32s3/atk_dnesp32s3.cc | 2 +- .../atoms3r-echo-base/atoms3r_echo_base.cc | 2 +- .../compact_wifi_board_lcd.cc | 2 +- main/boards/esp-box-3/esp_box3_board.cc | 2 +- .../boards/esp-sparkbot/esp_sparkbot_board.cc | 2 +- .../esp32-s3-touch-amoled-1.8.cc | 2 +- .../esp32s3_korvo2_v3_board.cc | 2 +- .../lichuang-c3-dev/lichuang_c3_dev_board.cc | 2 +- .../boards/lichuang-dev/lichuang_dev_board.cc | 2 +- .../lilygo-t-circle-s3/lilygo-t-circle-s3.cc | 2 +- .../boards/m5stack-core-s3/m5stack_core_s3.cc | 2 +- .../magiclick-2p4/magiclick_2p4_board.cc | 2 +- .../boards/magiclick-c3/magiclick_c3_board.cc | 2 +- .../movecall_moji_esp32s3.cc | 4 +- main/display/display.cc | 20 +- main/display/display.h | 7 +- main/display/lcd_display.cc | 184 +++++------------- main/display/lcd_display.h | 14 +- main/display/ssd1306_display.cc | 15 +- main/display/ssd1306_display.h | 2 - main/idf_component.yml | 7 +- sdkconfig.defaults | 20 +- sdkconfig.defaults.esp32s3 | 2 +- 26 files changed, 119 insertions(+), 197 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7343f63..f806b26 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.16) -set(PROJECT_VER "1.0.1") +set(PROJECT_VER "1.1.0") # Add this line to disable the specific warning add_compile_options(-Wno-missing-field-initializers) diff --git a/main/application.cc b/main/application.cc index a961835..53d8889 100644 --- a/main/application.cc +++ b/main/application.cc @@ -77,6 +77,7 @@ void Application::CheckNewVersion() { display->SetStatus("新版本 " + ota_.GetFirmwareVersion()); board.SetPowerSaveMode(false); + wake_word_detect_.StopDetection(); // 预先关闭音频输出,避免升级过程有音频操作 board.GetAudioCodec()->EnableOutput(false); { @@ -416,8 +417,10 @@ void Application::Start() { } void Application::Schedule(std::function callback) { - std::lock_guard lock(mutex_); - main_tasks_.push_back(std::move(callback)); + { + std::lock_guard lock(mutex_); + main_tasks_.push_back(std::move(callback)); + } xEventGroupSetBits(event_group_, SCHEDULE_EVENT); } @@ -437,9 +440,9 @@ void Application::MainLoop() { OutputAudio(); } if (bits & SCHEDULE_EVENT) { - mutex_.lock(); + std::unique_lock lock(mutex_); std::list> tasks = std::move(main_tasks_); - mutex_.unlock(); + lock.unlock(); for (auto& task : tasks) { task(); } diff --git a/main/boards/atk-dnesp32s3-box/atk_dnesp32s3_box.cc b/main/boards/atk-dnesp32s3-box/atk_dnesp32s3_box.cc index b9b44db..6efcb20 100644 --- a/main/boards/atk-dnesp32s3-box/atk_dnesp32s3_box.cc +++ b/main/boards/atk-dnesp32s3-box/atk_dnesp32s3_box.cc @@ -157,7 +157,7 @@ private: { .text_font = &font_puhui_20_4, .icon_font = &font_awesome_20_4, - .emoji_font = emoji_font_64_lite_init(), + .emoji_font = font_emoji_64_init(), }); } diff --git a/main/boards/atk-dnesp32s3/atk_dnesp32s3.cc b/main/boards/atk-dnesp32s3/atk_dnesp32s3.cc index 0c61061..6af32ce 100644 --- a/main/boards/atk-dnesp32s3/atk_dnesp32s3.cc +++ b/main/boards/atk-dnesp32s3/atk_dnesp32s3.cc @@ -137,7 +137,7 @@ private: { .text_font = &font_puhui_20_4, .icon_font = &font_awesome_20_4, - .emoji_font = emoji_font_64_lite_init(), + .emoji_font = font_emoji_64_init(), }); } diff --git a/main/boards/atoms3r-echo-base/atoms3r_echo_base.cc b/main/boards/atoms3r-echo-base/atoms3r_echo_base.cc index c84cbe7..93e4484 100644 --- a/main/boards/atoms3r-echo-base/atoms3r_echo_base.cc +++ b/main/boards/atoms3r-echo-base/atoms3r_echo_base.cc @@ -200,7 +200,7 @@ private: { .text_font = &font_puhui_16_4, .icon_font = &font_awesome_16_4, - .emoji_font = emoji_font_init(), + .emoji_font = font_emoji_32_init(), }); } diff --git a/main/boards/bread-compact-wifi-lcd/compact_wifi_board_lcd.cc b/main/boards/bread-compact-wifi-lcd/compact_wifi_board_lcd.cc index fd1efe4..fe3f6d8 100644 --- a/main/boards/bread-compact-wifi-lcd/compact_wifi_board_lcd.cc +++ b/main/boards/bread-compact-wifi-lcd/compact_wifi_board_lcd.cc @@ -79,7 +79,7 @@ private: { .text_font = &font_puhui_16_4, .icon_font = &font_awesome_16_4, - .emoji_font = DISPLAY_HEIGHT >= 240 ? emoji_font_64_lite_init() : emoji_font_init(), + .emoji_font = DISPLAY_HEIGHT >= 240 ? font_emoji_64_init() : font_emoji_32_init(), }); } diff --git a/main/boards/esp-box-3/esp_box3_board.cc b/main/boards/esp-box-3/esp_box3_board.cc index 2075155..93b86d4 100644 --- a/main/boards/esp-box-3/esp_box3_board.cc +++ b/main/boards/esp-box-3/esp_box3_board.cc @@ -126,7 +126,7 @@ private: { .text_font = &font_puhui_20_4, .icon_font = &font_awesome_20_4, - .emoji_font = emoji_font_64_lite_init(), + .emoji_font = font_emoji_64_init(), }); } diff --git a/main/boards/esp-sparkbot/esp_sparkbot_board.cc b/main/boards/esp-sparkbot/esp_sparkbot_board.cc index ee4a68a..d04bfe0 100644 --- a/main/boards/esp-sparkbot/esp_sparkbot_board.cc +++ b/main/boards/esp-sparkbot/esp_sparkbot_board.cc @@ -118,7 +118,7 @@ private: { .text_font = &font_puhui_20_4, .icon_font = &font_awesome_20_4, - .emoji_font = emoji_font_64_lite_init(), + .emoji_font = font_emoji_64_init(), }); } diff --git a/main/boards/esp32-s3-touch-amoled-1.8/esp32-s3-touch-amoled-1.8.cc b/main/boards/esp32-s3-touch-amoled-1.8/esp32-s3-touch-amoled-1.8.cc index 8f2ebf3..f4b2b78 100644 --- a/main/boards/esp32-s3-touch-amoled-1.8/esp32-s3-touch-amoled-1.8.cc +++ b/main/boards/esp32-s3-touch-amoled-1.8/esp32-s3-touch-amoled-1.8.cc @@ -52,7 +52,7 @@ public: { .text_font = &font_puhui_30_4, .icon_font = &font_awesome_30_4, - .emoji_font = emoji_font_64_lite_init(), + .emoji_font = font_emoji_64_init(), }) { DisplayLockGuard lock(this); diff --git a/main/boards/esp32s3-korvo2-v3/esp32s3_korvo2_v3_board.cc b/main/boards/esp32s3-korvo2-v3/esp32s3_korvo2_v3_board.cc index bd5ffd8..b71c175 100644 --- a/main/boards/esp32s3-korvo2-v3/esp32s3_korvo2_v3_board.cc +++ b/main/boards/esp32s3-korvo2-v3/esp32s3_korvo2_v3_board.cc @@ -102,7 +102,7 @@ private: { .text_font = &font_puhui_20_4, .icon_font = &font_awesome_20_4, - .emoji_font = emoji_font_64_lite_init(), + .emoji_font = font_emoji_64_init(), }); } diff --git a/main/boards/lichuang-c3-dev/lichuang_c3_dev_board.cc b/main/boards/lichuang-c3-dev/lichuang_c3_dev_board.cc index eed930d..9b14ee4 100644 --- a/main/boards/lichuang-c3-dev/lichuang_c3_dev_board.cc +++ b/main/boards/lichuang-c3-dev/lichuang_c3_dev_board.cc @@ -96,7 +96,7 @@ private: { .text_font = &font_puhui_16_4, .icon_font = &font_awesome_16_4, - .emoji_font = emoji_font_64_lite_init(), + .emoji_font = font_emoji_64_init(), }); } diff --git a/main/boards/lichuang-dev/lichuang_dev_board.cc b/main/boards/lichuang-dev/lichuang_dev_board.cc index 1b4ca5c..cc6f8bb 100644 --- a/main/boards/lichuang-dev/lichuang_dev_board.cc +++ b/main/boards/lichuang-dev/lichuang_dev_board.cc @@ -122,7 +122,7 @@ private: { .text_font = &font_puhui_20_4, .icon_font = &font_awesome_20_4, - .emoji_font = emoji_font_64_lite_init(), + .emoji_font = font_emoji_64_init(), }); } diff --git a/main/boards/lilygo-t-circle-s3/lilygo-t-circle-s3.cc b/main/boards/lilygo-t-circle-s3/lilygo-t-circle-s3.cc index 356ecec..eb94e38 100644 --- a/main/boards/lilygo-t-circle-s3/lilygo-t-circle-s3.cc +++ b/main/boards/lilygo-t-circle-s3/lilygo-t-circle-s3.cc @@ -175,7 +175,7 @@ private: { .text_font = &font_puhui_16_4, .icon_font = &font_awesome_16_4, - .emoji_font = emoji_font_init(), + .emoji_font = font_emoji_32_init(), }); gpio_config_t config; diff --git a/main/boards/m5stack-core-s3/m5stack_core_s3.cc b/main/boards/m5stack-core-s3/m5stack_core_s3.cc index b1e2870..85741cc 100644 --- a/main/boards/m5stack-core-s3/m5stack_core_s3.cc +++ b/main/boards/m5stack-core-s3/m5stack_core_s3.cc @@ -251,7 +251,7 @@ private: { .text_font = &font_puhui_20_4, .icon_font = &font_awesome_20_4, - .emoji_font = emoji_font_64_lite_init(), + .emoji_font = font_emoji_64_init(), }); } diff --git a/main/boards/magiclick-2p4/magiclick_2p4_board.cc b/main/boards/magiclick-2p4/magiclick_2p4_board.cc index 5acd51a..54af94e 100644 --- a/main/boards/magiclick-2p4/magiclick_2p4_board.cc +++ b/main/boards/magiclick-2p4/magiclick_2p4_board.cc @@ -29,7 +29,7 @@ public: { .text_font = &font_puhui_16_4, .icon_font = &font_awesome_16_4, - .emoji_font = emoji_font_init(), + .emoji_font = font_emoji_32_init(), }) { DisplayLockGuard lock(this); diff --git a/main/boards/magiclick-c3/magiclick_c3_board.cc b/main/boards/magiclick-c3/magiclick_c3_board.cc index 0f632d3..dc635c1 100644 --- a/main/boards/magiclick-c3/magiclick_c3_board.cc +++ b/main/boards/magiclick-c3/magiclick_c3_board.cc @@ -30,7 +30,7 @@ public: { .text_font = &font_puhui_16_4, .icon_font = &font_awesome_16_4, - .emoji_font = emoji_font_init(), + .emoji_font = font_emoji_32_init(), }) { DisplayLockGuard lock(this); diff --git a/main/boards/movecall-moji-esp32s3/movecall_moji_esp32s3.cc b/main/boards/movecall-moji-esp32s3/movecall_moji_esp32s3.cc index 1333d97..712c041 100644 --- a/main/boards/movecall-moji-esp32s3/movecall_moji_esp32s3.cc +++ b/main/boards/movecall-moji-esp32s3/movecall_moji_esp32s3.cc @@ -44,7 +44,7 @@ public: { .text_font = &font_puhui_20_4, .icon_font = &font_awesome_20_4, - .emoji_font = emoji_font_64_lite_init(), + .emoji_font = font_emoji_64_init(), }) { DisplayLockGuard lock(this); @@ -114,7 +114,7 @@ private: { .text_font = &font_puhui_20_4, .icon_font = &font_awesome_20_4, - .emoji_font = emoji_font_64_lite_init(), + .emoji_font = font_emoji_64_init(), }); } diff --git a/main/display/display.cc b/main/display/display.cc index fab491e..8df2d40 100644 --- a/main/display/display.cc +++ b/main/display/display.cc @@ -36,17 +36,21 @@ Display::Display() { .arg = this, .dispatch_method = ESP_TIMER_TASK, .name = "Update Display Timer", - .skip_unhandled_events = false, + .skip_unhandled_events = true, }; ESP_ERROR_CHECK(esp_timer_create(&update_display_timer_args, &update_timer_)); ESP_ERROR_CHECK(esp_timer_start_periodic(update_timer_, 1000000)); } Display::~Display() { - esp_timer_stop(notification_timer_); - esp_timer_stop(update_timer_); - esp_timer_delete(notification_timer_); - esp_timer_delete(update_timer_); + if (notification_timer_ != nullptr) { + esp_timer_stop(notification_timer_); + esp_timer_delete(notification_timer_); + } + if (update_timer_ != nullptr) { + esp_timer_stop(update_timer_); + esp_timer_delete(update_timer_); + } if (network_label_ != nullptr) { lv_obj_del(network_label_); @@ -54,6 +58,7 @@ Display::~Display() { lv_obj_del(status_label_); lv_obj_del(mute_label_); lv_obj_del(battery_label_); + lv_obj_del(emotion_label_); } } @@ -97,7 +102,7 @@ void Display::Update() { } else if (codec->output_volume() > 0 && muted_) { muted_ = false; lv_label_set_text(mute_label_, ""); - } + } } // 更新电池图标 @@ -177,13 +182,12 @@ void Display::SetEmotion(const std::string &emotion) { {FONT_AWESOME_EMOJI_SILLY, "silly"}, {FONT_AWESOME_EMOJI_CONFUSED, "confused"} }; - - DisplayLockGuard lock(this); // 查找匹配的表情 auto it = std::find_if(emotions.begin(), emotions.end(), [&emotion](const Emotion& e) { return e.text == emotion; }); + DisplayLockGuard lock(this); // 如果找到匹配的表情就显示对应图标,否则显示默认的neutral表情 if (it != emotions.end()) { lv_label_set_text(emotion_label_, it->icon); diff --git a/main/display/display.h b/main/display/display.h index 815cbd8..728ab8b 100644 --- a/main/display/display.h +++ b/main/display/display.h @@ -3,6 +3,7 @@ #include #include +#include #include @@ -30,7 +31,7 @@ protected: int width_ = 0; int height_ = 0; - lv_disp_t *disp_ = nullptr; + lv_display_t *display_ = nullptr; lv_obj_t *emotion_label_ = nullptr; lv_obj_t *network_label_ = nullptr; @@ -56,7 +57,9 @@ protected: class DisplayLockGuard { public: DisplayLockGuard(Display *display) : display_(display) { - display_->Lock(); + if (!display_->Lock(3000)) { + ESP_LOGE("Display", "Failed to lock display"); + } } ~DisplayLockGuard() { display_->Unlock(); diff --git a/main/display/lcd_display.cc b/main/display/lcd_display.cc index 1ff4327..4d46657 100644 --- a/main/display/lcd_display.cc +++ b/main/display/lcd_display.cc @@ -1,102 +1,27 @@ #include "lcd_display.h" -#include "font_awesome_symbols.h" +#include #include #include #include #include +#include #include "board.h" #define TAG "LcdDisplay" #define LCD_LEDC_CH LEDC_CHANNEL_0 -#define LCD_LVGL_TICK_PERIOD_MS 2 -#define LCD_LVGL_TASK_MAX_DELAY_MS 60 -#define LCD_LVGL_TASK_MIN_DELAY_MS 1 -#define LCD_LVGL_TASK_STACK_SIZE (4 * 1024) -#define LCD_LVGL_TASK_PRIORITY 1 - LV_FONT_DECLARE(font_awesome_30_4); -static lv_disp_drv_t disp_drv; -static void lcd_lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map) -{ - esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t)drv->user_data; - int offsetx1 = area->x1; - int offsetx2 = area->x2; - int offsety1 = area->y1; - int offsety2 = area->y2; - // copy a buffer's content to a specific area of the display - esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map); - lv_disp_flush_ready(&disp_drv); -} - -/* Rotate display and touch, when rotated screen in LVGL. Called when driver parameters are updated. */ -static void lcd_lvgl_port_update_callback(lv_disp_drv_t *drv) -{ - esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t)drv->user_data; - - switch (drv->rotated) - { - case LV_DISP_ROT_NONE: - // Rotate LCD display - esp_lcd_panel_swap_xy(panel_handle, false); - esp_lcd_panel_mirror(panel_handle, true, false); - break; - case LV_DISP_ROT_90: - // Rotate LCD display - esp_lcd_panel_swap_xy(panel_handle, true); - esp_lcd_panel_mirror(panel_handle, true, true); - break; - case LV_DISP_ROT_180: - // Rotate LCD display - esp_lcd_panel_swap_xy(panel_handle, false); - esp_lcd_panel_mirror(panel_handle, false, true); - break; - case LV_DISP_ROT_270: - // Rotate LCD display - esp_lcd_panel_swap_xy(panel_handle, true); - esp_lcd_panel_mirror(panel_handle, false, false); - break; - } -} - -void LcdDisplay::LvglTask() { - ESP_LOGI(TAG, "Starting LVGL task"); - uint32_t task_delay_ms = LCD_LVGL_TASK_MAX_DELAY_MS; - while (1) - { - // Lock the mutex due to the LVGL APIs are not thread-safe - if (Lock()) - { - task_delay_ms = lv_timer_handler(); - Unlock(); - } - if (task_delay_ms > LCD_LVGL_TASK_MAX_DELAY_MS) - { - task_delay_ms = LCD_LVGL_TASK_MAX_DELAY_MS; - } - else if (task_delay_ms < LCD_LVGL_TASK_MIN_DELAY_MS) - { - task_delay_ms = LCD_LVGL_TASK_MIN_DELAY_MS; - } - vTaskDelay(pdMS_TO_TICKS(task_delay_ms)); - } -} - - LcdDisplay::LcdDisplay(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_handle_t panel, gpio_num_t backlight_pin, bool backlight_output_invert, int width, int height, int offset_x, int offset_y, bool mirror_x, bool mirror_y, bool swap_xy, DisplayFonts fonts) : panel_io_(panel_io), panel_(panel), backlight_pin_(backlight_pin), backlight_output_invert_(backlight_output_invert), - mirror_x_(mirror_x), mirror_y_(mirror_y), swap_xy_(swap_xy), fonts_(fonts) { width_ = width; height_ = height; - offset_x_ = offset_x; - offset_y_ = offset_y; InitializeBacklight(backlight_pin); @@ -112,50 +37,45 @@ LcdDisplay::LcdDisplay(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_handle_ ESP_LOGI(TAG, "Initialize LVGL library"); lv_init(); - // alloc draw buffers used by LVGL - static lv_disp_draw_buf_t disp_buf; // contains internal graphic buffer(s) called draw buffer(s) - // it's recommended to choose the size of the draw buffer(s) to be at least 1/10 screen sized - lv_color_t *buf1 = (lv_color_t *)heap_caps_malloc(width_ * 10 * sizeof(lv_color_t), MALLOC_CAP_DMA); - assert(buf1); - lv_color_t *buf2 = (lv_color_t *)heap_caps_malloc(width_ * 10 * sizeof(lv_color_t), MALLOC_CAP_DMA); - assert(buf2); - // initialize LVGL draw buffers - lv_disp_draw_buf_init(&disp_buf, buf1, buf2, width_ * 10); - ESP_LOGI(TAG, "Register display driver to LVGL"); - lv_disp_drv_init(&disp_drv); - disp_drv.hor_res = width_; - disp_drv.ver_res = height_; - disp_drv.offset_x = offset_x_; - disp_drv.offset_y = offset_y_; - disp_drv.flush_cb = lcd_lvgl_flush_cb; - disp_drv.drv_update_cb = lcd_lvgl_port_update_callback; - disp_drv.draw_buf = &disp_buf; - disp_drv.user_data = panel_; + ESP_LOGI(TAG, "Initialize LVGL port"); + lvgl_port_cfg_t port_cfg = ESP_LVGL_PORT_INIT_CONFIG(); + lvgl_port_init(&port_cfg); - lv_disp_drv_register(&disp_drv); - - ESP_LOGI(TAG, "Install LVGL tick timer"); - // Tick interface for LVGL (using esp_timer to generate 2ms periodic event) - const esp_timer_create_args_t lvgl_tick_timer_args = { - .callback = [](void* arg) { - lv_tick_inc(LCD_LVGL_TICK_PERIOD_MS); + ESP_LOGI(TAG, "Adding LCD screen"); + const lvgl_port_display_cfg_t display_cfg = { + .io_handle = panel_io_, + .panel_handle = panel_, + .control_handle = nullptr, + .buffer_size = static_cast(width_ * 10), + .double_buffer = true, + .trans_size = 0, + .hres = static_cast(width_), + .vres = static_cast(height_), + .monochrome = false, + .rotation = { + .swap_xy = swap_xy, + .mirror_x = mirror_x, + .mirror_y = mirror_y, + }, + .color_format = LV_COLOR_FORMAT_RGB565, + .flags = { + .buff_dma = 1, + .buff_spiram = 0, + .sw_rotate = 0, + .swap_bytes = 1, + .full_refresh = 0, + .direct_mode = 0, }, - .arg = NULL, - .dispatch_method = ESP_TIMER_TASK, - .name = "LVGL Tick Timer", - .skip_unhandled_events = false }; - ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer_)); - ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer_, LCD_LVGL_TICK_PERIOD_MS * 1000)); - lvgl_mutex_ = xSemaphoreCreateRecursiveMutex(); - assert(lvgl_mutex_ != nullptr); - ESP_LOGI(TAG, "Create LVGL task"); - xTaskCreate([](void *arg) { - static_cast(arg)->LvglTask(); - vTaskDelete(NULL); - }, "LVGL", LCD_LVGL_TASK_STACK_SIZE, this, LCD_LVGL_TASK_PRIORITY, NULL); + display_ = lvgl_port_add_disp(&display_cfg); + if (display_ == nullptr) { + ESP_LOGE(TAG, "Failed to add display"); + return; + } + + lv_display_set_offset(display_, offset_x, offset_y); SetBacklight(100); @@ -163,9 +83,7 @@ LcdDisplay::LcdDisplay(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_handle_ } LcdDisplay::~LcdDisplay() { - ESP_ERROR_CHECK(esp_timer_stop(lvgl_tick_timer_)); - ESP_ERROR_CHECK(esp_timer_delete(lvgl_tick_timer_)); - + // 然后再清理 LVGL 对象 if (content_ != nullptr) { lv_obj_del(content_); } @@ -178,6 +96,9 @@ LcdDisplay::~LcdDisplay() { if (container_ != nullptr) { lv_obj_del(container_); } + if (display_ != nullptr) { + lv_display_delete(display_); + } if (panel_ != nullptr) { esp_lcd_panel_del(panel_); @@ -185,7 +106,6 @@ LcdDisplay::~LcdDisplay() { if (panel_io_ != nullptr) { esp_lcd_panel_io_del(panel_io_); } - vSemaphoreDelete(lvgl_mutex_); } void LcdDisplay::InitializeBacklight(gpio_num_t backlight_pin) { @@ -236,14 +156,11 @@ void LcdDisplay::SetBacklight(uint8_t brightness) { } bool LcdDisplay::Lock(int timeout_ms) { - // Convert timeout in milliseconds to FreeRTOS ticks - // If `timeout_ms` is set to 0, the program will block until the condition is met - const TickType_t timeout_ticks = (timeout_ms == 0) ? portMAX_DELAY : pdMS_TO_TICKS(timeout_ms); - return xSemaphoreTakeRecursive(lvgl_mutex_, timeout_ticks) == pdTRUE; + return lvgl_port_lock(timeout_ms); } void LcdDisplay::Unlock() { - xSemaphoreGiveRecursive(lvgl_mutex_); + lvgl_port_unlock(); } void LcdDisplay::SetupUI() { @@ -340,7 +257,7 @@ void LcdDisplay::SetEmotion(const std::string &emotion) { static const std::vector emotions = { {"😶", "neutral"}, - {"😊", "happy"}, + {"🙂", "happy"}, {"😆", "laughing"}, {"😂", "funny"}, {"😔", "sad"}, @@ -349,31 +266,30 @@ void LcdDisplay::SetEmotion(const std::string &emotion) { {"😍", "loving"}, {"😳", "embarrassed"}, {"😯", "surprised"}, - {"😨", "shocked"}, + {"😱", "shocked"}, {"🤔", "thinking"}, {"😉", "winking"}, {"😎", "cool"}, {"😌", "relaxed"}, - {"😋", "delicious"}, + {"🤤", "delicious"}, {"😘", "kissy"}, {"😏", "confident"}, {"😴", "sleepy"}, - {"🤪", "silly"}, - {"😕", "confused"} + {"😜", "silly"}, + {"🙄", "confused"} }; - - DisplayLockGuard lock(this); // 查找匹配的表情 auto it = std::find_if(emotions.begin(), emotions.end(), [&emotion](const Emotion& e) { return e.text == emotion; }); - + + DisplayLockGuard lock(this); // 如果找到匹配的表情就显示对应图标,否则显示默认的neutral表情 lv_obj_set_style_text_font(emotion_label_, fonts_.emoji_font, 0); if (it != emotions.end()) { lv_label_set_text(emotion_label_, it->icon); } else { - lv_label_set_text(emotion_label_, FONT_AWESOME_EMOJI_NEUTRAL); + lv_label_set_text(emotion_label_, "😶"); } } diff --git a/main/display/lcd_display.h b/main/display/lcd_display.h index fc98844..d0df11d 100644 --- a/main/display/lcd_display.h +++ b/main/display/lcd_display.h @@ -5,11 +5,14 @@ #include #include +#include #include #include #include #include -#include +#include + +#include class LcdDisplay : public Display { protected: @@ -17,14 +20,8 @@ protected: esp_lcd_panel_handle_t panel_ = nullptr; gpio_num_t backlight_pin_ = GPIO_NUM_NC; bool backlight_output_invert_ = false; - bool mirror_x_ = false; - bool mirror_y_ = false; - bool swap_xy_ = false; - int offset_x_ = 0; - int offset_y_ = 0; - SemaphoreHandle_t lvgl_mutex_ = nullptr; - esp_timer_handle_t lvgl_tick_timer_ = nullptr; + lv_draw_buf_t draw_buf_; lv_obj_t* status_bar_ = nullptr; lv_obj_t* content_ = nullptr; lv_obj_t* container_ = nullptr; @@ -35,7 +32,6 @@ protected: void InitializeBacklight(gpio_num_t backlight_pin); void SetBacklight(uint8_t brightness); - void LvglTask(); virtual void SetupUI(); virtual bool Lock(int timeout_ms = 0) override; diff --git a/main/display/ssd1306_display.cc b/main/display/ssd1306_display.cc index 4e89f3a..ba0344e 100644 --- a/main/display/ssd1306_display.cc +++ b/main/display/ssd1306_display.cc @@ -13,7 +13,7 @@ LV_FONT_DECLARE(font_awesome_30_1); Ssd1306Display::Ssd1306Display(void* i2c_master_handle, int width, int height, bool mirror_x, bool mirror_y, const lv_font_t* text_font, const lv_font_t* icon_font) - : mirror_x_(mirror_x), mirror_y_(mirror_y), text_font_(text_font), icon_font_(icon_font) { + : text_font_(text_font), icon_font_(icon_font) { width_ = width; height_ = height; @@ -76,8 +76,8 @@ Ssd1306Display::Ssd1306Display(void* i2c_master_handle, int width, int height, b .monochrome = true, .rotation = { .swap_xy = false, - .mirror_x = mirror_x_, - .mirror_y = mirror_y_, + .mirror_x = mirror_x, + .mirror_y = mirror_y, }, .flags = { .buff_dma = 1, @@ -88,9 +88,8 @@ Ssd1306Display::Ssd1306Display(void* i2c_master_handle, int width, int height, b }, }; - disp_ = lvgl_port_add_disp(&display_cfg); - - if (disp_ == nullptr) { + display_ = lvgl_port_add_disp(&display_cfg); + if (display_ == nullptr) { ESP_LOGE(TAG, "Failed to add display"); return; } @@ -136,7 +135,7 @@ void Ssd1306Display::Unlock() { void Ssd1306Display::SetupUI_128x64() { DisplayLockGuard lock(this); - auto screen = lv_disp_get_scr_act(disp_); + auto screen = lv_disp_get_scr_act(display_); lv_obj_set_style_text_font(screen, text_font_, 0); lv_obj_set_style_text_color(screen, lv_color_black(), 0); @@ -198,7 +197,7 @@ void Ssd1306Display::SetupUI_128x64() { void Ssd1306Display::SetupUI_128x32() { DisplayLockGuard lock(this); - auto screen = lv_disp_get_scr_act(disp_); + auto screen = lv_disp_get_scr_act(display_); lv_obj_set_style_text_font(screen, text_font_, 0); /* Container */ diff --git a/main/display/ssd1306_display.h b/main/display/ssd1306_display.h index 20ab4e6..e1fbf19 100644 --- a/main/display/ssd1306_display.h +++ b/main/display/ssd1306_display.h @@ -10,8 +10,6 @@ class Ssd1306Display : public Display { private: esp_lcd_panel_io_handle_t panel_io_ = nullptr; esp_lcd_panel_handle_t panel_ = nullptr; - bool mirror_x_ = false; - bool mirror_y_ = false; lv_obj_t* status_bar_ = nullptr; lv_obj_t* content_ = nullptr; diff --git a/main/idf_component.yml b/main/idf_component.yml index 4084bd4..6baa082 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -9,14 +9,13 @@ dependencies: 78/esp-wifi-connect: "~2.1.0" 78/esp-opus-encoder: "~2.1.0" 78/esp-ml307: "~1.7.1" - 78/xiaozhi-fonts: "~1.2.0" - 78/emoji_font: "~1.1.0" + 78/xiaozhi-fonts: "~1.3.2" espressif/led_strip: "^2.4.1" espressif/esp_codec_dev: "~1.3.2" espressif/esp-sr: "^1.9.0" espressif/button: "^3.3.1" - lvgl/lvgl: "~8.4.0" - esp_lvgl_port: "~2.4.1" + lvgl/lvgl: "~9.2.2" + esp_lvgl_port: "~2.4.4" ## Required IDF version idf: version: ">=5.3" diff --git a/sdkconfig.defaults b/sdkconfig.defaults index a8aba7d..0238295 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -17,21 +17,26 @@ ESP_TASK_WDT_TIMEOUT_S=10 CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y -CONFIG_LV_COLOR_16_SWAP=y -CONFIG_LV_MEM_CUSTOM=y - CONFIG_MBEDTLS_DYNAMIC_BUFFER=y CONFIG_ESP_WIFI_IRAM_OPT=n CONFIG_ESP_WIFI_RX_IRAM_OPT=n CONFIG_CODEC_I2C_BACKWARD_COMPATIBLE=n +# LVGL 9.2.2 + +CONFIG_LV_OS_FREERTOS=y +CONFIG_LV_USE_OS=2 +CONFIG_LV_USE_FREERTOS_TASK_NOTIFY=y +CONFIG_LV_USE_CLIB_MALLOC=y +CONFIG_LV_USE_CLIB_STRING=y +CONFIG_LV_USE_CLIB_SPRINTF=y CONFIG_LV_USE_IMGFONT=y # Use compressed font CONFIG_LV_FONT_FMT_TXT_LARGE=y CONFIG_LV_USE_FONT_COMPRESSED=y -CONFIG_LV_USE_FONT_SUBPX=y +CONFIG_LV_USE_FONT_PLACEHOLDER=y # Disable extra widgets to save flash size CONFIG_LV_USE_ANIMIMG=n @@ -39,18 +44,17 @@ CONFIG_LV_USE_CALENDAR=n CONFIG_LV_USE_CALENDAR_HEADER_ARROW=n CONFIG_LV_USE_CALENDAR_HEADER_DROPDOWN=n CONFIG_LV_USE_CHART=n -CONFIG_LV_USE_COLORWHEEL=n -CONFIG_LV_USE_IMGBTN=n CONFIG_LV_USE_KEYBOARD=n CONFIG_LV_USE_LED=n CONFIG_LV_USE_LIST=n CONFIG_LV_USE_MENU=n -CONFIG_LV_USE_METER=n CONFIG_LV_USE_MSGBOX=n CONFIG_LV_USE_SPAN=n -CONFIG_LV_SPAN_SNIPPET_STACK_SIZE=64 CONFIG_LV_USE_SPINBOX=n CONFIG_LV_USE_SPINNER=n CONFIG_LV_USE_TABVIEW=n CONFIG_LV_USE_TILEVIEW=n CONFIG_LV_USE_WIN=n + +CONFIG_LV_BUILD_EXAMPLES=n + diff --git a/sdkconfig.defaults.esp32s3 b/sdkconfig.defaults.esp32s3 index 5b99472..8c9678b 100644 --- a/sdkconfig.defaults.esp32s3 +++ b/sdkconfig.defaults.esp32s3 @@ -9,7 +9,7 @@ CONFIG_SPIRAM_MODE_OCT=y CONFIG_SPIRAM_SPEED_80M=y CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=4096 CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y -CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 +CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=49152 CONFIG_SPIRAM_MEMTEST=n CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=y