Skip to main content

Adafuit nRF52 Bootloader

The Adafruit nRF52 Bootloader is a magic value type bootloader, with some extra setup used to integrate with it.

Kconfig Symbol Enablement​

Three Kconfig symbols need to be enabled for this feature to work, namely RETAINED_MEM, RETENTION, and RETENTION_BOOT_MODE. Typically, this is done by implying the symbols for the board symbol in the Kconfig.<board>, file, e.g.:

config BOARD_TOFU65
select SOC_RP2040
imply RETAINED_MEM
imply RETENTION
imply RETENTION_BOOT_MODE

By using imply at the board level, users of the board can choose to override the setting and disable the feature if they so choose.

Magic Value Type Kconfig​

In addition to the core Kconfig symbols already set up, one additional Kconfig choice needs to be set, e.g. in Kconfig.defaults for the board:

choice ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE
default ZMK_BOOTMODE_MAGIC_VALUE_BOOTLOADER_TYPE_ADAFRUIT_NRF52

endchoice

This ensures the correct magic value is stored in the retained memory.

Devicetree Simple Include​

A simple shared file can be included in your board's devicetree to set up the retained memory and retention nodes. Near the top of your file, add an include for common/nordic/nrf52840_uf2_boot_mode.dtsi, e.g.:

/dts-v1/;

#include <nordic/nrf52840_qiaa.dtsi>
#include <common/nordic/nrf52840_uf2_boot_mode.dtsi>

Devicetree Manual Changes​

GPREGRET Setup​

Nordic nRF52840 has a dedicated register that can be used to store data to persist across resets. Zephyr has a retained mem driver over this register, so we'll add the boot mode retention to that existing node:

&gpregret1 {
adafruit_boot_retention: retention@0 {
compatible = "zephyr,retention";
status = "okay";
reg = <0x0 0x1>;
};
};

Magic Value Mapper​

Next, we'll set up our mapping retained mem driver, which will map from the Zephyr boot mode values to the values the bootloader is looking for:

/ {
magic_mapper {
compatible = "zmk,bootmode-to-magic-mapper";
status = "okay";

#address-cells = <1>;
#size-cells = <1>;

boot_retention: retention@0 {
compatible = "zephyr,retention";
status = "okay";
reg = <0x0 0x1>;
};
};
};

Chosen Node Properties​

Finally, we'll assign two chosen properties for the two nodes that have been defined:

/ {
chosen {
zephyr,boot-mode = &boot_retention;
zmk,magic-boot-mode = &adafruit_boot_retention;
};