- A restart between commitTempFile()'s remove and rename left only the .tmp;
loads now recover it (prefs, contacts, channels, scopes).
- CustomLR1121Wrapper lacked readLiveRSSI/readLiveSNR: LR1121 boards didn't
compile.
- The repeater and room server sims gain DynamicConfigSerializer.cpp and
CommonRadioPrefs.cpp (broken since the v1.18 merge).
- Comments still describing the removed DualSerialInterface.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- DisplayDriver takes ColorVal; each driver's .cpp defines the UIColor roles
(window_bkg, primary_txt, ...) in its own values. ui-new draws in two:
window_bkg and primary_txt. OLED and e-ink look as before (sim screens
pixel-identical).
- E213, E290, LGFX, Null, ST7735, ST7789LCD, U8g2 taken whole from upstream
(with them the rewritten ST7735 driver and the Heltec V4 R8 TFT display).
- SH1106, SSD1306, ST7789, EinkGfxDisplay and the sim drivers converted.
- ui-orig, ui-tiny, simple_* get upstream's colour roles; the repeater's UI
taken from upstream (its power-off screen).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Bluetooth + USB (+ WiFi/Ethernet/UART per build) in one interface_manager,
as upstream; frames go to every enabled link, USB is read while BT is
connected. DUAL_SERIAL now means ENABLE_USB_INTERFACE.
- WiFi interface with upstream's wifi_* prefs and set/get wifi.* CLI.
- isClientConnected moved into ArduinoSerialInterface (DTR on nRF52 and
ESP32 native CDC).
- UI uses isBluetoothEnabled/enableBluetooth/disableBluetooth; turning BT
off leaves USB and the other links on.
- DualSerialInterface removed.
- Sim build gains DynamicConfigSerializer.cpp (broken since bd64c203).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes and features from upstream: MACThenDecrypt / command buffer
overflow fixes, ACK forwarding delay, transport code 0 as unscoped,
hidden nodes don't answer DISCOVER, LR2021/LR1121 fixes, GPS cold-start
detection and waitFor()/drain(), NMEA fix-age counters, ESP32 RTC after a
crash, remote CLI by text message (TXT_TYPE_CLI_COMMAND),
PUSH_CODE_BINARY_RESPONSE, board.loop(), new boards (Wio Tracker L1 1W,
ThinkNode M4/M8, Muzi Base, Waveshare LR1121, Pico W).
Kept ours: NodePrefs, main.cpp, every UI, GxEPDDisplay. The companion CLI
stays MyMeshCli.h's handleCliCommand(); upstream's handleCommand() calls
it. The board's FEM gains go through attachDynamicPrefs() with an adapter
over our NodePrefs fields. Upstream's JSON prefs and MultiSerialInterface
come as their own stages.
Also: the display defaults were inside RADIO_FEM_TXGAIN's #else (a
missing #endif).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ESP32-S3FH4R2 (4MB flash, 2MB PSRAM, native USB-CDC) with an LR1121.
Pins, the DIO5/DIO6 RF switch table and the 1.8 V TCXO follow the HF
schematic and Waveshare's examples. Envs: repeater, room server,
companion USB/BLE and KISS modem, all on min_spiffs so roles share one
partition layout.
Only RFO_HP_LF is wired (R4 on RFO_LP_LF is not fitted), so the new
opt-in LR1121_FORCE_HP_PA flag keeps RadioLib on the HP PA at <= 14 dBm,
where it would otherwise select the unconnected LP PA.
- A pending DM shows a dot per send, as on the L1. The thread is read from
the SD archive, which a resend never updated: it does now, and the
thread's signature and patch state count the attempt.
- Nearby redraws when a node goes live, changes type or the units change;
the scan popup when a name or the remote SNR arrives.
- The user LED is active high: it was lit all the time and went dark
while transmitting.
- Sim hooks "dm" and "send" for testing a DM thread.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
Docs: the E-ink section describes the landscape and portrait builds, what
the tall screens add, and the settings, with three screenshots; the e-ink
build flags; the release file names. Sim: each orientation gets its own
factory, so a page can load both, and simEinkScale 0 leaves the canvas'
CSS size to the page. CI builds both into solo-sim-wasm.zip (wasm/eink/).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SIM_EINK=landscape|portrait builds the e-ink firmware for the browser,
drawn by the same EinkGfxDisplay as the panel. index.html and mesh.html
pick a build from the URL. The simulated sensors get a GPS switch, so the
UI's GPS toggle works.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DisplayDriver gains slideBegin()/slideCompose(): the driver keeps the frame
on screen and, in the next one, moves it out while the new rows follow.
SH1106 does it on its 1 KB buffer (+1 KB RAM for the copy), the sim on its
canvas; drivers that can't read their frame back keep cutting over (e-ink).
Home slides the content below the page-icon row in 220 ms with an ease-out
(the whole screen to and from the header-less clock), and the current-page
pill glides between icons.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The panel takes each 24-line band by DMA while LVGL draws the next one
into the other buffer (two 15 KB buffers in internal RAM; LovyanGFX's
4092-byte DMA descriptors leave PSRAM unaligned for the S3's DMA, which
showed as shifted and smeared bands). LVGL draws in the panel's byte
order, and so do map tiles and the frozen screen under a popup, so
nothing is swapped on the way out. Full frames ~10-25% faster (page1
19.9 -> 14.7 ms, Home 21.4 -> 18.2 ms). Without the internal RAM the
screen is sent as before. The arduino2 env keeps the old way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Trail on the L2: 32768 points every 5 m, no simplification, no point
spacing setting; copied to the card every minute and restored at power-on.
The line keeps up with the position dot (incremental sync, pending point).
Map: a tap's finger jitter no longer turns follow off; the GPS button
shows when the map follows. The trail is drawn as one polyline with
breaks and off-view chunks skipped (an lv_line queued a draw task per
point).
Fewer rebuilds: conversation bubbles patched (new messages, delivery
marks), home mini-map dots reused, Nearby rows rewritten in place,
history read in runs and each file opened once.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- CPU at 80 MHz with the screen on after 2 s without touch or animation;
a touch restores the full clock before its frame is drawn
- setText(): periodic refreshes no longer redraw unchanged labels
(status bar, Home, lock, Diag, GPS, compass, clock, map, nav, nearby)
- map markers kept across the 3 s rebuild when unchanged
- app connected: the loop blocks until a BLE frame arrives
(serialFrameArrived / hasPendingFrames) instead of polling every 2 ms
- PSRAM: boot frame sprite and the HTTP response buffer released
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- build-solo-sim.yml clones LVGL at the version pinned in
solo/wio-tracker-l2/platformio.ini and builds the SIM_UI=lvgl sim into
wasm/lvgl/ of solo-sim-wasm.zip, for the site's device switch.
- build_wasm.sh: LVGL_DIR can be overridden (CI has no .pio libdeps).
- sim_test_set_node_name(): names a sim node, for site screenshots.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Dead code gone: anim::fadeHide, radioctl::presetCount, the L2 board's
setSdPower / setGrovePower / expanderOK (awRead, gnssReset now private).
- buttonBar() / barButton() replace 7 copies of the popup button row.
- confirmBody(): one red-button confirm for reboot / power off, reset
counters, admin commands, preset and scope delete.
- tapConfirmed(): the 11 "tap again" buttons share one mechanism, 3 s
everywhere, the label restored when left alone.
- noteLabel() for ~30 wrapped notes.
- localTm() in NodePrefs.h and one MONTHS table: lvgl, MsgExpand, the L1
clock and lock screen.
- The sim keeps UI settings in an in-memory nvs::, so one set of load /
save helpers serves both.
- Asleep, the loop wakes every 50 ms (the button / touch poll), not 20.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two views, swapped with left / right: a polar sky plot (filled = used in the
fix, hollow = tracked, a pixel = no signal) beside fix, used / in view, HDOP,
PDOP and time to first fix; and a signal bar per satellite (used first, a
dotted 30 dB-Hz line) under per-constellation counts. The GPS stays awake
while it's open. Data from GpsSky (-D GPS_SKYVIEW, now on the L1 solo build).
The simulator's made-up sky moves from the L2's GpsScreen into
helpers/sensors/GpsSkySim.h, so both sims show it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Side button held + top button saves the screen, popups and toasts included,
to /sdcard/screenshots/scr_NNNN.bmp (24-bit BMP). The flush callbacks copy
one forced full re-render into a PSRAM buffer. A white flash and a toast
confirm it. The side button's mute now fires on release, so holding it a
little long before the top button doesn't also mute. In the sim, the page's
Screenshot button downloads the file.
- The lock screen goes dark after 30 s even with auto-off at Never (a boot
PIN, a pocket wake-up, a message), and sooner if auto-off is shorter.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The triangle draw descriptor's colour fields lost their bg_ prefix and style
getters take an lv_part_t. 9.6 sizes flex containers through the layout, so
popups no longer shrink when pulled past their end: lvgl_patches.py goes.
The sim wipes its LVGL object cache when the library version changes.
Flash +73 KB.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LVGL 9.2.2 measures a SIZE_CONTENT box from its children as scrolled, so an
elastic pull past the end of a capped popup list shrank it by the overshoot,
again on every pull. lvgl_patches.py fixes calc_content_height in the
downloaded library (a build middleware for PlatformIO, called directly by the
sim's build_wasm.sh).
The five popups that each built the same panel now share popupOpen() (fit to
content / full height / under the status bar).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- BLE (ESP32): fast advertising (20-30 ms) for 30 s, then 152.5 ms, as the
nRF52 interface; the library default kept 30-60 ms forever
- Live map tiles: the WiFi drops after a minute with nothing missing
- ES8311 to standby while the I2S clocks are off, set up again before the
amp comes on
- Buzzer: no channel (DMA out of memory) waits out the samples instead of
spinning above the UI loop
- OTA: the image header check waits for its 16 bytes
- Comments: P10 is just the LED; the LCD SPI clock is 40 MHz on the wire
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The LoRa noise floor with the board's parts off one at a time, sweeps of
850-930 MHz, the mesh channel and a 7.8 kHz zoom on its loudest point; a
slow cycle of the same states for a second radio beside the device; and
a spike hunt over 864-876 MHz listing the lines over the floor and their
spacing (how the I2S MCLK comb was found).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The speaker's I2S channel was only disabled when idle, which leaves MCLK
running. Its fractional divider (160 MHz / 39 1/16 = 4.096 MHz) makes a
comb of lines every 256 kHz: one at 869.632 MHz, in the EU narrow mesh
channel, lifted the LoRa noise floor from ~-102 to ~-85 dBm, and others
land near GPS L1 and BeiDou B1. The channel is now deleted and its pins
held low after each sound, and made again for the next one. Measured:
noise floor -102 dBm, outdoor first fix 87 s (was 620 s and more).
Also: TCXO at 3.0 V (the L2's part, as Meshtastic has it); GLONASS
enabled on the L76K after each power-up; begin() on a running receiver
no longer resets it (a reset threw away the acquisition in progress).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Power: the UI loop sleeps until something is due (never with packets
queued); screen off puts the CPU at 80 MHz, the GT911 to sleep (unless a
tap wakes the screen) and the LP5814 in standby. GPS off now cuts the
L76K's rail and UART on the L2 (L2GpsProvider). The battery divider is
powered only for a reading (measured: settles at once); readings within
2 s are reused. The SD mount is retried at most every 5 s.
Fixes: WiFi left on after leaving a scan, live tiles' WiFi kept with the
screen off on the map, an ADC read every second for the status bar, touch
polled on every pass while dark, a scan cutting an update's WiFi, relay
count not refreshing in a channel thread, raw @[nick] in room previews.
Labels skip unchanged text (no redraw).
Helpers: scrollList, dimOverlay, settingRow, flexBox, nvs::get/put,
trailFilePath (a second save in the same minute no longer overwrites),
unreadTotal. Dead code removed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The AW35615 USB-C controller (FUSB302-style registers, ID 0x91) only
reports VBUSOK with its measure block on; POWER resets to bandgap only,
so isExternalPowered() was always false. Board init turns it on
- Status bar shows a charge bolt on the cable, Diagnostics > Live has a
Power row, the GPS screen notes that charging disturbs GPS, and the
low-battery warning is skipped on USB as intended
- Roadmap: USB detection closed; GPS indoors still worse than the L1
even on battery, left open for later
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>