Open-source firmware for the Bitaxe Gamma and NerdQAxe++, written in Rust: AxeOS-compatible API, Stratum V1 + V2, signed online updates, one image for all boards. https://warppool.org/warpaxe
  • Rust 73.7%
  • HTML 14.9%
  • C 8.9%
  • Python 1.5%
  • Shell 0.8%
  • Other 0.2%
Find a file
dvb-projekt 42daf5c247
All checks were successful
CI / Rust checks (push) Successful in 44s
CI / Regulator scenarios (push) Successful in 50s
fix(tools): soak-test retries a read that times out instead of failing the watch
The v0.1.10 click update on the Gamma passed, but the watch stopped with
an uncaught URLError when one GET timed out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 07:11:56 +02:00
.github/workflows feat(board): regulator, thermal sensor, fan PID and board profiles, no_std 2026-09-24 09:54:12 +02:00
crates feat(board): Bitaxe Gamma Duo, Gamma Turbo, Naja Duo and Gamma Hex profiles, EMC2103 driver 2026-09-30 00:17:34 +02:00
docs docs(brand): Bitronics agreed to the NerdAxe Gaia wordmark on the boot screen 2026-09-30 01:55:38 +02:00
firmware v0.1.10: version, README 2026-09-30 06:30:51 +02:00
tools fix(tools): soak-test retries a read that times out instead of failing the watch 2026-09-30 07:11:56 +02:00
web/flasher Web flasher for the first install, stock-firmware comparison in the README 2026-09-28 07:13:52 +02:00
.gitignore feat(avalon): decaying MHS 15m, write verification in the bench, A/B live 2026-09-23 09:17:28 +02:00
Cargo.lock feat(sv2): Stratum V2 client crate, tested against the WarpPool server 2026-09-27 19:26:51 +02:00
Cargo.toml feat(sv2): Stratum V2 client crate, tested against the WarpPool server 2026-09-27 19:26:51 +02:00
LICENSE feat: workspace, CRC-5/16 and BM13xx framing with golden vectors 2026-09-23 06:43:59 +02:00
README.md v0.1.10: version, README 2026-09-30 06:30:51 +02:00

dvb-WarpAxe

Open-source Rust firmware for BM1370 Bitcoin miners
Bitaxe Gamma · NerdQAxe++ · NerdOCTAXE-γ · Stratum V1 + V2 · AxeOS-compatible API · Signed online updates

License Rust Tests Chip Release


dvb-WarpAxe is a from-scratch firmware for ESP32-S3 miners with BM1370 ASICs, written in Rust. It replaces AxeOS (Bitaxe) and NerdOS (NerdQAxe) on the device and speaks their HTTP API, so dashboards, tuners and fleet tools that talk to a Bitaxe keep working — including WarpTune, the clock-and-voltage regulator of dvb-WarpPool.

It does what the stock firmware does — Stratum V2 with the pool's authority key checked, Stratum V1 over TLS, a fallback pool that hands back to the main pool — and differs where it counts for running a fleet: signed online updates the miner fetches and checks itself, one image for every board with the board found on the first start and Wi-Fi and pool taken over from the previous AxeOS/NerdOS settings, a password-protected setup hotspot when there is no network to join, a regulator and sensor layer that rejects implausible readings instead of acting on them, the web UI over the USB cable as well as over Wi-Fi, and one web UI in eight languages for the Bitaxe and the Nerd series. The device display has animated special screens (yes, a found block gets a warp jump). See Compared with the stock firmware for where it is ahead and where it is not.

The chip protocol, the chain driver and the board drivers are no_std crates that run under cargo test against a simulated chain and a scripted I²C bus, so most of the firmware is tested on a laptop before it touches a miner.

Status: early (v0.1.10). It mines 24/7 on one Bitaxe Gamma and one NerdQAxe++ (Rev 6.1, on Stratum V2) under WarpTune, since 28 September on one NerdOCTAXE-γ (Rev 3.1, 6-phase regulator) and since 29 September on one NerdAxe Gaia and one BitForge Nano. Other boards have a profile but have not run it — see Supported boards before you flash.

