Skip to content

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.

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.

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, and platformio.ini for that board environment.
  • firmware/meshtastic/extra_variants/lia_v1/variant.cpp — hooks into Meshtastic’s earlyInitVariant()/lateInitVariant()/variant_shutdown() extension points to initialize LiaBoard and construct TrackerService, ChargeStatusService, and CommandService.
  • 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 shared MeshTargets.h target-node definition.

No core Meshtastic files are patched — everything hooks in via the extension points above.

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.

  1. Build (lia_v1 is the only variant — the correct build for both V1.0 and V1.1 boards):

    Terminal window
    cd firmware/tools
    ./build.ps1
  2. Build and flash in one step:

    Terminal window
    ./build.ps1 -Upload -Port COM7

Or manually, following the same steps the script automates:

  1. Clone Meshtastic’s firmware repository and check out the pinned tag (main is 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-firmware

    core.longpaths=true is required on Windows — some paths inside this repo exceed 260 characters.

  2. 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_v1
    Copy-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_v1
    Copy-Item firmware/meshtastic/extra_variants/lia_v1/* meshtastic-firmware/src/platform/extra_variants/lia_v1/
    New-Item -ItemType Directory -Force meshtastic-firmware/src/lia
    Copy-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/services
    Copy-Item firmware/services/*.h, firmware/services/*.cpp meshtastic-firmware/src/lia/services/
  3. Build:

    Terminal window
    cd meshtastic-firmware
    pio run -e lia_v1
  4. Flash:

    Terminal window
    pio run -e lia_v1 -t upload --upload-port <PORT>

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.

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.