Commit Graph
100 Commits
Author SHA1 Message Date
pelgraine ed8869e135 Bringing over Commit 0bbbc04 changes from main into dev 2026-09-15 19:19:04 +10:00
pelgraine d52802fed3 Update readme. Update build date. Fix stale comments in Max ini. 2026-09-15 19:09:17 +10:00
pelgraine e1964d00cb GBCEmulatorScreen.cpp → examples/companion_radio/ui-new/, fingerprint 1093 (build 28 was 1071). Replaces build 28; nothing else changes.
What changed
Quiet period 2 s → 20 s. A background save now only happens after the cart RAM has been untouched for 20 seconds, so ordinary in-game writes during active play no longer trip it. A real menu save is followed by a pause, so it still gets written.
Checksum guard. Before any save, background or on-quit, the live cart RAM is checksummed against what was last written; if the bytes are identical, nothing is written to the card. The game replaying identical state, which is what caused the save-just-after-opening, no longer touches the SD card at all. Seeded from the loaded .sav at launch, so opening a game and idling never writes.
2026-09-15 18:58:39 +10:00
pelgraine 37b3d343e7 GBC emulator: gate out of the 40 MHz battery-saver builds
The emulator needs 240 MHz to run at speed, so it has no place on the
40 MHz builds (meck_max_standalone_40mhz and the Pro's 40 MHz env).

- GamesMenuScreen.h: the Game Boy entry is omitted from the games menu
  on MECK_40MHZ_TEST builds (NUM_GAMES drops to 2, in lockstep with the
  entry list). Snake and Minesweeper are unaffected -- they run fine at
  40 MHz. The menu simply shows two games instead of three.
- UITask::gotoGBCScreen(): refuses on MECK_40MHZ_TEST with a brief
  "Game Boy needs 240MHz" alert and stays put. This is the single point
  every launch route (tile, J-key, games menu) funnels through, so it
  backstops the menu omission -- nothing can reach the emulator on
  those builds.

Files: examples/companion_radio/ui-new/{GamesMenuScreen.h, UITask.cpp}
2026-09-15 18:51:01 +10:00
pelgraine 5a911619f7 GBC sound (T-Deck Max), mesh stays live in-game, fast waveform at 12 frames, wrap fix
SOUND (Max, ES8311; Pro stays silent)
- minigb_apu vendored from Meck-P4 (MIT), run at 22050 Hz: at 44100 it
  cost 3.6-4.0 ms of the 16.7 ms frame and the game fell to 0.98x, which
  drained the DMA queue and glitched. Per-frame timings (core / apu /
  i2s wait) now print with the speed line.
- Bring-up reuses the notification-tone path: shared Audio object owns
  I2S port 0 (with MCLK), XL9555 routing and amp, then codec init after
  the clocks are running. Raw PCM written per frame; a repeated sample
  every sixth frame keeps production a hair above the DAC so its clock
  paces the game instead of the queue running dry.
- Software gain 1/8 (codec DAC sits at 0 dB); GBC_AUDIO_SHIFT to tune.
- 950 ms delay line (PSRAM) so sound lands with the picture, which
  reaches the glass ~1 s after its frame; GBC_AUDIO_DELAY_MS to tune.
- Games start muted; mic key toggles the codec mute in both keyboard
  drivers' raw mode; footer shows the current hint. Amp off on quit.
- Notification tones skipped while a game runs (game owns the codec).

MESH LIVE DURING PLAY
- The OTA-style radio pause is gone (GBC_PAUSE_RADIO=1 restores it):
  the mesh runs on the other core and already tolerates the panel
  blocking the loop. Game header now matches the home screen's -- the
  cumulative unread channel count where the node name goes, clock,
  battery percent. "New:" toasts suppressed only while a ROM is running
  (Snake and Minesweeper keep them).

DISPLAY
- Fast register waveform set to 12 frames per push (FAST_LUT_FRAMES):
  judged the best balance of UI speed and contrast. Interface only; the
  game keeps the factory waveform.
- Windowed game refresh dropped: measured to save nothing, and it left
  the footer row unrefreshed. Normal partial refresh, change-detected.
- Adafruit GFX auto-wrap turned off in the e-ink driver (all e-ink
  builds): it dropped a glyph onto the next line's margin when a line
  ran a few pixels past the edge (seen with Larger Noto in compose).
  Compose wrap width also allows for the driver's 2-unit x offset.
- Game start does one full refresh (tried as a ghosting fix; NPC
  ghosting in Pokemon Gold is the game + dither + factory partial
  waveform and shows on the stock build too).

Files: examples/companion_radio/{main.cpp, ui-new/GBCEmulatorScreen.{h,cpp},
ui-new/UITask.cpp, ui-new/minigb_apu.{c,h}}, src/helpers/ui/GxEPDDisplay.cpp,
src/helpers/ui/GxEPD2_310_GDEQ031T10_FAST.cpp,
variants/lilygo_tdeck_{max,pro}/TCA8418Keyboard.h
2026-09-15 18:42:55 +10:00
pelgraine 1bad37d1ad Large font channel message view word wrap bug fix: What changed:
Driver: setTextWrap(false) once at init. GFX no longer moves text to the next line by itself, anywhere. This is what put the stray "t" on the margin; without it, a line the screen miscounts is clipped at the edge instead, which is the lesser evil for a UI that does all its own wrapping. Applies to every e-ink build, Pro and Max.
Compose: the usable line width is now the panel width less the driver's 2-unit x offset, so the compose wrap and the glyphs' real positions agree and lines wrap one word earlier when they need to.

GxEPD2_310_GDEQ031T10_FAST.cpp → fingerprint 473 (was 464). The 9-frame bytes (0x89 / 0x49 / 0x09) become 0x8C / 0x4C / 0x0C: same level bits, count 12. Improves colour density in Max fastlut test build.
2026-09-13 21:10:08 +10:00
pelgraine c276597f60 E-ink fast-waveform experiment build; GBC loading box and save timing
EXPERIMENT (Max only, env meck_max_ble_fastlut; all other builds unchanged)
- New vendored driver src/helpers/ui/GxEPD2_310_GDEQ031T10_FAST.{h,cpp}:
  the GxEPD2 GDEQ031T10 driver with a selectable partial-refresh
  waveform. Default is "LUT from register" loaded with the register
  tables bitbank2/bb_epaper uses for this panel on the T-Deck Pro (one
  9-frame push per pixel); the factory OTP waveform stays available.
  Full refreshes unchanged. Measured on the Max: partial refresh 244 ms
  (652 ms on the factory waveform) on home, menus, ROM list and typing.
  Cost: one short push per pixel gives weaker blacks and half-develops
  dithered stipple, so it suits text and does not suit the game.
- GxEPDDisplay: setFastWaveform() and fastPartialsSinceFull(), no-ops
  outside the experiment env. Switching back to the factory waveform
  hibernates the panel so the next refresh goes through a hardware
  reset (tested as a ghosting fix; it was not one, kept as a clean
  hand-over).
- UITask::setCurrScreen: after EINK_FAST_FULL_EVERY (20) fast partials
  the redraw at the next screen change is a full refresh, so the
  register waveform's ink imbalance is cleared where a redraw is
  happening anyway rather than mid-typing.
- GBC emulator switches the driver to the factory waveform while a
  game runs (its dithered picture needs the longer drive) and back to
  fast on quit.
- Finding, for the record: moving-sprite ghosting in Pokemon Gold
  appears on the stock build too, so it is the game plus dither plus
  the factory partial waveform, not the experiment.

GBC EMULATOR (all T-Deck builds)
- "Loading..." alert box the moment Enter is pressed on a ROM row; the
  multi-second SD read now runs on the next loop pass, after the box is
  on the panel, instead of inside the key handler.
- Games start with a full refresh (clean panel; added during the
  ghosting investigation, kept pending review).
- Save writes are timed and the durations logged (remove/open/write/
  close), after one unexplained ~45 s UI stall coincided with a save.

Files: examples/companion_radio/ui-new/GBCEmulatorScreen.{h,cpp},
examples/companion_radio/ui-new/UITask.cpp, src/helpers/ui/GxEPDDisplay.h,
src/helpers/ui/GxEPD2_310_GDEQ031T10_FAST.{h,cpp},
variants/lilygo_tdeck_max/platformio.ini
2026-09-13 19:31:06 +10:00
pelgraine 7295df44b2 GBC emulator: T-Deck Pro support (iniitial build)
PRO PORT
- The emulator now builds for every T-Deck Pro companion env as well as
  the Max (guard moved from LilyGo_TDeck_Pro_Max to LilyGo_TDeck_Pro in
  main.cpp, UITask.{h,cpp}, GamesMenuScreen.h and the emulator files;
  the T5S3 stays excluded). Pro keyboard driver gains the same raw
  joypad mode as the Max's, minus the both-shifts backlight chord, which
  stays Max-only along with toggleKeyboardBacklight().
- Same chip, panel, keyboard controller and SD layout as the Max, so
  the speed and memory behaviour carries over; the Pro audio build's
  free internal RAM after Bluetooth is the one thing not yet measured.
- HYN-touch Pro envs are untested (no v1.1/CST3530 hardware on hand);
  to be marked experimental in the release notes.

Files: examples/companion_radio/{main.cpp, ui-new/GBCEmulatorScreen.{h,cpp},
ui-new/GamesMenuScreen.h, ui-new/UITask.{h,cpp}}, variants/lilygo_tdeck_pro/TCA8418Keyboard.h
2026-09-13 11:09:17 +10:00
pelgraine aadbac4996 Removed ptscan related reduncant code from gxepddisplay 2026-09-13 10:56:22 +10:00
pelgraine b6963e9411 GBC emulator: robust after Bluetooth, background saves, faster typing, font prefs on games menus
Follow-up to the v1.14 emulator commits. T-Deck Max unless noted.

MEMORY AND STABILITY (GBCEmulatorScreen.cpp)
- Emulator task stack is now 8 KB, static, reserved at boot. Once
  Bluetooth has been switched on in a boot its stack stays resident
  (SerialBLEInterface::disable() never releases it) and a later game
  launch could not find 12 KB of internal RAM in one piece. Measured
  use is about 2 KB.
- Core context released on every failed launch, not just on quit; a
  failure no longer holds 50 KB.
- No periodic full refresh during play (too distracting). The full
  refresh on quit stays, to clear ghosting before the ROM list.

SAVES
- .sav written in the background: cart-RAM writes mark it dirty and
  the UI task writes the file once the game has left its cart RAM
  alone for 2 s, i.e. shortly after the user saves in-game. Quit
  writes only if still dirty, and no longer draws and refreshes an
  intermediate "Saving..." frame (that frame cost 650 ms by itself).

INPUT
- Both-shifts keyboard-backlight chord works mid-game: it is the one
  key raw joypad mode lets through. The toggle body moved from
  handleKeyboardInput() into toggleKeyboardBacklight() (main.cpp) so
  the game and the normal path share one on/off state.
- On quit the keyboard stays in raw mode, still drained through the
  panel's busy wait, until the ROM list has been drawn. Keys pressed
  during the quit flash used to queue in the TCA8418 and replay as
  navigation afterwards (one held Q ran four screens back).

PICTURE
- Game pictures after the first refresh only the 216-line game window
  (GxEPDDisplay::requestWindowRefresh, consumed by endFrame). Measured
  at 652 ms either way, the same as full-panel: the panel's waveform
  time is the floor, so this saves data transfer only.

TYPING (main.cpp, all e-ink builds)
- COMPOSE_REFRESH_INTERVAL 700 -> 0. lastComposeRefresh is stamped
  after the blocking e-ink refresh completes, so the interval only
  added dead time on top of it. Worst-case keystroke-to-screen drops
  from about 1.6 s to about 0.9 s. COMPOSE_TYPING_PAUSE unchanged.

GAMES MENUS
- Games menu and Game Boy ROM list rows follow the user's font size
  and style via the NodePrefs helpers (as the channel picker does);
  Max touch hit-test updated to match. Footers read Q:Back.

BUILD ENVS (Pro)
- meck_audio_wifi_hyn and meck_audio_standalone_hyn, the HYN-touch
  counterparts of the existing meck_audio_ble_hyn.

Files: examples/companion_radio/{main.cpp, ui-new/GBCEmulatorScreen.{h,cpp},
ui-new/GamesMenuScreen.h}, src/helpers/ui/GxEPDDisplay.{h,cpp},
variants/lilygo_tdeck_max/TCA8418Keyboard.h,
variants/lilygo_tdeck_pro/platformio.ini
2026-09-13 07:21:33 +10:00
pelgraine d9524f3d64 Pro v1.1 diff touch drivers: Two new environments, meck_audio_wifi_hyn and meck_audio_standalone_hyn, each placed directly after its parent. 2026-09-13 01:43:44 +10:00
pelgraine 941f429ac4 Firmware version bump to 1.14 for Max and Pro 2026-09-13 01:39:20 +10:00
pelgraine fcd2bc7aa6 GBC emulator: Q quits; README documents the emulator
EMULATOR (T-Deck Max)
- Q now quits a running game, matching the back key used across the
  rest of the interface. Shift+Backspace still works. Added as a second
  exit latch in the keyboard driver's raw joypad mode; the on-screen
  hint reads "Q: Quit".
  variants/lilygo_tdeck_max/TCA8418Keyboard.h
  examples/companion_radio/ui-new/GBCEmulatorScreen.{h,cpp}

README
- New "Game Boy / Game Boy Color Emulator (T-Deck Max, v1.14+)"
  subsection under Games: what it is, where to get free homebrew ROMs
  (uCity, Halo: Combat Devolved), where to put them (/roms, .gb/.gbc,
  32 files, names under 48 characters), how to launch and play (key
  table, radio paused and CPU at 240 MHz while a game runs), what the
  picture looks like and why it updates about 1.4 times a second,
  saves (.sav on quit, no RTC state), and the release's limits.
- Contents entry for the new subsection; Games intro mentions the
  Games tile and the Max-only emulator.
- SD Card Requirements lists Game Boy ROMs and saves.
- T-Deck Max intro cross-references the emulator.
- Road-Map: emulator done on the Max; Pro support, ES8311 sound with
  mic-key mute, and RTC save state listed as to-do.
- Third-Party Libraries: Peanut-GB (MIT, Mahyar Koshkouei) added, with
  a note that no Game Boy software is bundled.

Version tags on the new items are v1.14; the global version bump
follows in the next commit.
2026-09-13 01:39:01 +10:00
pelgraine 3647bdcc88 GBC emulator: full speed, 1.5x dithered picture, live keys, ghosting control
Follow-up to the initial Game Boy emulator commit (T-Deck Max).

SPEED (GBCEmulatorScreen.cpp)
- Pacing keeps its deficit: a frame that finishes late is paid back by
  running the next ones back-to-back instead of resetting the deadline
  and forgiving the lost time, which held Pokemon Gold at 0.96x. Only a
  stall of more than 250 ms resyncs. Now measures 1.00x on every 5 s
  window. A 1 ms yield every 30 undelayed frames keeps the idle task
  (and the task watchdog) fed.
- The core context (49952 bytes) is allocated from internal RAM for
  the duration of a game and freed on quit, with PSRAM as the fallback
  if no internal block is free; the launch log says which it got.
- Speed line printed to serial every 5 s (window fps, average, ratio to
  real time).

INPUT (GBCEmulatorScreen.cpp, GxEPDDisplay.h)
- GxEPDDisplay::setBusyCallback() exposes GxEPD2's busy-wait hook. The
  emulator registers a keyboard poll on it while a game runs, so key
  presses and releases are seen through the ~650 ms panel refresh
  instead of waiting for it to finish.

PICTURE (GBCEmulatorScreen.cpp, UITask.cpp, GxEPDDisplay.{h,cpp})
- 1.5x nearest-neighbour scale to 240x216, the full panel width,
  centred; title line removed, quit hint kept.
- Ordered 4x4 Bayer dithering replaces the single threshold: the four
  Game Boy shades map to 0, 6, 11 and 16 dark pixels in 16, so
  sprites with mid-tone colours are no longer flattened to white or
  black. The pattern is fixed to panel position so it does not crawl
  between refreshes.
- UITask: the 800 ms minimum interval between e-ink refreshes is
  lifted while a game runs, so pictures follow at the panel's own
  partial-refresh rate (about 0.7 s).
- GxEPDDisplay::requestFullRefresh(): the next endFrame() uses the
  full black/white waveform regardless of frame change. The emulator
  requests one every 45 pictures (about 30 s) and once on quit, to
  clear the residue that continuous partial refreshes leave on the
  game screen and the home screen after it. No other screen calls it.

Files: examples/companion_radio/ui-new/GBCEmulatorScreen.{h,cpp},
examples/companion_radio/ui-new/UITask.cpp,
src/helpers/ui/GxEPDDisplay.{h,cpp}
2026-09-13 01:23:02 +10:00
pelgraine db9f5ae7b6 Fix Maps tile SD detection; add Garmin BLE build env; Game Boy emulator (T-Deck Max)
MAPS FIX (all T-Deck Pro and Max builds)
Opening Maps from the home tile showed "SD card not found" until the G key
had been pressed once that boot. The map screen's SD flag was only set by
the G key handler; the touch tile and CardKB routes opened the screen
without it. The G handler's setup (SD flag, GPS position, contact markers,
CPU boost) is now openMapScreen() in main.cpp and all three routes call
it. G on the map (re-centre) is unchanged.

