diff --git a/main/boards/jiuchuan-s3/jiuchuan_dev_board.cc b/main/boards/jiuchuan-s3/jiuchuan_dev_board.cc index a24364c8..a68ad090 100644 --- a/main/boards/jiuchuan-s3/jiuchuan_dev_board.cc +++ b/main/boards/jiuchuan-s3/jiuchuan_dev_board.cc @@ -132,14 +132,9 @@ private: } void InitializeButtons() { - auto& powerCtrl = PowerController::Instance(); - powerCtrl.SetState(PowerController::PowerState::ACTIVE); // 确保初始状态为ACTIVE - // 配置GPIO ESP_LOGI(TAG, "Configuring power button GPIO"); GpioManager::Config(GPIO_NUM_3, GpioManager::GpioMode::INPUT_PULLDOWN); - GpioManager::Config(PWR_EN_GPIO, GpioManager::GpioMode::OUTPUT); - GpioManager::SetLevel(PWR_EN_GPIO, 1); // 确保电源使能 boot_button_.OnClick([this]() { ESP_LOGI(TAG, "Boot button clicked"); @@ -150,7 +145,7 @@ private: ESP_LOGI(TAG, "Power button initial state: %d", GpioManager::GetLevel(PWR_BUTTON_GPIO)); // 高电平有效长按关机逻辑 - pwr_button_.OnLongPress([&powerCtrl]() { + pwr_button_.OnLongPress([this]() { ESP_LOGI(TAG, "Power button long press detected (high-active)"); // 高电平有效防抖确认 @@ -164,26 +159,20 @@ private: } vTaskDelay(100 / portTICK_PERIOD_MS); } - ESP_LOGI(TAG, "Confirmed power button pressed (level=1)"); ESP_LOGI(TAG, "Confirmed power button pressed - initiating shutdown"); - powerCtrl.SetState(PowerController::PowerState::SHUTDOWN); - - // 确保状态变更 - if (powerCtrl.GetState() != PowerController::PowerState::SHUTDOWN) { - ESP_LOGE(TAG, "Failed to set shutdown state!"); - } + power_manager_->SetPowerState(PowerState::SHUTDOWN); }); - wifi_button.OnClick([this, &powerCtrl]() { + wifi_button.OnClick([this]() { ESP_LOGI(TAG, "Wifi button clicked"); power_save_timer_->WakeUp(); - if (powerCtrl.GetState() == PowerController::PowerState::ACTIVE) { - ESP_LOGI(TAG, "Resetting WiFi configuration"); - GpioManager::SetLevel(PWR_EN_GPIO, 1); - ResetWifiConfiguration(); - } + + ESP_LOGI(TAG, "Resetting WiFi configuration"); + GpioManager::SetLevel(PWR_EN_GPIO, 1); + ResetWifiConfiguration(); + }); cmd_button.OnClick([this]() { @@ -191,40 +180,6 @@ private: power_save_timer_->WakeUp(); Application::GetInstance().ToggleChatState(); }); - - // 配置电源状态变更回调(优化版) - powerCtrl.OnStateChange([this](PowerController::PowerState newState) { - switch(newState) { - case PowerController::PowerState::SHUTDOWN: { - ESP_LOGI(TAG, "Entering shutdown sequence"); - - // 统一唤醒触发条件 - #ifndef __USER_GPIO_PWRDOWN__ - ESP_LOGD(TAG, "Configuring high-level wakeup on GPIO%d", PWR_BUTTON_GPIO); - ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(PWR_BUTTON_GPIO, 1)); // 高电平唤醒 - #else - ESP_LOGD(TAG, "Powering down via GPIO control"); - GpioManager::SetLevel(PWR_EN_GPIO, 0); - #endif - - // 确保所有外设已关闭 - vTaskDelay(200 / portTICK_PERIOD_MS); - ESP_LOGI(TAG, "Initiating deep sleep"); - - // 最后状态确认(通过单例访问) - if (PowerController::Instance().GetState() != PowerController::PowerState::SHUTDOWN) { - ESP_LOGE(TAG, "State inconsistency! Forcing shutdown"); - } - esp_deep_sleep_start(); - break; - } - - default: - ESP_LOGD(TAG, "State changed to %d", static_cast(newState)); - break; - } - }); - } void InitializeGC9301isplay() { diff --git a/main/boards/jiuchuan-s3/power_controller.h b/main/boards/jiuchuan-s3/power_controller.h index 1b26d949..2496152a 100644 --- a/main/boards/jiuchuan-s3/power_controller.h +++ b/main/boards/jiuchuan-s3/power_controller.h @@ -2,16 +2,19 @@ #include #include #include +#include #include - -class PowerController { -public: - enum class PowerState { +#include "config.h" +enum class PowerState { ACTIVE, LIGHT_SLEEP, DEEP_SLEEP, SHUTDOWN }; + +class PowerController { +public: + static PowerController& Instance() { static PowerController instance; @@ -42,7 +45,11 @@ public: } private: - PowerController() = default; + PowerController(){ + rtc_gpio_init(PWR_EN_GPIO); + rtc_gpio_set_direction(PWR_EN_GPIO, RTC_GPIO_MODE_OUTPUT_ONLY); + rtc_gpio_set_level(PWR_EN_GPIO, 1); + } ~PowerController() = default; PowerState currentState_ = PowerState::ACTIVE; diff --git a/main/boards/jiuchuan-s3/power_manager.h b/main/boards/jiuchuan-s3/power_manager.h index 42d8cb88..e306d105 100644 --- a/main/boards/jiuchuan-s3/power_manager.h +++ b/main/boards/jiuchuan-s3/power_manager.h @@ -4,8 +4,10 @@ #include #include -#include #include "adc_battery_estimation.h" +#include "power_controller.h" +#include +#include #define JIUCHUAN_ADC_UNIT (ADC_UNIT_1) #define JIUCHUAN_ADC_BITWIDTH (ADC_BITWIDTH_12) @@ -14,23 +16,28 @@ #define JIUCHUAN_RESISTOR_UPPER (200000) #define JIUCHUAN_RESISTOR_LOWER (100000) +#undef TAG +#define TAG "PowerManager" class PowerManager { private: esp_timer_handle_t timer_handle_; std::function on_charging_status_changed_; std::function on_low_battery_status_changed_; - gpio_num_t charging_pin_ = GPIO_NUM_NC; std::vector adc_values_; - uint32_t battery_level_ = 0; + int32_t battery_level_ = 100; bool is_charging_ = false; bool is_low_battery_ = false; + bool is_empty_battery_ = false; int ticks_ = 0; const int kBatteryAdcInterval = 60; const int kBatteryAdcDataCount = 3; const int kLowBatteryLevel = 20; adc_battery_estimation_handle_t adc_battery_estimation_handle; + PowerController* power_controller_; + + void CheckBatteryStatus() { // Get charging status @@ -61,11 +68,16 @@ private: float battery_capacity_temp = 0; adc_battery_estimation_get_capacity(adc_battery_estimation_handle, &battery_capacity_temp); ESP_LOGI("PowerManager", "Battery level: %.1f%%", battery_capacity_temp); - battery_level_ = battery_capacity_temp; + if(battery_capacity_temp > -10 && battery_capacity_temp <= 0){ + battery_level_ = 0; + }else{ + battery_level_ = battery_capacity_temp; + } } public: PowerManager(gpio_num_t pin) : charging_pin_(pin) { + power_controller_ = &PowerController::Instance(); // 初始化充电引脚 gpio_config_t io_conf = {}; io_conf.intr_type = GPIO_INTR_DISABLE; @@ -89,14 +101,14 @@ public: ESP_ERROR_CHECK(esp_timer_create(&timer_args, &timer_handle_)); ESP_ERROR_CHECK(esp_timer_start_periodic(timer_handle_, 1000000)); - // 初始化 ADC static const battery_point_t battery_ponint_table[]={ { 4.2 , 100}, { 4.06 , 80}, { 3.82 , 60}, { 3.58 , 40}, { 3.34 , 20}, - { 3.1 , 0} + { 3.1 , 0}, + { 3.0 , -10} }; adc_battery_estimation_t config = { @@ -113,6 +125,8 @@ public: }; adc_battery_estimation_handle = adc_battery_estimation_create(&config); + + RegisterAllCallbacks(); } ~PowerManager() { @@ -120,11 +134,15 @@ public: esp_timer_stop(timer_handle_); esp_timer_delete(timer_handle_); } + if (adc_battery_estimation_handle) { + adc_battery_estimation_destroy(adc_battery_estimation_handle); + } } bool IsCharging() { // 如果电量已经满了,则不再显示充电中 if (battery_level_ == 100) { + //ESP_LOGI(TAG, "电量已满,不再显示充电中"); return false; } return is_charging_; @@ -135,10 +153,44 @@ public: return !is_charging_; } - uint8_t GetBatteryLevel() { + int32_t GetBatteryLevel() { return battery_level_; } + void RegisterAllCallbacks() { + //注册电源状态变更回调函数(优化版) + power_controller_->OnStateChange([this](PowerState newState) { + switch(newState) { + case PowerState::SHUTDOWN: { + + ESP_LOGD(TAG, "关机"); + + //取消 PWR_EN 使能 + /* 防止关机后误唤醒 */ + ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(PWR_BUTTON_GPIO, 0)); + ESP_ERROR_CHECK(rtc_gpio_pulldown_en(PWR_BUTTON_GPIO)); // 内部下拉 + ESP_ERROR_CHECK(rtc_gpio_pullup_dis(PWR_BUTTON_GPIO)); + /* 关闭电源使能 */ + rtc_gpio_set_level(PWR_EN_GPIO, 0); + rtc_gpio_hold_dis(PWR_EN_GPIO); + + // 确保所有外设已关闭 + vTaskDelay(200 / portTICK_PERIOD_MS); + ESP_LOGI(TAG, "Initiating deep sleep"); + + esp_deep_sleep_start(); + break; + } + default: + ESP_LOGD(TAG, "State changed to %d", static_cast(newState)); + break; + } + }); + } + void SetPowerState(PowerState newState) { + power_controller_->SetState(newState); + } + void OnLowBatteryStatusChanged(std::function callback) { on_low_battery_status_changed_ = callback; }