Commit Graph
4187 Commits
Author SHA1 Message Date
JakubandClaude Opus 5.5 247fab08d0 perf(l2): map tiles decode on the other core
- TileCache: request() hands z/x/y to a task on core 0, which renders into
  a spare buffer; poll() swaps it into the LRU slot (stale results dropped
  after drop()/invalidate()); the sim runs the job at once
- MapScreen / Home map place finished tiles as they arrive; the longest
  UI stall with the map opening goes from ~340 to ~170 ms
- LVGL allocates from the PSRAM heap (lv_mem_psram.h), safe from both
  tasks; LVGL's own pool is gone
- lv_conf: notes why LV_OS_FREERTOS with two draw units stays off
  (measured slower: drawing is bound by PSRAM bandwidth)
- UI_PERF_TEST: the map (tile read/decode, pan, redraw), build time and
  the longest loop pass per screen

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:24:57 +02:00
JakubandClaude Opus 5.5 b3b77a1f6d feat(l2): long trails with a card copy; map follow and redraw fixes
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>
2026-09-29 22:02:49 +02:00
JakubandClaude Opus 5.5 5f6cbe34b3 fix(ui-lvgl): tile downloads ride out server errors instead of stopping
503/429 slow the pace down, transport errors retry after 2/8/30 s, failed
tiles get a second pass; the download only gives up after 10 minutes
without a single tile or on repeated 403s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 22:02:49 +02:00
JakubandClaude Opus 5.5 9938ae7a2d chore(ui-lvgl): comments name the real Settings pages
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 13:27:34 +02:00
JakubandClaude Opus 5.5 69c1418e17 docs(solo): USB tools and L2 screenshot notes; Units in the L2 settings list
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 12:39:33 +02:00
JakubandClaude Opus 5.5 e4d24650c5 feat(l2): screenshots over USB (RGB565); USB tools moved to the Solo site
- CMD_GET_SCREENSHOT on colour screens: display type 2 (RGB565 LE),
  32-bit payload size; ui-lvgl captureFrame() shared with the SD BMP
- ENABLE_SCREENSHOT in the L2 build; tools/screenshot.py decodes type 2
- docs and READMEs point to solo.marekzegarek.com/#pc-tools
- USB popup: "Keep card" instead of "Charge only" (only the card is lent;
  charging and USB serial work either way)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 12:27:59 +02:00
JakubandClaude Opus 5.5 4ab9d949ec perf(ui-lvgl): lower clock when idle, fewer redraws, wake on BLE frames
- 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>
2026-09-29 11:51:18 +02:00
JakubandClaude Opus 5.5 bc266a4f5c fix(ui-lvgl): smooth WiFi/Bluetooth switches; retry 404 tiles
- The WiFi and Bluetooth rows rebuilt the whole Settings page to update
  their hint, cutting the switch's animation short; the hint is now
  rewritten in place (rowHintSet). The "Bluetooth on" echo toast is gone.
- Map download: a 404 gets the same one retry as other errors
  (OpenTopoMap sends the odd 404 for a tile not rendered yet), and a
  download that ends with gaps says "Done, N missing - download again".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 10:41:18 +02:00
