Files
P4-USB-transfer/main/SCREEN/screen_sleep.c
T
zhengxinandCursor 851e347cf5 初始提交卡包 USB 工程
纳入固件源码、屏幕组件、nand_xfer 工具和文档。忽略本机构建产物、sdkconfig,以及含本机路径的依赖锁。

Co-authored-by: Cursor <[email protected]>
2026-10-13 21:54:50 +08:00

178 lines
6.0 KiB
C

/*****************************************************include files **************************************************************************/
#include "screen_sleep.h"
#include "ui/generated/events_init.h"
#include "ui/ui.h"
#define AUTO_SLEEP_DEFAULT_MS 0//默认休眠时间
/******************************************************* variable declaration ************************************************************************/
static uint32_t g_auto_sleep_timeout_ms = AUTO_SLEEP_DEFAULT_MS;
// 初始化为当前开机时间
int64_t last_activity_timestamp = 0; //最后一次用户活动的时间戳
static bool g_sleep_timeout_dirty = false; //休眠时间是否被改过但是没有写入NVS
static uint32_t g_sleep_commit_pending_ms = 0; //待提交到NVS的休眠时间缓存值
/* ===== 休眠设置 NVS 提交:离开休眠界面时写一次 ===== */
static TimerHandle_t g_sleep_commit_timer = NULL; //创建了freeRTOS的软件定时器句柄
extern volatile bool is_system_sleeping; //系统睡眠标记
extern bool block_auto_sleep ; //是否阻止自动休眠
extern int current_page_idx ; //当前页面索引
/******************************************************* functions declaration ************************************************************************/
static void save_timeout_to_nvs(uint32_t ms);
static void sleep_commit_timer_cb(TimerHandle_t xTimer);
/******************************************************* functions definition ************************************************************************/
// 【新增】从 NVS 加载休眠时间
void load_timeout_from_nvs(void)//从nvs加载休眠时间
{
nvs_handle_t my_handle;
esp_err_t err = nvs_open("system_cfg", NVS_READONLY, &my_handle);
if (err != ESP_OK)
{
ESP_LOGW("NVS", "打开 system_cfg 失败: %s,休眠时间使用默认 %lu ms",
esp_err_to_name(err), (unsigned long)AUTO_SLEEP_DEFAULT_MS);
g_auto_sleep_timeout_ms = AUTO_SLEEP_DEFAULT_MS;
system_keep_alive();
return;
}
uint32_t saved_val = 0;
if (nvs_get_u32(my_handle, "sleep_ms", &saved_val) == ESP_OK)
{
g_auto_sleep_timeout_ms = saved_val;
ESP_LOGI("NVS", "从 NVS 加载休眠时间: %lu ms", (unsigned long)g_auto_sleep_timeout_ms);
}
else
{
g_auto_sleep_timeout_ms = AUTO_SLEEP_DEFAULT_MS;
ESP_LOGW("NVS", "未找到 sleep_ms,使用默认 %lu ms", (unsigned long)AUTO_SLEEP_DEFAULT_MS);
}
nvs_close(my_handle);
/* 以完成 NVS 加载时刻为空闲计时起点,避免 last_activity 长期为 0 误判超时 */
system_keep_alive();
}
// 【新增】保存设置到 NVS
static void save_timeout_to_nvs(uint32_t ms)//保存休眠时间到nvs
{
nvs_handle_t my_handle;
esp_err_t err = nvs_open("system_cfg", NVS_READWRITE, &my_handle);
if (err == ESP_OK)
{
nvs_set_u32(my_handle, "sleep_ms", ms);
nvs_commit(my_handle); // 提交保存
nvs_close(my_handle);
ESP_LOGI("NVS", "休眠时间已保存: %lu ms", (unsigned long)ms);
}
else
{
ESP_LOGE("NVS", "无法打开 NVS 保存设置");
}
}
void persist_auto_sleep_timeout_ms_now(uint32_t ms)
{
if (g_sleep_commit_timer != NULL)
{
xTimerStop(g_sleep_commit_timer, pdMS_TO_TICKS(100));
}
g_auto_sleep_timeout_ms = ms;
g_sleep_timeout_dirty = false;
g_sleep_commit_pending_ms = ms;
system_keep_alive();
save_timeout_to_nvs(ms);
}
// 2. 【新增】设置超时时间的函数 (提供给按钮调用)
// 输入 0 代表永不休眠 设置自动休眠时间
void set_auto_sleep_timeout(uint32_t ms)
{
if (g_auto_sleep_timeout_ms == ms) {
return;
}
g_auto_sleep_timeout_ms = ms;
system_keep_alive();
ESP_LOGI("PM", "休眠设置更新: %lu ms (mark dirty)", (unsigned long)ms);
g_sleep_timeout_dirty = true;
}
// 【核心函数 1】系统保活:任何操作都应该调用这个函数
void system_keep_alive(void)//更新当前的活动时间戳
{
last_activity_timestamp = esp_timer_get_time() / 1000; // 更新为当前时间(ms)
}
//获取自动休眠时间
uint32_t get_auto_sleep_timeout(void)
{
return g_auto_sleep_timeout_ms;
}
//如果脏标记被设置过之后 发送自动休眠时间
void commit_auto_sleep_timeout_if_dirty(void)
{
if (!g_sleep_timeout_dirty)
return;
g_sleep_commit_pending_ms = g_auto_sleep_timeout_ms;
g_sleep_timeout_dirty = false;
/* 真正的 NVS 写放到 timer 回调里,避免在 LVGL 事件栈上下文里写 NVS */
if (g_sleep_commit_timer == NULL)
{
g_sleep_commit_timer = xTimerCreate("sleep_commit_tmr",
pdMS_TO_TICKS(50),
pdFALSE,
NULL,
sleep_commit_timer_cb);
}
if (g_sleep_commit_timer)
{
if (xTimerStart(g_sleep_commit_timer, 0) != pdPASS)
{
save_timeout_to_nvs(g_sleep_commit_pending_ms);
}
}
else
{
save_timeout_to_nvs(g_sleep_commit_pending_ms);
}
}
static void sleep_commit_timer_cb(TimerHandle_t xTimer)
{
(void)xTimer;
save_timeout_to_nvs(g_sleep_commit_pending_ms);
}
void auto_sleep_checker_cb(lv_timer_t *timer)
{
// 如果已经在睡觉,或者被阻止,或者设置为 0 (永不),直接返回
if (is_system_sleeping || block_auto_sleep || g_auto_sleep_timeout_ms == 0)
{
return;
}
int64_t now = esp_timer_get_time() / 1000;
// 使用变量 g_auto_sleep_timeout_ms 替代原来的 30000
if ((now - last_activity_timestamp) > g_auto_sleep_timeout_ms)
{
ESP_LOGW("PM", "系统空闲超时,自动进入休眠...");
if (current_page_idx != 0)
{
ui_change_page(0, LV_SCR_LOAD_ANIM_FADE_ON);
}
toggle_sleep_mode(true);
}
}