feat(ui-lvgl): quick panel from the status bar; L2 fixes from rc1

The quick panel, as a phone's: pulled down from the status bar (or a tap
on it). Bluetooth, WiFi, GPS, sound, trail and live share switch at a
tap; Advert opens the advert popup (moved here from the Nodes header);
Lock locks the screen; a brightness slider. Holding a tile opens its
settings. Lock and sun glyphs added to the fonts.

Fixes from rc1 testing on the L2:
- GPS status icon: none when GPS is off (the module kept its last fix
  valid, so it stayed green); grey on, green with a fix. ensureGps()
  turns GPS on before trusting that stale fix.
- Screen wake: the panel wakes dark, a frame is drawn, then the
  backlight fades in -- no white flash. Off fades out first.
- Power off / flat battery: the chip wakes every 30 s to look for USB
  power and starts when plugged in (it slept with no wake source before,
  until the reset button). Plugged in when switched off: stays off until
  re-plugged.
- Message ages in a conversation refresh every 2 s, as on ui-new; the
  message popup keeps its age, repeaters heard and delivery up to date.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-10-05 09:10:06 +02:00
co-authored by Claude Opus 5.5
parent d66f04ba94
commit b5e4845dae
17 changed files with 940 additions and 333 deletions
@@ -108,7 +108,43 @@ bool WioTrackerL2Board::initExpander() {
return true;
}
// Off -- Power off, or the battery ran down -- the chip sleeps, waking every
// OFF_POLL_SECS to look for USB power plugged in, and starts when it is: as
// an nRF board starts on its own once charged (a deep sleep with no wake
// source left it off until the reset button). Plugged in when switched off,
// it stays off until the cable is pulled and plugged in again. A look costs
// a boot as far as begin(), a fraction of a second.
static const uint32_t OFF_MAGIC = 0x4F464621; // "OFF!"
static const uint32_t OFF_POLL_SECS = 30;
RTC_NOINIT_ATTR static uint32_t s_off_magic;
RTC_NOINIT_ATTR static uint32_t s_off_vbus; // USB power at the last look
void WioTrackerL2Board::powerOff() {
s_off_vbus = isExternalPowered();
s_off_magic = OFF_MAGIC;
enterDeepSleep(OFF_POLL_SECS);
}
// Off and woken by the timer (or a brown-out of the flat battery): back to
// sleep unless USB power has come since the last look.
static void stayOffUnlessPlugged(WioTrackerL2Board& b) {
const esp_reset_reason_t r = esp_reset_reason();
if (s_off_magic != OFF_MAGIC || (r != ESP_RST_DEEPSLEEP && r != ESP_RST_BROWNOUT)) {
s_off_magic = 0;
return;
}
Wire.begin(PIN_BOARD_SDA, PIN_BOARD_SCL);
const bool vbus = b.isExternalPowered();
if (vbus && !s_off_vbus) { s_off_magic = 0; return; } // plugged in: start
s_off_vbus = vbus;
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
esp_sleep_enable_timer_wakeup(OFF_POLL_SECS * 1000000ULL);
esp_deep_sleep_start();
}
void WioTrackerL2Board::begin() {
stayOffUnlessPlugged(*this); // first: before the 3 s wait for a serial monitor below
// GNSS UART: NMEA arrives at ~500 B/s and the main loop can stall for
// hundreds of ms on SD tile decodes; the 256-byte default overflowed
Serial1.setRxBufferSize(1024);