Compared with the stock firmware

As of 2026-09-28, against ESP-Miner/AxeOS v2.15.3 and ESP-Miner-NerdQAxePlus (NerdOS) v1.1.0.1, from their source. Both move fast; corrections welcome.

AxeOS NerdOS WarpAxe
Stratum V2 (Noise, authority key, "require authentication") yes yes yes
Stratum V1 over TLS, certificate checked yes yes yes
Fallback pool, back to the main pool on its own yes yes (plus dual-pool mode) yes
Update: miner fetches the release itself no (download, then upload) yes (from GitHub) yes (from the release page, install on a click)
Update image signature-checked before flashing no no yes (BIP-340, key built into the firmware)
Images factory image per board version (update image shared) one per board one for all boards
Board set in NVS at the factory per image found on the first start (factory NVS, read-only I²C probe)
Settings on an update or reinstall kept on online update; web flasher can keep them kept with the update's "keep settings" option kept on online update and web-flasher reinstall; taken over from AxeOS/NerdOS when switching (Wi-Fi, pools — also AxeOS 2.15's —, hostname, clock and voltage, fans and temperature limits, display)
Back on after an overheat stop yes (≥ 30 s, regulator 10 °C cooler) not found yes (≥ 60 s, chip and regulator 10 °C cooler; the third stop within an hour stays off)
Regulator fault (PMBus STATUS_WORD) reported (power_fault), no reaction read once at init, logged reported (power_fault with codes, display and web UI) and treated like an overheat stop: core voltage off, faults cleared and retried after a minute, the third within an hour stays off
Wi-Fi setup without a network open hotspot (Bitaxe_XXXX), or Bluetooth open hotspot (Nerdaxe_XXXX) WPA2 hotspot, password shown only on the device display
Implausible sensor/regulator readings partly ignored (fan loop) not found rejected before the control loops see them
Web UI over the USB cable not found not found yes (USB network adapter, 192.168.7.1)
Web UI languages English 9 8
Language, tests C C++/C Rust; chip, chain and board drivers host-tested against a simulated chain and I²C bus
Supported boards ~20 board versions 11 boards 3 tested (see below)

Where the stock firmware is ahead: far more boards and years of use by a large community; AxeOS has a scoreboard, themes, the BAP accessory port and Wi-Fi setup over Bluetooth; NerdOS has two-factor login for updates, dual-pool mining, InfluxDB/Grafana export and alerts. WarpAxe is early; if you need any of that, stay with the stock firmware.

With WarpTune

WarpTune, the clock-and-voltage regulator of dvb-WarpPool, works on the stock firmware in full — it talks the AxeOS API, and WarpAxe keeps that API. The difference is what the firmware says about itself: WarpAxe reports these states explicitly, so WarpTune does not have to guess them from the power draw:

  • Overheat stop: overheat_mode while it lasts, overheatTrips and overheatCause (hot, a lost sensor, or a regulator fault: power, with the conditions in powerFaultCodes). WarpTune holds during the stop, and after a hot stop takes the clock one step down (two from the second stop in an hour); a lost sensor is no reason to step down.
  • Chips off or the chain still coming up: chainStopped and chainPhase, so a chain that is powering up is not taken for a dead chip.
  • Fallback pool and reject reasons, as on current AxeOS.

The table on the WarpPool side lists, firmware by firmware, what WarpTune gets from AxeOS, NerdOS, ForgeOS and WarpAxe.

Screenshots

Web UI

Dashboard: type plate with chip grid, hashrate, efficiency, shares, best difficulty, history, temperatures, fans, power, pool
Dashboard — chip grid and series colour, the hashrate with its share of the expected rate, efficiency, power, shares and best difficulty, the 1 h / 3 h history; below, temperature, fans and power, and the pool with the payout of a found block.

Swarm: the fleet's hashrate, power, efficiency and record difficulty, each miner's share, and one card per miner with sparkline and temperatures
Swarm — every miner on the network, WarpAxe or stock firmware, read by your browser: the fleet's hashrate and each miner's share of it, sparklines, chip and regulator temperatures against their limits.

