Manual Build & Flash

Build the firmware from source and flash it with the Rust ESP toolchain. This is the route to take if you want to modify the firmware. For a deeper tour of the codebase and the build/test commands, see Architecture and Building & Testing.

Install the toolchain

If you don’t have cargo yet, install Rust via rustup first. Then install the ESP toolchain:

cargo install espup --locked
espup install --toolchain-version 1.90.0.0
cat $HOME/export-esp.sh >> ~/.bashrc
source ~/.bashrc
cargo install espflash ldproxy

Note

Pass --toolchain-version exactly as shown. A release after 1.90.0.0 regressed the Xtensa LLVM backend, which then fails to compile serde_json’s f32 path with Cannot select: XtensaISD::PCREL_WRAPPER TargetConstantPool. CI pins the same version.

Build and flash

Clone the repository and build:

git clone https://github.com/f321x/offline-bitcoin-atm.git
cd offline-bitcoin-atm
cargo build --release
cargo run --release   # builds and flashes to the connected ESP32

cargo run uses the espflash runner configured in .cargo/config.toml.

JC3248W535C touchscreen (ESP32-S3)

The touchscreen board uses a different chip and a feature flag, so pass both explicitly (espup install above already covers the ESP32-S3 toolchain):

cargo run --release --features jc3248 --target xtensa-esp32s3-espidf

Tip

If no serial port shows up or flashing fails, hold the board’s BOOT button while plugging in the USB cable to force the bootloader.

Note

The flash step erases the NVS config partition, so the device returns to the WiFi configuration portal on the next boot. Continue with Configuration.

After flashing, the ATM starts a WiFi access point for initial configuration.