Files
wadamesh/platformio.ini
T
Kaj SchittecatandClaude Opus 5 335a64c118 touch: core-v1.17.1 (beta_60 boot loop + unreachable contacts) + release firmware-data gate
Core (core-v1.17.1, meshcomod 5406093): 1.17 reserved MAX_ANON_CONTACTS slots
at the head of contacts[], which broke two things in beta_60 —

- resetContacts() claimed those slots while the lazily-allocated PSRAM table was
  still NULL, so the new bootstrapRTCfromContacts() NULL-deref'd at boot on any
  device whose contact store loaded nothing: fresh install, erase-flash, or SD
  not mounted yet (#249). Boards with saved contacts booted fine, which is how
  it passed bench testing.
- getContactByIdx() stayed raw while getNumContacts() excludes the reserved
  slots, so every pairing of the two — contact list, action sheets, phone-app
  sync, getContactForSave — read empty slots and could not reach the newest 8
  real contacts. A just-added contact was invisible and its action-sheet
  operations resolved to a blank slot (#252).

Fork side:
- loadContacts() skips blank records, clearing the placeholder contacts beta_60
  wrote into the contacts file (the next save drops them permanently).
- Chat threads follow a peer's rename. The thread is matched by key but its name
  was never updated, while inbound messages are filed by sender name — so the
  first message after a rename created a duplicate thread (#252).
- release.sh derives FIRMWARE_VERSION / build date / core version from the tag
  and the pinned core, keeps the in-tree dev default in step, and ABORTS the
  release if any staged image does not embed its own tag. beta_60 shipped
  reporting v1.16.0-touch because that value was hand-maintained.

All 8 S3 envs build green on core-v1.17.1.

Reported-by: Pierre747, rustinmyeye, myshoeisonfire

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 08:20:00 +02:00

1540 lines
55 KiB
INI

; wadamesh — Heltec V4 TFT touch firmware.
; Standalone PlatformIO project: the MeshCore core is consumed as a library
; (lib/MeshCore here; a git-tagged fork once published). This env is the flattened
; equivalent of meshcomod's heltec_v4_tft_companion_radio_usb_tcp_touch.
[platformio]
default_envs =
heltec_v4_tft_companion_radio_usb_tcp_touch
LilyGo_TDeck_companion_radio_touch
ThinkNode_M9_companion_radio_touch
[env:heltec_v4_tft_companion_radio_usb_tcp_touch]
platform = platformio/espressif32@6.11.0
framework = arduino
board = heltec_v4
monitor_speed = 115200
board_build.partitions = partitions_tft_touch.csv
extra_scripts = pre:scripts/inject_wifi_env.py, merge-bin.py
build_flags =
; 1.17 core: ESP32Board.cpp includes <target.h> -> MicroNMEALocationProvider.h (header-only
; provider), so MicroNMEA never chains into the core lib's LDF scope -- hand it the path.
-I"${platformio.libdeps_dir}/${this.__env__}/MicroNMEA/src"
-Wno-deprecated-declarations -Wno-unused-parameter -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1
-D MC_VENDORED_TOUCH_APP
; NOTE: tried -D ARDUINO_USB_MODE=1 (HW-CDC, drops unused TinyUSB MSC/DFU ≈ 12 KB internal
; DRAM) — but on the real V4 the binary companion link regressed: small per-message frames
; arrived yet the larger device-profile frame (node name + keys) dropped bytes over HW-CDC's
; smaller TX FIFO. Reverted to the board JSON's TinyUSB CDC. Revisit only with an HW-CDC TX
; buffer/DTR-wait fix verified on hardware. (T-Deck ships MODE=1 and is fine — board-specific.)
-D LORA_FREQ=869.618
-D LORA_BW=62.5
-D LORA_SF=8
-D ENABLE_PRIVATE_KEY_IMPORT=1
-D ENABLE_PRIVATE_KEY_EXPORT=1
-D RADIOLIB_EXCLUDE_CC1101=1
-D RADIOLIB_EXCLUDE_RF69=1
-D RADIOLIB_EXCLUDE_SX1231=1
-D RADIOLIB_EXCLUDE_SI443X=1
-D RADIOLIB_EXCLUDE_RFM2X=1
-D RADIOLIB_EXCLUDE_SX128X=1
-D RADIOLIB_EXCLUDE_AFSK=1
-D RADIOLIB_EXCLUDE_AX25=1
-D RADIOLIB_EXCLUDE_HELLSCHREIBER=1
-D RADIOLIB_EXCLUDE_MORSE=1
-D RADIOLIB_EXCLUDE_APRS=1
-D RADIOLIB_EXCLUDE_BELL=1
-D RADIOLIB_EXCLUDE_RTTY=1
-D RADIOLIB_EXCLUDE_SSTV=1
-D ESP32_PLATFORM
; --- sensors ---
-D ENV_INCLUDE_GPS=1
-D ENV_INCLUDE_AHTX0=1
-D ENV_INCLUDE_BME280=1
-D ENV_INCLUDE_BMP280=1
-D ENV_INCLUDE_SHTC3=1
-D ENV_INCLUDE_SHT4X=1
-D ENV_INCLUDE_LPS22HB=1
-D ENV_INCLUDE_INA3221=1
-D ENV_INCLUDE_INA219=1
-D ENV_INCLUDE_INA226=1
-D ENV_INCLUDE_INA260=1
-D ENV_INCLUDE_MLX90614=1
-D ENV_INCLUDE_VL53L0X=1
-D ENV_INCLUDE_BME680=1
-D ENV_INCLUDE_BMP085=1
; --- Heltec LoRa32 V4 board ---
-I variants/heltec_v4
-D HELTEC_LORA_V4
-D USE_SX1262
-D ESP32_CPU_FREQ=80
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D P_LORA_TX_LED=35
-D P_LORA_DIO_1=14
-D P_LORA_NSS=8
-D P_LORA_RESET=12
-D P_LORA_BUSY=13
-D P_LORA_SCLK=9
-D P_LORA_MISO=11
-D P_LORA_MOSI=10
-D P_LORA_PA_POWER=7
-D P_LORA_PA_EN=2
-D P_LORA_PA_TX_EN=46
-D P_LORA_GC1109_PA_EN=2
-D P_LORA_GC1109_PA_TX_EN=46
-D P_LORA_KCT8103L_PA_CSD=2
-D P_LORA_KCT8103L_PA_CTX=5
-D PIN_USER_BTN=0
-D PIN_VEXT_EN=36
-D PIN_VEXT_EN_ACTIVE=HIGH
-D LORA_TX_POWER=10
-D MAX_LORA_TX_POWER=22
-D SX126X_REGISTER_PATCH=1
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
-D PIN_GPS_RX=38
-D PIN_GPS_TX=39
-D PIN_GPS_RESET=42
-D PIN_GPS_RESET_ACTIVE=LOW
-D PIN_GPS_EN=34
-D PIN_GPS_EN_ACTIVE=LOW
-D PIN_ADC_CTRL=37
-D PIN_VBAT_READ=1
; --- TFT ---
-D HELTEC_LORA_V4_TFT
-D PIN_BOARD_SDA=4
-D PIN_BOARD_SCL=3
-D DISPLAY_ROTATION=2
-D DISPLAY_SCALE_X=1.0
-D DISPLAY_SCALE_Y=1.0
-D PIN_TFT_RST=18
-D PIN_TFT_VDD_CTL=-1
-D PIN_TFT_LEDA_CTL=21
-D PIN_TFT_LEDA_CTL_ACTIVE=HIGH
-D PIN_TFT_CS=15
-D PIN_TFT_DC=16
-D PIN_TFT_SCL=17
-D PIN_TFT_SDA=33
; --- CHSC6x cap touch ---
-D HAS_HELTEC_V4_CAP_TOUCH=1
-D PIN_TOUCH_SDA=47
-D PIN_TOUCH_SCL=48
-D PIN_TOUCH_RST=44
-D HELTEC_V4_BUZZER_PIN=6
; --- touch UI / companion stack ---
-I include
-I src
-I src/ui-touch
-D UI_LVGL=1
-D HAS_TOUCH_UI=1
; Heltec V4 Expansion Kit: local environment sensors UI (Sensors tab, Home env
; widget, Local-Sensors page). Board-gated — only this env compiles it.
-D HAS_EXPANSION_KIT=1
-D FIRMWARE_OTA_ENV='"heltec_v4_tft_companion_radio_usb_tcp_touch"'
-D ENABLE_ADVERT_ON_BOOT=0
-D LV_CONF_PATH=lv_conf.h
-D LV_CONF_INCLUDE_SIMPLE=1
; Smoother scroll: lower deceleration than LVGL's default (10) so flicks glide
; longer instead of stopping abruptly. lv_conf leaves this unset, so this -D wins.
-D LV_INDEV_DEF_SCROLL_THROW=7
-D USER_SETUP_LOADED=1
-D ST7789_DRIVER=1
-D TFT_WIDTH=240
-D TFT_HEIGHT=320
-D TFT_MOSI=33
-D TFT_SCLK=17
-D TFT_CS=15
-D TFT_DC=16
-D TFT_RST=18
-D TFT_MISO=-1
-D SPI_FREQUENCY=80000000
-D TFT_RGB_ORDER=TFT_RGB
-D TFT_INVERSION_ON=1
-D TFT_BL=21
-D TFT_BACKLIGHT_ON=1
-D MAX_CONTACTS=2000
-D MAX_GROUP_CHANNELS=40
-D DISPLAY_CLASS=ST7789LCDDisplay
-D ADMIN_PASSWORD='"password"'
-D MULTI_TRANSPORT_COMPANION=1
-D WADAMESH_FORK_BUILD=1
-D TCP_PORT=5000
-D WS_PORT=8765
-D BLE_PIN_CODE=123456
-D CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=1
-D CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
-D CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096
build_src_filter =
+<*.cpp>
+<*.c>
+<helpers/*.cpp>
+<helpers/esp32/*.cpp>
+<helpers/input/*.cpp>
+<ui-touch/*.cpp>
+<ui-touch/*.c>
+<../variants/heltec_v4/*.cpp>
lib_deps =
; MeshCore core = the meshcomod monorepo built as a lib, pinned by tag.
; Touch-app files (TouchPrefsStore, WifiRuntimeStore, transports, ...) are
; vendored in this app's src/ and dropped from the lib via -DMC_VENDORED_TOUCH_APP.
https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.1
SPI
Wire
jgromes/RadioLib @ ^7.6.0
rweather/Crypto @ ^0.4.0
adafruit/RTClib @ ^2.1.3
melopero/Melopero RV3028 @ ^1.1.0
electroniccats/CayenneLPP @ 1.6.1
h2zero/NimBLE-Arduino @ 1.4.3
adafruit/Adafruit INA3221 Library @ ^1.0.1
adafruit/Adafruit INA219 @ ^1.2.3
robtillaart/INA226 @ ^0.6.4
adafruit/Adafruit INA260 Library @ ^1.5.3
adafruit/Adafruit AHTX0 @ ^2.0.5
adafruit/Adafruit BME280 Library @ ^2.3.0
adafruit/Adafruit BMP280 Library @ ^2.6.8
adafruit/Adafruit SHTC3 Library @ ^1.0.1
sensirion/Sensirion I2C SHT4x @ ^1.1.2
arduino-libraries/Arduino_LPS22HB @ ^1.0.2
adafruit/Adafruit MLX90614 Library @ ^2.1.5
adafruit/Adafruit_VL53L0X @ ^1.2.4
stevemarple/MicroNMEA @ ^2.0.6
adafruit/Adafruit BME680 Library @ ^2.0.4
adafruit/Adafruit BMP085 Library @ ^1.2.4
adafruit/Adafruit ST7735 and ST7789 Library @ ^1.11.0
https://github.com/Quency-D/chsc6x/archive/5cbead829d6b432a8d621ed1aafd4eb474fd4f27.zip
ESP32Async/ESPAsyncWebServer @ 3.10.3
file://arch/esp32/AsyncElegantOTA
lvgl/lvgl @ ^8.3.11
bodmer/TFT_eSPI @ ^2.5.43
densaugeo/base64 @ ~1.4.0
knolleary/PubSubClient @ ^2.8.0
; ======================================================================
; Heltec WiFi LoRa 32 V4-R8 (ESP32-S3R8, 8 MB OCTAL PSRAM) + Expansion Kit V2.
; Inherits the V4 TFT env and overrides ONLY the R8 deltas. The 8 MB octal PSRAM
; claims GPIO33-37, so Heltec moved every control signal off them and the V2
; expansion put the TFT on a hardware-SPI bus SHARED with a new micro-SD slot:
; Vext 36->40 (now active-LOW) · GPS_EN 34->42 · LED 35->46 · ADC_Ctrl removed
; TFT (LovyanGFX HW-SPI): MOSI=15 SCK=16 MISO=45 CS=47 DC=48 RST=21 BL=44
; touch (CHSC6x, shares board I2C on 17/18) · micro-SD (shared TFT SPI, CS=3)
; The build defines HELTEC_LORA_V4_TFT too, so it reuses ALL the V4 touch-UI code;
; HELTEC_LORA_V4_R8 gates only the deltas. USB stays TinyUSB-CDC (USB_MODE=0) like
; the V4 — HW-CDC regresses the companion link on this family (see the V4 note).
; UNTESTED (no hardware yet) — pin sources: Meshtastic heltec_v4_r8 variant +
; Heltec V4-R8 pinmap + Expansion_board_V2.03 schematic. On-device TODO: confirm
; the CHSC6x shares Wire on 17/18, the SD_CS=3 read, and the V2 PAM8904 buzzer.
; ======================================================================
[env:heltec_v4_r8_tft_companion_radio_usb_tcp_touch]
extends = env:heltec_v4_tft_companion_radio_usb_tcp_touch
board = heltec_v4_r8
; Own filter (not inherited): the R8's DISPLAY_CLASS is OUR LGFXDisplay, so the UIColor
; palette must be a project object (UIColorPalette.cpp) -- otherwise the linker pulls the
; core's same-named LGFXDisplay.o from the archive for UIColor and every method collides.
; (The base V4 env must NOT compile the palette: its core ST7789LCDDisplay.o carries one.)
build_src_filter =
+<*.cpp>
+<*.c>
+<helpers/*.cpp>
+<helpers/esp32/*.cpp>
+<helpers/input/*.cpp>
+<helpers/ui/UIColorPalette.cpp>
+<ui-touch/*.cpp>
+<ui-touch/*.c>
+<../variants/heltec_v4/*.cpp>
build_flags =
${env:heltec_v4_tft_companion_radio_usb_tcp_touch.build_flags}
; --- V4-R8 deltas (later -D wins on the GCC command line) ---
-D HELTEC_LORA_V4_R8
-D P_LORA_TX_LED=46
-D PIN_VEXT_EN=40
-D PIN_VEXT_EN_ACTIVE=LOW
-D PIN_GPS_EN=42
-D PIN_GPS_RESET=-1
-D PIN_ADC_CTRL=-1
-D ADC_MULTIPLIER=5.07
; TFT on hardware SPI (LovyanGFX), shared with the micro-SD
-D DISPLAY_CLASS=LGFXDisplay
-D PIN_TFT_RST=21
-D PIN_TFT_LEDA_CTL=44
-D PIN_TFT_CS=47
-D PIN_TFT_DC=48
-D PIN_TFT_SCL=16
-D PIN_TFT_SDA=15
-D PIN_TFT_MISO=45
; TFT_eSPI mirror (kept in sync though LovyanGFX drives the panel)
-D TFT_MOSI=15
-D TFT_SCLK=16
-D TFT_MISO=45
-D TFT_CS=47
-D TFT_DC=48
-D TFT_RST=21
-D TFT_BL=44
; touch (CHSC6x) + board I2C unified on GPIO17/18; micro-SD chip-select
-D PIN_TOUCH_SDA=17
-D PIN_TOUCH_SCL=18
; RST=-1 ON PURPOSE (tester repro fix): the Expansion V2 wires the CHSC6x reset to GPIO21 — the
; SAME line as the ST7789 reset. The chsc6x driver hard-pulses its RST at init (+3 retry sites),
; which RESET the LCD mid-boot and wiped its init: logo OK -> screen black -> white/garbled rows
; on any redraw. The LGFX display init already resets both chips via pin 21; the touch driver must
; never drive it (-1 = every pulse in chsc6x_platform no-ops).
-D PIN_TOUCH_RST=-1
-D PIN_TOUCH_INT=43
-D PIN_BOARD_SDA=17
-D PIN_BOARD_SCL=18
-D PIN_SD_CS=3
; Buzzer: the Expansion Kit V2 integrates a piezo behind a PAM8904 driver (U9). Per Heltec's
; Expansion_board_V2.03.pdf schematic: DIN = net "4" = GPIO4 (P2 header pin 15); EN1/EN2 are
; NOT GPIOs -- strapped high via 10K pull-ups (3x boost, always enabled) with DIP switch SW1
; on the expansion board as a HARDWARE MUTE (closed = EN grounded = silent). So the stock V4
; tone() chime works as-is on DIN. If a tester still hears nothing: check SW1 on their kit.
-D HELTEC_V4_BUZZER_PIN=4
-D FIRMWARE_OTA_ENV='"heltec_v4_r8_tft_companion_radio_usb_tcp_touch"'
lib_deps =
${env:heltec_v4_tft_companion_radio_usb_tcp_touch.lib_deps}
lovyan03/LovyanGFX@1.2.21
; ======================================================================
; Attaky Mesh Series: `pio run -e attaky_mesh_series_companion_radio_touch`.
; ======================================================================
[env:attaky_mesh_series_companion_radio_touch]
platform = platformio/espressif32@6.11.0
framework = arduino
board = attaky_mesh_series
monitor_speed = 115200
board_build.partitions = partitions_tft_touch.csv
extra_scripts = pre:scripts/inject_wifi_env.py, merge-bin.py
build_flags =
; 1.17 core: ESP32Board.cpp includes <target.h> -> MicroNMEALocationProvider.h (header-only
; provider), so MicroNMEA never chains into the core lib's LDF scope -- hand it the path.
-I"${platformio.libdeps_dir}/${this.__env__}/MicroNMEA/src"
-Wno-deprecated-declarations -Wno-unused-parameter -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1
-D MC_VENDORED_TOUCH_APP
-D LORA_FREQ=910.525
-D LORA_BW=250
-D LORA_SF=7
-D ENABLE_PRIVATE_KEY_IMPORT=1
-D ENABLE_PRIVATE_KEY_EXPORT=1
-D RADIOLIB_EXCLUDE_CC1101=1
-D RADIOLIB_EXCLUDE_RF69=1
-D RADIOLIB_EXCLUDE_SX1231=1
-D RADIOLIB_EXCLUDE_SI443X=1
-D RADIOLIB_EXCLUDE_RFM2X=1
-D RADIOLIB_EXCLUDE_SX128X=1
-D RADIOLIB_EXCLUDE_AFSK=1
-D RADIOLIB_EXCLUDE_AX25=1
-D RADIOLIB_EXCLUDE_HELLSCHREIBER=1
-D RADIOLIB_EXCLUDE_MORSE=1
-D RADIOLIB_EXCLUDE_APRS=1
-D RADIOLIB_EXCLUDE_BELL=1
-D RADIOLIB_EXCLUDE_RTTY=1
-D RADIOLIB_EXCLUDE_SSTV=1
-D ESP32_PLATFORM
-D ENV_INCLUDE_GPS=1
; 0x38 is the FT6636 touch controller, not an AHT10/20. The Adafruit probe
; mis-detects it as a sensor and can hang boot on its register 0xBA, so keep off.
-D ENV_INCLUDE_AHTX0=0
-D ENV_INCLUDE_BME280=1
-D ENV_INCLUDE_BMP280=1
-D ENV_INCLUDE_SHTC3=1
-D ENV_INCLUDE_SHT4X=1
-D ENV_INCLUDE_LPS22HB=1
-D ENV_INCLUDE_INA3221=1
-D ENV_INCLUDE_INA219=1
-D ENV_INCLUDE_INA226=1
-D ENV_INCLUDE_INA260=1
; 0x5A is the keyboard module's AW9523 (left half), not an MLX90614.
-D ENV_INCLUDE_MLX90614=0
-D ENV_INCLUDE_VL53L0X=1
-D ENV_INCLUDE_BME680=1
-D ENV_INCLUDE_BMP085=1
-I variants/attaky_mesh_series
-D ATTAKY_MESH_SERIES
-D HAS_ATTAKY_MESH_KEYBOARD=1
-D USE_SX1262
-D ESP32_CPU_FREQ=80
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D P_LORA_DIO_1=21
-D P_LORA_NSS=8
-D P_LORA_RESET=9
-D P_LORA_BUSY=16
-D P_LORA_SCLK=5
-D P_LORA_MISO=7
-D P_LORA_MOSI=6
-D PIN_USER_BTN=0
-D LORA_TX_POWER=10
-D MAX_LORA_TX_POWER=22
-D SX126X_REGISTER_PATCH=1
-D SX126X_DIO2_AS_RF_SWITCH=true
; Ra-01SH clocks the SX1262 from a 32 MHz crystal, not a TCXO, so DIO3 is not a
; TCXO supply. Must be 0 explicitly: std_init() defaults to 1.6 V otherwise.
-D SX126X_DIO3_TCXO_VOLTAGE=0
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
-D PIN_GPS_RX=18
-D PIN_GPS_TX=17
; EnvironmentSensorManager reads GPS_BAUD_RATE, not GPS_BAUD.
-D GPS_BAUD_RATE=9600
; ATGM336H cold-start can exceed the 1 s probe window. Without this the probe
; gives up and start_gps() never runs, so GPS reads on but nothing is parsed.
-D ENV_SKIP_GPS_DETECT=1
; Keep the base rotation portrait; UITask applies the landscape transform.
-D PIN_BOARD_SDA=2
-D PIN_BOARD_SCL=1
-D DISPLAY_ROTATION=2
-D DISPLAY_SCALE_X=1.0
-D DISPLAY_SCALE_Y=1.0
-D PIN_TFT_RST=10
-D PIN_TFT_VDD_CTL=-1
-D PIN_TFT_LEDA_CTL=14
-D PIN_TFT_LEDA_CTL_ACTIVE=HIGH
-D PIN_TFT_CS=45
-D PIN_TFT_DC=12
-D PIN_TFT_SCL=11
-D PIN_TFT_SDA=13
-I include
-I src
-I src/ui-touch
-D UI_LVGL=1
-D HAS_TOUCH_UI=1
-D FIRMWARE_OTA_ENV='"attaky_mesh_series_companion_radio_touch"'
-D ENABLE_ADVERT_ON_BOOT=0
-D LV_CONF_PATH=lv_conf.h
-D LV_CONF_INCLUDE_SIMPLE=1
-D LV_INDEV_DEF_SCROLL_THROW=7
-D USER_SETUP_LOADED=1
-D ST7789_DRIVER=1
-D TFT_WIDTH=240
-D TFT_HEIGHT=320
-D TFT_MOSI=13
-D TFT_SCLK=11
-D TFT_CS=45
-D TFT_DC=12
-D TFT_RST=10
-D TFT_MISO=-1
-D SPI_FREQUENCY=80000000
-D TFT_RGB_ORDER=TFT_RGB
-D TFT_INVERSION_ON=1
-D TFT_BL=14
-D TFT_BACKLIGHT_ON=1
-D MAX_CONTACTS=2000
-D MAX_GROUP_CHANNELS=40
-D DISPLAY_CLASS=ST7789LCDDisplay
-D ADMIN_PASSWORD='"password"'
-D MULTI_TRANSPORT_COMPANION=1
-D WADAMESH_FORK_BUILD=1
-D TCP_PORT=5000
-D WS_PORT=8765
-D BLE_PIN_CODE=123456
-D CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=1
-D CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
-D CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096
build_src_filter =
+<*.cpp>
+<*.c>
+<helpers/*.cpp>
+<helpers/esp32/*.cpp>
+<helpers/input/*.cpp>
; The Attaky driver provides the shared touch API.
-<helpers/input/TDeckTouch.cpp>
+<ui-touch/*.cpp>
+<ui-touch/*.c>
+<../variants/attaky_mesh_series/*.cpp>
lib_deps =
https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.1
SPI
Wire
jgromes/RadioLib @ ^7.6.0
rweather/Crypto @ ^0.4.0
adafruit/RTClib @ ^2.1.3
melopero/Melopero RV3028 @ ^1.1.0
electroniccats/CayenneLPP @ 1.6.1
h2zero/NimBLE-Arduino @ 1.4.3
adafruit/Adafruit INA3221 Library @ ^1.0.1
adafruit/Adafruit INA219 @ ^1.2.3
robtillaart/INA226 @ ^0.6.4
adafruit/Adafruit INA260 Library @ ^1.5.3
adafruit/Adafruit AHTX0 @ ^2.0.5
adafruit/Adafruit BME280 Library @ ^2.3.0
adafruit/Adafruit BMP280 Library @ ^2.6.8
adafruit/Adafruit SHTC3 Library @ ^1.0.1
sensirion/Sensirion I2C SHT4x @ ^1.1.2
arduino-libraries/Arduino_LPS22HB @ ^1.0.2
adafruit/Adafruit MLX90614 Library @ ^2.1.5
adafruit/Adafruit_VL53L0X @ ^1.2.4
stevemarple/MicroNMEA @ ^2.0.6
adafruit/Adafruit BME680 Library @ ^2.0.4
adafruit/Adafruit BMP085 Library @ ^1.2.4
adafruit/Adafruit ST7735 and ST7789 Library @ ^1.11.0
https://github.com/Quency-D/chsc6x/archive/5cbead829d6b432a8d621ed1aafd4eb474fd4f27.zip
ESP32Async/ESPAsyncWebServer @ 3.10.3
file://arch/esp32/AsyncElegantOTA
lvgl/lvgl @ ^8.3.11
bodmer/TFT_eSPI @ ^2.5.43
densaugeo/base64 @ ~1.4.0
knolleary/PubSubClient @ ^2.8.0
; ======================================================================
; LilyGo T-Deck / T-Deck Plus — flattened equivalent of meshcomod's
; LilyGo_TDeck_companion_radio_touch. ST7789 via Adafruit (not TFT_eSPI);
; GT911 touch + matrix keyboard + trackball; sensors off except GPS.
; ======================================================================
[env:LilyGo_TDeck_companion_radio_touch]
platform = platformio/espressif32@6.11.0
framework = arduino
board = t-deck
monitor_speed = 115200
board_build.partitions = variants/lilygo_tdeck/partitions_tdeck_touch.csv
extra_scripts = pre:scripts/inject_wifi_env.py, merge-bin.py
build_flags =
; 1.17 core: ESP32Board.cpp includes <target.h> -> MicroNMEALocationProvider.h (header-only
; provider), so MicroNMEA never chains into the core lib's LDF scope -- hand it the path.
-I"${platformio.libdeps_dir}/${this.__env__}/MicroNMEA/src"
-Wno-deprecated-declarations -Wno-unused-parameter -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1
-D MC_VENDORED_TOUCH_APP
-D LORA_FREQ=869.618
-D LORA_BW=62.5
-D LORA_SF=8
-D ENABLE_PRIVATE_KEY_IMPORT=1
-D ENABLE_PRIVATE_KEY_EXPORT=1
-D RADIOLIB_EXCLUDE_CC1101=1
-D RADIOLIB_EXCLUDE_RF69=1
-D RADIOLIB_EXCLUDE_SX1231=1
-D RADIOLIB_EXCLUDE_SI443X=1
-D RADIOLIB_EXCLUDE_RFM2X=1
-D RADIOLIB_EXCLUDE_SX128X=1
-D RADIOLIB_EXCLUDE_AFSK=1
-D RADIOLIB_EXCLUDE_AX25=1
-D RADIOLIB_EXCLUDE_HELLSCHREIBER=1
-D RADIOLIB_EXCLUDE_MORSE=1
-D RADIOLIB_EXCLUDE_APRS=1
-D RADIOLIB_EXCLUDE_BELL=1
-D RADIOLIB_EXCLUDE_RTTY=1
-D RADIOLIB_EXCLUDE_SSTV=1
-D ESP32_PLATFORM
; --- T-Deck board ---
-I variants/lilygo_tdeck
-D LILYGO_TDECK
-D BOARD_HAS_PSRAM=1
; 0 = silence ARDUHAL [E] spam (benign vfs_api cache-miss "no permits for
; creation" + Preferences nvs_open NOT_FOUND on first-namespace-access) that
; also pollutes the USB-CDC companion stream. Our own Serial.printf logs stay.
-D CORE_DEBUG_LEVEL=0
-D ARDUINO_USB_CDC_ON_BOOT=1
-D PIN_USER_BTN=0
-D PIN_PERF_POWERON=10
-D USE_SX1262
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
; The T-Deck's SX1262 antenna (TX/RX) switch is driven by DIO2 — this MUST be
; true. With it false, setDio2AsRfSwitch(false) leaves the switch uncontrolled,
; so on TX the +22 dBm PA is never routed to the antenna (~16 dB loss -> ~4 mW).
; That was issue #6. (Meshtastic's T-Deck + the Heltec V4 here + every other
; MeshCore SX1262 variant use true; the T-Deck was the lone outlier.)
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
-D SX126X_DIO3_TCXO_VOLTAGE=1.8f
-D P_LORA_DIO_1=45
-D P_LORA_NSS=9
-D P_LORA_RESET=17
-D P_LORA_BUSY=13
-D P_LORA_SCLK=40
-D P_LORA_MISO=38
-D P_LORA_MOSI=41
-D ENV_INCLUDE_GPS=1
-D ENV_SKIP_GPS_DETECT=1
-D ENV_INCLUDE_AHTX0=0
-D ENV_INCLUDE_BME280=0
-D ENV_INCLUDE_BMP280=0
-D ENV_INCLUDE_SHTC3=0
-D ENV_INCLUDE_SHT4X=0
-D ENV_INCLUDE_LPS22HB=0
-D ENV_INCLUDE_INA3221=0
-D ENV_INCLUDE_INA219=0
-D ENV_INCLUDE_INA226=0
-D ENV_INCLUDE_INA260=0
-D ENV_INCLUDE_MLX90614=0
-D ENV_INCLUDE_VL53L0X=0
-D ENV_INCLUDE_BME680=0
-D ENV_INCLUDE_BMP085=0
-D DISPLAY_SCALE_X=1.0
-D DISPLAY_SCALE_Y=1.0
-D PIN_TFT_RST=-1
-D PIN_TFT_VDD_CTL=-1
-D PIN_TFT_LEDA_CTL=42
-D PIN_TFT_CS=12
-D PIN_TFT_DC=11
-D PIN_TFT_SCL=40
-D PIN_TFT_SDA=41
-D PIN_GPS_RX=43
-D PIN_GPS_TX=44
-D GPS_BAUD_RATE=38400
; --- touch UI / companion stack ---
-I include
-I src
-I src/ui-touch
-D UI_LVGL=1
-D HAS_TOUCH_UI=1
-D FIRMWARE_OTA_ENV='"LilyGo_TDeck_companion_radio_touch"'
-D HAS_TDECK_GT911=1
-D HAS_TDECK_TRACKBALL=1
-D HAS_TDECK_KEYBOARD=1
-D ENABLE_ADVERT_ON_BOOT=0
-D PIN_TB_UP=15
-D PIN_TB_DOWN=3
-D PIN_TB_LEFT=2
-D PIN_TB_RIGHT=1
-D LV_CONF_PATH=lv_conf.h
-D LV_CONF_INCLUDE_SIMPLE=1
; Smoother scroll: lower deceleration than LVGL's default (10) so flicks glide
; longer instead of stopping abruptly. lv_conf leaves this unset, so this -D wins.
-D LV_INDEV_DEF_SCROLL_THROW=7
-D MAX_CONTACTS=2000
-D MAX_GROUP_CHANNELS=40
-D DISPLAY_CLASS=ST7789LCDDisplay
-D ADMIN_PASSWORD='"password"'
-D MULTI_TRANSPORT_COMPANION=1
-D WADAMESH_FORK_BUILD=1
-D TCP_PORT=5000
-D WS_PORT=8765
-D BLE_PIN_CODE=123456
-D CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=1
-D CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
-D CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096
build_src_filter =
+<*.cpp>
+<*.c>
+<helpers/*.cpp>
+<helpers/esp32/*.cpp>
+<helpers/input/*.cpp>
+<ui-touch/*.cpp>
+<ui-touch/*.c>
+<../variants/lilygo_tdeck/*.cpp>
lib_deps =
https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.1
SPI
Wire
jgromes/RadioLib @ ^7.6.0
rweather/Crypto @ ^0.4.0
adafruit/RTClib @ ^2.1.3
melopero/Melopero RV3028 @ ^1.1.0
electroniccats/CayenneLPP @ 1.6.1
h2zero/NimBLE-Arduino @ 1.4.3
adafruit/Adafruit INA3221 Library @ ^1.0.1
adafruit/Adafruit INA219 @ ^1.2.3
robtillaart/INA226 @ ^0.6.4
adafruit/Adafruit INA260 Library @ ^1.5.3
adafruit/Adafruit AHTX0 @ ^2.0.5
adafruit/Adafruit BME280 Library @ ^2.3.0
adafruit/Adafruit BMP280 Library @ ^2.6.8
adafruit/Adafruit SHTC3 Library @ ^1.0.1
sensirion/Sensirion I2C SHT4x @ ^1.1.2
arduino-libraries/Arduino_LPS22HB @ ^1.0.2
adafruit/Adafruit MLX90614 Library @ ^2.1.5
adafruit/Adafruit_VL53L0X @ ^1.2.4
stevemarple/MicroNMEA @ ^2.0.6
adafruit/Adafruit BME680 Library @ ^2.0.4
adafruit/Adafruit BMP085 Library @ ^1.2.4
adafruit/Adafruit ST7735 and ST7789 Library @ ^1.11.0
ESP32Async/ESPAsyncWebServer @ 3.10.3
file://arch/esp32/AsyncElegantOTA
lvgl/lvgl @ ^8.3.11
densaugeo/base64 @ ~1.4.0
knolleary/PubSubClient @ ^2.8.0
[env:tlora_pager_lr1121_companion_radio_touch]
platform = platformio/espressif32@6.11.0
framework = arduino
board = lilygo-t-lora-pager
monitor_speed = 115200
board_build.partitions = variants/lilygo_tlora_pager/partitions_tlora_pager_touch.csv
extra_scripts = pre:scripts/inject_wifi_env.py, pre:scripts/build/patch_nimble_freertos_timer.py, merge-bin.py
build_flags =
; 1.17 core: ESP32Board.cpp includes <target.h> -> MicroNMEALocationProvider.h (header-only
; provider), so MicroNMEA never chains into the core lib's LDF scope -- hand it the path.
-I"${platformio.libdeps_dir}/${this.__env__}/MicroNMEA/src"
-I"${platformio.libdeps_dir}/${this.__env__}/SensorLib/src" ; same: TLoraPagerBoard.h needs XL9555/BQ27220
-I"${platformio.libdeps_dir}/${this.__env__}/TFT_eSPI" ; same: pager target.h -> ST7796LCDDisplay.h -> TFT_eSPI.h
-Wno-deprecated-declarations -Wno-unused-parameter -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1
-D MC_VENDORED_TOUCH_APP
-D LORA_FREQ=869.618
-D LORA_BW=62.5
-D LORA_SF=8
-D ENABLE_PRIVATE_KEY_IMPORT=1
-D ENABLE_PRIVATE_KEY_EXPORT=1
-D RADIOLIB_EXCLUDE_CC1101=1
-D RADIOLIB_EXCLUDE_RF69=1
-D RADIOLIB_EXCLUDE_SX1231=1
-D RADIOLIB_EXCLUDE_SI443X=1
-D RADIOLIB_EXCLUDE_RFM2X=1
-D RADIOLIB_EXCLUDE_SX128X=1
-D RADIOLIB_EXCLUDE_AFSK=1
-D RADIOLIB_EXCLUDE_AX25=1
-D RADIOLIB_EXCLUDE_HELLSCHREIBER=1
-D RADIOLIB_EXCLUDE_MORSE=1
-D RADIOLIB_EXCLUDE_APRS=1
-D RADIOLIB_EXCLUDE_BELL=1
-D RADIOLIB_EXCLUDE_RTTY=1
-D RADIOLIB_EXCLUDE_SSTV=1
; LR11X0 stays IN (that's our radio family); SX126X isn't used by this env at all.
-D RADIOLIB_EXCLUDE_SX126X=1
-D ESP32_PLATFORM
; --- T-LoRa Pager board ---
-I variants/lilygo_tlora_pager
-D TLORA_PAGER=1
-D LV_FONT_MONTSERRAT_18=1
-D LV_FONT_MONTSERRAT_20=1
-D LV_FONT_MONTSERRAT_24=1
-D BOARD_HAS_PSRAM=1
; 0 = silence ARDUHAL [E] spam, same rationale as the other two envs.
-D CORE_DEBUG_LEVEL=0
-D ARDUINO_USB_CDC_ON_BOOT=1
-D PIN_USER_BTN=0
-D USE_LR1121=1
-D RADIO_CLASS=CustomLR1121
-D WRAPPER_CLASS=CustomLR1121Wrapper
; Full sub-GHz HP-PA power on boot, matching the T-Deck's own LORA_TX_POWER=22
; (not Heltec V4's conservative-10-then-raise-in-Settings pattern). +22dBm is
; this chip's real ceiling for freq < 1GHz -- confirmed against RadioLib's
; pinned LR1120::checkOutputPower() (LR1121 inherits it: HP PA auto-selects
; above 14dBm, valid range -9..22) and trail-mate's own
; TRAIL_MATE_LORA_TX_POWER_MAX_DBM=22 for this exact board -- not a guess
; carried over from the sibling boards. A weak default here (10dBm, ~16x less
; power) was silently degrading outbound range on real hardware: adverts/DMs
; sent FROM the pager were unreliable while inbound reception was fine, since
; the far node's own TX was unaffected.
-D LORA_TX_POWER=22
-D P_LORA_DIO_1=14
-D P_LORA_NSS=36
-D P_LORA_RESET=47
-D P_LORA_BUSY=48
-D P_LORA_SCLK=35
-D P_LORA_MISO=33
-D P_LORA_MOSI=34
-D ENV_INCLUDE_GPS=1
-D ENV_SKIP_GPS_DETECT=1
-D ENV_INCLUDE_AHTX0=0
-D ENV_INCLUDE_BME280=0
-D ENV_INCLUDE_BMP280=0
-D ENV_INCLUDE_SHTC3=0
-D ENV_INCLUDE_SHT4X=0
-D ENV_INCLUDE_LPS22HB=0
-D ENV_INCLUDE_INA3221=0
-D ENV_INCLUDE_INA219=0
-D ENV_INCLUDE_INA226=0
-D ENV_INCLUDE_INA260=0
-D ENV_INCLUDE_MLX90614=0
-D ENV_INCLUDE_VL53L0X=0
-D ENV_INCLUDE_BME680=0
-D ENV_INCLUDE_BMP085=0
-D DISPLAY_SCALE_X=1.0
-D DISPLAY_SCALE_Y=1.0
; AW9364 backlight enable/pulse pin (ST7796LCDDisplay owns brightness -- see
; the CGRAM_OFFSET comment below for why this isn't a plain PWM pin).
-D PIN_TFT_LEDA_CTL=42
; Swapped vs. trail-mate's raw GPS_RX=4/GPS_TX=12: wadamesh's core calls
; Serial1.setPins(PIN_GPS_TX, PIN_GPS_RX), and HardwareSerial::setPins()
; takes (rxPin, txPin) -- so PIN_GPS_TX must be the ESP's own RX pin (4) and
; PIN_GPS_RX the ESP's own TX pin (12). See TLORA_PAGER_PORT.md Risk 1c.
-D PIN_GPS_RX=12
-D PIN_GPS_TX=4
-D GPS_BAUD_RATE=38400
; --- touch UI / companion stack ---
-I include
-I src
-I src/ui-touch
-D UI_LVGL=1
-D HAS_TOUCH_UI=1
-D FIRMWARE_OTA_ENV='"tlora_pager_lr1121_companion_radio_touch"'
-D HAS_PAGER_KEYBOARD=1
-D HAS_PAGER_ENCODER=1
-D KB_INT=6
-D KB_BACKLIGHT=46
-D ROTARY_A=40
-D ROTARY_B=41
-D ROTARY_C=7
; ES8311 codec I2S pins (NS4150B amp downstream, enabled via XL9555
; AMP_EN -- see TLoraPagerBoard::setAmpEnabled()). Confirmed against the
; canonical arduino-esp32 pins_arduino.h for this board -- see
; TLORA_PAGER_PORT.md's Audio row.
-D PIN_I2S_MCLK=10
-D PIN_I2S_BCK=11
-D PIN_I2S_WS=18
-D PIN_I2S_DOUT=45
-D PIN_I2S_SDIN=17
-D ENABLE_ADVERT_ON_BOOT=0
-D LV_CONF_PATH=lv_conf.h
-D LV_CONF_INCLUDE_SIMPLE=1
; Smoother scroll: lower deceleration than LVGL's default (10) so flicks glide
; longer instead of stopping abruptly. lv_conf leaves this unset, so this -D wins.
-D LV_INDEV_DEF_SCROLL_THROW=7
-D MAX_CONTACTS=2000
-D MAX_GROUP_CHANNELS=40
-D DISPLAY_CLASS=ST7796LCDDisplay
-D ADMIN_PASSWORD='"password"'
-D MULTI_TRANSPORT_COMPANION=1
-D WADAMESH_FORK_BUILD=1
-D TCP_PORT=5000
-D WS_PORT=8765
-D BLE_PIN_CODE=123456
-D CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=1
-D CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
-D CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096
; --- ST7796 display (TFT_eSPI) ---
-D USER_SETUP_LOADED=1
-D ST7796_DRIVER=1
; REQUIRED: this panel's 222px glass is narrower than the ST7796 controller's
; 320px GRAM. TFT_eSPI's ST7796_Rotation.h only applies the needed 49px
; column/row offset when this is defined (unlike ST7789, it isn't automatic
; for ST7796) -- ST7796LCDDisplay.cpp #errors at compile time without it.
-D CGRAM_OFFSET=1
; REQUIRED on ESP32-S3: TFT_eSPI_ESP32_S3.h's raw register macros (_spi_user,
; _spi_cmd, _spi_mosi_dlen -- used by begin_tft_write()/TFT_WRITE_BITS) take
; SPI_PORT and feed it straight into IDF's SPI_USER_REG(i)/REG_SPI_BASE(i),
; which only resolves to a real peripheral for i>=2 (SPI2/SPI3); i<2 returns
; base address 0. Leaving both USE_HSPI_PORT/USE_FSPI_PORT undefined makes
; that file fall back to SPI_PORT=FSPI, but FSPI is the *Arduino* enum value
; (0 on S3) rather than the raw IDF host index TFT_eSPI's own macros need --
; so _spi_user resolves to address 0x10, and the very first writecommand()
; in ST7796LCDDisplay::begin()/TFT_eSPI::init() hard-crashes with a
; StoreProhibited panic (confirmed on hardware: black screen, boot-looping
; "Guru Meditation Error" at TFT_eSPI::begin_tft_write()). USE_FSPI_PORT
; forces SPI_PORT=2 (real SPI2/"GPSPI2") consistently across both the raw
; macros and the SPIClass(FSPI) object TFT_eSPI constructs internally.
; USE_HSPI_PORT (real SPI3) is deliberately NOT used here instead: the
; radio's own `SPIClass spi` (variants/lilygo_tlora_pager/target.cpp) takes
; its default ctor arg (HSPI), which the Arduino core also maps to real
; SPI3 -- so picking HSPI for the display would put both peripherals on the
; same physical SPI host and conflict.
-D USE_FSPI_PORT=1
-D TFT_WIDTH=222
-D TFT_HEIGHT=480
-D TFT_MOSI=34
-D TFT_SCLK=35
-D TFT_CS=38
-D TFT_DC=37
-D TFT_RST=-1
-D TFT_MISO=33
-D TFT_BL=-1
; trail-mate's kPagerDisplaySpiClockMhz = 80.
-D SPI_FREQUENCY=80000000
build_src_filter =
+<*.cpp>
+<*.c>
+<helpers/*.cpp>
+<helpers/esp32/*.cpp>
+<helpers/input/*.cpp>
+<helpers/ui/*.cpp>
+<ui-touch/*.cpp>
+<ui-touch/*.c>
+<../variants/lilygo_tlora_pager/*.cpp>
lib_deps =
https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.1
SPI
Wire
jgromes/RadioLib @ ^7.6.0
rweather/Crypto @ ^0.4.0
adafruit/RTClib @ ^2.1.3
melopero/Melopero RV3028 @ ^1.1.0
electroniccats/CayenneLPP @ 1.6.1
h2zero/NimBLE-Arduino @ 1.4.3
adafruit/Adafruit INA3221 Library @ ^1.0.1
adafruit/Adafruit INA219 @ ^1.2.3
robtillaart/INA226 @ ^0.6.4
adafruit/Adafruit INA260 Library @ ^1.5.3
adafruit/Adafruit AHTX0 @ ^2.0.5
adafruit/Adafruit BME280 Library @ ^2.3.0
adafruit/Adafruit BMP280 Library @ ^2.6.8
adafruit/Adafruit SHTC3 Library @ ^1.0.1
sensirion/Sensirion I2C SHT4x @ ^1.1.2
arduino-libraries/Arduino_LPS22HB @ ^1.0.2
adafruit/Adafruit MLX90614 Library @ ^2.1.5
adafruit/Adafruit_VL53L0X @ ^1.2.4
stevemarple/MicroNMEA @ ^2.0.6
adafruit/Adafruit BME680 Library @ ^2.0.4
adafruit/Adafruit BMP085 Library @ ^1.2.4
ESP32Async/ESPAsyncWebServer @ 3.10.3
file://arch/esp32/AsyncElegantOTA
lvgl/lvgl @ ^8.3.11
densaugeo/base64 @ ~1.4.0
knolleary/PubSubClient @ ^2.8.0
bodmer/TFT_eSPI @ ^2.5.43
adafruit/Adafruit TCA8418 @ ^1.0.2
lewisxhe/SensorLib @ 0.3.3
; Milestone 10: SX1262-variant env for pager units sold with that radio instead
; of LR1121 -- same board JSON, same variant dir, same physical NSS/RESET/BUSY/
; DIO1/SCLK/MISO/MOSI pins (same PCB slot, just a different chip populated —
; see TLORA_PAGER_PORT.md's hardware-facts table). RADIO_CLASS/WRAPPER_CLASS
; swap to the core fork's CustomSX1262/CustomSX1262Wrapper, the exact same
; generic classes the T-Deck already uses -- see target.cpp's radio_init()
; for why no new radio C++ code was needed, just these build flags.
[env:tlora_pager_sx1262_companion_radio_touch]
platform = platformio/espressif32@6.11.0
framework = arduino
board = lilygo-t-lora-pager
monitor_speed = 115200
board_build.partitions = variants/lilygo_tlora_pager/partitions_tlora_pager_touch.csv
extra_scripts = pre:scripts/inject_wifi_env.py, pre:scripts/build/patch_nimble_freertos_timer.py, merge-bin.py
build_flags =
; 1.17 core: ESP32Board.cpp includes <target.h> -> MicroNMEALocationProvider.h (header-only
; provider), so MicroNMEA never chains into the core lib's LDF scope -- hand it the path.
-I"${platformio.libdeps_dir}/${this.__env__}/MicroNMEA/src"
-I"${platformio.libdeps_dir}/${this.__env__}/SensorLib/src" ; same: TLoraPagerBoard.h needs XL9555/BQ27220
-I"${platformio.libdeps_dir}/${this.__env__}/TFT_eSPI" ; same: pager target.h -> ST7796LCDDisplay.h -> TFT_eSPI.h
-Wno-deprecated-declarations -Wno-unused-parameter -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1
-D MC_VENDORED_TOUCH_APP
-D LORA_FREQ=869.618
-D LORA_BW=62.5
-D LORA_SF=8
-D ENABLE_PRIVATE_KEY_IMPORT=1
-D ENABLE_PRIVATE_KEY_EXPORT=1
-D RADIOLIB_EXCLUDE_CC1101=1
-D RADIOLIB_EXCLUDE_RF69=1
-D RADIOLIB_EXCLUDE_SX1231=1
-D RADIOLIB_EXCLUDE_SI443X=1
-D RADIOLIB_EXCLUDE_RFM2X=1
-D RADIOLIB_EXCLUDE_SX128X=1
-D RADIOLIB_EXCLUDE_AFSK=1
-D RADIOLIB_EXCLUDE_AX25=1
-D RADIOLIB_EXCLUDE_HELLSCHREIBER=1
-D RADIOLIB_EXCLUDE_MORSE=1
-D RADIOLIB_EXCLUDE_APRS=1
-D RADIOLIB_EXCLUDE_BELL=1
-D RADIOLIB_EXCLUDE_RTTY=1
-D RADIOLIB_EXCLUDE_SSTV=1
; SX126X stays IN (that's this env's radio family); LR11X0 isn't used at all.
-D RADIOLIB_EXCLUDE_LR11X0=1
-D ESP32_PLATFORM
; --- T-LoRa Pager board (SX1262 variant) ---
-I variants/lilygo_tlora_pager
-D TLORA_PAGER=1
-D LV_FONT_MONTSERRAT_18=1
-D LV_FONT_MONTSERRAT_20=1
-D LV_FONT_MONTSERRAT_24=1
-D BOARD_HAS_PSRAM=1
; 0 = silence ARDUHAL [E] spam, same rationale as the other envs.
-D CORE_DEBUG_LEVEL=0
-D ARDUINO_USB_CDC_ON_BOOT=1
-D PIN_USER_BTN=0
-D USE_SX1262=1
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
; Same 22dBm ceiling as the LR1121 env -- trail-mate's own reference for this
; exact board (~/dev/trail-mate/boards/tlora_pager) uses the identical
; TRAIL_MATE_LORA_TX_POWER_MAX_DBM=22 for BOTH its LR1121 and SX1262 envs, and
; it's this chip's well-known real ceiling too.
-D LORA_TX_POWER=22
; SX126X_DIO2_AS_RF_SWITCH=true and SX126X_CURRENT_LIMIT=140 are carried over
; from the T-Deck's own SX1262 config -- NOT because this is the T-Deck, but
; because both are tied to the 22dBm target above, not to board-specific analog
; circuitry: RadioLib's own SX126x.cpp already defaults DIO2-as-switch to true
; internally (same value, just made explicit here), and its default current
; limit (60mA) is what silently capped the T-Deck's real TX power below its
; target before that env raised it to 140mA -- the same physics apply to any
; SX1262 module asked to reach 22dBm, not something unique to the T-Deck's PCB.
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
; LilyGoLib's SX1262 transmit/receive examples for this exact Pager explicitly
; drive the module's DIO3 TCXO supply at 3.0 V. The generic CustomSX1262
; fallback is only 1.6 V; that can leave this board's oscillator outside its
; specified supply range while still working at very short range. Pass the
; board value into begin() so calibration and all later RX/TX use the correct
; reference from the start.
-D SX126X_DIO3_TCXO_VOLTAGE=3.0f
-D P_LORA_DIO_1=14
-D P_LORA_NSS=36
-D P_LORA_RESET=47
-D P_LORA_BUSY=48
-D P_LORA_SCLK=35
-D P_LORA_MISO=33
-D P_LORA_MOSI=34
-D ENV_INCLUDE_GPS=1
-D ENV_SKIP_GPS_DETECT=1
-D ENV_INCLUDE_AHTX0=0
-D ENV_INCLUDE_BME280=0
-D ENV_INCLUDE_BMP280=0
-D ENV_INCLUDE_SHTC3=0
-D ENV_INCLUDE_SHT4X=0
-D ENV_INCLUDE_LPS22HB=0
-D ENV_INCLUDE_INA3221=0
-D ENV_INCLUDE_INA219=0
-D ENV_INCLUDE_INA226=0
-D ENV_INCLUDE_INA260=0
-D ENV_INCLUDE_MLX90614=0
-D ENV_INCLUDE_VL53L0X=0
-D ENV_INCLUDE_BME680=0
-D ENV_INCLUDE_BMP085=0
-D DISPLAY_SCALE_X=1.0
-D DISPLAY_SCALE_Y=1.0
; AW9364 backlight enable/pulse pin (ST7796LCDDisplay owns brightness -- see
; the CGRAM_OFFSET comment below for why this isn't a plain PWM pin).
-D PIN_TFT_LEDA_CTL=42
; Swapped vs. trail-mate's raw GPS_RX=4/GPS_TX=12: wadamesh's core calls
; Serial1.setPins(PIN_GPS_TX, PIN_GPS_RX), and HardwareSerial::setPins()
; takes (rxPin, txPin) -- so PIN_GPS_TX must be the ESP's own RX pin (4) and
; PIN_GPS_RX the ESP's own TX pin (12). See TLORA_PAGER_PORT.md Risk 1c.
-D PIN_GPS_RX=12
-D PIN_GPS_TX=4
-D GPS_BAUD_RATE=38400
; --- touch UI / companion stack ---
-I include
-I src
-I src/ui-touch
-D UI_LVGL=1
-D HAS_TOUCH_UI=1
-D FIRMWARE_OTA_ENV='"tlora_pager_sx1262_companion_radio_touch"'
-D HAS_PAGER_KEYBOARD=1
-D HAS_PAGER_ENCODER=1
-D KB_INT=6
-D KB_BACKLIGHT=46
-D ROTARY_A=40
-D ROTARY_B=41
-D ROTARY_C=7
; ES8311 codec I2S pins (NS4150B amp downstream, enabled via XL9555
; AMP_EN -- see TLoraPagerBoard::setAmpEnabled()). Confirmed against the
; canonical arduino-esp32 pins_arduino.h for this board -- see
; TLORA_PAGER_PORT.md's Audio row.
-D PIN_I2S_MCLK=10
-D PIN_I2S_BCK=11
-D PIN_I2S_WS=18
-D PIN_I2S_DOUT=45
-D PIN_I2S_SDIN=17
-D ENABLE_ADVERT_ON_BOOT=0
-D LV_CONF_PATH=lv_conf.h
-D LV_CONF_INCLUDE_SIMPLE=1
; Smoother scroll: lower deceleration than LVGL's default (10) so flicks glide
; longer instead of stopping abruptly. lv_conf leaves this unset, so this -D wins.
-D LV_INDEV_DEF_SCROLL_THROW=7
-D MAX_CONTACTS=2000
-D MAX_GROUP_CHANNELS=40
-D DISPLAY_CLASS=ST7796LCDDisplay
-D ADMIN_PASSWORD='"password"'
-D MULTI_TRANSPORT_COMPANION=1
-D WADAMESH_FORK_BUILD=1
-D TCP_PORT=5000
-D WS_PORT=8765
-D BLE_PIN_CODE=123456
-D CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=1
-D CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
-D CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096
; --- ST7796 display (TFT_eSPI) ---
-D USER_SETUP_LOADED=1
-D ST7796_DRIVER=1
; REQUIRED: this panel's 222px glass is narrower than the ST7796 controller's
; 320px GRAM. TFT_eSPI's ST7796_Rotation.h only applies the needed 49px
; column/row offset when this is defined (unlike ST7789, it isn't automatic
; for ST7796) -- ST7796LCDDisplay.cpp #errors at compile time without it.
-D CGRAM_OFFSET=1
; REQUIRED on ESP32-S3: see the LR1121 env's identical comment above --
; same display, same panel, same constraint, unrelated to the radio chip.
-D USE_FSPI_PORT=1
-D TFT_WIDTH=222
-D TFT_HEIGHT=480
-D TFT_MOSI=34
-D TFT_SCLK=35
-D TFT_CS=38
-D TFT_DC=37
-D TFT_RST=-1
-D TFT_MISO=33
-D TFT_BL=-1
; trail-mate's kPagerDisplaySpiClockMhz = 80.
-D SPI_FREQUENCY=80000000
build_src_filter =
+<*.cpp>
+<*.c>
+<helpers/*.cpp>
+<helpers/esp32/*.cpp>
+<helpers/input/*.cpp>
+<helpers/ui/*.cpp>
+<ui-touch/*.cpp>
+<ui-touch/*.c>
+<../variants/lilygo_tlora_pager/*.cpp>
lib_deps =
https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.1
SPI
Wire
jgromes/RadioLib @ ^7.6.0
rweather/Crypto @ ^0.4.0
adafruit/RTClib @ ^2.1.3
melopero/Melopero RV3028 @ ^1.1.0
electroniccats/CayenneLPP @ 1.6.1
h2zero/NimBLE-Arduino @ 1.4.3
adafruit/Adafruit INA3221 Library @ ^1.0.1
adafruit/Adafruit INA219 @ ^1.2.3
robtillaart/INA226 @ ^0.6.4
adafruit/Adafruit INA260 Library @ ^1.5.3
adafruit/Adafruit AHTX0 @ ^2.0.5
adafruit/Adafruit BME280 Library @ ^2.3.0
adafruit/Adafruit BMP280 Library @ ^2.6.8
adafruit/Adafruit SHTC3 Library @ ^1.0.1
sensirion/Sensirion I2C SHT4x @ ^1.1.2
arduino-libraries/Arduino_LPS22HB @ ^1.0.2
adafruit/Adafruit MLX90614 Library @ ^2.1.5
adafruit/Adafruit_VL53L0X @ ^1.2.4
stevemarple/MicroNMEA @ ^2.0.6
adafruit/Adafruit BME680 Library @ ^2.0.4
adafruit/Adafruit BMP085 Library @ ^1.2.4
ESP32Async/ESPAsyncWebServer @ 3.10.3
file://arch/esp32/AsyncElegantOTA
lvgl/lvgl @ ^8.3.11
densaugeo/base64 @ ~1.4.0
knolleary/PubSubClient @ ^2.8.0
bodmer/TFT_eSPI @ ^2.5.43
adafruit/Adafruit TCA8418 @ ^1.0.2
lewisxhe/SensorLib @ 0.3.3
[env:ThinkNode_M9_companion_radio_touch]
platform = platformio/espressif32@6.11.0
framework = arduino
board = thinknode_m9
monitor_speed = 115200
board_build.partitions = variants/thinknode_m9/partitions_m9_touch.csv
; patch_radiolib_lr11x0: preprod M9 LR1110s run old transceiver FW that rejects
; DriveDiosInSleepMode (0x012A, FW 0x0308+) with CMD_PERR -> begin() = -706.
; The pre-script makes RadioLib's config() skip it on old FW (idempotent,
; per-env libdeps copy). See scripts/build/patch_radiolib_lr11x0.py.
extra_scripts = pre:scripts/inject_wifi_env.py, pre:scripts/build/patch_radiolib_lr11x0.py, merge-bin.py
build_flags =
; 1.17 core: ESP32Board.cpp includes <target.h> -> MicroNMEALocationProvider.h (header-only
; provider), so MicroNMEA never chains into the core lib's LDF scope -- hand it the path.
-I"${platformio.libdeps_dir}/${this.__env__}/MicroNMEA/src"
-Wno-deprecated-declarations -Wno-unused-parameter -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1
-D MC_VENDORED_TOUCH_APP
-D LORA_FREQ=869.618
-D LORA_BW=62.5
-D LORA_SF=8
-D ENABLE_PRIVATE_KEY_IMPORT=1
-D ENABLE_PRIVATE_KEY_EXPORT=1
-D RADIOLIB_EXCLUDE_CC1101=1
-D RADIOLIB_EXCLUDE_RF69=1
-D RADIOLIB_EXCLUDE_SX1231=1
-D RADIOLIB_EXCLUDE_SI443X=1
-D RADIOLIB_EXCLUDE_RFM2X=1
-D RADIOLIB_EXCLUDE_SX128X=1
-D RADIOLIB_EXCLUDE_AFSK=1
-D RADIOLIB_EXCLUDE_AX25=1
-D RADIOLIB_EXCLUDE_HELLSCHREIBER=1
-D RADIOLIB_EXCLUDE_MORSE=1
-D RADIOLIB_EXCLUDE_APRS=1
-D RADIOLIB_EXCLUDE_BELL=1
-D RADIOLIB_EXCLUDE_RTTY=1
-D RADIOLIB_EXCLUDE_SSTV=1
-D ESP32_PLATFORM
; --- ThinkNode M9 board ---
-I variants/thinknode_m9
-D HAS_THINKNODE_M9
-D BOARD_HAS_PSRAM=1
; M9 uses the UART bridge (ttyUSB0), not native USB-CDC — confirmed during
; Specter bring-up. With ARDUINO_USB_CDC_ON_BOOT=1 (the T-Deck's setting)
; app Serial logs go to a ttyACM* port this board doesn't expose and
; appear completely silent.
-D ARDUINO_USB_CDC_ON_BOOT=0
-D PIN_USER_BTN=0
-D RADIO_CLASS=CustomLR1110
-D WRAPPER_CLASS=CustomLR1110Wrapper
-D LORA_TX_POWER=22
; LR1110 clock: TCXO mode at 3.3 V — EMPIRICALLY CONFIRMED on the tester's
; preproduction unit: Meshtastic's thinknode_m9 variant logs "using DIO3 as
; TCXO reference voltage at 3.300000 V" followed by "LR1110 init result 0".
; The earlier theory here (Y1 = self-powered active oscillator -> tcxo must
; be 0) was disproven on hardware: with 0 the chip boots on its internal RC
; (SPI alive, no -2) but the first command needing the real 32 MHz clock is
; rejected -> radio init failed -707 (bring-up build #1, 2026-07-06). The
; schematic's "VTCXO rail" feeding Y1 is evidently the LR1110's own
; TCXO-supply output, so the chip must drive it.
-D LR11X0_DIO3_TCXO_VOLTAGE=3.3
; Bring-up only: RadioLib's own boot prints (found-chip line with the
; transceiver/WiFi/GNSS FW versions, calibration errors). Goes to Serial =
; UART0 on this board. Low volume; drop once the radio is proven.
-D RADIOLIB_DEBUG_BASIC=1
-D RX_BOOSTED_GAIN=true
; DIO5/DIO6 -> RFSW0_V1/RFSW1_V2 confirmed against the V1.0 schematic (LR1110
; block, U7 pins 19/20 -> R19/R20 -> U8 V1/V2) — see target.cpp for the table
; and M9_PORT.md for the crop. The per-mode polarity is the conventional
; 2-pin table every other MeshCore LR1110 board uses, not independently
; re-derived from U8's datasheet (part number isn't printed on the schematic).
-D RF_SWITCH_TABLE
; --- LR1110 SPI / control pins (verified: V1.0 schematic + boot log) ---
-D P_LORA_NSS=39
-D P_LORA_DIO_1=42
-D P_LORA_RESET=45
-D P_LORA_BUSY=41
-D P_LORA_SCLK=40
-D P_LORA_MISO=38
-D P_LORA_MOSI=47
; --- Peripheral I2C bus 0 (Wire): RTC PCF8563 0x51 / IMU QMI8658 0x6b /
; compass QMC6309 0x7c. Brought up by ESP32Board::begin(). ---
-D PIN_BOARD_SDA=7
-D PIN_BOARD_SCL=6
-D PIN_VBAT_READ=13
; --- GPS (CC1167Q, UART1) ---
-D ENV_INCLUDE_GPS=1
-D PIN_GPS_RX=3
-D PIN_GPS_TX=2
-D PIN_GPS_EN=11
-D PIN_GPS_RESET=5
-D PIN_GPS_RESET_ACTIVE=HIGH
; GPS_RST1 -> R46 -> NPN Q16 base: GPIO HIGH turns Q16 on, pulling the module's
; reset pin to GND — so HIGH asserts reset, LOW releases it (inverted vs. library default)
-D PIN_GPS_EN_ACTIVE=LOW
; GPIO10 (GPS ON_OFF) and GPIO4 (1PPS) exist on the schematic but have no
; consumer in this driver yet — reserved, not wired.
-D GPS_BAUD_RATE=115200
-D THINKNODE_M9_BUZZER_PIN=9
-D ENV_INCLUDE_AHTX0=0
-D ENV_INCLUDE_BME280=0
-D ENV_INCLUDE_BMP280=0
-D ENV_INCLUDE_SHTC3=0
-D ENV_INCLUDE_SHT4X=0
-D ENV_INCLUDE_LPS22HB=0
-D ENV_INCLUDE_INA3221=0
-D ENV_INCLUDE_INA219=0
-D ENV_INCLUDE_INA226=0
-D ENV_INCLUDE_INA260=0
-D ENV_INCLUDE_MLX90614=0
-D ENV_INCLUDE_VL53L0X=0
-D ENV_INCLUDE_BME680=0
-D ENV_INCLUDE_BMP085=0
; --- ST7789 panel (manufacturer-confirmed; NOT ILI9341) ---
; No LILYGO_TDECK / HELTEC_LORA_V4_TFT macro is defined, so ST7789LCDDisplay
; uses its default branch (Adafruit_ST7789 over the global `SPI`, the same
; instance the radio uses) — matches the LR1110 reference variants, which
; also share one SPI peripheral across radio + display + (on the M9) SD.
-D DISPLAY_SCALE_X=1.0
-D DISPLAY_SCALE_Y=1.0
; HARDWARE-VERIFIED (bring-up #6, 2026-07-06): rotation 3 rendered the UI
; 180 degrees off on the tester's unit; 1 is the correct landscape
; orientation (keyboard below screen). Adafruit rotations 1/3 are the two
; landscape options, 180 degrees apart.
-D DISPLAY_ROTATION=1
; PIN_TFT_LEDA_CTL is set to -1, NOT left undefined: the installed ST7789LCDDisplay
; references it unconditionally (`if (PIN_TFT_LEDA_CTL != -1)`, no #ifdef guard around
; the macro itself — leaving it undefined is a compile error, not a no-op). -1 makes
; that check skip the pin entirely, since the vendored class always drives it
; active-HIGH, but the M9's backlight is a PNP transistor (active-LOW) — so
; ThinkNodeM9Board owns BL_EN (GPIO17) directly instead (see M9Board.h/.cpp).
; PIN_PERIPH_POWER is the OTHER (also active-low) rail, gating the LCD/GPS/sensors,
; and IS passed through ST7789LCDDisplay's RefCountedDigitalPin constructor arg in
; target.cpp.
-D PIN_TFT_LEDA_CTL=-1
-D PIN_PERIPH_POWER=18
-D PIN_TFT_BL_EN=17
-D PIN_TFT_RST=14
-D PIN_TFT_DC=15
-D PIN_TFT_CS=16
; PIN_TFT_SCL / PIN_TFT_SDA intentionally NOT defined: only the
; USE_PIN_TFT / LILYGO_TDECK / HELTEC_LORA_V4_TFT branches of
; ST7789LCDDisplay's constructor consume them, and M9 uses none of those —
; it takes the default `display(&SPI, PIN_TFT_CS, PIN_TFT_DC, PIN_TFT_RST)`
; branch (global SPI, same instance the radio uses).
;
; NOTE: a software-SPI (USE_PIN_TFT) diagnostic build was tried here to test
; whether the class's hardcoded 80MHz hardware SPI clock was corrupting the
; boot-splash write. It wasn't — software SPI reproduced the EXACT same
; freeze-then-TG1WDT_SYS_RST at the exact same point, just slower, which
; rules out the SPI clock/signal-integrity theory entirely. See
; M9_PORT.md / git history if revisiting that path.
; microSD: on the shared LoRa SPI bus, same as T-Deck. CS is GPIO48 — the
; schematic net SPICLK_N, which is NOT one of the GPIO33-37 octal-PSRAM
; lines: SPICLK_N/GPIO48 (and SPICLK_P/GPIO47) are only reserved on the
; R8V/R16V 1.8V-differential-clock variants. This board is a plain R8 (see
; the env comment above), which uses the ordinary single-ended SPICLK
; instead, so GPIO48 is genuinely free. Confirmed via schematic: GPS_RST1
; and this net were the ones directly identified, not inferred.
-D PIN_SD_CS=48
-D HAS_M9_KEYBOARD=1
; Keyboard bus SCHEMATIC-VERIFIED (V1.0 sheet, bring-up #9): S3 GPIO20 =
; net ESP32-2_SDA, GPIO21 = ESP32-2_SCL, to the keyboard ESP32-S2 (its
; GPIO7/6) through R2/R1 series resistors, pullups R73/R72, S2 powered from
; always-on 3V3 via R3. GPIO19/20 are also the S3's native USB D-/D+ pads —
; M9Board::begin() must release the USB-Serial-JTAG pad claim first.
-D PIN_KB_SDA=20
-D PIN_KB_SCL=21
-D PIN_KB_ADDR=0x6c
; --- touch UI / companion stack (M9 has no touch — keyboard + d-pad text
; entry only; keypad-nav focus traversal is NOT wired yet, see
; M9_PORT.md) ---
-I include
-I src
-I src/ui-touch
-D UI_LVGL=1
-D HAS_TOUCH_UI=1
-D FIRMWARE_OTA_ENV='"ThinkNode_M9_companion_radio_touch"'
-D ENABLE_ADVERT_ON_BOOT=0
-D LV_CONF_PATH=lv_conf.h
-D LV_CONF_INCLUDE_SIMPLE=1
-D LV_INDEV_DEF_SCROLL_THROW=7
-D MAX_CONTACTS=2000
-D MAX_GROUP_CHANNELS=40
-D DISPLAY_CLASS=ST7789LCDDisplay
-D ADMIN_PASSWORD='"password"'
-D MULTI_TRANSPORT_COMPANION=1
-D WADAMESH_FORK_BUILD=1
-D TCP_PORT=5000
-D WS_PORT=8765
-D BLE_PIN_CODE=123456
-D CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=1
-D CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
-D CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096
build_src_filter =
+<*.cpp>
+<*.c>
+<helpers/*.cpp>
+<helpers/esp32/*.cpp>
+<helpers/input/*.cpp>
+<ui-touch/*.cpp>
+<ui-touch/*.c>
+<../variants/thinknode_m9/*.cpp>
lib_deps =
https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.1
SPI
Wire
jgromes/RadioLib @ ^7.6.0
rweather/Crypto @ ^0.4.0
adafruit/RTClib @ ^2.1.3
melopero/Melopero RV3028 @ ^1.1.0
electroniccats/CayenneLPP @ 1.6.1
h2zero/NimBLE-Arduino @ 1.4.3
adafruit/Adafruit INA3221 Library @ ^1.0.1
adafruit/Adafruit INA219 @ ^1.2.3
robtillaart/INA226 @ ^0.6.4
adafruit/Adafruit INA260 Library @ ^1.5.3
adafruit/Adafruit AHTX0 @ ^2.0.5
adafruit/Adafruit BME280 Library @ ^2.3.0
adafruit/Adafruit BMP280 Library @ ^2.6.8
adafruit/Adafruit SHTC3 Library @ ^1.0.1
sensirion/Sensirion I2C SHT4x @ ^1.1.2
arduino-libraries/Arduino_LPS22HB @ ^1.0.2
adafruit/Adafruit MLX90614 Library @ ^2.1.5
adafruit/Adafruit_VL53L0X @ ^1.2.4
stevemarple/MicroNMEA @ ^2.0.6
adafruit/Adafruit BME680 Library @ ^2.0.4
adafruit/Adafruit BMP085 Library @ ^1.2.4
adafruit/Adafruit ST7735 and ST7789 Library @ ^1.11.0
ESP32Async/ESPAsyncWebServer @ 3.10.3
file://arch/esp32/AsyncElegantOTA
lvgl/lvgl @ ^8.3.11
densaugeo/base64 @ ~1.4.0
knolleary/PubSubClient @ ^2.8.0
; ======================================================================
; RAK WisMesh Tap V2 — ST7789 TFT + FT5x06 capacitive touch + SX1262.
; RAK3312 module (ESP32-S3, 16 MB Flash DIO, 8 MB Octal PSRAM).
; ======================================================================
[env:rak_tap_v2_companion_radio_touch]
platform = platformio/espressif32@6.11.0
framework = arduino
board = rak_tap_v2
monitor_speed = 115200
board_build.flash_mode = dio ; RAK3312 requires DIO (board JSON defaults to qio)
board_build.partitions = variants/rak_tap_v2/partitions_rak_tap_v2_touch.csv
extra_scripts = pre:scripts/inject_wifi_env.py, merge-bin.py
; Round-1b USB: MODE=1 HW CDC (single COM7). No 1200bps touch — use DTR/RTS reset.
build_unflags =
-D ARDUINO_USB_MODE=0
upload_speed = 460800
upload_flags =
--before=default_reset
--after=hard_reset
build_flags =
; 1.17 core: ESP32Board.cpp includes <target.h> -> MicroNMEALocationProvider.h (header-only
; provider), so MicroNMEA never chains into the core lib's LDF scope -- hand it the path.
-I"${platformio.libdeps_dir}/${this.__env__}/MicroNMEA/src"
-Wno-deprecated-declarations -Wno-unused-parameter -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1
-D MC_VENDORED_TOUCH_APP
-D LORA_FREQ=869.618
-D LORA_BW=62.5
-D LORA_SF=8
-D ENABLE_PRIVATE_KEY_IMPORT=1
-D ENABLE_PRIVATE_KEY_EXPORT=1
-D RADIOLIB_EXCLUDE_CC1101=1
-D RADIOLIB_EXCLUDE_RF69=1
-D RADIOLIB_EXCLUDE_SX1231=1
-D RADIOLIB_EXCLUDE_SI443X=1
-D RADIOLIB_EXCLUDE_RFM2X=1
-D RADIOLIB_EXCLUDE_SX128X=1
-D RADIOLIB_EXCLUDE_AFSK=1
-D RADIOLIB_EXCLUDE_AX25=1
-D RADIOLIB_EXCLUDE_HELLSCHREIBER=1
-D RADIOLIB_EXCLUDE_MORSE=1
-D RADIOLIB_EXCLUDE_APRS=1
-D RADIOLIB_EXCLUDE_BELL=1
-D RADIOLIB_EXCLUDE_RTTY=1
-D RADIOLIB_EXCLUDE_SSTV=1
-D ESP32_PLATFORM
; --- sensors (GPS + AHTx0 + BME680 enabled) ---
-D ENV_INCLUDE_GPS=1
-D ENV_INCLUDE_AHTX0=1
-D ENV_INCLUDE_BME280=0
-D ENV_INCLUDE_BMP280=0
-D ENV_INCLUDE_SHTC3=0
-D ENV_INCLUDE_SHT4X=0
-D ENV_INCLUDE_LPS22HB=0
-D ENV_INCLUDE_INA3221=0
-D ENV_INCLUDE_INA219=0
-D ENV_INCLUDE_INA226=0
-D ENV_INCLUDE_INA260=0
-D ENV_INCLUDE_MLX90614=0
-D ENV_INCLUDE_VL53L0X=0
-D ENV_INCLUDE_BME680=1
-D ENV_INCLUDE_BMP085=0
; --- LoRa SX1262 (RAK3312 module, same pins as RAK3112) ---
-I variants/rak_tap_v2
-D RAK_WISMESH_TAP_V2=1
-D USE_SX1262
-D ESP32_CPU_FREQ=240
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D P_LORA_TX_LED=46
-D P_LORA_DIO_1=47
-D P_LORA_NSS=7
-D P_LORA_RESET=8
-D P_LORA_BUSY=48
-D P_LORA_SCLK=5
-D P_LORA_MISO=3
-D P_LORA_MOSI=6
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
-D PIN_GPS_RX=43
-D PIN_GPS_TX=44
-D PIN_USER_BTN=0
-D PIN_VEXT_EN=14
-D PIN_BOARD_SDA=9
-D PIN_BOARD_SCL=40
; --- TFT (ST7789 240x320, LovyanGFX hardware SPI on FSPI/SPI2_HOST SCL=13/SDA=11) ---
; USB: ARDUINO_USB_* from boards/rak_tap_v2.json (MODE=1 HW CDC, Meshtastic-aligned)
-D DISPLAY_CLASS=LGFXDisplay
-D LGFX_INVERT_COLOR=true ; false=white bg, true=black bg (ST7789 INVON)
-D DISPLAY_ROTATION=3
-D DISPLAY_SCALE_X=1.0
-D DISPLAY_SCALE_Y=1.0
-D PIN_TFT_RST=-1
-D PIN_TFT_LEDA_CTL=41
-D PIN_TFT_LEDA_CTL_ACTIVE=HIGH
-D PIN_TFT_CS=12
-D PIN_TFT_DC=42
-D PIN_TFT_SCL=13
-D PIN_TFT_SDA=11
; --- FT5x06 capacitive touch (I2C0 addr 0x38, SDA=9/SCL=40) ---
-D HAS_RAK_TAP_V2=1
-D RAK_TS_FLIP_X=1
-D RAK_TS_FLIP_Y=1
-D PIN_TOUCH_SDA=9
-D PIN_TOUCH_SCL=40
-D PIN_TOUCH_INT=39
; --- touch UI / companion stack ---
-I include
-I src
-I src/ui-touch
-D UI_LVGL=1
-D HAS_TOUCH_UI=1
-D FIRMWARE_OTA_ENV='"rak_tap_v2_companion_radio_touch"'
-D ENABLE_ADVERT_ON_BOOT=0
-D LV_CONF_PATH=lv_conf.h
-D LV_CONF_INCLUDE_SIMPLE=1
-D LV_INDEV_DEF_SCROLL_THROW=7
-D USER_SETUP_LOADED=1
-D ST7789_DRIVER=1
-D TFT_WIDTH=320
-D TFT_HEIGHT=240
-D TFT_MOSI=11
-D TFT_SCLK=13
-D TFT_CS=12
-D TFT_DC=42
-D TFT_RST=-1
-D TFT_MISO=-1
-D SPI_FREQUENCY=40000000
-D TFT_RGB_ORDER=TFT_RGB
-D TFT_INVERSION_ON=1
-D TFT_BL=41
-D TFT_BACKLIGHT_ON=1
-D MAX_CONTACTS=2000
-D MAX_GROUP_CHANNELS=40
-D ADMIN_PASSWORD='"password"'
-D MULTI_TRANSPORT_COMPANION=1
-D WADAMESH_FORK_BUILD=1
-D TCP_PORT=5000
-D WS_PORT=8765
-D BLE_PIN_CODE=123456
-D CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=1
-D CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
-D CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096
build_src_filter =
+<*.cpp>
+<helpers/*.cpp>
+<helpers/esp32/*.cpp>
+<helpers/input/*.cpp>
; RAK's DISPLAY_CLASS is OUR LGFXDisplay (variants/rak_tap_v2) -- the UIColor palette
; must come from a project object, or the linker pulls the core's same-named
; LGFXDisplay.o from the archive for it and every method collides.
+<helpers/ui/UIColorPalette.cpp>
+<ui-touch/*.cpp>
+<ui-touch/*.c>
+<../variants/rak_tap_v2/*.cpp>
lib_deps =
https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.1
SPI
Wire
jgromes/RadioLib @ ^7.6.0
rweather/Crypto @ ^0.4.0
adafruit/RTClib @ ^2.1.3
melopero/Melopero RV3028 @ ^1.1.0
electroniccats/CayenneLPP @ 1.6.1
h2zero/NimBLE-Arduino @ 1.4.3
adafruit/Adafruit INA3221 Library @ ^1.0.1
adafruit/Adafruit INA219 @ ^1.2.3
robtillaart/INA226 @ ^0.6.4
adafruit/Adafruit INA260 Library @ ^1.5.3
adafruit/Adafruit AHTX0 @ ^2.0.5
adafruit/Adafruit BME280 Library @ ^2.3.0
adafruit/Adafruit BMP280 Library @ ^2.6.8
adafruit/Adafruit SHTC3 Library @ ^1.0.1
sensirion/Sensirion I2C SHT4x @ ^1.1.2
arduino-libraries/Arduino_LPS22HB @ ^1.0.2
adafruit/Adafruit MLX90614 Library @ ^2.1.5
adafruit/Adafruit_VL53L0X @ ^1.2.4
stevemarple/MicroNMEA @ ^2.0.6
adafruit/Adafruit BME680 Library @ ^2.0.4
adafruit/Adafruit BMP085 Library @ ^1.2.4
adafruit/Adafruit ST7735 and ST7789 Library @ ^1.11.0
ESP32Async/ESPAsyncWebServer @ 3.10.3
file://arch/esp32/AsyncElegantOTA
lvgl/lvgl @ ^8.3.11
lovyan03/LovyanGFX@1.2.21
bodmer/TFT_eSPI @ ^2.5.43
densaugeo/base64 @ ~1.4.0
knolleary/PubSubClient @ ^2.8.0