Makerdiary nRF52840 MDK USB Dongle fix reset button
Background
I was playing around with a Makerdiary nRF52840 MDK USB Dongle and somehow managed to soft-brick the dongle by flashing an application that overwrote the reset button pin, meaning I couldn’t enter the bootloader to flash a new application onto the dongle. To be honest I don’t even know what was the application since the dongle was sitting in my drawer for so long after a long break from playing around with it.
The dongle either contains (1) Open Bootloader or (2) UF2 Bootloader as per documentation.
It is advised if your dongle was shipped with Open Bootloader (older dongle versions) to upgrade to the UF2 bootloader due to it’s
easy to use feature of appearing as a flash drive and loading new applications onto the flash drive when in DFU mode.
In order to get the dongle into DFU mode, one must hold the RESET/USER button (see image 2) while inserting the device into the USB slot.
If successful, the onboard LED will blink red twice and then a solid green. You are now in DFU mode and if using the UF2
bootloader a new (emulated) flash drive will appear on your computer which accepts .uf2
format application images - details
in the official documentation.
Problem
Since the RESET/USER button is wired directly to P0.18/RESET pin on the nRF52840 (see image 3) it can either be programed as a GPIO pin or nRESET. By default it is set as GPIO so that the bootloader can detect the button press and start DFU mode. However in my case I accidentally programmed the dongle with an application that sets the pin as nRESET, this causes the dongle to reset (i.e. restart) when holding the button while inserting into USB instead of entering DFU mode.
The trickly detail is that setting this pin mode is stored into non-volatile memory (NVM), specifically in the UICR (User Information Configuration Register) - source nRF52840 Product Specification v1.7 page 43. This means that when we cause a power cycle of the dongle, the pin is still configured as nRESET and in turn the bootloader will not trigger DFU mode if the RESET button is being held during insertion.
Solution
So in order to fix this we need to clear the UICR register. Luckily I figured that whatever I flashed actually would go into DFU mode if I pressed the button twice after being already inserted in the USB slot. This saved me a great deal of work since I wouldn’t need to flash the SoC using J-Link / DAPLink (source) but simply run an application that resets the UICR register by drag and dropping the UF2 formatted application while the dongle is in DFU mode.
Then I also found out that such an application that would reset the UICR register already exists in the MDK’s dongle Git repository pselreset_erase. And as a bonus, there was already a compiled version in UF2 format.
Quickly reviewing the pselreset_erase application reveals that it clears the PSELRESET UICR register and then indicates to the user that it is finished by toggling the LED.
Commands
So to summarize in my case when using the UF2 bootloader:
- Enter DFU mode on the dongle (if you are lucky like me, otherwise you will need a J-Link / DAPLink)
$ sudo su - $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 1 3.9M 0 disk mmcblk0 179:0 0 29.1G 0 disk ├─mmcblk0p1 179:1 0 256M 0 part /boot └─mmcblk0p2 179:2 0 28.9G 0 part / mmcblk0boot0 179:32 0 4M 1 disk mmcblk0boot1 179:64 0 4M 1 disk $ mkdir /mnt/mdk/ $ mount /dev/sda /mnt/mdk $ cp pselreset_erase_dongle.uf2 /mnt/mdk/ $ umount /mnt/mdk
- Wait for the LED lights to toggle; in my case the LED started to pulse from green -> yellow -> white -> purple -> blue -> off repeat.
- Unplug the dongle
- Enter DFU mode by holding the RESET button while inserting the dongle into the USB slot.
If step 5 works, you have successfully fixed the reset button. You may now flash a new application onto the dongle, but be sure not to override the P0.18/RESET pin mode.