Files
pyxis/platformio.ini
T
torlando-tech a9d79660a4 sec: move PYXIS_TEST_TCP_HOST/PORT to env vars + .env.example
The previous hardcoded LAN IP in platformio.ini identified a specific
deployment (Mac rnsd at a 10.0.0.x address). Move host:port to env
vars read at build time via PIO's ${sysenv.X} interpolation, with
a .env.example template + .env gitignored. Production builds (no
PYXIS_TEST_HOOKS) skip the macros entirely.

Changes:
  - platformio.ini (both env blocks): replace literal IP/port with
    ${sysenv.PYXIS_TEST_TCP_HOST} / ${sysenv.PYXIS_TEST_TCP_PORT}.
    Both quoted so an unset env var expands to an empty string
    literal "" rather than an empty token (the latter would break
    the PORT > 0 numeric compare in main.cpp).
  - src/main.cpp test-hooks block: guard host/port assignment so
    empty values fall back to NVS-stored settings. atoi() handles
    the port string side. Missing env var won't silently brick
    test mode — it just becomes "use whatever's in NVS".
  - .env.example: checked-in template with placeholder values
    (TEST-NET-1 192.0.2.x range, not a real LAN IP).
  - .gitignore: add `.env` so the populated local copy stays out
    of source.

Build: verified clean with env vars UNSET (NVS-fallback path) and
SET (override path); 27.4% RAM, 79.8% Flash in both cases.
2026-05-11 00:06:35 -04:00

343 lines
15 KiB
INI

; T-Deck environment using Bluedroid BLE stack (fallback, uses more RAM)
[env:tdeck-bluedroid]
extra_scripts =
pre:version.py
pre:generate_splash.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
; Dependencies
lib_deps =
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
universal_filesystem
sx1262_interface
tone
auto_interface
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
https://github.com/attermann/microStore.git
; 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+
; (was: lib_extra_dirs = deps/microReticulum — replaced by an
; explicit file:// lib_dep below. lib_extra_dirs caused the duplicate
; compilation that produced two _path_store statics.)
; Build configuration
build_type = release
build_flags =
-std=gnu++11
-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
-DUSE_BLUEDROID
-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
; Default T-Deck environment using NimBLE BLE stack (uses ~100KB less RAM than Bluedroid)
[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
; 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.
https://github.com/torlando-tech/microReticulum.git#3ee2bd8337801173ed107c8d1deb6865739d37ff
; microLXMF — pinned to main HEAD. Same coordination rule as
; microReticulum: bump both pins together if upstream changes.
https://github.com/torlando-tech/microLXMF.git#9876dfff8ec4a2ed1e28adef4375ec57b7e9eb4b
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
universal_filesystem
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
https://github.com/attermann/microStore.git
; Build configuration
build_flags =
-std=gnu++11
-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
-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
[env:tdeck-ota]
extends = env:tdeck
upload_protocol = custom
upload_command = "$PYTHONEXE" tools/espota.py -i pyxis-tdeck.local -p 3232 -f $SOURCE