This is a tool to update the nRF91 modem firmware using the probe-rs crate. It provides both a CLI and library interface. Used in production on the nRF9160 Feather and nRF9151 Feather.
Validated working on:
- nRF9160
- nRF9151
- nRF9161
Install Rust using rustup.
On macOS and Linux:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shOn Windows download and run the installer from rustup.rs, then open a new PowerShell or Command Prompt window.
After installation, confirm the toolchain is available:
rustc --version
cargo --versioncargo install --git https://github.com/circuitdojo/modem_updater.gitThis places the updater binary in ~/.cargo/bin (or the equivalent on Windows).
Sometimes you may need to install dependencies. If your compilation fails here are some suggestions:
- Linux: ensure
libusb-1.0andlibudev-devare present (sudo apt install libusb-1.0-0 libudev-dev). - macOS: install Homebrew and run
brew install libusbif it is not already available. - Windows: if necessary, use Zadig to install a WinUSB driver for your debug probe.
To verify the modem firmware, run:
updater verify <path_to_firmware_zip>To program and verify the modem firmware, run:
updater program <path_to_firmware_zip>The CLI auto-detects the connected nRF91 target by reading the device part number.
If raw debug access is unavailable, updater will attempt to restore access using the same
nRF91 unlock flow as the companion recovery tool before continuing.
Install Rust using rustup.
On macOS and Linux:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shOn Windows download and run the installer from rustup.rs, then open a new PowerShell or Command Prompt window.
After installation, confirm the toolchain is available:
rustc --version
cargo --versiongit clone https://github.com/circuitdojo/modem_updater.git
cd modem_updaterBuild a release binary locally:
cargo build --releaseThe resulting executable are located in target/release/:
updater- Main firmware update tool
The library and CLI support both nrf9151 and nrf9160 target profiles.
updaterauto-detects the target profile from FICR part information- if debug access is blocked,
updaterfirst tries to restore access non-interactively - if the device is still locked,
updaterfalls back to the nRF91 CTRL-AP erase-and-reset flow
This split exists because the modem DFU bring-up sequence is not identical across the chips. In particular, UICR programming and IPC receive masks differ between the profiles.
This project is based on the work of @maxd-nordic in the pyOCD project.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT) at your option.