- Fix link packet routing in microReticulum to only transmit on the
link's attached interface (was flooding all interfaces including LoRa)
- Batch up to 8 Codec2 frames per Reticulum packet to reduce per-packet
encryption/transport overhead (~3 packets/sec instead of 25)
- Add TX diagnostics: hex dump of first 2 packets, per-interval stats
with link status, idle/drop warnings
- Audio now reaches remote end (TX=325 frames in 12s test call)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace custom ES7210 register-level driver with the verbatim LilyGO
T-Deck Plus ES7210 library. The custom driver was writing MODE_CONFIG
and clock doubler registers (master mode path) which broke the ES7210's
clock chain, causing all-zero PCM output. The LilyGO library in slave
mode leaves those registers at power-on defaults, which is correct since
the ESP32 I2S master provides MCLK/BCLK/LRCK.
Also includes LXST voice call protocol improvements:
- LXST IN destination for receiving calls
- Announce handler for tracking voice-capable peers
- Path request before outgoing calls
- Throttled SPIFFS saves in microReticulum (dirty flag)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix thread safety: defer Reticulum link callbacks (packet, link_closed)
to call_update() which runs under LVGL lock, preventing crashes from
concurrent LVGL access across cores
- Fix outgoing call signal handling: store link reference and re-register
packet/link_closed callbacks in on_call_link_established so signals
are actually received
- Fix call answer screen freeze: update UI before blocking audio init
(I2S/ES7210/Codec2 setup) so screen renders immediately
- Fix audio direction: use startPlayback() (speaker RX) instead of
startCapture() (mic TX) so received audio is actually heard
- Add msgpack wire format for LXST signalling and audio frames
- Add LXST IN destination for receiving calls + announce support
- Add incoming call UI (Answer/Reject buttons) on CallScreen
- Add path request before outgoing call link establishment
- Add LXST announce handler registration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add ES7210 I2C address and I2S mic capture pin definitions
- Add ring/hangup tone helpers to Tone library
- Add lxst_audio library scaffold
- Add Codec2 dependency to platformio.ini
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add CallScreen with ring/active/ended states and call controls
- Add call state machine to UIManager (link establish, identify, ring, answer)
- Add call button to ChatScreen header
- Add call initiate/hangup with Reticulum Link management
- Add StatusScreen call status display
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix slow screen wake: track screen_off_time and wake on any activity
newer than when screen turned off (was requiring activity <1s ago)
- Add MEMORY_MONITOR_POLL() to main loop for deferred logging
- Add NVS crash breadcrumb system for LXST call debugging
- Update microReticulum submodule (memory stability fixes)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Enable CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL to move NimBLE's
internal buffer pools (~35-45KB) from internal heap to PSRAM.
Fixes heap exhaustion crash during BLE operations.
Before: free=17952 max_block=11252 (crash)
After: free=97396 max_block=86004 at boot, stable ~38KB during operation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace std::map and std::vector with fixed-size pools in
BLEInterface (fragmenters, pending handshakes, pending data)
- Track keepalive failures and disconnect after 3 consecutive
- Force-disconnect zombie peers detected by BLEPeerManager
- Add periodic advertising refresh (every 60s) to combat silent stops
- Buffer incoming data when identity not yet mapped instead of dropping
- Subtract ATT_OVERHEAD from MTU in NimBLEPlatform connection setup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update microReticulum submodule: static pool arrays (~20 pools) moved
from BSS segment to PSRAM via heap_caps_aligned_alloc at startup.
Before: boot heap ~116KB, steady-state max_block 7.6KB, constant skipped announces
After: boot heap ~161KB, steady-state max_block 65KB, zero skipped announces
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Includes:
- Link operator== / operator!= for correct pool lookups
- activate_link null guard and copy-before-remove
- Known destinations pool increased to 2048 slots
- Proactive culling at 90% threshold
- Low-memory guard for resource retries on ESP32
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
32KB was insufficient for the deep call chain when receiving large
messages over links (transport → link → resource → LXMF unpack →
crypto → msgpack). Crashed with StoreProhibited on 935-byte messages.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TCP interface was never created if WiFi wasn't connected at boot time.
The settings-changed handler tried to restart it but the objects didn't
exist. Extract TCP creation into start_tcp_interface() helper and call
it from boot, settings changes, and a WiFi state-change detector in
the main loop.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The 16KB stack was insufficient for deep call chains during message
delivery proof handling (transport → crypto → proof callback → app
callback → SPIFFS I/O → msgpack unpack), causing crashes every few
minutes. Also adds the stack size flag to tdeck-bluedroid env which
was missing it entirely.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add version.py PlatformIO pre-build script that reads version from
`git describe --tags --always` and defines FIRMWARE_VERSION as a build
flag. Local builds without tags fall back to "dev". Also rename
FIRMWARE_NAME from "microReticulum" to "Pyxis".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace manual DTR toggle with esploader's built-in hardReset() which
uses RTS (EN pin) to properly reset the ESP32-S3 after flashing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Transport tracing and missing enableTracing flag caused timing issues
with ESP32-S3 USB-Serial/JTAG during bootloader sync. Also fixes
flashMode/flashFreq format, routes esptool output to on-page log,
and adds firmware binaries.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split T-Deck firmware from microReticulum examples/lxmf_tdeck/ into its
own repo. microReticulum is consumed as a git submodule dependency pinned
to feat/t-deck. All include paths updated from relative symlinks to bare
includes resolved via library build flags.
Both tdeck (NimBLE) and tdeck-bluedroid environments compile successfully.
Licensed under AGPLv3.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>