JakubandClaude Opus 5.5 890ee6533e build(sim): colour-touch (ui-lvgl) WASM in the solo-sim release zip
- 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>
2026-09-29 10:18:39 +02:00
JakubandClaude Opus 5.5 e822242660 docs: stage I3 -- documentation rewritten under docs/solo
Short pages by feature (getting started, messages, contacts, navigation,
tools, settings, lock, hardware) instead of one page per OLED screen, with
Wio Tracker L2 differences as notes; facts checked against the code
(keyboard scripts vs. hold-for-accents, {batt}/{dist}, L2 limits and
settings layout). Developer guides and build flags under docs/solo/developer.
Old docs/solo_features and its ~50 screenshots removed; a hero banner and
three simulator screenshots added; links updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 08:41:10 +02:00
JakubandClaude Opus 5.5 3adf0b0436 chore: stage I1 -- repo cleanup, minimal README
Working plans (docs/development, docs/design redesign notes) removed; the
two developer guides moved to docs/developer/. README cut to devices,
flashing, links and building (Wio Tracker L2 added); its feature list and
doc tables moved to docs/solo_features/README.md. RELEASE.md describes the
Solo release flow. Upstream's GitHub Pages workflow (docs.meshcore.io)
dropped, CLAUDE.md untracked, Buy Me a Coffee back in FUNDING.yml.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 07:36:15 +02:00
JakubandClaude Opus 5.5 b09a9d4082 docs: plan-next -- stage E (OTA) tested
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 07:20:57 +02:00
JakubandClaude Opus 5.5 6164526057 docs: plan-next -- stage H ticked
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dev-ota-test
2026-09-29 00:41:05 +02:00
JakubandClaude Opus 5.5 7826360d13 build(solo): offline queue 128 on the nRF52 builds
The phone app's offline queue took 256 x 177 B = 45 KB, which with the
on-device UI left the L1 ~5 KB of heap from boot (the sign buffer of #38
never fit). The UI keeps its own message history, and a full queue drops
the oldest channel messages first, so 128 is plenty: the L1 heap now has
~27 KB free. L1 OLED / e-ink, ProMicro, T-Echo Lite, both GAT562; the
upstream variants/ are unchanged (build_unflags in solo/).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 00:29:22 +02:00
JakubandClaude Opus 5.5 e28b5c5c51 fix(ui-lvgl): no USB drive behind the screen PIN; drop the NVS PIN migration
The SD card (message history) could be lent to a computer from the lock
card before the PIN was entered. While locked with a PIN, usbPoll() no
longer reacts; a cable plugged in meanwhile is offered once unlocked.

The plain-text NVS PIN never shipped, so there's nothing to migrate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 00:13:33 +02:00
JakubandClaude Opus 5.5 4bda4f3a76 fix(ui-new): keyboard letters were blank
Since bf1e6fca kbApplyCapsUtf8 wanted 4 bytes free before each codepoint;
the ABC grid passes a 3-byte cell buffer, so every cell came out empty (T9
and CardKB Compact draw no such cells, so it went unnoticed). A codepoint
is now copied when it fits with the NUL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 00:06:01 +02:00
JakubandClaude Opus 5.5 358f92222a Merge PR #37: lock screen PIN (3urobeat), adapted
The contributor's feature -- a PIN asked before the screen unlocks, on
boot, and when the magnet cover opens, stored as a salted SHA-256 -- on
top of this branch, with:

- ui-core/ScreenLock.h: set / check / isSet and the tries limit, shared by
  L1 and L2. isSet looks at every byte (the PR tested only the first, so one
  PIN in 256 silently disabled the lock). 5 misses pause entry for 30 s.
- NodePrefs: the fields at the tail after quiet hours, sentinel 0xC0DE0031,
  sizeof 2880; an older file's bytes there are cleared. A sentinel bump no
  longer resets display_brightness_pct from a file that already has it.
- DataStore: no AGPL header (the project is MIT), no whitespace churn.
- Keyboard: the number pad is a widget flag (pin_mode) with a prompt in the
  preview ("New PIN", "Again", "PIN"), not keyboard_type = 2 written into the
  prefs and restored after.
- L1 Settings: "Lock PIN" right after the schema's "Lock screen" row, typed
  twice, at least 4 characters, saved at once (a power-off right after
  setting it kept no PIN). Home is told about a boot-time lock once it
  exists (also fixes booting with the cover closed).
- L2: the screen PIN moves from plain text in NVS to the same hash in
  NodePrefs; the old one is migrated on first boot and removed. The pad
  unlocks as soon as the hash matches from 4 digits on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 00:06:01 +02:00