PLATFORMIO (variants/lilygo_tdeck_max)
- New meck_max_ble_garmin env for the Garmin watch companion: identical to
  meck_max_ble with BLE_DEBUG_LOGGING, MECK_BLE_JUST_WORKS (no-passkey
  pairing), MECK_BLE_SMALL_MTU_SPLIT (23-byte ATT frame slicing),
  MECK_WATCH_EXT (watch extension commands) and MECK_BLE_SLOW_INTERVAL
  switched on.
- meck_max_ble now has those five flags commented out, so the standard
  phone-app build is isolated from the watch experiments.

GAME BOY / GAME BOY COLOR EMULATOR (T-Deck Max only in this build)
New "Game Boy" entry in the Games menu. Lists .gb/.gbc ROMs in /roms on
the SD card and runs them with the Peanut-GB core (same patched copy as
Meck-P4) in its own task on core 0 at the real 59.73 fps, drawing a
black-and-white snapshot to the e-ink at the panel's refresh rate.
- Keys: W/A/S/D d-pad, K = A, J = B, Enter = Start, Space = Select,
  Shift+Backspace = quit (save written). No sound yet.
- Saves: .sav next to the ROM, written on quit.
- LoRa radio in standby and mesh loop paused while a game runs (reuses
  the OTA pause). CPU held at 240 MHz.