Settings: clock and voltage presets, fans and temperature, display
Settings — clock and voltage as the manufacturer's steps (Wi-Fi, hostname and time are on their own Network tab); ?oc in the address unlocks free values and the expert section (fan PID, second fan output, suggested difficulty, job interval).

Network: Wi-Fi, hostname, time by NTP and time zone
Network — Wi-Fi with a list of networks found, hostname, time by NTP and time zone.

System: online update, maintenance, live log
System — online update from the releases, upload, download mode for a reinstall with the web flasher, maintenance (switch the chips off without losing the device, reset overheat) and the live log.

Pool page: connection, shares, coinbase payout and outputs, pool settings
Pool — the connection (protocol, Noise/TLS, fallback), shares with reject reasons, and who a found block pays: your share, the coinbase value and each output. Below, main and fallback pool, each Stratum V1 with optional TLS or Stratum V2 with the pool's authority key.

Device display

NerdQAxe++ LCD pages: cockpit, Bitcoin, device, pool
NerdQAxe++ (320×170 LCD) — the cockpit and three of the four pages the page key steps through (a log page follows). Block height, halving and network difficulty come from the pool's job; the BTC price line appears only if you switch it on.

Block found animation: warp jump
Block found — stars accelerate into a warp jump, a flash, then the height with shock rings until a key is pressed.

Special screens: overheat, chips off, firmware update
Special screens — overheat (pulsing frame), chips off, firmware update with progress.

Wi-Fi setup screen on the NerdQAxe++ LCD: hotspot name and a ten-digit password Wi-Fi setup on the Bitaxe OLED: name, password and address take turns
Setup hotspot — name and password (new at every start, example shown) on the LCD; on the OLED they take turns with the address.

Bitaxe Gamma OLED rotation
Bitaxe Gamma (128×32 OLED) — hashrate large, rotating values, full-width info slides and the wordmark.

All display images are rendered from the firmware's own drawing code (tools/display-preview) with sample values; a device's screen can be read back at any time with GET /api/v1/display/frame.

Features

Mining

  • BM1370 chain driver: enumeration, baud switch, PLL solved (not looked up) and ramped, work dispatch, nonce attribution, stale and duplicate filtering, per-chip silence watchdog.
  • Stratum V2 per pool: Noise handshake (secp256k1 + EllSwift, ChaCha20-Poly1305), extended channel, the pool's certificate checked against its authority key (Base58Check, as pools publish it). "Require pool authentication" is on by default: without a key, or before the clock is set by NTP, there is no connection. The TLS switch applies to V1 only; V2 is always encrypted. The display shows "V2" with the lock. Settings from NerdOS (sv2_proto, sv2_auth_pk, sv2_reqauth) are taken over on the first start.
  • Stratum V1 with version rolling (BIP 310), mining.suggest_difficulty, optional TLS (esp-tls, built-in CA bundle, hostname checked).
  • Fallback pool: after three failed attempts on the main pool; a probe every five minutes brings it back as soon as the main pool answers.
  • Block height, network difficulty and the pool's coinbase tag read from the job; a nonce at or above the network difficulty is reported as a found block.

Board

  • Regulators: TPS546 (Bitaxe Gamma), TPS53647/TPS53667 (Nerd boards).
  • Sensors and fans: EMC2101, EMC2302 (two outputs), TMP1075, FXL6408 GPIO expander.
  • Fan PID with ESP-Miner's gains, a second output that follows the regulator temperature — or, with Link the fans, runs at the chip fan's speed for cases where every fan cools the whole board (Y-cables) — minimum speed, polarity.
  • Overheat shutdown of the core voltage and a guard for a lost chip sensor (60 s blind = off). The chips start again on their own once chip and regulator are 10 °C below their limits (at least 60 s off; after a lost sensor only with real readings back); the third stop within an hour stays off until it is cleared by hand.
  • Plausibility windows for every reading: a regulator that answers garbage while it powers up is reported as "no reading", never as a value a tuner could act on.
  • Switch the chips off and on again from the web UI or the API; the device stays reachable.

