Adafruit nRF52 bootloader with enhanced OTA DFU, forked for Meshtastic from oltaco's OTAFIX bootloader. This is the bootloader several nRF52-based Meshtastic devices ship with, and the one the Meshtastic Android app can upgrade in-app.
Current release: OTAFIX 2.3 — see changelog.md for version history.
- How this fits together
- Boards supported
- BLE advertising names
- Installation
- Bootloader upgrade from the Meshtastic Android app
- Troubleshooting
- Recommended OTA DFU settings
- Notes on Xiao NRF52840 BLE
- Notes on RAK4631 bootloader
- Contributing
- Getting help
- License
This repo builds only the bootloader — the small program that runs
before anything else on the device. It does not contain the Meshtastic
application (the LoRa mesh, BLE, and display code); that's built entirely
separately in meshtastic/firmware.
This bootloader's job is just to start that application, or, when asked,
replace it (or itself) with a new version.
On every power-up or reset, a tiny fixed piece of code at the very start of flash — Nordic's MBR — hands off to this bootloader. From there, the bootloader either:
- boots straight into the installed Meshtastic application, or
- if no valid application is installed, or the user has asked for it, waits for a new one.
A new application image — or occasionally the bootloader itself — can be installed three different ways:
| Method | Transport | Typical use |
|---|---|---|
| UF2 drag-and-drop | USB, appears as a drive | Manual flashing — see Installation |
| Serial DFU | USB, appears as a serial port | Recovery, and flashing a full bootloader+SoftDevice package with adafruit-nrfutil — see Installation |
| BLE OTA DFU | Bluetooth, no cable needed | The Meshtastic Android app's firmware/bootloader update, and any Nordic DFU app — see below and recommended settings |
BLE OTA DFU is the only wireless path, which is what the "OTA" in "OTAFIX" refers to — and it's also the bootloader's default fallback: since OTAFIX 2.0, if no valid application is present, the device waits in BLE OTA mode automatically rather than risk getting stuck (see Troubleshooting).
The application also relies on Nordic's SoftDevice — a closed-source,
precompiled Bluetooth stack (vendored here as a hex blob under
lib/softdevice/) that sits in flash alongside it. The bootloader and the
application both call into it for BLE, so bootloader and SoftDevice
versions are usually flashed together as a matched pair (that's why the
Installation instructions below mention flashing "a full
bootloader and SoftDevice zip package").
- Elecrow ThinkNode M1
- Elecrow ThinkNode M3
- Elecrow ThinkNode M6
- Heltec T096
- Heltec T1
- Heltec T114 / HT-nRF5262
- LilyGO T-Echo
- Minewsemi MX25LE01
- Nologo ProMicro NRF52840 (aka SuperMini NRF52840)
- RAK 3401
- RAK 4631 (See note)
- RAK WisMesh Tag
- Seeed Studio SenseCAP Card Tracker T1000-E
- Seeed SenseCAP Solar Node P1
- Seeed Studio Wio Tracker L1
- Seeed Studio XIAO nRF52840 BLE (See note)
- Seeed Studio XIAO nRF52840 BLE SENSE
If there is another nRF52840-based Meshtastic board you would like to see supported, please raise a GitHub issue — or see Adding a new board in CONTRIBUTING.md if you want to submit it yourself.
When in OTA DFU mode, devices advertise using a board-specific name rather than the generic AdaDFU.
| Board | OTA DFU advertising name |
|---|---|
| Elecrow ThinkNode M1 | TNM1_DFU |
| Elecrow ThinkNode M3 | TNM3_DFU |
| Elecrow ThinkNode M6 | TNM6_DFU |
| Heltec T096 | T096_DFU |
| Heltec T1 | T1_DFU |
| Heltec T114 | T114_DFU |
| LILYGO T-Echo | LGTE_DFU |
| Minewsemi MX25LE01 | MX25_DFU |
| ProMicro NRF52840 | PROM_DFU |
| RAK 4631 | 4631_DFU |
| RAK 3401 | 3401_DFU |
| RAK WisMesh Tag | RTAG_DFU |
| Seeed SenseCAP Solar Node P1 | SCAP_DFU |
| Seeed T1000e | T1KE_DFU |
| Seeed WioTracker L1 | WTL1_DFU |
| XIAO NRF52 BLE / SENSE | XIAO_DFU |
The recommended way to install the bootloader is using the UF2 file.
Download the UF2 file for your board (they can be found in the releases with filenames beginning with update-), enter UF2 mode (usually by double pressing the reset button within 0.5s) and copy the UF2 file across.
If an incorrect bootloader has been flashed to the device, a full bootloader and SoftDevice zip package will need to be flashed using adafruit-nrfutil.
The Meshtastic Android app can flash this bootloader directly — no manual UF2 drag-and-drop needed.
With the radio connected over USB/serial (not Bluetooth), open the connected radio's configuration, go to Advanced → Firmware Update, and where an upgraded bootloader is published for your board you'll see an Upgrade bootloader option alongside Erase and reinstall. The app reads INFO_UF2.TXT from the device's update drive first to confirm the board and Bluetooth stack before writing anything, and will ask you to select the update drive twice — once for the bootloader image, once for the firmware. See the app's Firmware Updates guide for the full flow.
If the device does not show up on your computer after flashing the bootloader or performing an OTA update, it may be waiting in OTA DFU mode.
In OTAFIX 2.0 and above, OTA DFU is the default state when no valid application is present.
In this mode:
- No UF2 drive is exposed
- No serial port is available
- The device is waiting for an OTA firmware update over BLE
What to do:
- Perform an OTA update using a supported DFU app, or
- Explicitly request UF2/serial mode using double-reset.
This behaviour is intentional and prevents devices from getting stuck in UF2 mode after failed OTA updates.
If an OTA update consistently fails early with Error: Operation Failed, this is often caused by BLE stack incompatibilities when Request High MTU is enabled.
What to try:
- Experiment with different PRN settings — try 12, 8, 1, or off altogether.
- Disable Request High MTU in the DFU app.
While high MTU significantly improves performance on supported devices, it is not required for a successful OTA update.
To perform the OTA update, use nRF Device Firmware Update
(Android / iOS)
or nRF Connect
(Android / iOS).
nRF Device Firmware Update is the recommended app of the two.
For OTAFIX 2.0 and later, the following settings are recommended (these may change — feel free to experiment and report findings via a GitHub issue):
|
Packet Receipt Notification (PRN): ON Notes:
|
Recommended settings for versions prior to 2.0 can be found here.
IMPORTANT:
On older versions of the bootloader, performing an OTA update while the device was connected to a computer USB host would complete successfully but would not automatically boot into the new application firmware, requiring a manual reset.
This issue is fixed in OTAFIX 2.0.
Many of these boards are shipped with the Sense version of the bootloader installed. If your board has the Sense version installed you must use the Sense version when updating via UF2.
You can look at the INFO_UF2.TXT file on the UF2 drive to check what version is currently installed.
To check:
- Enter UF2 DFU mode (double-press reset)
- Open the
INFO_UF2.TXTfile on the mounted drive
If the file shows: "Board-ID: nRF52840-SeeedXiaoSense-v1" then the SENSE variant must be used if updating via UF2 file.
This version of the RAK4631 bootloader is based on a much newer version (0.9.2) of the Adafruit nRF52 bootloader than what RAK Wireless uses on their official bootloader (0.6.2-11). It has been tested with no problems found; whether RAK's own patches to the Adafruit bootloader introduce any behavioral difference has not been investigated. A variant of the official RAK bootloader with these patches included instead is available here.
Want to build from source, add a board, or submit a fix? See
CONTRIBUTING.md for the development setup and PR
process, and AGENTS.md for how the codebase is put
together.
- Questions or troubleshooting: Meshtastic Discussions
- Bug reports and feature requests: open an issue
- Security vulnerabilities: see
SECURITY.md— please do not open a public issue - General Meshtastic docs: meshtastic.org
MIT, originally Copyright (c) 2016 Adafruit Industries.