Dzbj_C3_Key/main/sleep_mgr/sleep_mgr.c
Rdzleo f9dc7d4861 feat: 触屏版迁移到按键版,两键实现全部交互功能
1. 按键驱动重构:GPIO中断+手动去抖 → iot_button组件(单击/双击/长按)
2. 新增key_nav按键导航管理器:上下文状态机 + Set界面焦点蓝色边框高亮
3. 移除所有触摸手势/点击事件(ScreenHome/ScreenImg/ScreenSet)
4. 应援灯颜色切换优化:DISPOFF→直接写GRAM→DISPON,消除分band刷新
5. 亮度调节按键化:BOOT +10% / KEY -10% / KEY长按退出
6. 休眠管理适配:按键唤醒统一由key_nav处理
7. 新增迁移总结文档 docs/touch-to-button-migration.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 14:57:14 +08:00

220 lines
6.8 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_mgr.h"
#include "pages.h"
#include "esp_log.h"
#include "esp_timer.h"
#include "esp_lvgl_port.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "lvgl.h"
#include "../ui/screens/ui_ScreenSet.h"
#include "../lcd/include/lcd.h"
#include <stdio.h>
static const char *TAG = "SLEEP";
static bool sleep_enabled = false;
static bool screen_off = false;
static int64_t last_activity_us = 0;
static uint8_t saved_brightness = 50;
static const uint8_t DEFAULT_BRIGHTNESS = 50; // 默认亮度
static const uint8_t SLEEP_MODE_BRIGHTNESS = 10; // 休眠模式亮度
// 通知有用户活动
void sleep_mgr_notify_activity(void)
{
last_activity_us = esp_timer_get_time();
// 如果屏幕已关闭,立即唤醒
if (screen_off) {
screen_off = false;
// 恢复 LVGL 和触摸输入
if (lvgl_port_lock(100)) {
// 1. 启用所有输入设备(恢复触摸事件处理)
lv_indev_t *indev = lv_indev_get_next(NULL);
while (indev) {
lv_indev_enable(indev, true);
ESP_LOGI(TAG, "输入设备已启用");
indev = lv_indev_get_next(indev);
}
// 2. 恢复刷新定时器(恢复屏幕重绘)
lv_timer_t *refr_timer = _lv_disp_get_refr_timer(NULL);
if (refr_timer) {
lv_timer_resume(refr_timer);
ESP_LOGI(TAG, "LVGL 刷新定时器已恢复");
}
// 3. 强制刷新当前屏幕因为GRAM被清空为黑色需要重绘
lv_obj_invalidate(lv_scr_act());
ESP_LOGI(TAG, "已标记屏幕需要重绘");
lvgl_port_unlock();
}
// 延迟50ms等待LVGL完成至少一次重绘避免看到黑屏
vTaskDelay(pdMS_TO_TICKS(50));
// 恢复背光
pwm_set_brightness(saved_brightness);
ESP_LOGI(TAG, "屏幕唤醒,恢复亮度%d%%", saved_brightness);
}
}
// 关闭屏幕(熄屏进入低功耗)
static void screen_turn_off(void)
{
if (screen_off) return;
// 保存当前亮度
saved_brightness = pwm_get_brightness();
if (saved_brightness == 0) {
saved_brightness = 50; // 防止保存到0值
}
// 暂停 LVGL 并禁用触摸输入
if (lvgl_port_lock(100)) {
// 1. 暂停刷新定时器(停止屏幕重绘)
lv_timer_t *refr_timer = _lv_disp_get_refr_timer(NULL);
if (refr_timer) {
lv_timer_pause(refr_timer);
ESP_LOGI(TAG, "LVGL 刷新定时器已暂停");
}
// 2. 禁用所有输入设备(停止触摸事件处理)
lv_indev_t *indev = lv_indev_get_next(NULL);
while (indev) {
lv_indev_enable(indev, false);
ESP_LOGI(TAG, "输入设备已禁用");
indev = lv_indev_get_next(indev);
}
lvgl_port_unlock();
}
// 清空LCD GRAM为黑色避免关闭背光后看到残影
lcd_clear_screen_black();
// 关闭背光
screen_off = true;
pwm_set_brightness(0);
ESP_LOGI(TAG, "屏幕已关闭(亮度=%d%%系统进入真正低功耗模式Light Sleep + LVGL暂停 + LCD GRAM清空", saved_brightness);
}
// 休眠管理任务
static void sleep_mgr_task(void *pvParameters)
{
while (1) {
uint32_t delay_ms = 500; // 默认轮询间隔 500ms
if (sleep_enabled) {
// 检查LVGL触摸活动屏幕开启时
if (!screen_off) {
if (lvgl_port_lock(50)) {
uint32_t inactive_ms = lv_disp_get_inactive_time(NULL);
lvgl_port_unlock();
// 屏幕开启状态:检测到新触摸(< 500ms立即更新活动时间
if (inactive_ms < 500) {
sleep_mgr_notify_activity();
}
}
// 检查超时熄屏
int64_t now = esp_timer_get_time();
int64_t elapsed_ms = (now - last_activity_us) / 1000;
if (elapsed_ms >= SLEEP_TIMEOUT_MS) {
screen_turn_off();
}
}
// 屏幕关闭状态:禁用触摸唤醒,只允许按键唤醒
// 如需启用触摸唤醒,取消注释以下代码:
/*
else {
if (lvgl_port_lock(50)) {
uint32_t inactive_ms = lv_disp_get_inactive_time(NULL);
lvgl_port_unlock();
// 检测到触摸(< 2000ms立即唤醒
if (inactive_ms < 2000) {
sleep_mgr_notify_activity();
ESP_LOGI(TAG, "触摸唤醒屏幕inactive=%lums", inactive_ms);
}
}
}
*/
}
vTaskDelay(pdMS_TO_TICKS(delay_ms));
}
}
void sleep_mgr_init(void)
{
last_activity_us = esp_timer_get_time();
// 按键唤醒由key_nav模块统一处理这里不再注册按键回调
xTaskCreate(sleep_mgr_task, "sleep_mgr", 3072, NULL, 3, NULL);
ESP_LOGI(TAG, "休眠管理器初始化完成(超时=%ds", SLEEP_TIMEOUT_MS / 1000);
}
// 更新ScreenSet界面的亮度UI控件
static void update_brightness_ui(uint8_t brightness)
{
if (!lvgl_port_lock(100)) {
return;
}
// 更新滑块位置
if (ui_SliderBrightness) {
lv_slider_set_value(ui_SliderBrightness, brightness, LV_ANIM_OFF);
}
// 更新亮度文本标签
if (ui_LabelBrightness) {
char buf[8];
snprintf(buf, sizeof(buf), "%d%%", brightness);
lv_label_set_text(ui_LabelBrightness, buf);
}
lvgl_port_unlock();
}
void sleep_mgr_set_enabled(bool enabled)
{
sleep_enabled = enabled;
if (enabled) {
last_activity_us = esp_timer_get_time();
// 进入休眠模式时将亮度调节到10%
pwm_set_brightness(SLEEP_MODE_BRIGHTNESS);
update_brightness_ui(SLEEP_MODE_BRIGHTNESS);
ESP_LOGI(TAG, "休眠模式已启用,亮度已调节至%d%%%ds无操作将熄屏",
SLEEP_MODE_BRIGHTNESS, SLEEP_TIMEOUT_MS / 1000);
} else {
// 禁用休眠模式时恢复到默认亮度50%
if (screen_off) {
screen_off = false;
pwm_set_brightness(DEFAULT_BRIGHTNESS);
update_brightness_ui(DEFAULT_BRIGHTNESS);
ESP_LOGI(TAG, "休眠模式已禁用,屏幕已恢复,亮度恢复到%d%%", DEFAULT_BRIGHTNESS);
} else {
pwm_set_brightness(DEFAULT_BRIGHTNESS);
update_brightness_ui(DEFAULT_BRIGHTNESS);
ESP_LOGI(TAG, "休眠模式已禁用,亮度恢复到%d%%", DEFAULT_BRIGHTNESS);
}
}
}
bool sleep_mgr_is_enabled(void)
{
return sleep_enabled;
}
bool sleep_mgr_is_screen_off(void)
{
return screen_off;
}