-
Notifications
You must be signed in to change notification settings - Fork 129
Bootloader
Generic Bluetooth modules such as E73 usually sell blank so you have to write your own bootloader. They also come write-protection-locked so you have to remove protection (latest E73 batches are sometimes factory-unlocked).
Pro Micro-compatible boards have a bootloader, so you may skip this page and go ZMK (double reset to open USB drive).
- New! An official bootloader VID/PID 1209/5284 https://github.com/adafruit/Adafruit_nRF52_Bootloader/pull/342
For 2G4M08S1C modules you can use either a standard pca10056 bootloader from the Adafruit nRF52 Bootloader releases section or a customized pca10056 with nRFMicro patch that blinks and supports OTA (maps LED to 1.10 and DFU to 1.02):
- nrfmicro_nrf52840_bootloader-0.8.0-dirty_nosd.hex (pca10056-based nRFMicro bootloader, no softdevice, recommended)
- nrfmicro_nrf52840_bootloader-0.5.0-dirty_s140_6.1.1.hex (legacy nRFMicro bootloader with Nordic S140 softdevice)
- pca10056_bootloader-0.2.11_s140_6.1.1.hex (standard pca10056 bootloader, direct link to Adafruit releases)
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. ZMK doesn't need softdevice (sd, Nordic Bluetooth stack) but you can flash it separately, if needed.
There's reset firmware for ZMK that erases bonds (updated 31 oct 2023): zmk_clear.uf2, old one is here: erase_flash.uf2.
The nice!nano bootloader flashes the same way, documentation and files are here https://nicekeyboards.com/docs/nice-nano.
For 2G4M08S1E modules (nRF52833-based) you will need a pca10100-based bootloader. See ZMK#nrf52833 if something goes wrong. See releases section for updates. Also see https://github.com/krikun98/zmk/tree/nrf52833.
- nrfmicro_833_bootloader-0.6.3-49-ge18dabd-dirty_s140_6.1.1.hex (customized nRFMicro bootloader, recommended)
- pca10100_bootloader-0.6.3_s140_6.1.1.hex (standard pca10100 Adafruit bootloader for nRF52833)
ZMK reset: 833_reset.uf2. Bootloader update in UF2: update-nrfmicro_833_bootloader-0.6.3-49-ge18dabd-dirty_nosd.uf2.
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.
You can flash Bluepill into Blackmagic probe. It's much cheaper than stock ST-LINK, it provides an extra virtual COM port for debugging and it does not use OpenOCD (there is an embedded GDB in the Blackmagic firmware). Beware of the resistor issue in the latest boards: https://github.com/joric/bluetosis/issues/13.
You will also need UART adapter but just once (to upgrade Bluepill to the Blackmagic probe). Direct links to Aliexpress:
- 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)
Avoid STM32F103C6T6A-based bluepills (32K), buy STM32F103C8T6 (64K). See https://github.com/joric/nrfmicro/issues/61.
If you build Blackmagic from scratch it needs to be stripped down to 64kb as here (only stm32f1 and nrf5x supported)
- blackmagic_dfu.bin (Blackmagic DFU bootloader)
- blackmagic.bin (Blackmagic firmware 1.6.1, stripped down for 64k)
- GNU Arm Embedded Toolchain (arm-none-eabi-gdb, use 8-2018-q4 for blackmagic 1.6.1)
- STM32 Flash loader demonstrator (official STM32 flasher)
- Zadig (USB drivers)
Locally hosted blackmagic binaries, just in case
- blackmagic_dfu.bin (7k, same as blackmagic_dfu.bin above).
- blackmagic_v1.6.1.bin (51k, same as blackmagic.bin above).
- blackmagic_v1.8.3.bin (105k, newer binary, doesn't fit 64K MCUs, but supports newer gdb).
- blackmagic_v1.8.3_dfu.bin (7k, blackmagic 1.8.3 bluepill dfu).
- blackmagic_v1.8.3_stlink.bin (105k, blackmagic 1.8.3 built for st-link).
- 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>
- 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)
You can use ST-Link either with OpenOCD or with blackmagic. You can buy ST-Link/V2 for about $2 on Aliexpress.
This tool flashes ST-LINK/V2 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)
There's sakana280's fork for 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
Newer stlink-tool (31 oct 2023):
Blackmagic apparently resets after power off (this is expected behavior), so you have to reflash it with stlink-tool
each time.
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.
First line is unlock, second line is flash. 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".
Console log for unlocking (see https://github.com/AndruPol/nrf52832-recover/issues/1#issuecomment-478393782):
arm-none-eabi-gdb.exe
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) target extended-remote \\.\COM8
Remote debugging using \\.\COM8
(gdb) mon swdp_scan
Target voltage: unknown
Available Targets:
No. Att Driver
1 ARM Cortex-M
2 Nordic nRF52 Access Port
(gdb) attach 2
Attaching to Remote target
warning: while parsing target description: no element found
warning: Could not load XML target description; ignoring
PC register is not available
(gdb) mon erase_mass
(gdb) quit
A debugging session is active.
Inferior 1 [Remote target] will be detached.
Quit anyway? (y or n) y
Detaching from program: , Remote target
[Inferior 1 (Remote target) detached]
C:\SDK\gcc-arm-none-eabi-8-2018-q4-major-win32\bin>
Actual "erase_mass" took just a moment (I guess it just removed the protection bits). After that it becomes fully programmable.
I recommend flashing ST-LINK/V2 into a blackmagic probe as above. If you prefer generic ST-LINK/V2 with an OpenOCD client software mind that it needs a CMSIS-DAP patch to unlock the chip. Possible OpenOCD commands (untested):
- 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"
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
There's a guide on J-Link here: https://github.com/Ladniy/jiran-ble-lite/wiki/Firmware
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
Connect your RPi to the Internet.
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.
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.
- 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.
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
.
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
.
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.
For flashing the bootloader, you can also use a raspberrypi pico with picoprobe firmware. This command line will work on ubuntu:
openocd -d2 -f interface/cmsis-dap.cfg -f target/nrf52.cfg -s tcl
- https://github.com/raspberrypi/picoprobe
- https://github.com/joric/nrfmicro/issues/67
(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.
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:
- 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