Bootloader - rittme/nrfmicro GitHub Wiki
E73 modules sell without bootloader and also write-protection locked (latest batches are sometimes unlocked) so you might have to remove protection and write a bootloader.
Downloads
nRF52840
Use either standard pca10056 bootloader from the Adafruit nRF52 Bootloader releases section or nRFMicro bootloader that blinks and supports OTA (maps LED to 1.10 and DFU to 1.02):
- pca10056_bootloader-0.5.0-dirty_s140_6.1.1.hex (nRF52840-based, e.g. 2G4M08S1C modules, uses nRFMicro patch)
These bootloaders support both UF2 Mass Storage updates and DFU serial, press RESET (short RST with GND) twice within 500 ms for the update mode. You don't need to flash softdevice separately, it's already merged into the .hex file.
There's also reset firmware that erases bonds for ZMK, never used it but just in case: erase_flash.ino.uf2
nRF52833
Note that nRF52833-based modules such as 2G4M08S1E need another (pca10100) bootloader. Also see ZMK#nrf52833 if something goes wrong. Also see releases section for updates.
- nrfmicro_833_bootloader-0.6.3-49-ge18dabd-dirty_s140_6.1.1.hex (nRF52833-based, e.g. 2G4M08S1E modules)
- update-nrfmicro_833_bootloader-0.6.3-49-ge18dabd-dirty_nosd.uf2, also 833_reset.uf2
- https://github.com/krikun98/zmk/tree/nrf52833
SWD Programmers
To flash the bootloader you need J-Link or ST-Link or the Bluepill board or Raspberry Pi. Original J-Link is pretty expensive. ST-LINK/V2 needs CMSIS-DAP patch or Blackmagic firmware. The cheapest option is a Bluepill board as a Blackmagic probe.
Bluepill
Bluepill flashed into Blackmagic won't need OpenOCD and also provides an extra virtual COM port for debugging. You will also need UART adapter but just once (to upgrade Bluepill to the Blackmagic probe). Direct links to the Aliexpress shop:
- Bluepill - STM32F103C8T6 ARM STM32 Minimum System Development Board ($1.56)
- CP2102-based Micro USB to UART TTL Module ($0.98, if you don't have an UART adapter)
Downloads
- blackmagic_dfu.bin (Blackmagic DFU bootloader)
- blackmagic.bin (Blackmagic firmware)
- GNU Arm Embedded Toolchain (arm-none-eabi-gdb)
- STM32 Flash loader demonstrator (official STM32 flasher)
- Zadig (USB drivers)
If you build Blackmagic from scratch it needs to be stripped down to 57kb as here (only stm32f1 and nrf5x supported)
Bluepill upgrade on Windows
- Hook up an UART adapter to Bluepill (A9 - RX pin, A10 - TX pin).
- Set Bluepill jumpers to the bootloader mode (BOOT0 jumper=1, BOOT1 jumper=0).
- Plug in UART adapter to the computer. Run "STM32 Flash loader demonstrator".
- Download to device
blackmagic_dfu.bin
at offset0x8000000
with "Global Erase" option. - Download to device
blackmagic.bin
at offset0x8002000
with "Erase necessary pages" option. - Put Bluepill jumpers back to the operational mode (BOOT0 jumper=0, BOOT1 jumper=0).
- Remove UART adapter, plug in Bluepill to the computer via its own onboard USB.
- Update USB drivers with libusb-win32 from "Zadig" (Options - List All Devices).
Make sure you got both "Black Magic GDB server" and "Black Magic UART port", you need GDB port (e.g. COM9).
Now, if you run this, you should get blackmagic version from the command line:
arm-none-eabi-gdb --batch -ex "target extended-remote \\.\COM9" -ex "monitor"
Black Magic Probe (Firmware v1.6.1-267-g302ff20) (Hardware Version 0)
Copyright (C) 2015 Black Sphere Technologies Ltd.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
Possible issues
- https://github.com/joric/bluetosis/issues/13 (Bluepill is not accesible via UART, revision/resistor issue)
- http://amitesh-singh.github.io/stm32/2017/05/27/Overcoming-wrong-pullup-in-blue-pill.html (fixing wrong pullup)
- https://github.com/joric/bluetosis/wiki/Uploading (MacOS/Linux setup and other SWD programmers)
- https://github.com/joric/nrfmicro/issues/59 (Black magic probe does not show up in COM ports)
ST-Link
You can use ST-LINK/V2 with OpenOCD or use this tool to flash it via USB into a Blackmagic probe (you can revert it back):
- https://github.com/UweBonnes/stlink-tool/tree/stlinkv21 (USB tool, no UART needed)
- https://github.com/blacksphere/blackmagic/tree/master/src/platforms/stlink (firmware)
It works as Blackmagic programmer, so you don't need OpenOCD. With sakana280's fork you can use it under Windows:
- https://github.com/sakana280/stlink-tool/releases/download/1.0-Win64/stlink-tool.exe
- https://github.com/sakana280/stlink-tool/releases/download/1.0-Win64/blackmagic.bin
You can buy ST-Link/V2 for about $2 on Aliexpress:
ST-LINK/V2 apparently resets after power off (this is expected behavior), so you have to reflash it with stlink-tool
each time.
Unlocking nRF52 and flashing bootloader
Power up nRFMicro from USB-C, plug in your selected programmer into the same computer (you need common ground), press and hold SWD and SWC pins against nRFMicro pads on the back (Bluepill A5 is SWC, B14 is SWD), then run commands.
Blackmagic
First line is unlock, second line is flash (ST-LINK/V2 needs CMSIS-DAP firmware upgrade to unlock). For Blackmagic you would need GNU Arm Embedded Toolchain (make sure arm-none-eabi-gdb
is in the PATH).
You usually don't need Unlock for already preflashed boards. Also most boards come factory unlocked now.
- Unlock:
arm-none-eabi-gdb --batch -ex "target extended-remote \\.\COM5" -ex "mon swdp_scan" -ex "att 1" -ex "mon erase_mass"
- Flash:
arm-none-eabi-gdb --batch -ex "target extended-remote \\.\COM5" -ex "mon swdp_scan" -ex "file bootloader.hex" -ex "att 1" -ex "mon erase" -ex load
Explanation: target 2 is protected and "mon erase_mass" is the only available command on target 1. After erasing with "mon erase_mass" on target 1, the next scan should recognize target 1 as Nordic nRF52. COM5 in this example is the first virtual port in the device manager (the second port is UART for debugging). Some versions mix targets up, try "att 2" instead of "att 1".
ST-LINK/V2
If you prefer generic ST-LINK/V2 with an OpenOCD client software mind that it needs a CMSIS-DAP patch (alternatively you can just flash it into a Blackmagic probe as described above).
- Unlock:
openocd -d2 -f interface/cmsis-dap.cfg -f target/nrf52.cfg -c "nrf52.dap apreg 1 0x04 0x01"
- Flash:
openocd -f interface/stlink.cfg -f target/nrf52.cfg -c "gdb_flash_program enable" -c "gdb_breakpoint_override hard" -c "init" -c "reset halt" -c "flash write_image erase ./bootloader.hex"
J-Link
This is the last resort, the very expensive option (starts from $30, segger clones may cost $15). I haven't used that much.
- Unlock:
nrfjprog --recover --log
- Flash:
nrfjprog -f nrf52 --program bootloader.hex --sectorerase
Flashing the nRF52's bootloader using Raspberry Pi's GPIO and OpenOCD
Confirmed working on Raspberry Pi 3 Model B rev 1.3 with latest software / firmware at the time of the writing but should work on any other Raspberry Pi.
You will need:
- Raspberry Pi
- USB cable to connect nRFMicro to Raspberry Pi
- Two jumper wires to connect GPIO to nRFMicro
Preparation
Connect your RPi to the Internet.
Compiling OpenOCD
Open terminal, run the following commands:
sudo apt update
sudo apt install git autoconf libtool make pkg-config libusb-1.0-0 libusb-1.0-0-dev telnet
git clone http://openocd.zylin.com/openocd
cd openocd
./bootstrap
./configure --enable-bcm2835gpio
make
sudo make install
NB that "make" command will take a long time.
Creating RPi specific configuration
mkdir openocd-config
cd openocd-config
nano openocd.cfg
Paste the following contents comment / uncomment stuff for your particular setup and save the file:
adapter driver bcm2835gpio
# Raspi1 peripheral_base address
# bcm2835gpio peripheral_base 0x20000000
# Raspi2 and Raspi3 peripheral_base address
bcm2835gpio peripheral_base 0x3F000000
# Raspi4 peripheral_base address
# bcm2835gpio peripheral_base 0xFE000000
# Raspi1 BCM2835: (700Mhz)
# bcm2835gpio speed_coeffs 113714 28
# Raspi2 BCM2836 (900Mhz):
# bcm2835gpio speed_coeffs 146203 36
# Raspi3 BCM2837 (1200Mhz):
bcm2835gpio speed_coeffs 194938 48
# Raspi4 BCM2711 (1500Mhz):
# bcm2835gpio speed_coeffs 236181 60
# SWD GPIO set: swclk swdio
bcm2835gpio swd_nums 25 24
transport select swd
set CHIPNAME nrf52840
source [find target/nrf52.cfg]
# Uncomment & lower speed to address errors, defaults to 1000
# adapter speed 800
init
targets
reset halt
It's a good idea to download the bootloader to the same folder, I will go with the one linked above, namely pca10056_bootloader-0.2.11_s140_6.1.1.hex:
wget https://github.com/adafruit/Adafruit_nRF52_Bootloader/releases/download/0.2.11/pca10056_bootloader-0.2.11_s140_6.1.1.hex
You can use a more recent release, be sure to use the correct filename when flashing in that case.
Connecting nRFMicro to RPi
- Connect nRFMicro using USB cable to one of RPi's USB ports.
- Use two jumper wires to connect GPIO25 to SWC and GPIO24 to SWD.
You need to ensure a proper connection or maybe even to apply some pressure to the jumpers with your finger for it to work. If something's not working, check the physical connection or lower the adapter speed.
Flashing the bootloader using OpenOCD
Running OpenOCD
Launch OpenOCD: sudo openocd
If it's successfully connected, you'll see the following:
Open On-Chip Debugger 0.11.0+dev-00210-gbb81ec8bf-dirty (2021-06-11-18:27)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : BCM2835 GPIO JTAG/SWD bitbang driver
Info : clock speed 802 kHz
Info : SWD DPIDR 0x2ba01477
Info : nrf52840.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for nrf52840.cpu on 3333
Info : Listening on port 3333 for gdb connections
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x00000a80 msp: 0x20000400
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Open another terminal instance and run: telnet localhost 4444
You can check the chip state with: targets
, banks with: flash banks
, registers with: reg
.
Checking unlock state and unlocking
My module arrived unlocked from the factory, so I can't tell whether you can unlock it with this method or not.
You can check whether your chip is locked using: nrf52840.dap apreg 1 0x0C
, if it outputs 1 means unlocked and 0 means locked.
Supposedly, you can unlock it with: nrf52840.dap apreg 1 0x04 0x00000001
or nrf52_recover
.
Flashing the bootloader
Erase the storage with: nrf5 mass_erase
.
To flash the bootloader, run the following command: flash write_image pca10056_bootloader-0.2.11_s140_6.1.1.hex
You should see the following:
Padding image section 0 at 0x00000b00 with 1280 bytes
Flash write discontinued at 0x00025de8, next section at 0x000f4000
wrote 183992 bytes from file pca10056_bootloader-0.2.11_s140_6.1.1.hex in 1.870176s (96.076 KiB/s)
Verify the result: flash verify_image pca10056_bootloader-0.2.11_s140_6.1.1.hex
. If it's successful, you are done.
Reset the chip with reset run
.
It should mount as USB storage and you'll be able to drag and drop or use wget download and flash the firmware.
Linux guide
(Taken from here: https://okke-formsma.github.io/blackmagic-on-a-bluepill.html)
To flash nrfmicro chips, you can use a bluepill with blackmagic installed.
The bluepill has some issues with wrong resistors (I had to change R3 on the bluepill from 100k to 10k ohm). The blackpill with stm32f103 processor does not have this problem, and is recommended. (Black Magic is not supported on blackpill 1.2 (stm32f401) or blackpill 2.0 (stm32f411) at this time.
- Connect the usb-to-uart converter to the bluemicro and set the bluemicro boot0 jumper to 1.
- Find the usb port that the converter is attached to
> dmesg | grep tty
[157210.247340] cp210x ttyUSB0: cp210x converter now disconnected from ttyUSB0
[157221.140041] usb 1-2: cp210x converter now attached to ttyUSB0
- Install the dfu. Run stm32loader.py on python2 with the pySerial package installed:
python2 stm32loader.py -p /dev/ttyUSB0 -ewv blackmagic_dfu.bin
- Install the blackmagic firmware:
stm32flash -w blackmagic.bin /dev/ttyUSB0 -S 0x08002000
- Set the jumper back to 0, disconnect the uart adapter, connect the bluepill to usb. *Check if the blackmagic probe is recognized with lsusb.
OTA updates
This was never tested. The bootloader apparently can be used for OTA (Over The Air) wireless updates but I haven't tried that (it would need a signed firmware package), see https://github.com/adafruit/Adafruit_nRF52_Bootloader
DFU = LOW and FRST = LOW
: Enter bootloader with OTA, to upgrade with a mobile application such as Nordic nrfConnect/Toolbox
You'd need to short two pins to ground, 0.12 is FRST and 0.11 is DFU in pca10056. Mind that 0.11 does not exist on E73 module so it would need fixing and recompiling the bootloader (e.g. put DFU button BUTTON_1 to pin 1.02 in pca10056/board.h).
That still needs a specialized software such as nRFGo Studio so it's not very convenient. Read this article for details:
Video
References
- https://github.com/adafruit/Adafruit_nRF52_Bootloader/releases
- https://mvdlande.wordpress.com/2015/10/05/cmsis-dap-on-a-cheap-st-link-v2-mini-adapter
- https://okke-formsma.github.io/blackmagic-on-a-bluepill.html
- https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/flashing-and-debugging-nrf5152-with-a-cheap-blackm
- https://nicekeyboards.com/docs/nice-nano/troubleshooting#my-nicenano-seems-to-be-acting-up-and-i-want-to-re-flash-the-bootloader