Files
ZephCore/zephcore/helpers/boot_prefs.h
T
ZephCore T096 1d33c7177f leds: persist brightness across reboots and firmware updates
leds.brightness (PWM-capable boards) was RAM-only since it was added: it
always reset to ZEPHCORE_LED_DEFAULT_BRIGHTNESS_PCT (10%) on every boot,
regardless of what a user had last set it to.

New field led_brightness on NodePrefs, following the exact same
append-only pattern as leds_radio_mode/leds_hb_mode added just before it:
offset 311 in RepeaterDataStore.cpp (repeater/room-server/observer,
shared file), offset 174 in ZephyrDataStore.cpp (companion). Both are
backward compatible by construction: a prefs file written before this
field existed simply leaves it at the initNodePrefs() default (10%),
which is exactly the behaviour every already-deployed node has today --
no special-casing needed to keep "10% on a new/not-yet-upgraded node" as
the effective default.

CommonCLI.cpp's "set leds.brightness" handler now writes the prefs field
and calls savePrefs(), same as the leds.radio/leds.hb handlers right
above it; "get leds.brightness" now reads from prefs instead of the RAM
getter directly, for the same reason those two already do (always in
sync, prefs is the source of truth). The four boot call sites
(main_companion.cpp, main_repeater.cpp, main_room_server.cpp,
main_observer.cpp) each gained a zephcore_led_set_brightness_pct() call
seeding the RAM cache from the persisted value, mirroring the existing
leds_radio_mode/leds_hb_mode lines right next to them.

Verified building for heltec_t096/nrf52840 (companion) and rak3401_1watt
(repeater), the two roles/datastores touched by this change.
2026-09-28 22:01:08 +02:00

53 lines
1.9 KiB
C

/*
* ZephCore - apply persisted prefs to hardware at boot
* Copyright (c) 2025 ZephCore
* SPDX-License-Identifier: MIT
*
* Shared by the repeater, room server and observer mains. Header-only so it
* logs under the including file's log module.
*/
#ifndef ZEPHCORE_BOOT_PREFS_H
#define ZEPHCORE_BOOT_PREFS_H
#include <zephyr/logging/log.h>
#include <helpers/NodePrefs.h>
#include "led_gate.h"
#include "ZephyrGPSManager.h"
/* Push the prefs that drive hardware directly (LED gate, GPS duty) into their
* managers. Ordering is load-bearing:
* - after loadPrefs(): before it the struct still holds the initNodePrefs()
* defaults (leds on, gps_interval=300, the companion value). On
* repeater/room server loadPrefs() is also where the 48 h GPS default is
* set and persisted. Calling this too early is the bug class where CLI
* readback is correct and the hardware disagrees.
* - after ui_init(), so the heartbeat cycle exists to be stopped.
* - after the GPS fix/event callbacks are registered, because
* gps_enable() starts acquisition immediately.
* gps_time_sync: put GPS in repeater (time-sync-only) mode and apply
* prefs.gps_enabled, as upstream's applyGpsPrefs(). Only roles that own the
* GPS pass true. */
static inline void apply_boot_prefs(const NodePrefs *p, bool gps_time_sync)
{
bool leds_off = p->leds_disabled != 0;
zephcore_leds_set_disabled(leds_off);
zephcore_leds_set_radio_mode(p->leds_radio_mode);
zephcore_leds_set_hb_mode(p->leds_hb_mode);
zephcore_led_set_brightness_pct(p->led_brightness);
LOG_INF("LEDs: %s (from prefs)", leds_off ? "disabled" : "enabled");
if (gps_time_sync && gps_is_available()) {
gps_set_poll_interval_sec(p->gps_interval);
gps_set_repeater_mode(true);
if (p->gps_enabled) {
gps_enable(true);
} else {
gps_ensure_power_state(false);
}
}
}
#endif /* ZEPHCORE_BOOT_PREFS_H */