- Keyboard polled through the e-ink busy wait so input is not delayed by
  the ~650 ms refresh; the 800 ms refresh floor is lifted during play.
- Speed line printed to serial every 5 s.
Files:
- ui-new/GBCEmulatorScreen.{h,cpp} (new), ui-new/peanut_gb.h (new)
- ui-new/GamesMenuScreen.h: GAME_GBC entry
- ui-new/UITask.{h,cpp}: gbc_screen, goto/is/get, resetIdleTimer(),
  no refresh floor while a game runs
- main.cpp: launch, exit and key routing
- variants/lilygo_tdeck_max/TCA8418Keyboard.h: raw joypad mode
- src/helpers/ui/GxEPDDisplay.h: setBusyCallback()
Pro builds compile unchanged (all emulator code is guarded).
2026-09-13 00:47:40 +10:00
pelgraine 7ebe1b900f Garmin: Regions: derive per-channel scope key at set/load; BLE slice length byte and relaxed watch interval
- ChannelDetails gains scope_key[16]; MyMesh::setChannel derives it from
  scope_name on every write (screens, serial, phone sync, boot load), so
  sending copies bytes instead of doing a name lookup and derivation per
  message. Port of the Meck Watch regions fix.
- getChannelScopeName now copies out instead of returning a pointer into
  a local (dangling; caused intermittent unscoped sends).
