nRF52840-MDK dongle initial experience

Hello, I’m looking for help.

I’ve got two nRF52840-MKD dongles and my experience with them is not so good so far. I’m trying to use them for prototyping using tinygo, but I can’t even upload the blink example.

This is what the boards have in their storage:

UF2 Bootloader 0.2.13-42-g82464f9-dirty lib/nrfx (v2.0.0) lib/tinyusb (legacy-1500-g23df777b) s140 6.1.1
Model: nRF52840 MDK USB Dongle
Board-ID: nRF52840-Dongle-v1
Date: Feb  3 2020

Obviously it has been shipped with UF2 bootloader.
The tinygo is configured to use the old style flashing (Open bootloader) via OpenOCD. This is the first issue, the device does not work with tinygo (although the documentation states otherwise).

I tried to reconfigure tinygo to use “msd” way of flashing as per this:

{
	"inherits": ["nrf52840"],
	"build-tags": ["nrf52840_mdk", "softdevice", "s140v6"],
	"flash-1200-bps-reset": "true",
	"flash-method": "msd",
	"msd-volume-name": "MDK-DONGLE",
	"msd-firmware-name": "firmware.uf2",
	"uf2-family-id": "0xADA52840"
}

Then run the following (in the root of your project/blinky example):

tinygo flash -target=nrf52840-mdk

This successfully builds the blinky example and uploads “uf2”-format firmware, but the dongle just flashes red after uploading. There is not any debug information as to what is happening, I’m guessing there is something not right with the generated firmware. So this is the second issue - poor debugging capabilities, there is not any way to debug (or get error info) on what’s wrong with firmware during uploading.

Then I tried to use “nRF Connect” suite to flash firmware, but it says:

Is “nRF Connect” supposed to work with UF2 bootloader?

System info:

MacOS Mojave 10.14.6

go version go1.15.2 darwin/amd64

nRF Connect - v3.5.0

JLink - v622g

Please help.
cc @Zelin

@vkolotov nRF Connect does not support UF2 bootloader. You can just convert your hex file to uf2 file and then put it onto the bootloader disk.
Here is the tutorial:
https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle/programming/#dfu-via-uf2-bootloader

Thanks @Zelin for a quick reply, but this does not work either.
When I convert hex file that is generated by tinygo, copy it, then the result is the same - rapid blinking with red LED.

@vkolotov Make sure your firmware run from 0x1000 . Here is the example of memory regions:

MEMORY
{
  FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0xff000
  RAM (rwx) :  ORIGIN = 0x20000008, LENGTH = 0x3fff8
}

Here is what I do:

tinygo build -o=./fw.hex -target=nrf52840-mdk
python ~/projects/private/nrf52840-mdk-usb-dongle/tools/uf2conv.py fw.hex -c -f 0xADA52840
Converting to uf2, output size: 12288, start address: 0x0
Wrote 12288 bytes to flash.uf2.
cp flash.uf2 /Volumes/MDK-DONGLE/

Blinking red rapidly (not working as expected).

@Zelin, how do I specify regions? I’m following the documentation here.

I tried this:

python ~/projects/private/nrf52840-mdk-usb-dongle/tools/uf2conv.py fw.hex -c -b 0x1000 -f 0xADA52840
Converting to uf2, output size: 12288, start address: 0x0
Wrote 12288 bytes to flash.uf2.

Same result.

BTW, whatever I pass to “-b” parameter, it says start address: 0x0.

The memory regions is set here: tinygo/targets/nrf52840.ld in the tinygo source code. After changing the config, you need to rebuild the source code.

Thanks for your support.

This is what we’ve got in the nrf52840.ld by default:

MEMORY
{
    FLASH_TEXT (rw) : ORIGIN = 0x1000, LENGTH = 1M
    RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 256K
}

_stack_size = 4K;

INCLUDE "targets/arm.ld"

I suppose it already contains correct regions (starts with 0x1000).

