Files
xiaozhi-esp32/main/boards/common/sleep_timer.cc
Xiaoxia 3c71558a5f v1.8.0: Audio 代码重构与低功耗优化 (#943)
* Reconstruct Audio Code

* Remove old IoT implementation

* Add MQTT-UDP documentation

* OTA升级失败时,可以继续使用
2025-07-19 22:45:22 +08:00

115 lines
3.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "sleep_timer.h"
#include "application.h"
#include "board.h"
#include "display.h"
#include <esp_log.h>
#include <esp_sleep.h>
#include <esp_lvgl_port.h>
#define TAG "SleepTimer"
SleepTimer::SleepTimer(int seconds_to_light_sleep, int seconds_to_deep_sleep)
: seconds_to_light_sleep_(seconds_to_light_sleep), seconds_to_deep_sleep_(seconds_to_deep_sleep) {
esp_timer_create_args_t timer_args = {
.callback = [](void* arg) {
auto self = static_cast<SleepTimer*>(arg);
self->CheckTimer();
},
.arg = this,
.dispatch_method = ESP_TIMER_TASK,
.name = "sleep_timer",
.skip_unhandled_events = true,
};
ESP_ERROR_CHECK(esp_timer_create(&timer_args, &sleep_timer_));
}
SleepTimer::~SleepTimer() {
esp_timer_stop(sleep_timer_);
esp_timer_delete(sleep_timer_);
}
void SleepTimer::SetEnabled(bool enabled) {
if (enabled && !enabled_) {
ticks_ = 0;
enabled_ = enabled;
ESP_ERROR_CHECK(esp_timer_start_periodic(sleep_timer_, 1000000));
ESP_LOGI(TAG, "Sleep timer enabled");
} else if (!enabled && enabled_) {
ESP_ERROR_CHECK(esp_timer_stop(sleep_timer_));
enabled_ = enabled;
WakeUp();
ESP_LOGI(TAG, "Sleep timer disabled");
}
}
void SleepTimer::OnEnterLightSleepMode(std::function<void()> callback) {
on_enter_light_sleep_mode_ = callback;
}
void SleepTimer::OnExitLightSleepMode(std::function<void()> callback) {
on_exit_light_sleep_mode_ = callback;
}
void SleepTimer::OnEnterDeepSleepMode(std::function<void()> callback) {
on_enter_deep_sleep_mode_ = callback;
}
void SleepTimer::CheckTimer() {
auto& app = Application::GetInstance();
if (!app.CanEnterSleepMode()) {
ticks_ = 0;
return;
}
ticks_++;
if (seconds_to_light_sleep_ != -1 && ticks_ >= seconds_to_light_sleep_) {
if (!in_light_sleep_mode_) {
in_light_sleep_mode_ = true;
if (on_enter_light_sleep_mode_) {
on_enter_light_sleep_mode_();
}
app.Schedule([this, &app]() {
while (in_light_sleep_mode_) {
auto& board = Board::GetInstance();
board.GetDisplay()->UpdateStatusBar(true);
lv_refr_now(nullptr);
lvgl_port_stop();
// 配置timer唤醒源30秒后自动唤醒
esp_sleep_enable_timer_wakeup(30 * 1000000);
// 进入light sleep模式
esp_light_sleep_start();
lvgl_port_resume();
auto wakeup_reason = esp_sleep_get_wakeup_cause();
if (wakeup_reason != ESP_SLEEP_WAKEUP_TIMER) {
break;
}
}
WakeUp();
});
}
}
if (seconds_to_deep_sleep_ != -1 && ticks_ >= seconds_to_deep_sleep_) {
if (on_enter_deep_sleep_mode_) {
on_enter_deep_sleep_mode_();
}
esp_deep_sleep_start();
}
}
void SleepTimer::WakeUp() {
ticks_ = 0;
if (in_light_sleep_mode_) {
in_light_sleep_mode_ = false;
if (on_exit_light_sleep_mode_) {
on_exit_light_sleep_mode_();
}
}
}