From fd6235750d3bd918a2ab051c85c3d460e997f5ce Mon Sep 17 00:00:00 2001 From: Terrence Date: Wed, 7 May 2025 04:55:51 +0800 Subject: [PATCH] Upgrade components --- main/boards/common/button.cc | 72 ++++++++++--------- main/boards/common/button.h | 10 +-- main/boards/common/dual_network_board.h | 3 + main/boards/df-k10/df_k10_board.cc | 60 ++++++++-------- .../boards/esp-box-lite/esp_box_lite_board.cc | 24 +++++-- .../esp32-s3-touch-lcd-1.46.cc | 60 +++++++++------- .../esp32-s3-touch-lcd-1.85.cc | 62 ++++++++-------- .../sensecap-watcher/sensecap_watcher.cc | 56 ++++++++------- .../xingzhi_cube_1_54tft_dual_board.cc | 15 +++- main/idf_component.yml | 12 ++-- 10 files changed, 209 insertions(+), 165 deletions(-) diff --git a/main/boards/common/button.cc b/main/boards/common/button.cc index feb1ce34..8735cac3 100644 --- a/main/boards/common/button.cc +++ b/main/boards/common/button.cc @@ -1,42 +1,28 @@ #include "button.h" +#include #include -static const char* TAG = "Button"; -#if CONFIG_SOC_ADC_SUPPORTED -Button::Button(const button_adc_config_t& adc_cfg) { - button_config_t button_config = { - .type = BUTTON_TYPE_ADC, - .long_press_time = 1000, - .short_press_time = 50, - .adc_button_config = adc_cfg - }; - button_handle_ = iot_button_create(&button_config); - if (button_handle_ == NULL) { - ESP_LOGE(TAG, "Failed to create button handle"); - return; - } -} -#endif +#define TAG "Button" -Button::Button(gpio_num_t gpio_num, bool active_high) : gpio_num_(gpio_num) { +Button::Button(button_handle_t button_handle) : button_handle_(button_handle) { +} + +Button::Button(gpio_num_t gpio_num, bool active_high, uint16_t long_press_time, uint16_t short_press_time) : gpio_num_(gpio_num) { if (gpio_num == GPIO_NUM_NC) { return; } button_config_t button_config = { - .type = BUTTON_TYPE_GPIO, - .long_press_time = 1000, - .short_press_time = 50, - .gpio_button_config = { - .gpio_num = gpio_num, - .active_level = static_cast(active_high ? 1 : 0) - } + .long_press_time = long_press_time, + .short_press_time = short_press_time }; - button_handle_ = iot_button_create(&button_config); - if (button_handle_ == NULL) { - ESP_LOGE(TAG, "Failed to create button handle"); - return; - } + button_gpio_config_t gpio_config = { + .gpio_num = gpio_num, + .active_level = static_cast(active_high ? 1 : 0), + .enable_power_save = false, + .disable_pull = false + }; + ESP_ERROR_CHECK(iot_button_new_gpio_device(&button_config, &gpio_config, &button_handle_)); } Button::~Button() { @@ -50,7 +36,7 @@ void Button::OnPressDown(std::function callback) { return; } on_press_down_ = callback; - iot_button_register_cb(button_handle_, BUTTON_PRESS_DOWN, [](void* handle, void* usr_data) { + iot_button_register_cb(button_handle_, BUTTON_PRESS_DOWN, nullptr, [](void* handle, void* usr_data) { Button* button = static_cast(usr_data); if (button->on_press_down_) { button->on_press_down_(); @@ -63,7 +49,7 @@ void Button::OnPressUp(std::function callback) { return; } on_press_up_ = callback; - iot_button_register_cb(button_handle_, BUTTON_PRESS_UP, [](void* handle, void* usr_data) { + iot_button_register_cb(button_handle_, BUTTON_PRESS_UP, nullptr, [](void* handle, void* usr_data) { Button* button = static_cast(usr_data); if (button->on_press_up_) { button->on_press_up_(); @@ -76,7 +62,7 @@ void Button::OnLongPress(std::function callback) { return; } on_long_press_ = callback; - iot_button_register_cb(button_handle_, BUTTON_LONG_PRESS_START, [](void* handle, void* usr_data) { + iot_button_register_cb(button_handle_, BUTTON_LONG_PRESS_START, nullptr, [](void* handle, void* usr_data) { Button* button = static_cast(usr_data); if (button->on_long_press_) { button->on_long_press_(); @@ -89,7 +75,7 @@ void Button::OnClick(std::function callback) { return; } on_click_ = callback; - iot_button_register_cb(button_handle_, BUTTON_SINGLE_CLICK, [](void* handle, void* usr_data) { + iot_button_register_cb(button_handle_, BUTTON_SINGLE_CLICK, nullptr, [](void* handle, void* usr_data) { Button* button = static_cast(usr_data); if (button->on_click_) { button->on_click_(); @@ -102,10 +88,28 @@ void Button::OnDoubleClick(std::function callback) { return; } on_double_click_ = callback; - iot_button_register_cb(button_handle_, BUTTON_DOUBLE_CLICK, [](void* handle, void* usr_data) { + iot_button_register_cb(button_handle_, BUTTON_DOUBLE_CLICK, nullptr, [](void* handle, void* usr_data) { Button* button = static_cast(usr_data); if (button->on_double_click_) { button->on_double_click_(); } }, this); } + +void Button::OnMultipleClick(std::function callback, uint8_t click_count) { + if (button_handle_ == nullptr) { + return; + } + on_multiple_click_ = callback; + button_event_args_t event_args = { + .multiple_clicks = { + .clicks = click_count + } + }; + iot_button_register_cb(button_handle_, BUTTON_MULTIPLE_CLICK, &event_args, [](void* handle, void* usr_data) { + Button* button = static_cast(usr_data); + if (button->on_multiple_click_) { + button->on_multiple_click_(); + } + }, this); +} \ No newline at end of file diff --git a/main/boards/common/button.h b/main/boards/common/button.h index d2e44fd3..55341e86 100644 --- a/main/boards/common/button.h +++ b/main/boards/common/button.h @@ -3,14 +3,13 @@ #include #include +#include #include class Button { public: -#if CONFIG_SOC_ADC_SUPPORTED - Button(const button_adc_config_t& cfg); -#endif - Button(gpio_num_t gpio_num, bool active_high = false); + Button(button_handle_t button_handle); + Button(gpio_num_t gpio_num, bool active_high = false, uint16_t long_press_time = 1000, uint16_t short_press_time = 50); ~Button(); void OnPressDown(std::function callback); @@ -18,16 +17,17 @@ public: void OnLongPress(std::function callback); void OnClick(std::function callback); void OnDoubleClick(std::function callback); + void OnMultipleClick(std::function callback, uint8_t click_count = 3); private: gpio_num_t gpio_num_; button_handle_t button_handle_ = nullptr; - std::function on_press_down_; std::function on_press_up_; std::function on_long_press_; std::function on_click_; std::function on_double_click_; + std::function on_multiple_click_; }; #endif // BUTTON_H_ diff --git a/main/boards/common/dual_network_board.h b/main/boards/common/dual_network_board.h index 7450d9e5..947e2ea3 100644 --- a/main/boards/common/dual_network_board.h +++ b/main/boards/common/dual_network_board.h @@ -43,6 +43,9 @@ public: // 获取当前网络类型 NetworkType GetNetworkType() const { return network_type_; } + // 获取当前活动的板卡引用 + Board& GetCurrentBoard() const { return *current_board_; } + // 重写Board接口 virtual std::string GetBoardType() override; virtual void StartNetwork() override; diff --git a/main/boards/df-k10/df_k10_board.cc b/main/boards/df-k10/df_k10_board.cc index d18e0342..ed80382b 100644 --- a/main/boards/df-k10/df_k10_board.cc +++ b/main/boards/df-k10/df_k10_board.cc @@ -31,6 +31,16 @@ private: button_handle_t btn_a; button_handle_t btn_b; + static Df_K10Board* instance_; + + static uint8_t GetButtonALevel(button_driver_t *button_driver) { + return instance_->IoExpanderGetLevel(IO_EXPANDER_PIN_NUM_2); + } + + static uint8_t GetButtonBLevel(button_driver_t *button_driver) { + return instance_->IoExpanderGetLevel(IO_EXPANDER_PIN_NUM_12); + } + void InitializeI2c() { // Initialize I2C peripheral i2c_master_bus_config_t i2c_bus_cfg = { @@ -96,24 +106,19 @@ private: } } void InitializeButtons() { + instance_ = this; + // Button A button_config_t btn_a_config = { - .type = BUTTON_TYPE_CUSTOM, .long_press_time = 1000, - .short_press_time = 50, - .custom_button_config = { - .active_level = 0, - .button_custom_init =nullptr, - .button_custom_get_key_value = [](void *param) -> uint8_t { - auto self = static_cast(param); - return self->IoExpanderGetLevel(IO_EXPANDER_PIN_NUM_2); - }, - .button_custom_deinit = nullptr, - .priv = this, - }, + .short_press_time = 50 }; - btn_a = iot_button_create(&btn_a_config); - iot_button_register_cb(btn_a, BUTTON_SINGLE_CLICK, [](void* button_handle, void* usr_data) { + button_driver_t btn_a_driver = { + .enable_power_save = false, + .get_key_level = GetButtonALevel + }; + ESP_ERROR_CHECK(iot_button_create(&btn_a_config, &btn_a_driver, &btn_a)); + iot_button_register_cb(btn_a, BUTTON_SINGLE_CLICK, nullptr, [](void* button_handle, void* usr_data) { auto self = static_cast(usr_data); auto& app = Application::GetInstance(); if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) { @@ -121,7 +126,7 @@ private: } app.ToggleChatState(); }, this); - iot_button_register_cb(btn_a, BUTTON_LONG_PRESS_START, [](void* button_handle, void* usr_data) { + iot_button_register_cb(btn_a, BUTTON_LONG_PRESS_START, nullptr, [](void* button_handle, void* usr_data) { auto self = static_cast(usr_data); auto codec = self->GetAudioCodec(); auto volume = codec->output_volume() - 10; @@ -134,22 +139,15 @@ private: // Button B button_config_t btn_b_config = { - .type = BUTTON_TYPE_CUSTOM, .long_press_time = 1000, - .short_press_time = 50, - .custom_button_config = { - .active_level = 0, - .button_custom_init =nullptr, - .button_custom_get_key_value = [](void *param) -> uint8_t { - auto self = static_cast(param); - return self->IoExpanderGetLevel(IO_EXPANDER_PIN_NUM_12); - }, - .button_custom_deinit = nullptr, - .priv = this, - }, + .short_press_time = 50 }; - btn_b = iot_button_create(&btn_b_config); - iot_button_register_cb(btn_b, BUTTON_SINGLE_CLICK, [](void* button_handle, void* usr_data) { + button_driver_t btn_b_driver = { + .enable_power_save = false, + .get_key_level = GetButtonBLevel + }; + ESP_ERROR_CHECK(iot_button_create(&btn_b_config, &btn_b_driver, &btn_b)); + iot_button_register_cb(btn_b, BUTTON_SINGLE_CLICK, nullptr, [](void* button_handle, void* usr_data) { auto self = static_cast(usr_data); auto& app = Application::GetInstance(); if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) { @@ -157,7 +155,7 @@ private: } app.ToggleChatState(); }, this); - iot_button_register_cb(btn_b, BUTTON_LONG_PRESS_START, [](void* button_handle, void* usr_data) { + iot_button_register_cb(btn_b, BUTTON_LONG_PRESS_START, nullptr, [](void* button_handle, void* usr_data) { auto self = static_cast(usr_data); auto codec = self->GetAudioCodec(); auto volume = codec->output_volume() + 10; @@ -253,3 +251,5 @@ public: }; DECLARE_BOARD(Df_K10Board); + +Df_K10Board* Df_K10Board::instance_ = nullptr; diff --git a/main/boards/esp-box-lite/esp_box_lite_board.cc b/main/boards/esp-box-lite/esp_box_lite_board.cc index 633fab17..fa9b262f 100644 --- a/main/boards/esp-box-lite/esp_box_lite_board.cc +++ b/main/boards/esp-box-lite/esp_box_lite_board.cc @@ -8,7 +8,9 @@ #include "config.h" #include "iot/thing_manager.h" #include "assets/lang_config.h" + #include +#include #include #include #include @@ -86,7 +88,7 @@ private: ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO)); } - void changeVol(int val) { + void ChangeVol(int val) { auto codec = GetAudioCodec(); auto volume = codec->output_volume() + val; if (volume > 100) { @@ -109,7 +111,11 @@ private: void InitializeButtons() { /* Initialize ADC esp-box lite的前三个按钮采用是的adc按钮,而非gpio */ - button_adc_config_t adc_cfg; + button_config_t btn_config = { + .long_press_time = 2000, + .short_press_time = 50, + }; + button_adc_config_t adc_cfg = {}; adc_cfg.adc_channel = ADC_CHANNEL_0; // ADC1 channel 0 is GPIO1 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) const adc_oneshot_unit_init_cfg_t init_config1 = { @@ -121,27 +127,31 @@ private: adc_cfg.button_index = BSP_ADC_BUTTON_PREV; adc_cfg.min = 2310; // middle is 2410mV adc_cfg.max = 2510; - adc_button_[0] = new Button(adc_cfg); + ESP_ERROR_CHECK(iot_button_new_adc_device(&btn_config, &adc_cfg, &adc_button_[0])); + adc_button_[0] = new Button(adc_button_[0]); adc_cfg.button_index = BSP_ADC_BUTTON_ENTER; adc_cfg.min = 1880; // middle is 1980mV adc_cfg.max = 2080; - adc_button_[1] = new Button(adc_cfg); + ESP_ERROR_CHECK(iot_button_new_adc_device(&btn_config, &adc_cfg, &adc_button_[1])); + adc_button_[1] = new Button(adc_button_[1]); adc_cfg.button_index = BSP_ADC_BUTTON_NEXT; adc_cfg.min = 720; // middle is 820mV adc_cfg.max = 920; - adc_button_[2] = new Button(adc_cfg); + + ESP_ERROR_CHECK(iot_button_new_adc_device(&btn_config, &adc_cfg, &adc_button_[2])); + adc_button_[2] = new Button(adc_button_[2]); auto volume_up_button = adc_button_[BSP_ADC_BUTTON_NEXT]; - volume_up_button->OnClick([this]() {changeVol(10);}); + volume_up_button->OnClick([this]() {ChangeVol(10);}); volume_up_button->OnLongPress([this]() { GetAudioCodec()->SetOutputVolume(100); GetDisplay()->ShowNotification(Lang::Strings::MAX_VOLUME); }); auto volume_down_button = adc_button_[BSP_ADC_BUTTON_PREV]; - volume_down_button->OnClick([this]() {changeVol(-10);}); + volume_down_button->OnClick([this]() {ChangeVol(-10);}); volume_down_button->OnLongPress([this]() { GetAudioCodec()->SetOutputVolume(0); GetDisplay()->ShowNotification(Lang::Strings::MUTED); diff --git a/main/boards/esp32-s3-touch-lcd-1.46/esp32-s3-touch-lcd-1.46.cc b/main/boards/esp32-s3-touch-lcd-1.46/esp32-s3-touch-lcd-1.46.cc index bfc1a691..d6629bb0 100644 --- a/main/boards/esp32-s3-touch-lcd-1.46/esp32-s3-touch-lcd-1.46.cc +++ b/main/boards/esp32-s3-touch-lcd-1.46/esp32-s3-touch-lcd-1.46.cc @@ -65,6 +65,15 @@ private: esp_io_expander_handle_t io_expander = NULL; LcdDisplay* display_; button_handle_t boot_btn, pwr_btn; + static CustomBoard* instance_; + + static uint8_t GetBootButtonLevel(button_driver_t *button_driver) { + return gpio_get_level(BOOT_BUTTON_GPIO); + } + + static uint8_t GetPwrButtonLevel(button_driver_t *button_driver) { + return gpio_get_level(PWR_BUTTON_GPIO); + } void InitializeI2c() { // Initialize I2C peripheral @@ -158,23 +167,20 @@ private: gpio_set_level(PWR_Control_PIN, true); } void InitializeButtons() { + instance_ = this; InitializeButtonsCustom(); - button_config_t btns_config = { - .type = BUTTON_TYPE_CUSTOM, + + // Boot Button + button_config_t boot_btn_config = { .long_press_time = 2000, - .short_press_time = 50, - .custom_button_config = { - .active_level = 0, - .button_custom_init = nullptr, - .button_custom_get_key_value = [](void *param) -> uint8_t { - return gpio_get_level(BOOT_BUTTON_GPIO); - }, - .button_custom_deinit = nullptr, - .priv = this, - }, + .short_press_time = 50 }; - boot_btn = iot_button_create(&btns_config); - iot_button_register_cb(boot_btn, BUTTON_SINGLE_CLICK, [](void* button_handle, void* usr_data) { + button_driver_t boot_btn_driver = { + .enable_power_save = false, + .get_key_level = GetBootButtonLevel + }; + ESP_ERROR_CHECK(iot_button_create(&boot_btn_config, &boot_btn_driver, &boot_btn)); + iot_button_register_cb(boot_btn, BUTTON_SINGLE_CLICK, nullptr, [](void* button_handle, void* usr_data) { auto self = static_cast(usr_data); auto& app = Application::GetInstance(); if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) { @@ -182,24 +188,24 @@ private: } app.ToggleChatState(); }, this); - iot_button_register_cb(boot_btn, BUTTON_LONG_PRESS_START, [](void* button_handle, void* usr_data) { + iot_button_register_cb(boot_btn, BUTTON_LONG_PRESS_START, nullptr, [](void* button_handle, void* usr_data) { // 长按无处理 }, this); - btns_config.long_press_time = 5000; - btns_config.custom_button_config.button_custom_get_key_value = [](void *param) -> uint8_t { - return gpio_get_level(PWR_BUTTON_GPIO); + // Power Button + button_config_t pwr_btn_config = { + .long_press_time = 5000, + .short_press_time = 50 }; - pwr_btn = iot_button_create(&btns_config); - iot_button_register_cb(pwr_btn, BUTTON_SINGLE_CLICK, [](void* button_handle, void* usr_data) { - // auto self = static_cast(usr_data); // 以下程序实现供用户参考 ,实现单击pwr按键调整亮度 - // if(self->GetBacklight()->brightness() > 1) // 如果亮度不为0 - // self->GetBacklight()->SetBrightness(1); // 设置亮度为1 - // else - // self->GetBacklight()->RestoreBrightness(); // 恢复原本亮度 + button_driver_t pwr_btn_driver = { + .enable_power_save = false, + .get_key_level = GetPwrButtonLevel + }; + ESP_ERROR_CHECK(iot_button_create(&pwr_btn_config, &pwr_btn_driver, &pwr_btn)); + iot_button_register_cb(pwr_btn, BUTTON_SINGLE_CLICK, nullptr, [](void* button_handle, void* usr_data) { // 短按无处理 }, this); - iot_button_register_cb(pwr_btn, BUTTON_LONG_PRESS_START, [](void* button_handle, void* usr_data) { + iot_button_register_cb(pwr_btn, BUTTON_LONG_PRESS_START, nullptr, [](void* button_handle, void* usr_data) { auto self = static_cast(usr_data); if(self->GetBacklight()->brightness() > 0) { self->GetBacklight()->SetBrightness(0); @@ -248,3 +254,5 @@ public: }; DECLARE_BOARD(CustomBoard); + +CustomBoard* CustomBoard::instance_ = nullptr; diff --git a/main/boards/esp32-s3-touch-lcd-1.85/esp32-s3-touch-lcd-1.85.cc b/main/boards/esp32-s3-touch-lcd-1.85/esp32-s3-touch-lcd-1.85.cc index db05dd8a..8ce2d85e 100644 --- a/main/boards/esp32-s3-touch-lcd-1.85/esp32-s3-touch-lcd-1.85.cc +++ b/main/boards/esp32-s3-touch-lcd-1.85/esp32-s3-touch-lcd-1.85.cc @@ -220,6 +220,15 @@ private: esp_io_expander_handle_t io_expander = NULL; LcdDisplay* display_; button_handle_t boot_btn, pwr_btn; + static CustomBoard* instance_; + + static uint8_t GetBootButtonLevel(button_driver_t *button_driver) { + return gpio_get_level(BOOT_BUTTON_GPIO); + } + + static uint8_t GetPwrButtonLevel(button_driver_t *button_driver) { + return gpio_get_level(PWR_BUTTON_GPIO); + } void InitializeI2c() { // Initialize I2C peripheral @@ -374,23 +383,20 @@ private: gpio_set_level(PWR_Control_PIN, true); } void InitializeButtons() { + instance_ = this; InitializeButtonsCustom(); - button_config_t btns_config = { - .type = BUTTON_TYPE_CUSTOM, + + // Boot Button + button_config_t boot_btn_config = { .long_press_time = 2000, - .short_press_time = 50, - .custom_button_config = { - .active_level = 0, - .button_custom_init = nullptr, - .button_custom_get_key_value = [](void *param) -> uint8_t { - return gpio_get_level(BOOT_BUTTON_GPIO); - }, - .button_custom_deinit = nullptr, - .priv = this, - }, + .short_press_time = 50 }; - boot_btn = iot_button_create(&btns_config); - iot_button_register_cb(boot_btn, BUTTON_SINGLE_CLICK, [](void* button_handle, void* usr_data) { + button_driver_t boot_btn_driver = { + .enable_power_save = false, + .get_key_level = GetBootButtonLevel + }; + ESP_ERROR_CHECK(iot_button_create(&boot_btn_config, &boot_btn_driver, &boot_btn)); + iot_button_register_cb(boot_btn, BUTTON_SINGLE_CLICK, nullptr, [](void* button_handle, void* usr_data) { auto self = static_cast(usr_data); auto& app = Application::GetInstance(); if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) { @@ -398,24 +404,18 @@ private: } app.ToggleChatState(); }, this); - iot_button_register_cb(boot_btn, BUTTON_LONG_PRESS_START, [](void* button_handle, void* usr_data) { - // 长按无处理 - }, this); - btns_config.long_press_time = 5000; - btns_config.custom_button_config.button_custom_get_key_value = [](void *param) -> uint8_t { - return gpio_get_level(PWR_BUTTON_GPIO); + // Power Button + button_config_t pwr_btn_config = { + .long_press_time = 5000, + .short_press_time = 50 }; - pwr_btn = iot_button_create(&btns_config); - iot_button_register_cb(pwr_btn, BUTTON_SINGLE_CLICK, [](void* button_handle, void* usr_data) { - // auto self = static_cast(usr_data); // 以下程序实现供用户参考 ,实现单击pwr按键调整亮度 - // if(self->GetBacklight()->brightness() > 1) // 如果亮度不为0 - // self->GetBacklight()->SetBrightness(1); // 设置亮度为1 - // else - // self->GetBacklight()->RestoreBrightness(); // 恢复原本亮度 - // 短按无处理 - }, this); - iot_button_register_cb(pwr_btn, BUTTON_LONG_PRESS_START, [](void* button_handle, void* usr_data) { + button_driver_t pwr_btn_driver = { + .enable_power_save = false, + .get_key_level = GetPwrButtonLevel + }; + ESP_ERROR_CHECK(iot_button_create(&pwr_btn_config, &pwr_btn_driver, &pwr_btn)); + iot_button_register_cb(pwr_btn, BUTTON_LONG_PRESS_START, nullptr, [](void* button_handle, void* usr_data) { auto self = static_cast(usr_data); if(self->GetBacklight()->brightness() > 0) { self->GetBacklight()->SetBrightness(0); @@ -465,3 +465,5 @@ public: }; DECLARE_BOARD(CustomBoard); + +CustomBoard* CustomBoard::instance_ = nullptr; diff --git a/main/boards/sensecap-watcher/sensecap_watcher.cc b/main/boards/sensecap-watcher/sensecap_watcher.cc index 76710555..6ddc868c 100644 --- a/main/boards/sensecap-watcher/sensecap_watcher.cc +++ b/main/boards/sensecap-watcher/sensecap_watcher.cc @@ -5,7 +5,6 @@ #include "display/lcd_display.h" #include "font_awesome_symbols.h" #include "application.h" -#include "button.h" #include "knob.h" #include "config.h" #include "led/single_led.h" @@ -17,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -25,9 +25,9 @@ #include #include #include -#include "esp_console.h" -#include "esp_mac.h" -#include "nvs_flash.h" +#include +#include +#include #include "assets/lang_config.h" @@ -95,6 +95,8 @@ private: esp_lcd_panel_io_handle_t panel_io_ = nullptr; esp_lcd_panel_handle_t panel_ = nullptr; uint32_t long_press_cnt_; + static SensecapWatcher* instance_; + void InitializePowerSaveTimer() { power_save_timer_ = new PowerSaveTimer(-1, 60, 300); power_save_timer_->OnEnterSleepMode([this]() { @@ -228,22 +230,14 @@ private: ESP_LOGI(TAG, "Knob initialized with pins A:%d B:%d", BSP_KNOB_A_PIN, BSP_KNOB_B_PIN); } + // 添加一个静态成员实例指针,用于按钮回调 + static uint8_t GetKnobButtonLevel(button_driver_t *button_driver) { + return instance_->IoExpanderGetLevel(BSP_KNOB_BTN); + } + void InitializeButton() { - button_config_t btn_config = { - .type = BUTTON_TYPE_CUSTOM, - .long_press_time = 2000, - .short_press_time = 50, - .custom_button_config = { - .active_level = 0, - .button_custom_init =nullptr, - .button_custom_get_key_value = [](void *param) -> uint8_t { - auto self = static_cast(param); - return self->IoExpanderGetLevel(BSP_KNOB_BTN); - }, - .button_custom_deinit = nullptr, - .priv = this, - }, - }; + // 设置静态实例指针 + instance_ = this; // watcher 是通过长按滚轮进行开机的, 需要等待滚轮释放, 否则用户开机松手时可能会误触成单击 ESP_LOGI(TAG, "waiting for knob button release"); @@ -251,8 +245,18 @@ private: vTaskDelay(50 / portTICK_PERIOD_MS); } - btns = iot_button_create(&btn_config); - iot_button_register_cb(btns, BUTTON_SINGLE_CLICK, [](void* button_handle, void* usr_data) { + button_config_t btn_config = { + .long_press_time = 2000, + .short_press_time = 50 + }; + button_driver_t btn_driver = { + .enable_power_save = false, + .get_key_level = GetKnobButtonLevel + }; + + ESP_ERROR_CHECK(iot_button_create(&btn_config, &btn_driver, &btns)); + + iot_button_register_cb(btns, BUTTON_SINGLE_CLICK, nullptr, [](void* button_handle, void* usr_data) { auto self = static_cast(usr_data); auto& app = Application::GetInstance(); if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) { @@ -261,7 +265,8 @@ private: self->power_save_timer_->WakeUp(); app.ToggleChatState(); }, this); - iot_button_register_cb(btns, BUTTON_LONG_PRESS_START, [](void* button_handle, void* usr_data) { + + iot_button_register_cb(btns, BUTTON_LONG_PRESS_START, nullptr, [](void* button_handle, void* usr_data) { auto self = static_cast(usr_data); bool is_charging = (self->IoExpanderGetLevel(BSP_PWR_VBUS_IN_DET) == 0); self->long_press_cnt_ = 0; @@ -273,7 +278,7 @@ private: } }, this); - iot_button_register_cb(btns, BUTTON_LONG_PRESS_HOLD, [](void* button_handle, void* usr_data) { + iot_button_register_cb(btns, BUTTON_LONG_PRESS_HOLD, nullptr, [](void* button_handle, void* usr_data) { auto self = static_cast(usr_data); self->long_press_cnt_++; // 每隔20ms加一 // 长按10s 恢复出厂设置: 2+0.02*400 = 10 @@ -283,7 +288,6 @@ private: esp_restart(); } }, this); - } void InitializeSpi() { @@ -467,7 +471,6 @@ private: .func = NULL, .argtable = NULL, .func_w_context = [](void *context,int argc, char** argv) -> int { - auto self = static_cast(context); nvs_flash_erase(); esp_restart(); return 0; @@ -576,3 +579,6 @@ public: }; DECLARE_BOARD(SensecapWatcher); + +// 定义静态成员变量 +SensecapWatcher* SensecapWatcher::instance_ = nullptr; diff --git a/main/boards/xingzhi-cube-1.54tft-dual/xingzhi_cube_1_54tft_dual_board.cc b/main/boards/xingzhi-cube-1.54tft-dual/xingzhi_cube_1_54tft_dual_board.cc index 9c154162..27719dd2 100644 --- a/main/boards/xingzhi-cube-1.54tft-dual/xingzhi_cube_1_54tft_dual_board.cc +++ b/main/boards/xingzhi-cube-1.54tft-dual/xingzhi_cube_1_54tft_dual_board.cc @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -86,13 +87,23 @@ private: } void InitializeButtons() { + boot_button_.OnPressDown([this]() { + auto& app = Application::GetInstance(); + if (GetNetworkType() == NetworkType::WIFI) { + if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) { + // cast to WifiBoard + auto& wifi_board = static_cast(GetCurrentBoard()); + wifi_board.ResetWifiConfiguration(); + } + } + }); + boot_button_.OnClick([this]() { power_save_timer_->WakeUp(); auto& app = Application::GetInstance(); app.ToggleChatState(); }); - boot_button_.OnLongPress([this]() { SwitchNetType(); auto& app = Application::GetInstance(); @@ -182,7 +193,7 @@ private: public: XINGZHI_CUBE_1_54TFT_DUAL() : DualNetworkBoard(ML307_TX_PIN, ML307_RX_PIN, 4096), - boot_button_(BOOT_BUTTON_GPIO), + boot_button_(BOOT_BUTTON_GPIO, false, 3000), volume_up_button_(VOLUME_UP_BUTTON_GPIO), volume_down_button_(VOLUME_DOWN_BUTTON_GPIO) { InitializePowerManager(); diff --git a/main/idf_component.yml b/main/idf_component.yml index 5712a8fa..f43d97be 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -10,17 +10,17 @@ dependencies: espressif/esp_lcd_panel_io_additions: "^1.0.1" 78/esp_lcd_nv3023: "~1.0.0" 78/esp-wifi-connect: "~2.4.2" - 78/esp-opus-encoder: "~2.3.1" + 78/esp-opus-encoder: "~2.3.2" 78/esp-ml307: "~1.9.1" 78/xiaozhi-fonts: "~1.3.2" - espressif/led_strip: "^2.4.1" + espressif/led_strip: "^2.5.5" espressif/esp_codec_dev: "~1.3.2" - espressif/esp-sr: "==2.0.3" - espressif/button: "^3.3.1" + espressif/esp-sr: "~2.1.1" + espressif/button: "~4.1.3" espressif/knob: "^1.0.0" - espressif/esp_lcd_touch_ft5x06: "~1.0.6" + espressif/esp_lcd_touch_ft5x06: "~1.0.7" lvgl/lvgl: "~9.2.2" - esp_lvgl_port: "~2.4.4" + esp_lvgl_port: "~2.6.0" espressif/esp_io_expander_tca95xx_16bit: "^2.0.0" tny-robotics/sh1106-esp-idf: version: "^1.0.0"