Building the Firmware
Stock Meshtastic firmware runs on LIA hardware fine using a generic ESP32-S3 target, but it has no way to know about LIA-specific peripherals — peripheral power gating, the status LED, the mode switch, the charger status pins, the battery gauge, or the IMU. The lia_v1 board variant and its support code, under firmware/ in this repository, exists to fill that gap.
Which variant
Section titled “Which variant”There is a single board variant, lia_v1, and it’s the correct build for both the V1.0 and V1.1 boards. The LSM6DSOXTR IMU’s SDA/SCL lines were originally crossed as manufactured, which caused I2C bus errors — a solder rework crossing them back fixes this, and both hardware revisions now ship with that rework done, so both have a working IMU and MAX17048 battery gauge over I2C. V1.0 and V1.1 are a hardware-only distinction (18650 3500mAh vs. 5023450 1000mAh battery, and a corresponding enclosure difference — see Enclosure and Battery); there is no firmware difference and no separate board variant for V1.1.
What’s involved
Section titled “What’s involved”Meshtastic’s own firmware build (meshtastic/firmware on GitHub) isn’t vendored into this repository — it’s a large, independently-versioned project. Building for LIA means applying this repo’s overlay on top of a checkout of it:
firmware/meshtastic/variants/esp32s3/lia_v1/—variant.h(GPIO pin mapping, derived from the schematic — see Microcontroller),pins_arduino.h, andplatformio.inifor that board environment.firmware/meshtastic/extra_variants/lia_v1/variant.cpp— hooks into Meshtastic’searlyInitVariant()/lateInitVariant()/variant_shutdown()extension points to initializeLiaBoardand constructTrackerService,ChargeStatusService, andCommandService.firmware/board/—LiaBoard, the hardware abstraction for peripheral power gating, the status LED, the mode switch, and charger status.firmware/drivers/—ImuMotionDriver, talking to the LSM6DSOXTR directly (stock Meshtastic’s own accelerometer support doesn’t drive this specific chip — see Accelerometer).firmware/services/—TrackerService(position broadcasts + the BMS state machine),ChargeStatusService(charge-status messages),CommandService(the text-command interface), plus the sharedMeshTargets.htarget-node definition.
No core Meshtastic files are patched — everything hooks in via the extension points above.
Build steps
Section titled “Build steps”firmware/tools/build.ps1 automates all of this (clone-if-missing, checkout the pinned tag, copy the overlay, pio run). Run it from a native PowerShell session, not Git Bash/MSYS — the ESP-IDF toolchain this platform pulls in refuses to run under MSYS.
-
Build (
lia_v1is the only variant — the correct build for both V1.0 and V1.1 boards):Terminal window cd firmware/tools./build.ps1 -
Build and flash in one step:
Terminal window ./build.ps1 -Upload -Port COM7
Or manually, following the same steps the script automates:
-
Clone Meshtastic’s firmware repository and check out the pinned tag (
mainis a moving development branch):Terminal window git -c core.longpaths=true clone --recurse-submodules --depth 1 `--branch v2.7.26.54e0d8d https://github.com/meshtastic/firmware.git meshtastic-firmwarecore.longpaths=trueis required on Windows — some paths inside this repo exceed 260 characters. -
Copy this repo’s overlay into the checkout:
Terminal window Copy-Item firmware/meshtastic/boards/lia_v1.json meshtastic-firmware/boards/New-Item -ItemType Directory -Force meshtastic-firmware/variants/esp32s3/lia_v1Copy-Item firmware/meshtastic/variants/esp32s3/lia_v1/* meshtastic-firmware/variants/esp32s3/lia_v1/New-Item -ItemType Directory -Force meshtastic-firmware/src/platform/extra_variants/lia_v1Copy-Item firmware/meshtastic/extra_variants/lia_v1/* meshtastic-firmware/src/platform/extra_variants/lia_v1/New-Item -ItemType Directory -Force meshtastic-firmware/src/liaCopy-Item firmware/board/*.h, firmware/board/*.cpp meshtastic-firmware/src/lia/Copy-Item firmware/drivers/*.h, firmware/drivers/*.cpp meshtastic-firmware/src/lia/New-Item -ItemType Directory -Force meshtastic-firmware/src/lia/servicesCopy-Item firmware/services/*.h, firmware/services/*.cpp meshtastic-firmware/src/lia/services/ -
Build:
Terminal window cd meshtastic-firmwarepio run -e lia_v1 -
Flash:
Terminal window pio run -e lia_v1 -t upload --upload-port <PORT>
Standalone bring-up tests
Section titled “Standalone bring-up tests”Two small, Meshtastic-free PlatformIO projects under firmware/tools/ isolate specific hardware questions from the rest of the firmware’s complexity, useful when debugging just the GPS or the battery gauge in isolation:
gps_test/— powers the GNSS module and prints whatever it’s decoded every 10 seconds.battery_test/— prints the MAX17048’s charge percentage and cell voltage every 2 seconds, via two independently-computed read paths side by side (this is what isolated a real gauge-reading bug — see Battery).
Each has its own platformio.ini and README with build/flash instructions.
Provisioning after flashing
Section titled “Provisioning after flashing”Set the device role to TRACKER and note the target node LIA sends everything to (position broadcasts, charge-status messages, and CommandService replies are all direct messages to a single hardcoded node — see Meshtastic Configuration for exactly what’s required and why).
See also: Getting Started, Meshtastic Configuration, and Microcontroller.

