Files
P4-USB-transfer/main/SCREEN/screen_brightness.c
T

172 lines
6.1 KiB
C
Raw Normal View History

2026-10-13 21:54:50 +08:00
/*****************************************************include files **************************************************************************/
#include "screen_brightness.h"
#include "LVGL/lvgl_init.h"
#include "ui.h"
/******************************************************* variable declaration ************************************************************************/
/*
* 亮度模型:UI/BLE 的 0~100% 线性映射到面板 PWM [BRIGHTNESS_PWM_MIN, BRIGHTNESS_PWM_MAX]。
* 选 55 作为下限:约 21.5% 全量程,且 (255-55)=200,duty = 55 + percent*2,0~100 与整数 PWM 一一对应、无除法舍入误差。
* 若硬件需其它暗场门限,只改 BRIGHTNESS_PWM_MIN(需保持 SPAN 与映射公式一致或同步改除法)。
*/
#define BRIGHTNESS_PWM_MIN 55
#define BRIGHTNESS_PWM_MAX 255
#define BRIGHTNESS_PWM_SPAN (BRIGHTNESS_PWM_MAX - BRIGHTNESS_PWM_MIN)
// 当前面板 PWM(BRIGHTNESS_PWM_MIN~BRIGHTNESS_PWM_MAX);未读 NVS 前取中间偏亮,避免明显过暗
uint8_t g_current_brightness = (uint8_t)(BRIGHTNESS_PWM_MIN + BRIGHTNESS_PWM_SPAN * 3 / 4);
static bool g_brightness_dirty = false;
static uint8_t g_brightness_commit_pending = 0;
static TimerHandle_t g_brightness_commit_timer = NULL;
/******************************************************* functions declaration ************************************************************************/
void save_brightness_to_nvs(uint8_t value); /* forward declaration for timer callback */
void commit_brightness_if_dirty(void);
extern esp_err_t panel_qspi_amoled_set_brightness(esp_lcd_panel_handle_t panel, uint8_t brightness);
/******************************************************* functions definition ************************************************************************/
// 保存亮度到 NVS
void save_brightness_to_nvs(uint8_t value)
{
nvs_handle_t my_handle;
esp_err_t err = nvs_open("system_cfg", NVS_READWRITE, &my_handle);
if (err == ESP_OK)
{
nvs_set_u8(my_handle, "brightness", value);
nvs_commit(my_handle);
nvs_close(my_handle);
// ESP_LOGI("NVS", "亮度已保存: %d", value);
}
}
static void brightness_commit_timer_cb(TimerHandle_t xTimer)
{
(void)xTimer;
save_brightness_to_nvs(g_brightness_commit_pending);
}
// 从 NVS 读取亮度
void load_brightness_from_nvs(void)
{
nvs_handle_t my_handle;
esp_err_t err = nvs_open("system_cfg", NVS_READONLY, &my_handle);
if (err == ESP_OK)
{
uint8_t saved_val = 0;
if (nvs_get_u8(my_handle, "brightness", &saved_val) == ESP_OK)
{
g_current_brightness = saved_val;
if (g_current_brightness < BRIGHTNESS_PWM_MIN)
g_current_brightness = BRIGHTNESS_PWM_MIN;
if (g_current_brightness > BRIGHTNESS_PWM_MAX)
g_current_brightness = BRIGHTNESS_PWM_MAX;
ESP_LOGI("NVS", "加载保存的亮度: %d", g_current_brightness);
}
nvs_close(my_handle);
}
}
// ================= 对外接口 =================
// 设置亮度 (供 UI 和 BLE 调用)
// 参数 percent: 0-100,0 对应 PWM_MIN、100 对应 PWM_MAX
void set_system_brightness(int percent)
{
if (percent < 0)
percent = 0;
if (percent > 100)
percent = 100;
uint8_t duty = (uint8_t)(BRIGHTNESS_PWM_MIN + ((unsigned)percent * BRIGHTNESS_PWM_SPAN) / 100U);
// 3. 应用到硬件
if (panel_handle)
{
panel_qspi_amoled_set_brightness(panel_handle, duty);
}
// 4. 更新全局变量并保存
if (g_current_brightness != duty)
{
g_current_brightness = duty;
g_brightness_dirty = true;
request_brightness_slider_sync();
}
/* BLE/UI 共用:有变更时经定时器落盘 NVS(避免在回调里同步写) */
commit_brightness_if_dirty();
}
/* 退出亮度界面时调用:只写一次 NVS,避免频繁保存导致不稳定 */
void commit_brightness_if_dirty(void)
{
if (!g_brightness_dirty)
return;
g_brightness_commit_pending = g_current_brightness;
g_brightness_dirty = false;
/* NVS 写放到 timer 任务上下文,避免在 LVGL 点击事件回调里同步写导致崩溃 */
if (g_brightness_commit_timer == NULL)
{
g_brightness_commit_timer = xTimerCreate("brightness_commit_tmr",
pdMS_TO_TICKS(50),
pdFALSE,
NULL,
brightness_commit_timer_cb);
}
if (g_brightness_commit_timer)
{
xTimerStop(g_brightness_commit_timer, 0);
if (xTimerStart(g_brightness_commit_timer, 0) != pdPASS)
{
/* 定时器队列满等异常时仍落盘,避免已清 dirty 却永不写入 NVS */
save_brightness_to_nvs(g_brightness_commit_pending);
}
}
else
{
/* xTimerCreate 失败(如堆不足)时直接写 NVS,否则与蓝牙路径行为不一致 */
save_brightness_to_nvs(g_brightness_commit_pending);
}
}
// 获取当前亮度百分比 (供 UI 初始化滑块与 BLE 查询,0~100)
int get_system_brightness_percent(void)
{
unsigned d = g_current_brightness;
if (d <= BRIGHTNESS_PWM_MIN)
return 0;
if (d >= BRIGHTNESS_PWM_MAX)
return 100;
return (int)((d - BRIGHTNESS_PWM_MIN) * 100U / BRIGHTNESS_PWM_SPAN);
}
// 【核心函数 2】设置是否阻止休眠 (例如 OTA 时调用 set_block_sleep(true))
void set_block_auto_sleep(bool block)
{
block_auto_sleep = block;
if (block)
{
system_keep_alive(); // 阻止时顺便刷新一下时间
}
}
/* 亮度滑动条同步:将设置页滑动条与当前系统亮度对齐 */
void request_brightness_slider_sync(void)
{
extern lv_ui guider_ui;
extern int get_system_brightness_percent(void);
int percent = get_system_brightness_percent();
if (guider_ui.screen_set_slider_light != NULL &&
lv_obj_is_valid(guider_ui.screen_set_slider_light)) {
lv_slider_set_value(guider_ui.screen_set_slider_light, percent, LV_ANIM_OFF);
}
}