Sorry I’m wrong, I updated it already with 0x1000.
This is the original content of nrf52840.ld:

MEMORY
{
    FLASH_TEXT (rw) : ORIGIN = 0x00000000, LENGTH = 1M
    RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 256K
}

_stack_size = 4K;

INCLUDE "targets/arm.ld"

Anyways, after updating it with 0x1000, I can see that the LED now changes to “blue” color, but does not blink. I suppose it freezes…

Is there any easy way to figure out what’s happening?

My go program:

func main() {
	led := machine.LED_BLUE
	led.Configure(machine.PinConfig{Mode: machine.PinOutput})
	for {
		led.Low()
		time.Sleep(time.Millisecond * 1000)

		led.High()
		time.Sleep(time.Millisecond * 1000)
	}
}

This is the original blinky1, with changed LED to LED_BLUE and 500ms to 1000ms.
It just always stays BLUE once uploaded to the board.

I’ve also tried to use “ld” file from itsybitsy express as it is a similar board to MDK (itsybitsy-nrf52840.json) with the following changes (new file - targets/nrf52840-mdk.ld):


MEMORY
{
    FLASH_TEXT (rw) : ORIGIN = 0x00000000+0x1000, LENGTH = 0xED000-0x1000 /* SoftDevice S140. See https://learn.adafruit.com/introducing-the-adafruit-nrf52840-feather/hathach-memory-map. Application starts at 0x26000; user data starts at 0xED000 */
    RAM (xrw)       : ORIGIN = 0x20004180, LENGTH = 37K
}

_stack_size = 2K;

/* This value is needed by the Nordic SoftDevice. */
__app_ram_base = ORIGIN(RAM);

INCLUDE "targets/arm.ld"

My “json” file is:

{
	"inherits": ["nrf52840"],
	"build-tags": ["nrf52840_mdk", "nrf52840_reset_uf2", "softdevice", "s140v6"],
	"flash-1200-bps-reset": "true",
	"flash-method": "msd",
	"msd-volume-name": "MDK-DONGLE",
	"msd-firmware-name": "firmware.uf2",
	"uf2-family-id": "0xADA52840",
	"linkerscript": "targets/nrf52840-mdk.ld"
}

It gives the same result, e.g. LED does not blink (although it changes to BLUE).

@Zelin I’ve tried both uf2conv.py and tinygo flash -target=nrf52840-mdk -no-debug with no success.

Ok, with the very scientific approach of trial and error, it works now wit the following config:

nrf52840-mdk.json:

{
	"inherits": ["nrf52840"],
	"build-tags": ["nrf52840_mdk"],
	"flash-method": "msd",
	"msd-volume-name": "MDK-DONGLE",
	"msd-firmware-name": "firmware.uf2",
	"uf2-family-id": "0xADA52840",
	"linkerscript": "targets/nrf52840-mdk.ld"
}

New file nrf52840-mdk.ld:


MEMORY
{
    FLASH_TEXT (rw) : ORIGIN = 0x00000000+0x1000, LENGTH = 0xff000
    RAM (xrw)       : ORIGIN = 0x20000008, LENGTH = 0x3fff8
}

_stack_size = 4K;
__app_ram_base = ORIGIN(RAM);

INCLUDE "targets/arm.ld"

Now it blinks, I’m happy.

@Zelin thanks for your support. Please confirm that the config above makes sense for you.

I will try to create a new PR for tinygo once I’ve tested it a bit more.

Great! It really helps to run tinygo on the dongle. Thanks @vkolotov

@Zelin, is there any technical issue with ADC in tinygo? It says that it is not supported:
https://tinygo.org/microcontrollers/nrf52840-mdk/

I see that the board definition (board_nrf52840-mdk.go) lacks analogue pins, is this just the reason or there is something behind that?

@vkolotov There is no hardware issue with ADC. It’s just not supported by tinygo currently.