- BLE small-MTU slices become [tag][len][payload] (18 payload bytes) so
  stream transports (nRF52) can find slice boundaries; same format on
  ESP32 for one dialect across nodes and the Garmin app.
- New MECK_BLE_SLOW_INTERVAL flag: request a 100-200 ms connection
  interval instead of 15-20 ms for the watch build.
2026-09-08 06:21:26 +10:00
pelgraine 372bdf8292 Persist per-channel region names in /channels2.scope companion file 2026-09-07 21:01:20 +10:00
pelgraine 312df5a6f2 Garmin: MECK_WATCH_EXT: favourite-N and prefix-resolve 2026-09-07 20:24:23 +10:00
pelgraine 5fe4942c87 Garmin additions - trace and discover support added into mymesh 2026-09-07 19:00:06 +10:00
pelgraine 7c39700770 Garmin MECK_WATCH_EXT: watch-client commands, rich channel frame, canned/scope/heard-by reads 2026-09-07 17:53:29 +10:00
pelgraine 51a4435008 BLE: small-MTU slicing verified with Garmin 2026-09-07 17:34:00 +10:00
pelgraine fe13fc96a9 BLE: recover deviceConnected when auth completes before GATT connect 2026-09-07 06:43:57 +10:00
pelgraine c40e5e20be Canned messages (Max), 40 MHz test builds, Pro v1.1 HYN touch, Pro audio Phone tile removal
Canned messages (T-Deck Max only):
- NodePrefs gains canned_msgs[10][134] as the final field; DataStore load is short-read tolerant (older prefs upgrade to empty slots), NUL-forced, appended in savePrefs. Storage is shared across boards so the prefs layout stays uniform; the Settings entry point is gated to the Max.
- Settings -> Canned Messages: ten slots, full-length inline editor (tail + n/133 counter); Enter commits, empty clears, Sh+Del cancels. T5S3 VKB path exists behind the same gate.
- Channel screen overlay: the speech-bubble pad toggles the list on a channel or DM conversation; tapping a row sends via sendComposedMessage() (channel -> that channel, DM conversation -> DM to that contact); all-empty shows an alert. Other screens keep the channel-picker action.
- Post-test fixes: tap intercept moved ahead of the vy<18 go-home rule that ate row taps and left the overlay stuck; any keyboard key closes the overlay in handleKeyboardInput (keys never reach ChannelScreen::handleInput on Pro/Max); setViewChannelIdx resets overlay state like the path overlay.

40 MHz extreme-battery test builds: meck_max_standalone_40mhz, meck_audio_standalone_40mhz, meck_4g_standalone_40mhz. CPU idle/boost/low-power all 40 MHz; MECK_40MHZ_TEST gates the modem (forced off, config kept), GPS (rail off, page hidden), browser/OTA, alarms, audio features and notification MP3s; gated tiles dither and go inert; MESH_DEBUG=1. The Pro envs deliberately re-run the March 80->40 TCA8418 config (noted in env comments).

