#include "power_manager.h" #include "esp_sleep.h" #include "driver/rtc_io.h" #include "esp_log.h" #include "config.h" #include #include "esp_log.h" #include "settings.h" #define TAG "PowerManager" static QueueHandle_t gpio_evt_queue = NULL; uint16_t battCnt;//闪灯次数 int battLife = 70; //电量 // 中断服务程序 static void IRAM_ATTR batt_mon_isr_handler(void* arg) { uint32_t gpio_num = (uint32_t) arg; xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); } // 添加任务处理函数 static void batt_mon_task(void* arg) { uint32_t io_num; while(1) { if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) { battCnt++; } } } static void calBattLife() { // 计算电量 battLife = battCnt; if (battLife > 100){ battLife = 100; } // ESP_LOGI(TAG, "Battery life:%d", (int)battLife); // 重置计数器 battCnt = 0; } PowerManager::PowerManager(){ m_bt_task_handle = nullptr; bt_link_callback_ = nullptr; } void PowerManager::Initialize(){ // 初始化5V控制引脚 gpio_config_t io_conf_5v = { .pin_bit_mask = 1<(arg); self->CheckBatteryStatus(); }, .arg = this, .dispatch_method = ESP_TIMER_TASK, .name = "battery_check_timer", .skip_unhandled_events = true, }; ESP_ERROR_CHECK(esp_timer_create(&timer_args, &timer_handle_)); ESP_ERROR_CHECK(esp_timer_start_periodic(timer_handle_, 1000000)); } void PowerManager::CheckBatteryStatus(){ call_count_++; if(call_count_ >= MON_BATT_CNT) { calBattLife(); call_count_ = 0; } bool new_charging_status = IsCharging(); if (new_charging_status != is_charging_) { is_charging_ = new_charging_status; if (charging_callback_) { charging_callback_(is_charging_); } } bool new_discharging_status = IsDischarging(); if (new_discharging_status != is_discharging_) { is_discharging_ = new_discharging_status; if (discharging_callback_) { discharging_callback_(is_discharging_); } } } bool PowerManager::IsCharging() { return gpio_get_level(MON_USB_PIN) == 1 && !IsChargingDone(); } bool PowerManager::IsDischarging() { return gpio_get_level(MON_USB_PIN) == 0; } bool PowerManager::IsChargingDone() { return battLife >= 95; } int PowerManager::GetBatteryLevel() { return battLife; } void PowerManager::OnChargingStatusChanged(std::function callback) { charging_callback_ = callback; } void PowerManager::OnChargingStatusDisChanged(std::function callback) { discharging_callback_ = callback; } void PowerManager::CheckStartup() { Settings settings1("board", true); if(settings1.GetInt("sleep_flag", 0) > 0){ vTaskDelay(pdMS_TO_TICKS(1000)); if( gpio_get_level(BOOT_BUTTON_PIN) == 1) { Sleep(); //进入休眠模式 }else{ settings1.SetInt("sleep_flag", 0); } } } void PowerManager::Start5V() { gpio_set_level(BOOT_5V_PIN, 1); } void PowerManager::Shutdown5V() { gpio_set_level(BOOT_5V_PIN, 0); } void PowerManager::Start4G() { gpio_set_level(BOOT_4G5V_PIN, 1); } void PowerManager::Shutdown4G() { gpio_set_level(BOOT_4G5V_PIN, 0); gpio_set_level(ML307_RX_PIN,1); gpio_set_level(ML307_TX_PIN,1); } void PowerManager::Enable4G() { gpio_set_level(BOOT_4GEN_PIN, 1); } void PowerManager::Disable4G() { gpio_set_level(BOOT_4GEN_PIN, 0); } void PowerManager::Sleep() { ESP_LOGI(TAG, "Entering deep sleep"); Settings settings("board", true); settings.SetInt("sleep_flag", 1); Disable4G(); Shutdown4G(); Shutdown5V(); if(gpio_evt_queue) { vQueueDelete(gpio_evt_queue); gpio_evt_queue = NULL; } ESP_ERROR_CHECK(gpio_isr_handler_remove(BOOT_BUTTON_PIN)); ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(BOOT_BUTTON_PIN, 0)); ESP_ERROR_CHECK(rtc_gpio_pulldown_dis(BOOT_BUTTON_PIN)); ESP_ERROR_CHECK(rtc_gpio_pullup_en(BOOT_BUTTON_PIN)); esp_deep_sleep_start(); } void PowerManager::InitializeBtModul() { if (MON_BTLINK_PIN == GPIO_NUM_NC) { ESP_LOGW(TAG, "MON_BTLINK_PIN not configured, skipping GPIO polling setup"); return; } gpio_config_t io_conf = {}; io_conf.intr_type = GPIO_INTR_DISABLE; io_conf.pin_bit_mask = (1ULL << MON_BTLINK_PIN); io_conf.mode = GPIO_MODE_INPUT; io_conf.pull_up_en = GPIO_PULLUP_DISABLE; io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; if (gpio_config(&io_conf) != ESP_OK) { ESP_LOGE(TAG, "Failed to configure GPIO %d", MON_BTLINK_PIN); return; } BaseType_t ret = xTaskCreate(BtTask, "bt_task", 2048, this, 10, &m_bt_task_handle); if (ret != pdPASS) { ESP_LOGE(TAG, "Failed to create BT task"); return; } } void PowerManager::DeinitBtModul() { if (MON_BTLINK_PIN == GPIO_NUM_NC) { return; } if (m_bt_task_handle != nullptr) { vTaskDelete(m_bt_task_handle); m_bt_task_handle = nullptr; } gpio_reset_pin(MON_BTLINK_PIN); } void PowerManager::BtTask(void *arg) { PowerManager *instance = static_cast(arg); int last_level = -1; for (;;) { vTaskDelay(pdMS_TO_TICKS(100)); int level = gpio_get_level(MON_BTLINK_PIN); if (level != last_level) { last_level = level; if (level == 1) { ESP_LOGI(TAG, "BTLINK %d high - BT connected", MON_BTLINK_PIN); if (instance->bt_link_callback_) { instance->bt_link_callback_(true); } } else { ESP_LOGI(TAG, "BTLINK %d low - BT disconnected", MON_BTLINK_PIN); if (instance->bt_link_callback_) { instance->bt_link_callback_(false); } } } } vTaskDelete(NULL); } void PowerManager::OnBtLinkStatusChanged(std::function callback) { bt_link_callback_ = callback; }