JakubandClaude Opus 5.5 0e1b3c9cfd fix(companion): signing takes the buffer it can get (#38)
CMD_SIGN_START promised the app 8K before a malloc it never checked. On
the L1 the nRF52 heap has ~5K free from boot, so the malloc always failed
and every CMD_SIGN_DATA answered ERR_CODE_BAD_STATE. Now it allocates
first, halving down to 256 B, and reports the size it got; nothing at all
is an error on SIGN_START itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 23:34:29 +02:00
JakubandClaude Opus 5.5 b355922d32 feat(companion): core parity -- L1 sends via the core, shared telemetry, schema settings on L1
- L1's MessagesScreen sends through UiCore::sendDirectText / sendChannelText
  (its own copy of send + file + ACK tracking gone).
- ui-core/Telemetry.h: the dashboard fields (numbers, names, formats) and
  sensor readings as text, each frontend passing its Style; L2 Home, L1's
  clock page, lock screen, sensors page and GPS altitude use it.
- L2: the side button held in the first 8 s is the CLI rescue, as on L1.
- L1's repeater radio goes through rptctl.
- L1 Settings are built from SettingsSchema: short labels for small
  screens, SCHEMA_* placeholders expand to the schema's sections, one
  generic row (switch ON/OFF, bars for brightness / volume). 20 hand-written
  rows and their tables gone; L1 implements applyDisplayPrefs /
  applySoundPrefs. settings::text / step / indexOf shared with L2.
- Schema: auto-off gains 5 s; the advert sound scope reads "Direct".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 23:19:47 +02:00
JakubandClaude Opus 5.5 0a669e1fd7 docs: plan-next -- stage F ticked
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 22:35:32 +02:00
JakubandClaude Opus 5.5 ece849db3b refactor(ui-lvgl): review -- shared button bar, confirms, notes, local time
- 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>
2026-09-28 22:35:26 +02:00
JakubandClaude Opus 5.5 1def29335c feat(companion): quiet hours -- muted on a schedule, the alarm still rings
Settings > Sound > Quiet hours (L2: its own group; L1: Quiet hrs / from /
until): from quiet_from to quiet_to (local hours, wrapping past midnight)
the buzzer is muted and a message doesn't wake the screen; the clock alarm
still rings. A manual mute or unmute inside the window stands until the
window ends. Off with the clock unset.

NodePrefs gains quiet_hours / quiet_from / quiet_to (appended to the file,
sentinel 0xC0DE0030; sizeof 2832 on nRF52 and ESP32), off by default,
22:00-07:00. hourInWindow() / localHour() are shared with the bot's quiet
hours. soundctl::tick() replaces autoTick() (Auto and quiet hours).

Also fixes the L2 side-button mute: it went by the mode, not by whether
the buzzer was muted, so with Auto + an app connected (and now quiet hours)
the first press muted instead of unmuting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 21:59:40 +02:00
JakubandClaude Opus 5.5 2e9654fd1c refactor(ui-lvgl): Diagnostics > Noise is one measurement for any board
The Noise tab held the L2's interference hunt: parts of the board off one
by one, a slow cycle for a second radio, a spike hunt and three sweeps
(~90 s, L2 only). It is now one Measure: the noise floor on the mesh
frequency (median and 10th percentile of 5 s) and a +-1.1 MHz sweep round
it, ~12 s, with a short legend for reading it. Works wherever the variant
defines the radio.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 21:41:16 +02:00
JakubandClaude Opus 5.5 e47738ce01 feat(ui-lvgl): map tools regrouped; a map area previews when picked
Map tools: TRAIL, LIVE SHARE and ARRIVAL ALERT each with their own options
page (that section of Map options; back returns to Map tools), the arrival
alert switch where its state is shown, OFFLINE MAPS (Map areas, Live
tiles; the separate Download an area is gone -- a running or unfinished
download shows at the top of Map areas) and LAYERS.

Map areas: picking one frames it on the map above a small sheet (no Show
button, the map above isn't dimmed); closing the sheet, however it's
closed, puts the map back where it was and drops the outline -- it used
to stay on the map. New popup kind POP_BOTTOM.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 21:30:46 +02:00
JakubandClaude Opus 5.5 a11df8431b fix(ui-lvgl): 16 KB UI stack (screenshots reset the device); USB popup after the splash
The UI runs on Arduino's loop task, whose stock 8 KB stack had 340 B left
at its deepest point; a screenshot's file write went past it and reset the
device. The loop stack is now 16 KB (measured peak ~7.8 KB) and the
screenshot's line buffer is static. Diagnostics names the row
"UI stack free (lowest)".

With a cable in at boot, the USB popup waited for nothing and showed over
the splash; it now comes once the splash has faded.

Adds docs/development/plan-next.md, the plan up to the merge into dev.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 21:30:46 +02:00
JakubandClaude Opus 5.5 7a21e58c54 feat(ui-lvgl): arrange Home's apps -- drag to move, tap to hide
Hold an app on Home (or Settings > Home apps) to arrange them: every app
is shown, hidden ones dimmed with a +; a drag drops the app into the slot
under the finger, held at a screen edge it goes to that page; a tap hides
or shows it. Settings stays shown. The order is kept in NVS (letters per
app, lower case = hidden), saved on Done or on leaving Home.

Roadmap: note the speaker-knock experiment (DAC ramp didn't help).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 18:29:00 +02:00
JakubandClaude Opus 5.5 51530ac451 feat(ui-lvgl): SD card as a USB drive, message banner, card format, restart screen
- USB through TinyUSB (ARDUINO_USB_MODE=0) instead of USB-Serial/JTAG: the
  serial port stays, and plugged into a computer (enumerated, the bus not
  suspended -- on battery an unplug only shows as a suspend) the device asks
  "Charge only / USB drive". As a drive the firmware lets go of the card and
  the computer gets its sectors; ejected or unplugged, the device restarts.
- Incoming messages: a banner slides down from under the status bar (icon,
  sender or channel, two lines of the text from history); a tap opens the
  conversation (not while locked), a swipe up dismisses it, not shown for
  the conversation already open. Toasts moved up there too, under the banner
  when both are up; the ones only echoing a switch or a choice are gone.
- Storage > Format card: a popup saying what goes, then Format tapped twice;
  one FAT32 volume over the whole card (readable or not), then a restart.
- A deliberate restart shows a full "Restarting..." screen with the reason
  instead of the screen just freezing.
- The screenshot flash is a thin frame round the edges: a full-screen fade
  redrew all 320x240 each step and tore.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 17:17:38 +02:00
JakubandClaude Opus 5.5 95c4c093f0 feat(ui-new): Tools > Satellites -- sky plot and signal bars on the 128x64 OLED
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>
2026-09-28 16:33:41 +02:00
JakubandClaude Opus 5.5 e82cedaf23 feat(ui-lvgl): several saved WiFi networks, joined by signal; Save checks the password
- Settings > WiFi keeps up to 8 networks (NVS "s0".."s7" / "p0".."p7"; the
  single one older builds saved moves over). A tap loads one to change its
  password, Forget asks with a second tap, a scan marks the known ones.
- Map downloads, live tiles and updates join the strongest saved network in
  range (a short scan first when more than one is saved), else the newest
  one -- which also covers a hidden network.
- Save joins the network once: "password OK", turned away (forgotten again,
  the form keeps it to fix) or not in range (kept, checked later).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 16:24:10 +02:00
JakubandClaude Opus 5.5 2765ac6d8b feat(ui-lvgl): screenshots (side + top button), lock screen always times out
- 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>
2026-09-28 16:03:48 +02:00
JakubandClaude Opus 5.5 cf9ffc29b0 feat(wio-tracker-l2): internal flash as LittleFS instead of SPIFFS
helpers/esp32/InternalFS.h picks the filesystem: -D ESP32_LITTLEFS mounts
LittleFS on the same "spiffs" partition, otherwise SPIFFS as before. Only the
L2 LVGL envs set it; every other ESP32 board is unchanged. A settings save
drops from ~0.5 s to ~80 ms and the files survive power loss mid-write.
No migration: the first boot formats the partition (fresh identity).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 15:47:57 +02:00
JakubandClaude Opus 5.5 063f81e1df perf(ui-lvgl): save settings on leaving the screen, not on every toggle
Every toggle / stepper wrote the prefs file straight away (0.1-0.6 s on the
ESP32's SPIFFS), which stuttered the UI and wore the flash. prefsSave() now
only marks them dirty; they're written once when the screen is left, when the
display goes off, or after 60 s at the latest -- the L1's approach. Shutdown
and the pre-restart OTA save still write immediately.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 15:47:57 +02:00
JakubandClaude Opus 5.5 350393436a feat(ui-lvgl): AM / PM beside the big clock on a 12-hour clock
It was a muted prefix on the date line, easy to miss. clockFace() -- the
digits and a small AM / PM on their baseline -- is shared by Home and both
lock screens (the PIN card showed no AM / PM at all). The date loses the
prefix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 15:19:10 +02:00
JakubandClaude Opus 5.5 ed5c903c3b build(wio-tracker-l2): LVGL 9.2.2 -> 9.6.0
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>
2026-09-28 15:06:23 +02:00
JakubandClaude Opus 5.5 4d6e9ad20e fix(esp32-ble): stay findable after a NimBLE host reset or a link that never pairs
While nothing is connected, every 5 s: if advertising has stopped (a host
reset ends it with no disconnect to restart it), start it again. A link up
for 60 s without pairing is dropped, so advertising comes back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 14:52:43 +02:00
JakubandClaude Opus 5.5 9d4f018696 fix(ui-lvgl): popups no longer shrink when their list is pulled past its end
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>
2026-09-28 14:45:19 +02:00
JakubandClaude Opus 5.5 ff6354fd05 docs(l2-roadmap): L1 LVGL spike results -- doesn't fit the nRF52's RAM
The spike (a throwaway ui-oled frontend, not kept) ran in the simulator but
never got past building its screens on the L1: LVGL's pool and stack sit
outside the heap and UiCore needs 27 KB of it in one piece. Flash was fine.
Decision: no LVGL on the nRF52 boards; the v2 look goes into ui-new.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 14:14:33 +02:00
JakubandClaude Opus 5.5 4431d754a2 fix(ui-lvgl): drop the GPS screen's USB-charging warning
The GPS trouble on the cable was the I2S MCLK comb (fixed in b50ecc83):
fix times match with and without USB now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 14:20:49 +02:00
JakubandClaude Opus 5.5 958627d6e9 fix(wio-tracker-l2): radios and codec idle when unused; buzzer and OTA fixes
- 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>
2026-09-27 14:13:39 +02:00
JakubandClaude Opus 5.5 782f8aa567 feat(ui-lvgl): Diagnostics > Noise tab for RF noise hunting
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>
2026-09-27 13:54:25 +02:00
JakubandClaude Opus 5.5 b50ecc83d5 fix(wio-tracker-l2): stop the I2S clock between sounds; GPS and TCXO fixes
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>
2026-09-27 13:54:25 +02:00
JakubandClaude Opus 5.5 002f478231 feat(ui-lvgl): vector region packs, PBF input, region list
One .vpk file per region in /vmap (header, sorted index of tiles and
points, then the data), read in place with the index in PSRAM; loose
{dz}/{x}/{y}.vt/.vp files still work. osm_vector.py writes packs
(--pack/--name), reads OSM PBF extracts for a box (--pbf/--bbox, via
pyosmium) and picks label languages (--lang). Map tools > Vector regions
lists the packs on the card: show one on the map, delete it. No
on-device download: packs are made with the tool.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 13:54:25 +02:00
JakubandClaude Opus 5.5 16144bd48b feat(ui-lvgl): contour lines on the vector map
osm_vector.py --dem adds contours from the Terrain Tiles on AWS Open Data
(SRTM, ~25 m; tools/maps/dem.py, standard library only: PNG decode,
smoothing, marching squares, line joining). Every 100 m from zoom 12,
every 20 m from zoom 15; the credit names the elevation source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 11:35:21 +02:00
JakubandClaude Opus 5.5 117b7513bc feat(ui-lvgl): vector map route stripes and point labels
Hiking routes are stored per stretch with the waymark colours of every
route along it and drawn as side-by-side stripes on a white band (half
the route ways in the Tatra sample carry two or more routes), less
simplified; demanding / alpine paths are dotted. Named points (places,
peaks with height, huts, passes, springs, viewpoints, caves) come in
small .vp files and are placed by priority as a layer over the tiles,
clear of each other and of the map controls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 11:25:08 +02:00
JakubandClaude Opus 5.5 ba4e13e2b2 feat(ui-lvgl): VT3 vector tiles, delta varint points
Points as zigzag varint deltas, a byte length per feature to skip it,
natural land cover simplified harder: the Tatra sample goes from 4.4 MB
to 2.3 MB, panning at z14 from ~63 to ~45 ms per tile on the L2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 10:41:01 +02:00
JakubandClaude Opus 5.5 1973361244 feat(ui-lvgl): vector map spike (own VT2 format from OSM)
tools/maps/osm_vector.py turns Overpass JSON into VT2 tiles (data zooms
10/12/14, per-feature bbox, simplified); VectorTileProvider draws them
into 256 px tiles (scanline polygons, thick lines with round joins) with
a small PSRAM cache of data files. Behind Map tools > Vector map (test),
raster where there is no vector data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 10:31:33 +02:00
JakubandClaude Opus 5.5 c90cf474fe feat(ui-lvgl): pick download areas with a frame, list of map areas
- Download an area: a frame with four corner handles on the map (kept in
  world coordinates, the map pans / zooms under it); a bar gives its size,
  zoom range, tile count and size, the trails switch and Get; areas on the
  card are outlined
- Map tools > Map areas: the downloaded areas (map/AreaStore.h,
  /sdcard/maps/areas.txt) -- show (framed, outlined), rename, fill gaps,
  refresh (force re-download), trails on / off, delete (in steps, keeping
  tiles another area covers)
- TileDownloader: force and per-job trails options

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 09:51:29 +02:00
JakubandClaude Opus 5.5 00e961ca63 feat(ui-lvgl): grid and scale bar under the map
A square grid drawn under the tiles (map, Nodes map, Home minimap), its step
a round distance for the zoom in metric or imperial units, with a scale bar
one step long; gives position and scale where no tile is loaded. The
missing-tiles hint moves up, off own position.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 09:39:37 +02:00
JakubandClaude Opus 5.5 ad890a49f6 feat(ui-lvgl): hiking trails overlay on the map
Waymarked Trails' transparent hiking layer, kept in /sdcard/maps-trails and
blended over the base tile at render time (Map tools > Hiking trails, NVS).
An area download fetches each tile's trails after its base tile, so
re-running an area on the card adds just the trails; with live tiles on, a
shown tile missing its trails has them fetched. Tiles without a trail are
stored as 0-byte files (no cluster on FAT).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 09:32:00 +02:00
JakubandClaude Opus 5.5 8b231935ba feat(ui-lvgl): foldable Messages sections with New in the header, storage bar by category
- Messages: New message moves to the header; Channels / Direct / Rooms fold
  on a tap of their title (kept in NVS), a folded one shows its unread count
- Storage: the card's bar is split into one coloured segment per category
  (plus the uncounted rest), each category row keyed with its colour

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 09:08:25 +02:00