mirror of
https://github.com/torlando-tech/pyxis.git
synced 2026-07-18 17:46:28 +00:00
Settings/clock (user-reported):
- Announce interval: default 1h (was 60s); the field is now MINUTES (label
"Announce Interval (min):", populate /60, read *60).
- Prop sync interval: default 4h (was 1h); the field is now HOURS (label
"Prop Sync Interval (hrs):", populate /3600, read *3600); log prints hours.
- Settings clock now ticks live: SettingsScreen::tick() (throttled ~1s) is hooked
into UIManager::update() like the announce-list tick, so the Time/GPS/system
readouts refresh while the screen is open instead of being a static snapshot.
OTA repair (was broken two ways; diagnosed via an ultracode workflow):
- patch_nimble.py hardcoded the `tdeck` libdeps path, so building any OTHER env
(tdeck-ota gets its own libdeps tree) never received the NimBLE patch that
DEFINES nimble_host_reset_reason -> undefined-reference link error. Made it
env-aware (env.get("PIOENV",...)), matching the four sibling pre-scripts. Also
restores 3 NimBLE stability patches that were silently missing from OTA builds.
- ArduinoOTA onStart synchronously called TCPClientInterface::stop() (blocks up to
30s), overrunning espota's ~10s connect-back window -> "No response from device"
(phase 2), and its un-fed watchdog tripped reboots. Made onStart non-blocking.
- [env:tdeck-ota] upload_command invoked a non-existent tools/espota.py -> switched
to upload_protocol=espota.
- Do NOT WiFi.setSleep(false): the ESP32 requires WiFi modem-sleep when WiFi+BT
coexist (aborts at boot otherwise) -- documented inline.
Verified on device: tdeck-ota links; OTA over WiFi completes 100% (Result: OK) and
the device reboots clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UWZuYkHBRqNb6BZHV8sTG5
240 lines
12 KiB
INI
240 lines
12 KiB
INI
[env:tdeck]
|
|
extra_scripts =
|
|
pre:version.py
|
|
pre:generate_splash.py
|
|
pre:patch_nimble.py
|
|
pre:patch_msgpack.py
|
|
; patch_filestore.py silences upstream microStore's spammy
|
|
; "[ustore] get: key not found in index" print (fires on every
|
|
; path-store miss; saturated USB CDC during LXST calls). Set
|
|
; PYXIS_FILESTORE_DIAG=1 to also enable exists()/put() diagnostic
|
|
; prints when investigating path-store drift.
|
|
pre:patch_filestore.py
|
|
; patch_littlefs_paths.py normalizes microStore's LittleFS adapter paths to
|
|
; a leading "/" — ESP32 Arduino LittleFS rejects "./"-prefixed paths, which
|
|
; broke the path store (no peer paths learned). See the script header.
|
|
pre:patch_littlefs_paths.py
|
|
; sync_file_libdeps.py mirrors file:// lib_deps source trees into
|
|
; .pio/libdeps before each build. PIO doesn't re-sync file:// deps
|
|
; after first install — without this, edits to ~/repos/
|
|
; microReticulum (or any other file:// dep) silently never reach
|
|
; the device. That bit us on a microReticulum security fix.
|
|
pre:sync_file_libdeps.py
|
|
platform = espressif32
|
|
board = esp32-s3-devkitc-1
|
|
framework = arduino
|
|
|
|
; T-Deck Plus has ESP32-S3 with 8MB Flash + 8MB PSRAM
|
|
board_build.flash_mode = qio
|
|
board_build.partitions = partitions.csv
|
|
board_build.arduino.memory_type = qio_opi
|
|
board_upload.flash_size = 8MB
|
|
|
|
; Enable PSRAM (required for LVGL buffers)
|
|
board_build.arduino.psram_type = opi
|
|
|
|
; Serial monitor
|
|
monitor_speed = 115200
|
|
monitor_filters =
|
|
esp32_exception_decoder
|
|
time
|
|
|
|
; Library dependency finder mode (deep search)
|
|
; deep+ scans #include statements and auto-fetches matching libs from the
|
|
; registry — that pulled a parallel copy of microReticulum into
|
|
; .pio/libdeps/tdeck/microReticulum/ alongside our deps/microReticulum/
|
|
; overlay, and the linker picked the registry copy (silently dropping
|
|
; all our local .cpp changes). chain+ follows only explicit dependencies
|
|
; declared in library.json, so deps/microReticulum (via lib_extra_dirs)
|
|
; is the only microReticulum source.
|
|
lib_ldf_mode = chain+
|
|
|
|
; Build type
|
|
build_type = release
|
|
lib_deps =
|
|
; Explicit git dep so PIO links exactly ONE microReticulum (the
|
|
; live source). lib_extra_dirs was creating duplicate compilations
|
|
; — PIO compiled deps/microReticulum/ as one library AND auto-
|
|
; fetched the same source as another, leaving two copies of
|
|
; Transport::_path_store / _new_path_table in BSS. Different TUs
|
|
; ended up linking against different statics, so put() and
|
|
; exists() landed in different stores.
|
|
;
|
|
; Pinned to torlando-tech/microReticulum:pyxis-fixes-on-0.3.0 at
|
|
; SHA 3ee2bd8 — vanilla 0.3.0 + 4 PR-ready Cryptography + 1 link-
|
|
; proof + Resource progress-callback firing fixes. Bump SHA in
|
|
; tandem with conformance-bridge/CMakeLists.txt's FetchContent
|
|
; tag if either side updates.
|
|
; microReticulum: torlando-tech/microReticulum:pyxis-fixes-on-0.4.1 —
|
|
; upstream attermann/microReticulum master (0.4.1+16) + the small
|
|
; still-needed fixes: PKCS7/HMAC/X25519 crypto (proven byte-identical to
|
|
; python RNS 1.3.1), Packet link-proof callback, Identity short-sig guard,
|
|
; and the bz2 layer + decompress-on-receive in Resource::assemble(). The
|
|
; far-diverged 0.3.0 fork's Resource/Transport/Identity work is subsumed by
|
|
; upstream's reimplementation. Bump in lockstep with microLXMF below.
|
|
; cb71ace: OS::ltime() now uses the monotonic 64-bit esp_timer instead of a
|
|
; racy 32-bit millis() rollover counter (static low32/high32 raced across
|
|
; FreeRTOS tasks, inflating OS::time() by N*49.7 days — garbage convo
|
|
; timestamps, e.g. "Future"/"49w ago"/year-2046 now).
|
|
; 97fecfe: Identity::recall now accounts for the optional ratchet when
|
|
; extracting announce app_data (matches validate_announce). Without it,
|
|
; ratchet-bearing announces (Sideband/Columba) had app_data read 32 bytes
|
|
; too early, garbling peer display names ("ySId!M@pB`Z:ev"-style prefix).
|
|
; 3885b90: DestinationEntry caps persisted random_blobs to 16 (upstream defines
|
|
; PERSIST_RANDOM_BLOBS but never enforced it) — the unbounded set pushed path
|
|
; entries past microStore's 1024B value cap so they were rejected (empty path
|
|
; table), and under a raised cap bloated the FS until compaction crashed.
|
|
; 6054f6b: mirrors learned paths into the in-memory _path_table so path_table()
|
|
; (the UI announce list + T:PATHS) can enumerate them. *** STOPGAP ***: upstream
|
|
; attermann/microReticulum is mid-migration to the microStore-backed
|
|
; _new_path_table (no enumeration API) and left path_table()'s source
|
|
; (_path_table) unpopulated. When bumping past upstream finishing that migration
|
|
; (_path_table removed / a for_each API added), DELETE the mirror — see the long
|
|
; comment at the _path_table mirror in Transport::inbound for details.
|
|
https://github.com/torlando-tech/microReticulum.git#6054f6ba82367628a85cd07fcb668b95e947f046
|
|
; microLXMF: chore/microreticulum-0.4.1-layout — includes namespaced to
|
|
; <microReticulum/...> for the 0.4.x src/microReticulum/ layout.
|
|
; 3cdde79: faster load_message_metadata — single LittleFS open (read_file
|
|
; returns 0 on miss, no separate file_exists probe) + JSON field filter that
|
|
; skips the large "packed" blob. ~2x quicker conversation load.
|
|
https://github.com/torlando-tech/microLXMF.git#3cdde79172af915c4e330be36ff9775550e57fa5
|
|
lvgl/lvgl@^8.3.11
|
|
bblanchon/ArduinoJson@^7.4.2
|
|
hideakitai/MsgPack@^0.4.2
|
|
rweather/Crypto@^0.4.0
|
|
mikalhart/TinyGPSPlus@^1.0.3
|
|
jgromes/RadioLib@^6.0
|
|
WiFi
|
|
SPI
|
|
Wire
|
|
SD
|
|
FS
|
|
LittleFS
|
|
tdeck_ui
|
|
sx1262_interface
|
|
tone
|
|
auto_interface
|
|
h2zero/NimBLE-Arduino@^2.1.0
|
|
ble_interface
|
|
lxst_audio
|
|
sh123/esp32_codec2@^1.0.7 ; carries modern codec2 since PR #4 (Jan 2026); -D__EMBEDDED__ + -DMEMORY_CRITICAL set in build_flags below put codebooks in flash
|
|
libbz2
|
|
; Pinned to attermann/microStore@ceea8f5 (2026-04-14 "Added SD
|
|
; filesystem and enhanced Flash filesystem"). Pre-0.1.6 — newer
|
|
; commits introduced a dynamic segment-size refactor that hasn't
|
|
; been validated against pyxis's MessageStore / path-store usage
|
|
; patterns. Bump the SHA when ready to re-validate. Matches the
|
|
; same pin used in conformance bridge builds.
|
|
https://github.com/attermann/microStore.git#c5fb69d68229e684c7fbd17692a67ae8193b84e2
|
|
|
|
; Build configuration
|
|
build_flags =
|
|
-std=gnu++17
|
|
-DBOARD_HAS_PSRAM
|
|
-DBOARD_ESP32
|
|
; Arduino loop task stack — Codec2 decode (lpc_post_filter + kiss_fft)
|
|
; uses ~6KB stack on top of ~10KB normal peak. 24KB gives safe headroom.
|
|
-DARDUINO_LOOP_STACK_SIZE=24576
|
|
-DARDUINO_USB_CDC_ON_BOOT=1
|
|
-DARDUINO_USB_MODE=1
|
|
-DLV_CONF_INCLUDE_SIMPLE
|
|
-Ilib
|
|
-Ilib/libbz2
|
|
; -Ideps/microReticulum/src — removed in favor of PIO's lib_deps
|
|
; auto-include of .pio/libdeps/tdeck/microReticulum/src. Keeping
|
|
; the hardcoded -Ideps/... path here would shadow PIO's path
|
|
; (build_flags are searched first) and let the submodule's stale
|
|
; headers win over the freshly-fetched git pin from lib_deps.
|
|
;
|
|
; -Ilib/microreticulum-shim alone is enough — subdir lookups use <Cryptography/BZ2.h>,
|
|
; <Utilities/Stream.h>, etc. Don't add -Ilib/microreticulum-shim/Utilities on top:
|
|
; that puts our Stream.h on the GLOBAL header path and breaks Arduino's
|
|
; Wire.cpp (`class TwoWire: public Stream` finds ours first).
|
|
-Ilib/microreticulum-shim
|
|
-DBZ_NO_STDIO
|
|
; codec2 codebooks in flash (.const) instead of RAM — without this
|
|
; ~127KB of codebook tables land in BSS and compete with LVGL's
|
|
; framebuffer. Moved here from lib/codec2/library.json when we
|
|
; swapped the vendor for sh123/esp32_codec2_arduino@1.0.7
|
|
; (which carries modern codec2 since their PR #4 / Jan 2026).
|
|
-D__EMBEDDED__
|
|
-DMEMORY_CRITICAL
|
|
; Move microReticulum allocations from internal DRAM (~320KB total)
|
|
; to PSRAM (~8MB on T-Deck Plus). The default `::operator new` on
|
|
; ESP32 prefers internal SRAM and would otherwise compete with LVGL
|
|
; framebuffers, BLE/WiFi, etc — under heavy announce flood we saw
|
|
; the path table fill internal heap and "Failed to add destination
|
|
; to path table" / "PropagationNodeManager: Pool full" spam.
|
|
; RNS_PSRAM_ALLOCATOR routes default new/delete to ps_malloc;
|
|
; RNS_PSRAM_POOL_ALLOCATOR routes long-lived STL containers (path
|
|
; table) into a dedicated 2MB TLSF pool in PSRAM.
|
|
-DRNS_DEFAULT_ALLOCATOR=RNS_PSRAM_ALLOCATOR
|
|
-DRNS_CONTAINER_ALLOCATOR=RNS_PSRAM_POOL_ALLOCATOR
|
|
-DRNS_PSRAM_POOL_BUFFER_SIZE=2048000
|
|
; Enable filesystem-backed path persistence in microReticulum.
|
|
; Without these, Transport::start() skips _path_store.init(), and
|
|
; every announce-driven _new_path_table.put() bails silently at
|
|
; TypedStore::isValid() → "Failed to add destination to path table"
|
|
; spam. With LittleFS as the backend (USTORE_USE_LITTLEFS) the
|
|
; sustained-write pattern is tractable.
|
|
-DRNS_USE_FS
|
|
-DRNS_PERSIST_PATHS
|
|
; Test-mode hooks: hard-override the TCP server NVS settings to
|
|
; point at the Mac-side rnsd (<MAC-RNSD-HOST>:4242) and add a `T:`-
|
|
; prefixed serial command interface (T:DEST, T:SEND, T:STATE,
|
|
; T:RX, T:ANN, etc.) for the harness to drive the device. Remove
|
|
; this group of flags for production firmware.
|
|
-DPYXIS_TEST_HOOKS
|
|
; Read host:port from env vars so they aren't hardcoded in source.
|
|
; Set PYXIS_TEST_TCP_HOST / PYXIS_TEST_TCP_PORT before `pio run`
|
|
; (e.g. via a sourced .env file, or in your shell profile). If
|
|
; unset they default to empty/0; main.cpp's test-hooks block falls
|
|
; back to NVS-stored values when host is empty so unset env vars
|
|
; don't brick test mode silently. See .env.example.
|
|
; Both quoted so an unset env var → empty string literal (`""`)
|
|
; instead of an empty token (which breaks `PORT > 0` parse).
|
|
; main.cpp's atoi() handles the port string side.
|
|
'-DPYXIS_TEST_TCP_HOST="${sysenv.PYXIS_TEST_TCP_HOST}"'
|
|
'-DPYXIS_TEST_TCP_PORT="${sysenv.PYXIS_TEST_TCP_PORT}"'
|
|
; microStore LittleFS adapter — replaces pyxis's pre-graft
|
|
; lib/universal_filesystem/ (which targeted SPIFFS directly).
|
|
; LittleFS reuses the existing partition labeled "spiffs" (LittleFS's
|
|
; default partitionLabel is "spiffs" too) and reformats it on first
|
|
; boot. SPIFFS was swapped out because its GC-induced flush stalls
|
|
; caused FileStore::put → flush_buffer() to fail under sustained
|
|
; announce writes (~3/sec), surfacing as path-table-add error spam.
|
|
-DUSTORE_USE_LITTLEFS
|
|
; Cap the path-store live record count (defense-in-depth). microReticulum now
|
|
; bounds each entry's random_blobs (the actual leak that filled the FS), but this
|
|
; also bounds the TOTAL live set so the compaction output segment (path_store_0)
|
|
; cannot bloat the 1.875MB partition over long uptime — prune_index runs inside
|
|
; put() and compact(). 400 records x ~560B ~= 225KB, far from full.
|
|
-DUSTORE_DEFAULT_MAX_RECS=400
|
|
-DUSE_NIMBLE
|
|
-DCONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=1
|
|
-Os
|
|
-DCORE_DEBUG_LEVEL=2
|
|
; Enable memory instrumentation (heap/stack monitoring)
|
|
; Remove this flag to disable instrumentation and eliminate overhead
|
|
-DMEMORY_INSTRUMENTATION_ENABLED
|
|
; Enable boot profiling (timing instrumentation for setup phases)
|
|
; Remove this flag to disable boot profiling
|
|
-DBOOT_PROFILING_ENABLED
|
|
; Reduce log verbosity during boot for faster startup
|
|
; CORE_DEBUG_LEVEL=2 (WARNING) reduces INFO-level log output
|
|
-DBOOT_REDUCED_LOGGING
|
|
|
|
; OTA flashing environment (wireless upload via ArduinoOTA)
|
|
; Usage: pio run -e tdeck-ota -t upload
|
|
; The old upload_command pointed at tools/espota.py (which does not exist in the
|
|
; repo); use PlatformIO's built-in espota uploader instead.
|
|
; NOTE: espota resolves the host via gethostbyname, which on macOS does NOT do
|
|
; mDNS, so the .local default may fail to resolve -- if upload can't find the
|
|
; host, pass the device's LAN IP explicitly:
|
|
; pio run -e tdeck-ota -t upload --upload-port <device-ip>
|
|
[env:tdeck-ota]
|
|
extends = env:tdeck
|
|
upload_protocol = espota
|
|
upload_port = pyxis-tdeck.local
|
|
upload_flags = --port=3232
|