Web UI and API

  • One UI for every board, series colour and chip grid on the type plate; English, German, Spanish, French, Italian, Brazilian Portuguese, Japanese and Chinese, each reviewed by a native speaker (the device display in the six Latin-script ones).
  • Dashboard and Pool page in the warp design: one hero with the hashrate, its share of the expected rate and the 1 h / 3 h history (hashrate as a two-minute average, temperature in steps of at least 0.5 °C, so counting noise does not fill the chart), then temperature, fan/power and pool instruments; live log.
  • Coinbase payout of every job, as AxeOS shows it: the share of a found block that goes to your address (green from 95 %, red below), the coinbase value and its outputs, over Stratum V1 and V2.
  • Swarm page for the other miners on the network — AxeOS, NerdOS, ForgeOS or WarpAxe: fleet hashrate, power, J/TH and record difficulty, each miner's share, a card per miner with a sparkline and its temperatures. The browser reads every miner's /api/system/info directly (every 30 s by default, not while the tab is hidden, one request per miner at a time); this miner stores only the address list. Read-only: it never changes or restarts another miner. Add miners by address or by a search of the local /24.
  • Tabs in the stock order: Dashboard, Swarm, Network, Pool, Settings, System; the starfield background of dvb-WarpPool.
  • AxeOS/NerdOS-compatible endpoints: /api/system/info, PATCH /api/system, /api/system/asic, /api/v2/settings, restart, OTA upload.
  • WarpAxe's own: /api/v1/state, /api/v1/history, /api/v1/log, chips off/on, overheat and best-difficulty reset, Wi-Fi scan, display frame / key / demo, online update, download mode for the web flasher, the swarm list (/api/v1/swarm).
  • States a tuner would otherwise have to guess from the power draw are in /api/system/info: chainStopped and chainPhase, overheat_mode, overheatTrips (stops in the last hour), overheatCause (hot, a lost sensor or a regulator fault), overheatLatched, power_fault (AxeOS's field and wording) with powerFaultCodes, isUsingFallbackStratum, sharesRejectedReasons, AxeOS's coinbaseOutputs, coinbaseValueTotalSatoshis and coinbaseValueUserSatoshis, and temptarget (the fan target, under ESP-Miner's name) so a tuner keeps its own target above it.
  • Setup hotspot: with no network in the settings, or none reached within three minutes of a start, the miner opens WarpAxe-XXXX — WPA2, with a ten-digit password made at every start and shown only on the device display. A phone that joins it gets the Wi-Fi setup page by itself (captive portal); after saving, the miner restarts, joins the network and closes the hotspot. The log names the address behind every restart, download-mode and overheat-reset request.

Device display

  • NerdQAxe++ LCD: cockpit with the last hour's hashrate, Bitcoin, device, pool and log pages, anti-aliased fonts (Space Grotesk, JetBrains Mono, Inter) pre-rendered at build time.
  • Bitaxe OLED: large hashrate, rotating values, info slides, share blink.
  • Special screens for block found, overheat, chips off and firmware update; display language, time zone, screen timeout.
  • Optional BTC price and fee rates from mempool.space — off by default; with it off the miner talks to its pool and nothing else (plus the update check, which you can switch off too).

Updates

  • Online update: the miner checks this repository's releases at start and every hour, the web UI shows the new version and its notes (and a pill in the header on every page), and one click downloads, verifies (SHA-256 and the release signature: BIP-340 Schnorr with the key built into the firmware, warpaxe.bin.sig) and installs it. A release without a signature still installs for now and is marked as unsigned; that tolerance ends once every release carries one. Nothing installs by itself: an update restarts the miner.
  • Downloads are tried up to three times; the log names the address that started an install, an upload or an update check, and the last install (version and signature result) is kept across the restart.
  • Upload a warpaxe.bin in the web UI, or curl --data-binary @warpaxe.bin http://<miner>/api/system/OTA — a manual upload is your own image and is not signature-checked.
  • The web UI and its fonts are part of the image: one file, one update.

Supported boards

Board ASICs Regulator Status
Bitaxe Gamma (601/602) 1× BM1370 TPS546 runs 24/7
NerdQAxe++ (every revision but Rev 7; NerdOS treats them alike) 4× BM1370 TPS53647 runs 24/7 (on a Rev 6.1)
NerdQAxe++ Rev 7 4× BM1370 TPS546 (two voltage domains) profile from NerdOS, recognised on the bus and offered for one click; not run yet
NerdOCTAXE-γ Rev 3.1 8× BM1370 TPS53667 (6-phase) runs since 2026-09-28; at 700 MHz / 1210 mV the pool counts 11.59 TH/s ± 2.5 % (NerdOS: 11.71) since v0.1.9 paces work as NerdOS does (the 4-phase TPS53647 variant has not run)
BitForge Nano (800) 2× BM1370 TPS546 + INA260 runs since 2026-09-29 (ForgeOS's 525 MHz / 1150 mV: about 2.2 TH/s at 43–45 W); offered on the first start, never taken on its own
Bitaxe Gamma Duo (650) 2× BM1370 TPS546 profile only, not run yet
Bitaxe Gamma Turbo (801) 2× BM1370 2× TPS546 profile only, not run yet
Bitaxe Naja Duo (1201) 2× BM1373 2× TPS546 (two domains) profile only, not run yet
Bitaxe Gamma Hex (1300) 6× BM1370 4× TPS546 (two domains) profile only, not run yet
NerdAxe Gamma 1× BM1370 TPS546 profile only, not run yet
NerdAxe Gaia 1× BM1373 TPS546 (12 V) runs since 2026-09-29; at 420 MHz / 960 mV the pool counts 102 % of the expected rate, as with its stock firmware, but the core then draws 31–33 A against the regulator's 33 A limit; clock and voltage capped at 420 MHz / 970 mV
NerdQX (Q1370 / Q1373) 4× BM1370 / BM1373 TPS53647 profile only, not run yet

Boards marked "profile only" have pins, regulator window and limits taken from their stock firmware, but nobody has run WarpAxe on one yet. Please don't flash them unless you can recover the stock firmware over USB.

Install

First install needs a USB cable once; after that the miner sets itself up and updates itself:

  1. Keep a way back — tools/flash-backup.sh reads the whole flash (16 MB) over USB; or keep the stock firmware at hand (the Bitaxe and NerdQAxe web flashers put it back).
  2. Install WarpAxe from the browser with the web flasher at warppool.org/warpaxe (Chrome or Edge on a computer). It writes bootloader, partition table and app and leaves the settings partition alone, so WarpAxe reads what AxeOS or NerdOS left there; it checks every part against the flash and restarts the miner when it is done. The flasher serves the current release; its image carries the same signature the online update checks. Coming from the stock firmware, the flasher usually puts the miner into download mode by itself; otherwise hold BOOT, press RST, release BOOT (on a miner that already runs WarpAxe: System → Download mode). A miner that stays dark after a cancelled install is still in download mode: take it off power completely — power supply and USB cable — for a few seconds. Without a browser: warpaxe-factory.bin from the release at offset 0 with esptool (this one starts with empty settings), or Build from source.
  3. On the first start WarpAxe takes Wi-Fi, pools, hostname, clock and voltage, fan settings, temperature limits and display orientation from the previous firmware (not the fan PID gains, which belong to its own loop) and finds the board: from the model AxeOS stored at the factory, or from the chips that answer on the board's I²C bus (read-only probes on pins that switch nothing). A Bitaxe Gamma starts mining at once. For the Nerd boards the web UI asks once which board it is — the NerdQAxe++ and the NerdOctaxe look alike on the bus — and the chips stay off until you answer.
  4. Open the web UI at the miner's address — or, on boards with native USB, at http://192.168.7.1 over the USB cable (the miner shows up as a USB network adapter). If there was no Wi-Fi to take over, or it cannot be reached, the miner opens its setup hotspot after three minutes: join WarpAxe-XXXX with the password on its display and choose your network.

Updates after that come from the web UI: System → Online update → Install, or upload warpaxe.bin from the releases page. Every release carries warpaxe.bin (one image for all boards — the board is configuration), warpaxe.bin.sha256 and warpaxe.bin.sig; for the first install also warpaxe-factory.bin (bootloader, partition table and app in one image) and web-flasher.tar.gz (the web flasher as published), with their checksums in install.sha256. tools/verify-release.py checks an image's signature without the Rust toolchain.

Build from source

Host crates and tests:

cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
cargo build -p warpaxe-core --target thumbv7em-none-eabihf   # proves no_std

Firmware (Xtensa, ESP-IDF 5.3 via esp-idf-svc; toolchain from espup; its export script must be sourced first, the C code in secp256k1-sys needs xtensa-esp32s3-elf-gcc on the PATH):

cd firmware/warpaxe
cargo build --release
espflash save-image --chip esp32s3 --flash-size 16mb \
    target/xtensa-esp32s3-espidf/release/warpaxe warpaxe.bin   # OTA image
espflash flash --partition-table partitions.csv \
    target/xtensa-esp32s3-espidf/release/warpaxe                # first install over USB

Display preview on the host (every page, special screen and OLED slide as PNG, from the firmware's own drawing code):

cargo run --release --manifest-path tools/display-preview/Cargo.toml -- /tmp/frames
for f in /tmp/frames/*.raw; do python3 tools/frame2png.py "$f" "${f%.raw}.png"; done

Fonts and the splash are generated from tools/fonts (SIL Open Font License) and docs/brand by tools/make-fonts.py and tools/make-splash.py; releases are published with tools/release-firmware.sh.

Repository

Path What
crates/core BM13xx wire protocol: frames, CRCs, decoders, PLL solver, register payloads, chip profiles with the init sequence as data — no_std, no alloc
crates/chain the chain driver over a Uart trait — no_std, the code the firmware runs
crates/board regulators, sensors, fans, fan PID, OLED, board profiles over an I2c trait — no_std, tested against a scripted bus
crates/stratum Stratum V1 without sockets: messages, jobs, coinbase reading, tested against a captured WarpPool session
crates/sv2 Stratum V2 client: Noise handshake, framing, mining messages, release-signature tool; tested against WarpPool's Sv2 server
crates/sim, crates/simuart a simulated BM1370 chain and board with fault injection
crates/axeos, crates/cgminer AxeOS- and cgminer-compatible devices on top of the simulator, for testing tuners
crates/scenarios WarpTune's regulator in-process against the simulated devices (git dependency on dvb-WarpPool)
firmware/warpaxe the ESP32-S3 firmware: Wi-Fi and USB networking, Stratum, miner, board, web UI, display, updates
tools/ font and splash generators, display preview, flash backup, release script

Run the simulated AxeOS device, for example to test a tuner:

cargo run --release -p warpaxe-axeos -- --port 8811 --time-scale 30
curl -s http://127.0.0.1:8811/api/system/info | jq .
curl -s -X POST -d '{"board":{"SilentVrShutdown":{"above_hz":600000000}}}' http://127.0.0.1:8811/sim/fault

Design

Short version: registers and init sequences are data, not code per chip; the PLL is solved, so the reported frequency is the real one; and the simulator exists to make field failures reproducible — including the one that started this project, a regulator that shut down silently while the stock firmware kept reporting full hashrate.

Provenance

The BM1370/BM1373 have no public datasheet. What is known comes from reverse engineering, chiefly ESP-Miner (GPL-3.0) and, for the Nerd boards, ESP-Miner-NerdQAxePlus (GPL-3.0). Every constant lifted from there says so in its doc comment; every test vector says where it came from. The Bitcoin whitepaper served by the firmware is Satoshi Nakamoto's bitcoin.pdf (SHA-256 b1674191…f553).

License

GPL-3.0-or-later (see LICENSE), for the reason above. The fonts in tools/fonts are under the SIL Open Font License.