brightness: user-cyclable level persisted to NVS, via idle
idle owns the panel brightness (it fades between a "full" level and 0), so
user brightness control routes through a new idle_set_awake_brightness():
idle now fades to a runtime awake level instead of the hard-coded
DISPLAY_DEFAULT_BRIGHTNESS, and the chosen level survives idle fades + wake.
brightness.{h,cpp} holds a 4-step ramp {64,128,200,255} (default 200 == the
old constant, so default behavior is unchanged) persisted to NVS, and applies
the level through idle. Wired to the PWR button in the next commit.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
98a513a403
commit
ddb812ab5d
@@ -0,0 +1,39 @@
|
|||||||
|
#include "brightness.h"
|
||||||
|
#include "idle.h"
|
||||||
|
#include <Preferences.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
// Four-step ramp. The default (index 2) is 200 — identical to the prior
|
||||||
|
// hard-coded DISPLAY_DEFAULT_BRIGHTNESS, so cycling is purely additive.
|
||||||
|
static const uint8_t LEVELS[] = {64, 128, 200, 255};
|
||||||
|
#define LEVELS_COUNT (sizeof(LEVELS) / sizeof(LEVELS[0]))
|
||||||
|
#define DEFAULT_IDX 2
|
||||||
|
|
||||||
|
static uint8_t cur_idx = DEFAULT_IDX;
|
||||||
|
|
||||||
|
void brightness_init(void) {
|
||||||
|
Preferences prefs;
|
||||||
|
prefs.begin("clawdmeter", true);
|
||||||
|
uint8_t saved_idx = prefs.getUChar("brt_idx", 0xFF);
|
||||||
|
prefs.end();
|
||||||
|
|
||||||
|
if (saved_idx < LEVELS_COUNT) cur_idx = saved_idx;
|
||||||
|
idle_set_awake_brightness(LEVELS[cur_idx]);
|
||||||
|
Serial.printf("Brightness init: level=%u (idx=%u)\n", LEVELS[cur_idx], cur_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void brightness_cycle(void) {
|
||||||
|
cur_idx = (cur_idx + 1) % LEVELS_COUNT;
|
||||||
|
|
||||||
|
Preferences prefs;
|
||||||
|
prefs.begin("clawdmeter", false);
|
||||||
|
prefs.putUChar("brt_idx", cur_idx);
|
||||||
|
prefs.end();
|
||||||
|
|
||||||
|
idle_set_awake_brightness(LEVELS[cur_idx]);
|
||||||
|
Serial.printf("Brightness cycled: level=%u (idx=%u)\n", LEVELS[cur_idx], cur_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t brightness_get(void) {
|
||||||
|
return LEVELS[cur_idx];
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// User-controlled display brightness, persisted to NVS. The middle (PWR)
|
||||||
|
// button short-press cycles through the levels via brightness_cycle().
|
||||||
|
// idle owns the actual panel brightness, so this routes the chosen level
|
||||||
|
// through idle_set_awake_brightness().
|
||||||
|
void brightness_init(void); // load saved level from NVS and apply
|
||||||
|
void brightness_cycle(void); // advance to next level, save, apply
|
||||||
|
uint8_t brightness_get(void); // current PWM level (0..255)
|
||||||
+13
-5
@@ -17,13 +17,14 @@ static uint32_t fade_started_ms = 0;
|
|||||||
static uint32_t fade_last_step_ms = 0;
|
static uint32_t fade_last_step_ms = 0;
|
||||||
static uint8_t fade_from = DISPLAY_DEFAULT_BRIGHTNESS;
|
static uint8_t fade_from = DISPLAY_DEFAULT_BRIGHTNESS;
|
||||||
static uint8_t fade_to = 0;
|
static uint8_t fade_to = 0;
|
||||||
|
static uint8_t awake_brightness = DISPLAY_DEFAULT_BRIGHTNESS; // user-set "full" level (brightness.cpp)
|
||||||
|
|
||||||
static void apply_brightness(uint8_t b) {
|
static void apply_brightness(uint8_t b) {
|
||||||
display_hal_set_brightness(b);
|
display_hal_set_brightness(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void begin_fade(uint8_t to, uint32_t now) {
|
static void begin_fade(uint8_t to, uint32_t now) {
|
||||||
fade_from = (to == 0) ? DISPLAY_DEFAULT_BRIGHTNESS : 0;
|
fade_from = (to == 0) ? awake_brightness : 0;
|
||||||
fade_to = to;
|
fade_to = to;
|
||||||
fade_started_ms = now;
|
fade_started_ms = now;
|
||||||
fade_last_step_ms = now;
|
fade_last_step_ms = now;
|
||||||
@@ -32,7 +33,14 @@ static void begin_fade(uint8_t to, uint32_t now) {
|
|||||||
void idle_init(void) {
|
void idle_init(void) {
|
||||||
state = STATE_AWAKE;
|
state = STATE_AWAKE;
|
||||||
last_activity_ms = millis();
|
last_activity_ms = millis();
|
||||||
apply_brightness(DISPLAY_DEFAULT_BRIGHTNESS);
|
apply_brightness(awake_brightness);
|
||||||
|
}
|
||||||
|
|
||||||
|
void idle_set_awake_brightness(uint8_t level) {
|
||||||
|
awake_brightness = level;
|
||||||
|
// Apply now if fully awake so a button press is visible immediately;
|
||||||
|
// during fades/sleep the next fade-in picks it up.
|
||||||
|
if (state == STATE_AWAKE) apply_brightness(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idle_note_activity(void) {
|
void idle_note_activity(void) {
|
||||||
@@ -41,7 +49,7 @@ void idle_note_activity(void) {
|
|||||||
if (state == STATE_AWAKE) return;
|
if (state == STATE_AWAKE) return;
|
||||||
// Asleep/fading-out shouldn't reach here in normal flow (callers gate via
|
// Asleep/fading-out shouldn't reach here in normal flow (callers gate via
|
||||||
// idle_consume_wake_press first), but if it does: trigger a wake.
|
// idle_consume_wake_press first), but if it does: trigger a wake.
|
||||||
begin_fade(DISPLAY_DEFAULT_BRIGHTNESS, last_activity_ms);
|
begin_fade(awake_brightness, last_activity_ms);
|
||||||
state = STATE_FADING_IN;
|
state = STATE_FADING_IN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +57,7 @@ bool idle_consume_wake_press(void) {
|
|||||||
if (state == STATE_ASLEEP || state == STATE_FADING_OUT) {
|
if (state == STATE_ASLEEP || state == STATE_FADING_OUT) {
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
last_activity_ms = now;
|
last_activity_ms = now;
|
||||||
begin_fade(DISPLAY_DEFAULT_BRIGHTNESS, now);
|
begin_fade(awake_brightness, now);
|
||||||
state = STATE_FADING_IN;
|
state = STATE_FADING_IN;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -75,7 +83,7 @@ void idle_tick(void) {
|
|||||||
if (!IDLE_SLEEP_WHEN_CHARGING && power_hal_is_vbus_in()) {
|
if (!IDLE_SLEEP_WHEN_CHARGING && power_hal_is_vbus_in()) {
|
||||||
last_activity_ms = now;
|
last_activity_ms = now;
|
||||||
if (state == STATE_ASLEEP || state == STATE_FADING_OUT) {
|
if (state == STATE_ASLEEP || state == STATE_FADING_OUT) {
|
||||||
begin_fade(DISPLAY_DEFAULT_BRIGHTNESS, now);
|
begin_fade(awake_brightness, now);
|
||||||
state = STATE_FADING_IN;
|
state = STATE_FADING_IN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,12 @@ void idle_init(void);
|
|||||||
void idle_tick(void);
|
void idle_tick(void);
|
||||||
void idle_note_activity(void);
|
void idle_note_activity(void);
|
||||||
|
|
||||||
|
// Set the "awake" brightness target (0..255). idle owns display brightness
|
||||||
|
// (it fades between this and 0), so user brightness control routes through
|
||||||
|
// here. Applied immediately if the screen is currently fully awake; otherwise
|
||||||
|
// picked up by the next fade-in. See brightness.{h,cpp}.
|
||||||
|
void idle_set_awake_brightness(uint8_t level);
|
||||||
|
|
||||||
// Returns true if this press was consumed as a wake-up (caller MUST skip the
|
// Returns true if this press was consumed as a wake-up (caller MUST skip the
|
||||||
// button's normal action). Returns false when already awake — also notes the
|
// button's normal action). Returns false when already awake — also notes the
|
||||||
// activity, so callers don't need a separate idle_note_activity() call.
|
// activity, so callers don't need a separate idle_note_activity() call.
|
||||||
|
|||||||
Reference in New Issue
Block a user