feat(l2,core): battery curve editor and an L2 feedback round

- Battery curve: NodePrefs batt_curve_mv[11] (voltage at 0..100 %, all
  zeros = built-in LiPo curve, sentinel 0xC0DE0032). ui-core/Battery.h
  uses it for every percentage. L1: Settings > System > Batt curve list
  (Left/Right 10 mV, Reset); L2: Settings > Power > Battery curve chart
  with draggable points and a line at the cell's voltage.
- L2: the Nodes map is the full navigation map plus the nodes, Back
  returns to Nodes; the favourite button is lit while it is one; pinning
  to the Home dial uses a thumbtack (fonts regenerated); minimap dots
  follow the accent; arranging tiles shows where they land while dragging;
  emoji row in Diagnostics > Font.
- Sim hooks: sim_open nodesmap / accent@N / homeedit / battcurve.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-10-02 11:25:58 +02:00
co-authored by Claude Opus 5.5
parent 1166ea8dde
commit 61c75946f6
21 changed files with 702 additions and 227 deletions
+11 -2
View File
@@ -556,6 +556,13 @@ struct NodePrefs { // persisted to file
uint8_t lock_screen_password[LOCK_HASH_LEN];
uint8_t lock_screen_password_salt[LOCK_SALT_LEN];
// ── Battery curve (0xC0DE0032) ─────────────────────────────────────────
// The cell voltage (mV) at 0, 10, ... 100 %, for the battery percentage
// (ui-core/Battery.h). All zeros = the built-in LiPo curve. Settings >
// Battery curve edits it; anything not rising point to point reads as unset.
static const uint8_t BATT_CURVE_PTS = 11;
uint16_t batt_curve_mv[BATT_CURVE_PTS];
// Single source of truth for the live-share option tables (shared by the Map
// UI labels and the auto-send engine in UITask).
static const uint8_t LOC_SHARE_MOVE_COUNT = 4;
@@ -643,7 +650,7 @@ struct NodePrefs { // persisted to file
// repeat_* fields) instead of at the tail, which shifted every field after
// them by 25 bytes when loading an older file. Never released, but a dev
// build wrote it, so the number must not be reused for anything else.
static const uint32_t SCHEMA_SENTINEL = 0xC0DE0031;
static const uint32_t SCHEMA_SENTINEL = 0xC0DE0032;
// Bit-index for each home page. Used by page_order (entries store bit+1) and
// by home_pages_mask. Single source of truth — both HomeScreen::pageBit/bitToPage
@@ -828,7 +835,9 @@ static inline bool inQuietHours(const NodePrefs& p, uint32_t utc) {
// to buzzer_auto, rounded up to the alignment) -- sizeof 2832, confirmed via real
// WioTrackerL1_companion_solo_dual (nRF52/ARM) and L2 (ESP32) builds.
// lock_screen_password / _salt (0xC0DE0031) added 48 bytes -- sizeof 2880.
static_assert(sizeof(NodePrefs) == 2880,
// batt_curve_mv[11] (0xC0DE0032) added 16 bytes, not 22 (6 went into tail
// padding) -- sizeof 2896, confirmed via real L1 (nRF52) and L2 (ESP32) builds.
static_assert(sizeof(NodePrefs) == 2896,
"NodePrefs layout changed — sync DataStore save/load + clamp, bump "
"SCHEMA_SENTINEL, then update this size (see steps above).");