Federico Fuga

Engineering, Tech, Informatics & science

Changing the firwmare of a MDK USB dongle to RCP

19 May 2023 15:24 CEST

For my OpenThread/Matter project I built a Border Router with an Adafruit Feather nrf52840 that perfectly fit this purpose. Recompiling and flashing the RCP firmware on it is as easy as literally following the Nordic Recipe, especially because I have a Nordic nrf52840dk board that includes a Segger programmer.

But the form factor is not so convenient, especially because an USB cable is required and to avoid messing with the board you need to fix it somewhere, for example on a breadboard.

So I decided to buy a ready made dongle. The MDK USB dongle was perfect.

The MDK USB Dongle

But it seems that it comes by default with a NCP firmware, that is not so suitable with the default and Open Thread boarder router as explained in the Nordic recipe. The ot-agent requires a Radio firmware, not a Network firmware.

It seems that actually there’s no recipe for a RCP firmware on the MDK dongle.

But building the firmware is not so difficult indeed, though it is not documented. The main recipe is the step 4 of Open Thread codelab, named “Set up the rcp joiner”.

Let’s first clone the ot-nrf52840 repository.

$ cd ~/src
$ git clone --recursive https://github.com/openthread/ot-nrf528xx.git
$ cd ot-nrf528xx

The dongle uses the USB interface, but it also requires a USB bootloader, otherwise once flashed you’ll need a Segger programmer to reflash and unbrick the dongle. The option for it is well hidden in the CMake project: in src/nrf52840/nrf52840.cmake file, we see how to instruct the project to select and enable the correct bootloader option:

option(OT_BOOTLOADER "OT nrf bootloader type")
if(OT_BOOTLOADER STREQUAL "USB")
    list(APPEND OT_PLATFORM_DEFINES "APP_USBD_NRF_DFU_TRIGGER_ENABLED=1")
    set(LD_FILE "${CMAKE_CURRENT_SOURCE_DIR}/nrf52840/nrf52840_bootloader_usb.ld")
elseif(OT_BOOTLOADER STREQUAL "UART")
    set(LD_FILE "${CMAKE_CURRENT_SOURCE_DIR}/nrf52840/nrf52840_bootloader_uart.ld")
elseif(OT_BOOTLOADER STREQUAL "BLE")
    set(LD_FILE "${CMAKE_CURRENT_SOURCE_DIR}/nrf52840/nrf52840_bootloader_ble.ld")
else()
    set(LD_FILE "${CMAKE_CURRENT_SOURCE_DIR}/nrf52840/nrf52840.ld")
endif()

So let’s add it to the build string:

$ script/build nrf52840 USB_trans -DOT_BOOTLOADER:String=USB

Note the OT_BOOLOADER variable.

When the compilation succeedes, you’ll have an ELF file that must be translated first to intel HEX format, then on UF2.

Let’s use objcopy first and then uf2conv.py.

$ arm-none-eabi-objcopy -O ihex build/bin/ot-rcp build/ot-rcp.hex
$ uf2conv.py build/ot-rcp.hex -c -f 0xada52840 -o build/ot-rcp.uf2
Converted to uf2, output size: 133632, start address: 0x1000
Wrote 133632 bytes to build/ot-rcp.uf2

Ok, put the dongle in uf2 mode by connecting it while pressing the button, drag and drop the uf2 file there.

Put the dongle in your border router USB, restart the agent.

You’ll need to reform your network, but after that the dongle will work flawlessly.