T-Deck Pro v1.1 HYN touch (meck_audio_ble_hyn, Meck v1.12.6.HYN): opt-in MECK_PRO_HYN_TOUCH switches touch to the vendored Hynitron driver, auto-detecting CST3530/CST328 at 0x1A. Seven driver guards widened; XL9555 callbacks stay Max-only; explicit config SDA13/SCL14/RST38/INT12; the manual GPIO38 reset pulse is suppressed (driver self-resets); readTouch and the 4G dialer dispatch widened. Link fix: ui-new/*.c added to the env src filter (the cst66xx/cst3xx/cst226se providers were not compiled). Confirmed working by an affected v1.1 (CST3530) user.

Pro audio builds: the full-width Phone tile is no longer rendered (no modem; its tap was already inert).
2026-08-13 20:01:21 +10:00
pelgraine b01e78322e Test T-Deck Max 40mhz extreme battery saving build, gating out all features that would require more than 40mhz CPU including gps. Confirmed touch and keyboard navigation and serial output working for meck_max_standalone_40mhz 2026-08-12 21:28:37 +10:00
pelgraine 50ba2f5119 update firmware build date 2026-07-26 15:32:41 +10:00
pelgraine 213e7d6b9e Footer fixes when the N was truncated.
Added new Contacts screen for phone contacts for Pro 4G and Max.

Added touch recognition to phone screen app menu.
2026-07-26 15:23:34 +10:00
pelgraine 0a2e736ba5 Max backlight bugfix - light was occasionally still remaining on when the autolockscreen timer activated. Now turning off as it should 2026-07-25 16:53:53 +10:00
pelgraine f485596c74 Update firmware version and build date for Max and Pro 4G. Fix accidentally Max battery size change commit 2026-07-25 16:42:29 +10:00
pelgraine 922f0e3c17 New Max home UI on all T-Deck Pro builds; Call Log; lock screen notifications
Home UI
- Widen the tile-grid home screen (e1300190) from Max-only to all T-Deck Pro
  builds: guard flips from LilyGo_TDeck_Pro_Max to LilyGo_TDeck_Pro at five
  sites in UITask.cpp (HomeIcons include, tile-flag set/reset, page-dot
  offset, tile render block) and at the touch hit-test in main.cpp. Max
  defines both flags, so Max behaviour is unchanged -- verified by diffing
  both files preprocessed with the Max define set.

Call Log (HAS_4G_MODEM)
- New CALL_LOG subview; app menu is now Dial / SMS Inbox / Call Log.
- SMSStore gains a fixed-size CallLogRecord store in /sms/calllog.dat
  (timestamp, duration, type, seen, phone), capped at 32 entries with the
  oldest trimmed on append: appendCallLog, loadCallLog (newest first),
  deleteCallLogEntry (rewrite via tmp + rename) and markMissedSeen
  (in-place flag update). Same SD idioms as the SMS store.
- Logs incoming and outgoing calls with duration, plus missed, busy and
  no-answer attempts. Calls arriving with no caller ID are logged and shown
  as "Unknown" rather than dropped.
- List mirrors inbox conventions: contact name via SMSContacts, detail line
  with type, duration and local date/time. Enter dials, D deletes, Q backs
  out. Menu row carries an unseen-missed [n] badge matching SMS Inbox.

Lock screen (HAS_4G_MODEM)
- Show outstanding unread SMS and unseen missed calls at height()-12 with
  setTextSize(1). Counts derive from the inbox read flags and call log seen
  flags, so they persist across re-locks and reboots and clear only when the
  conversation or the Call Log is opened. State loads at boot in
  setSDReady().

Phone screen fixes
- An incoming call now drops the lock screen. Keyboard and touch input are
  both blocked while locked, which left the ringing screen unable to answer
  or reject. The device stays unlocked afterwards.
- gotoSMSScreen() no longer calls activate() mid-call, which was resetting
  the view to the app menu and wiping the ringing screen.
- Widen the app menu footer right margin so "Ent:Open" is not clipped.
2026-07-25 16:40:01 +10:00
pelgraine e130019061 New Max Home UI design 2026-07-21 19:03:52 +10:00
pelgraine 409ab81760 Forgot to add Australia mid preset whoops 2026-07-20 22:44:00 +10:00
pelgraine e447b17f37 Remove T-Watch code from repo 2026-07-19 11:55:31 +10:00
pelgraine 1d03b64e92 T-Watch: added heard by details for outgoing messages - accessible via boot button for S3 Plus or power button on S3 on outgoing selected messages (tap to select message). 2026-07-19 11:03:06 +10:00
pelgraine 4b84f92088 T-Watch S3 - made gamescreen replacement for the alarm time and updated games ui hint text & tap steering method(s). Increased snake speed for the watch 2026-07-18 19:19:09 +10:00
pelgraine 45aebd5bfe T-Watch S3 - watch alarm screen and associated diagnostic build removed due to power drain issue 2026-07-18 18:47:27 +10:00
pelgraine b90edc5995 T-Decks Pro & Max: reverted back to Q to exit in most instances (not involving text entry, where it remains sh+del to exit) 2026-07-18 18:16:27 +10:00
pelgraine 627039cd36 T-Watch: Leaving tilt debug back in on S3 builds 2026-07-18 14:57:03 +10:00
pelgraine b9e59953e6 T-Watch - fixed datastore chunked save trigger so contacts import from ble app are saved properly, overriding usual 12hr trigger in that instance 2026-07-18 14:13:48 +10:00
pelgraine 4f8cceea24 T-Watch update firmware version and build date 2026-07-18 13:57:42 +10:00
pelgraine c360850773 T-Watch = contacts screen overlay enabling favouriting/deleting on long press. Favourites toaster popup confirmation 1-3 seconds after favourite enabled 2026-07-18 13:56:43 +10:00
pelgraine 82982002be T-Watch - fix touch and ui bugs so that ticker scroll display works for longer text rows, and long press to open rx log 2026-07-18 12:03:41 +10:00
pelgraine 2cf7945136 T-Watch - update settingscreen touch so rxlog displays on watch with auto-scroll updates.
Added persistent channel message history with swipe to scroll up and down.
2026-07-17 22:02:16 +10:00
pelgraine 619e8f44a5 T-Watch: fix discovery screen wrap. Add no alarm tick s3 temp diagnostic build and removed prior faulty temp no pmu diagnostic build. Updated tracescreen.h functionality and UI for t-watch builds. 2026-07-17 19:29:15 +10:00
pelgraine a436beb9d1 T-Watch S3: fixed tilt raise bug.
Applied the same memw barrier + identical comment to twatchs3plusboard.cpp, hardening the Plus against the same latent race it was previously surviving only by luck
2026-07-16 19:00:38 +10:00
pelgraine ade92cf1e1 All Boards DM delivery confirmation fixes & T-Watch build additions and updates.
T-Watch:

Disabled rx boosted gain & removed meck rx duty cycle flag for S3 and S3 Plus.
Bumped charge rate on S3 to 150MA.
Added watch custom incoming path/hops view in channel message view mode.
Added diagnostic pmubtn build to S3 plus to iron out source of power drain in S3 firmware.

All boards:
ChannelScreen.h -- delivered DMs now render Delivered  in the prefix position, exactly where Sending x/N and Failed sit, and the drawn tick is gone entirely (the branch, the reserved gap and the drawDeliveredTick helper -- zero references remain). For what it's worth, the photo vindicates the change: those stray pixels below the line next to "2s" are the tick misplaced, because the GFX fonts position from the baseline rather than the glyph top, so the hand-drawn glyph landed too low. Text is the robust answer.
UITask.cpp -- the toast persistence is a scheduling starvation, and the status pushes made it visible. Dismissal works by scheduling a render at _alert_expiry; but after every frame the e-ink throttle applies an 800ms floor (minNext, UITask.cpp:2856-2860), and the ~644ms partial-refresh block inside endFrame() shifts millis() before the clamp runs. So any render landing inside the alert window -- which a delivered/attempt push now triggers via forceRefresh() -- redraws the overlay and then gets its expiry wake clamped past the expiry. Your user's photo is precisely that frame: tick and toast on screen together, with the clearing render deferred. The fix is a single insertion after the shared clamp: if an alert is still active and lapses before the next scheduled render, wake at expiry instead. One bounded extra render per toast, both display branches covered, and the toast now clears on time no matter what the retry engine pushes mid-window.
2026-07-15 20:55:37 +10:00
pelgraine 4f28d22217 Add device-side DM retries with Sending x/N counter, delivered tick and Failed status in conversation view.
Tracked DM sends now retry like the app: 3 flood attempts with no path
set, or 5 with a path (4 direct, then path reset and a final flood).
Each attempt waits its own hop-aware est_timeout. Delivered resolves on
the recipient's ack for any attempt and draws a tick after the message
prefix; Failed shows once all attempts are exhausted.

Status is session-only: SD message format unchanged at v4. Wired for
keyboard, touch, CardKB and T-Watch compose plus channel share. BLE app
sends and the voice envelope path are untouched.
2026-07-15 07:11:06 +10:00
pelgraine 43b1ba082b Update firmware version and build date 2026-07-15 06:16:31 +10:00
pelgraine 3e40ccbaa1 T-Watch - amend text wrap on settingscreen 2026-07-15 06:14:11 +10:00
pelgraine 5ce0540486 T-Watch: standalone channel config screen (region, notifications, delete)
The SettingsScreen SUB_CHANNELS sub-screen drives every per-channel
action from physical-keyboard hotkeys (Ent: scope, N: notif, T: tone,
X/Hold: delete), so on the touch-only watches the channel list rendered
but nothing was actionable. Replace it on MECK_TWATCH builds with a
standalone WatchChannelConfigScreen following the WatchAlarmScreen /
WatchNotesScreen conventions. Desktop builds are unchanged.

LIST shows each channel with its region scope tag and notification
state (tap to select, tap again or button to open, paged like Notes).
DETAIL offers: Region -- opens the watch keyboard via a new TWKB_SCOPE
purpose, pre-filled with the current scope, committed through the same
setChannel + saveChannels path as desktop (empty submission clears);
Clear region -- reverts to the device default directly; Notify --
tap-cycles All -> Mentions -> Off with savePrefs, matching the desktop
N-key order. Delete is button-driven rather than touch: a short press
(PWR on the S3, boot button on the Plus) arms it, a second press
within 3s confirms. Channel 0 remains protected. The tone picker is
deliberately absent -- the watch has no audio path.

Settings hands off via a _wantsWatchChannels flag polled by
UITask::loop (mirrors the _needsTextVKB handshake); Back returns to
Settings via gotoSettingsScreen. Keyboard results route through the
existing consumeSendRequest purpose dispatch.

Note: deleteChannel replicates SettingsScreen's compaction verbatim,
including its existing quirk of not shifting channel_notif[] -- kept
faithful rather than silently diverging; fix both together if desired.

Files: WatchChannelConfigScreen.h (new, both variant dirs),
TWatchComposeScreens.h (both variant dirs, TWKB_SCOPE),
SettingsScreen.h, UITask.h, UITask.cpp, main.cpp
2026-07-14 21:02:49 +10:00
pelgraine e647fde02d Yet again fix t-watch compose screen & tw_picker accidental regression 2026-07-14 20:25:10 +10:00
pelgraine 2cc66568e1 Update readme 2026-07-14 19:23:18 +10:00
pelgraine 0f5b62f36b T-Watch S3 Plus - The whole TILT TEMP diagnostic is now gone: printout, timer, counter declaration, definition, and the ISR increment. 2026-07-14 19:11:52 +10:00
pelgraine 2d5b9b1432 T-Watches.:
S3 fix (CHG_VOL_4V2 → CHG_VOL_4V35 in TWatchS3Board.cpp

Notes screen:
WatchNotesScreen.h → both variants/lilygo_twatch_s3/ and variants/lilygo_twatch_s3_plus/ (byte-identical copies, like TWatchComposeScreens.h).
TWatchComposeScreens.h → both variant dirs. Adds TWKB_NOTE to the Purpose enum and a setInitialText() (clamped at the 133-char MAXLEN) for prefill editing.
UITask.h → watch_notes_screen member, isOnWatchNotesScreen(), getWatchNotesScreen(), all MECK_TWATCH-gated, mirroring the alarm-screen pattern exactly.
UITask.cpp → include, construction in begin() (after the LittleFS mount, like the alarm), gotoNotesScreen() now routes to the watch screen on MECK_TWATCH (T-Deck/T5S3 behaviour untouched — the SD NotesScreen path below is unreached on watches), the TWKB_NOTE result case (save via applyComposedNote, alert on error, return to the notes screen), and the loop poll that opens the keyboard — prefilling via setInitialText(getEditText()) when editPending().
main.cpp → include plus the tap-dispatch block, same shape as the alarm's.
2026-07-14 18:54:46 +10:00
pelgraine 28046a7441 Fix t-watch compose screen & tw_picker accidental regression 2026-07-13 18:01:57 +10:00
pelgraine 2b31e56e4c T-Watch changes:
CPUPowerManager.h — S3 variant, CPU_FREQ_BOOST capped to 80 MHz.
main.cpp — locked-loop throttle extended to the watches via the two MECK_TWATCH guard additions.
2026-07-12 20:07:18 +10:00
pelgraine a5dacc3db8 T-Watch: reduce brightness to 25 2026-07-12 17:39:16 +10:00
pelgraine 29f60c5bcd Contacts: cap chunked save to twice a day; flush on low battery
Throttle the ESP32 lazy contact save from a 5s debounce to a 12h
interval (CONTACTS_SAVE_INTERVAL). A new _nextContactSaveDue anchors
the next flush 12h out on the first dirty pass and only writes once
reached, clearing after each save so the next dirty event re-anchors.
Cuts the recurring ~95KB LittleFS rewrites on busy meshes. nRF52/STM32
blocking-save path unchanged.

Flush contacts (blocking) in the AUTO_SHUTDOWN_MILLIVOLTS path before
shutdown() so low-battery power-off doesn't drop up to 12h of contact
learning. Manual power-off left untouched.

Gate the SHUTDOWN home page out on the watch (MECK_TWATCH): removed
from the HomePage enum with render/input/isOnShutdownPage guarded.
The AXP2101 PWR-button long-press is the shutdown path there.

Files: MyMesh.h, MyMesh.cpp, UITask.cpp
2026-07-12 17:37:04 +10:00
pelgraine 1c0778b00e T-Watch: fix touch method for tw_picker 2026-07-12 15:02:50 +10:00
pelgraine fcd8b70384 Watches: persistent step counts + 7-day history subscreen
Fixes a pre-existing bug on both watches. SensorBMA423::begin() calls
bma423_write_config_file(), which re-flashes the BMA423 feature engine and zeroes
the step register on every boot. _stepBaseline and _lastStepDay were RAM-only, so
a reboot mid-day silently reset the day's steps to zero. Persisting the baseline
would not have helped, since the raw count it is measured against restarts at 0.

Replaces the baseline model with accumulate-plus-reset-detection:

  delta = (raw >= lastRaw) ? raw - lastRaw : raw
  todaySteps += delta

lastRaw is seeded from the chip on the first read rather than from the file,
which is correct whether or not the counter survived the reset.

Persists lastStepDay, todaySteps and history[6] to /steps.dat on the LittleFS
'maps' partition, already mounted before UITask::begin(). Written on day rollover
and at most every 5 minutes otherwise: a >=6s PWR hold is a hardware power cut by
the AXP2101, so there is no clean-shutdown hook to flush from. A rollover across
several days shifts in the completed day then pads with zeros for the days the
watch was off; a clock corrected backwards re-anchors without disturbing history.

Adds StepsHistoryScreen: today plus the previous six days as labelled bars, today
in the tile blue. Reached by long-pressing the steps screen, which on the S3 the
PWR key's short press also delivers (both arrive as KEY_ENTER). Any input returns
to the steps screen.

Gated on MECK_TWATCH, so the Plus gets both the fix and the screen.
2026-07-10 20:04:16 +10:00
pelgraine cf4105ee7d Add LilyGo T-Watch S3 variant (non-GPS, 470 mAh)
Same silicon and the same pin map as the T-Watch S3 Plus, verified against the
T_WATCH-S3 schematic (rev 25-03-24) and LilyGo's utilities.h. The differences
are what is populated:

  - no onboard GNSS. HAS_GPS/ENV_INCLUDE_GPS are left undefined, which drops the
    map screen, the GPS home page and BLDO1 rail control via the gates added in
    the MECK_TWATCH rename.
  - no GPIO button. Schematic sheet 1 wires the side switch SW7 to net PWR_KEY
    -> AXP2101 pin 30 (PWRON), so PIN_USER_BTN is undefined and MECK_PMU_BUTTON
    selects PMUButton, which reads PKEY interrupts over I2C. Short press is
    enter/select; a 6s hold is a hardware power-off the firmware never sees.
  - DLDO1 is the MAX98357A speaker rail (schematic sheet 6, net SPK_VDD), not
    'unused' as LilyGo's doc claims. It stays off, so the amp is unpowered.
  - VBACKUP is enabled at 3300 mV. It charges the MS412FE coin cell (J12) that
    backs the PCF8563's single-VDD supply. Leaving it off drained the cell with
    nothing to replenish it.

New envs: meck_twatch_s3_standalone, meck_twatch_s3_ble.
No existing board is affected: MECK_PMU_BUTTON is defined only here.
2026-07-10 18:57:09 +10:00
pelgraine 0fa7a321bf Rename LILYGO_TWATCH_S3_PLUS to MECK_TWATCH as the watch form-factor gate
The macro was doing double duty: gating the 240x240 touch UI (tile grid, lock
screen, VKB, grey palette) and gating the Plus's onboard GNSS. A non-GPS watch
cannot reuse the first without dragging in the second.

  MECK_TWATCH             watch form factor
  LILYGO_TWATCH_S3_PLUS   Plus-only hardware (GNSS on BLDO1, GPIO0 user button)
  MECK_PMU_BUTTON         user button is the AXP2101 PWRON key, not a GPIO

84 sites renamed across 14 files. The WatchMapScreen include, construction and
its three touch handlers now also require HAS_GPS, as does the Maps tile branch
inside the home tile grid.

Behaviour-preserving: the Plus defines both MECK_TWATCH and HAS_GPS=1, so every
new condition evaluates as before. No other board defines MECK_TWATCH.
2026-07-10 18:40:53 +10:00
pelgraine 732cc2e8b2 T-watch: fix gps toggle bug caused by previous spiffs+littlefs partition additions wipe and update 2026-07-09 18:55:51 +10:00
pelgraine 32d0055e93 T-watch - implemented tw_picker and ensured it takes precedence 2026-07-06 19:59:23 +10:00
pelgraine f6d7c48845 watch ui updates prelim 2026-07-04 22:06:33 +10:00
pelgraine 9aa791b8eb updated t-deck pro & max firmware versions and build date 2026-07-04 14:00:48 +10:00
pelgraine e21dd81dc7 Renamed T-Watch S3 Plus WIP folder again 2026-07-04 13:56:39 +10:00
pelgraine 66f515e818 revise accidental max battery size change commit 2026-07-02 06:18:46 +10:00
pelgraine 443aa42e7b What you now have on the CLI:
get dutycycle → reports the current duty as a percentage (e.g. > 50%)
set dutycycle <10-100> → sets it, saves to prefs, persists on reboot; anything below 10 or above 100 returns ERR - duty cycle must be 10-100
set af <value> is untouched, for anyone who prefers the raw factor
2026-07-02 06:17:56 +10:00
pelgraine ad05c24881 Minor footer fixes. Adjust key_cancel behaviour bug in main.cpp caused by swap from Q to sh+del 2026-06-30 20:24:08 +10:00
pelgraine 444631e08b update lock screen reference in Readme; update footers and exit behaviour so nearly all instances of Q:Exit is now Shift+Delete=Exit. Add first pass change for Meck issue 20 to dispatcher cpp and h 2026-06-30 20:05:51 +10:00
pelgraine cbc30e54fe Rename T-Watch Plus S3 folder to WIP 2026-06-30 06:52:40 +10:00
pelgraine b80184cf96 initial builds, standalone and ble twatch s3 plus 2026-06-26 19:28:24 +10:00
pelgraine 7005bd065e Merge pull request #22 from nabbi/fix/full-build-failures-on-main
Fix remaining build failures found by a full pio run across all envs
2026-06-24 21:43:29 +10:00
pelgraine 6747568556 Merge pull request #21 from nabbi/fix/case-sensitive-variant-include-paths
Fix case-sensitive filesystem build failures (Linux) for ESP32 LilyGo variants
2026-06-24 21:42:59 +10:00
pelgraine 8133ab5856 Max: update build date and firmware version. Add keyboard LED brightness setting (MAX); fix standalone unread counter
Keyboard LED brightness (T-Deck Pro MAX):
Adds a "Keyboard LED" row to Settings (MAX only), below Backlight
Brightness and mirroring it: 5-100% in 5% steps, default 50%. The
both-shifts keyboard backlight toggle previously used a hardcoded PWM
level of 8 (~3%), too dim for some users; it now reads the stored
percentage and maps it to PWM, taking effect on the next toggle.
- NodePrefs.h: new kb_backlight_pct field (5..100, default 50)
- Settingsscreen.h: ROW_KB_BACKLIGHT row plus label/edit handling
- DataStore.cpp: load/save/clamp, appended so existing prefs files stay
  compatible (fall back to 50%)
- main.cpp: toggle uses kb_backlight_pct (percent -> PWM) instead of 8

Standalone unread counter fix:
On standalone builds the home-page MSG count and channel-picker unread
badges never updated, although messages arrived and displayed normally.
ArduinoSerialInterface::isConnected() is hardcoded to return true (a plain
UART has no connection state), so the periodic
setHasConnection(_serial->isConnected()) in MyMesh left hasConnection()
permanently true -- making UITask mark every received message read on
arrival. The same stuck flag also suppressed the DM counter and the
new-message screen wake. Guard the call so only builds with a real
companion (BLE / WiFi / wired SERIAL_RX) derive connection state from the
interface; companion-less builds report not-connected. The core
ArduinoSerialInterface is unchanged, preserving wired-companion behaviour.
- MyMesh.cpp: guard setHasConnection() for companion-less builds
2026-06-22 07:01:18 +10:00
pelgraine 6aa12f27b5 Settingsscreen.h — added isInWifiNetworkSelect() (returns true while EDIT_WIFI + WIFI_PHASE_SELECT), sitting next to isInWifiPasswordEntry().
main.cpp — added a dispatch block in the Settings handler: when the network picker is showing and key=='\b' with shift consumed, it calls ui_task.injectKey('q'), which runs the existing 'q' exit path synchronously (tear-down of EDIT_WIFI, onboarding handling, wifiReconnectSaved()) and refreshes. So Shift+Del and Q now both exit the picker, with no duplicated exit logic.
2026-06-17 07:02:21 +10:00
pelgraine 7a61f3efe2 fix regression on the pro and max where q was causing early exit on wifi password and notes screen. update firmware version and build date. 2026-06-17 06:33:28 +10:00
pelgraine c72253eb7b update firmware version and build date 2026-06-10 23:16:32 +10:00
pelgraine 40571e398e fix battery size for max in variant.h and comments 2026-06-10 23:11:25 +10:00
pelgraine 62628ec751 fix Max battery size 2026-06-10 22:57:46 +10:00
pelgraine 7f9503c988 Fix alarm screen hint text when autolock has been applied 2026-06-07 22:17:57 +10:00
pelgraine 51ef01f3a6 Max - Silent alarm option added 2026-06-07 21:33:25 +10:00
pelgraine 9a04bd1a67 fix outdated readme links 2026-06-07 06:45:13 +10:00
pelgraine 9e11178374 update readme 2026-06-07 06:35:20 +10:00
pelgraine ed039aa711 SMS: show unread count on the inbox badge instead of conversation count.
The "SMS Inbox" badge on the Phone & SMS landing screen previously showed
the number of conversations regardless of read state. It now shows the
number of unread received messages and disappears when there are none.
Read state is tracked persistently, so it survives reboots and modem
power-cycles (the flag lives in each record on the SD card).

SMSStore:
- Add a `read` byte to SMSRecord, reusing one of the reserved bytes so the
  record stays 256 bytes and every existing field offset is unchanged
  (existing .sms files remain readable).
- saveMessage marks sent messages read and received messages unread.
- loadConversations scans each file and reports unreadCount (received
  messages with read=0); preview / last-message behaviour is unchanged.
- markConversationRead / markFileRead flip received-unread records to read
  in place (open "r+", rewrite only the affected records).
- begin() runs a one-time migration on first boot that marks all
  pre-existing history read, gated by a marker file (/sms/rdmig.dat), so
  old messages do not all appear as unread after the update.

SMSScreen:
- Landing-screen badge sums unreadCount across conversations, hidden at zero.
- Opening a conversation marks it read and clears its in-RAM count.
- A message arriving while its conversation is open is marked read.
- Inbox reloads on the landing screen as well as the inbox view, so the
  badge updates live when a message arrives.
2026-06-07 06:15:45 +10:00
pelgraine 57b63bed47 Max - grid alignment fixes and more cells 2026-06-07 05:52:30 +10:00
pelgraine 38656f9d1d Add on-device Rx Log packet sniffer and RX packet counter
RX packet counter: shows total received packets (flood + direct) on the
radio details page; RAM-only, resets on boot and on any SF/freq/BW change.

Rx Log: app-style packet sniffer opened from Settings > "Rx Log >>".
Captures the last 100 received packets pre-filter via Dispatcher::logRx
into a PSRAM ring, with decoded "sender: message" lines matched by packet
hash for decryptable channels. Each entry shows route/type, time, size,
hash, path, channel or From/To, SNR. W/S scroll, Q back to Settings;
T5S3 swipe-scroll rides the same path.

Files: MyMesh.h/.cpp, RxLogScreen.h (new), UITask.h/.cpp,
SettingsScreen.h, main.cpp.
2026-06-07 05:14:16 +10:00
pelgraine 353048aab3 So the power investigation wraps up like this:
GPS — fixed (the "off" toggle and boot path now actually cut the XL9555 rail). Kept in main.cpp + UITask.cpp.
BLE controller — the ~13 mA between the BLE build (BLE off) and standalone is the controller staying initialised; the boot-gate in SerialBLEInterface.cpp/.h defers BLEDevice::init() until first enable, reclaiming it. That's the meaningful idle win.
CPU, gyro rail, ES8311, frontlight — all measured and ruled out. The residual ~12 mA Max-vs-Pro is distributed always-on hardware with no software switch — hardware overhead, not a bug.

Defer ESP32 BLE controller bring-up to first user enable
MyMesh::startInterface() called serial.enable() unconditionally at boot. On the ESP32 BLE build this ran the deferred-init SerialBLEInterface's _realBegin()/BLEDevice::init() and powered the BT controller before main.cpp's boot-time disable(), which only stops advertising and cannot power the controller back down -- so the controller stayed up while "off", drawing ~13 mA at idle. Guard the enable() so ESP32 BLE builds skip it at boot; the controller now comes up lazily on the first enable() when the user turns Bluetooth on from the Bluetooth page. WiFi builds are unaffected and still enable at boot.
2026-06-07 00:09:56 +10:00
pelgraine 8ac9aeed28 Max - fixed usb C wake auto power on after shutdown is used, and minor ui fix to home screen when BLE is on but not connected 2026-06-06 21:23:44 +10:00
pelgraine 378db7932c udpate firmware version 2026-06-06 21:09:48 +10:00
pelgraine ea98eaead4 audiobook player guide updated.
Summary of what changed in each file, all confined to the change points shown in the diffs:
ChannelScreen.h — ChannelMessage gains a session-only scope_idx (initialised to 0xFF in the constructor and explicitly reset to 0xFF on SD load, since region is not persisted); addMessage gains a trailing defaulted scope_idx and stores it. The message-list line now renders (Xh)(Xb) Xm, with the byte figure taken from path_len's upper bits for floods and from the_mesh.getNodePrefs()->path_hash_mode + 1 for the 0xFF/0 sentinels. The path overlay shows Route: ... (N-byte) and a new Region: line (name, or (reg unknown), or nothing when unscoped).
MyMesh.h / .cpp — a fixed 28-entry SCOPE_NAMES table, a _scope_keys array precomputed once at the end of begin() via initScopeKeys(), resolveScopeIndex() (matches pkt->transport_codes[0] against the candidates; 0xFF unscoped, 0xFE unmatched), and the public getScopeName() accessor. onChannelMessageRecv resolves the index and passes it to newMsg.
AbstractUITask.h / UITask.h / UITask.cpp — newMsg gains a trailing uint8_t scope_idx = 0xFF; only the channel addMessage call forwards it. DMs and sent echoes keep the default, so they stay unscoped.
MsgFileRecord and the SD save/load format are untouched, so there's no version bump.
2026-06-06 20:42:21 +10:00
pelgraine 451f4b01f3 remove redundant merge script 2026-06-05 07:38:23 +10:00
pelgraine f372b7158a fixed merged firmware bootloader script 2026-06-05 07:37:48 +10:00
pelgraine 54ca0638eb update readme 2026-06-05 04:54:50 +10:00
pelgraine 28f50ae373 update firmware build date. add toaster popup to voice messages screen for when contact doesn't have direct path 2026-06-05 02:58:31 +10:00
pelgraine 585bf7e381 Fixed audiobookplayer crowded footer text and filtering out m4b files for now until we get that sorted. Fixed voice message recording playback for the max. 2026-06-05 02:39:29 +10:00
pelgraine 9080af8037 Max - increased buzzer length 2026-06-05 00:34:47 +10:00
pelgraine a594153b88 update readme for Max features 2026-06-05 00:26:20 +10:00
pelgraine fb4d8273a9 Max - New buzzer(vibrate) option in custom channel notification preferences - silent buzz notification. 2026-06-04 23:54:07 +10:00
pelgraine b6e3c7e0a5 implemented $PCAS04,7 - Multi-constellation mode (GPS, Galileo, BeiDou, and QZSS)
The default LilyGo/MeshOS firmware uses GPS-only ($PCAS04,1) & $PMTK869,1,1 - EASY predicted ephemeris
2026-06-04 23:25:03 +10:00