From 4f28bd3482f95cec076550ccae591b330dc2778a Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sun, 26 Jul 2020 16:21:54 +0200 Subject: [PATCH] boards/nrf52840-mdk-dongle: add nRF52840 MDK USB Dongle --- boards/nrf52840-mdk-dongle/Kconfig | 19 ++++ boards/nrf52840-mdk-dongle/Makefile | 3 + boards/nrf52840-mdk-dongle/Makefile.dep | 6 ++ boards/nrf52840-mdk-dongle/Makefile.features | 10 ++ boards/nrf52840-mdk-dongle/Makefile.include | 19 ++++ boards/nrf52840-mdk-dongle/board.c | 38 ++++++++ boards/nrf52840-mdk-dongle/doc.txt | 62 ++++++++++++ boards/nrf52840-mdk-dongle/include/board.h | 94 +++++++++++++++++++ .../nrf52840-mdk-dongle/include/gpio_params.h | 66 +++++++++++++ .../nrf52840-mdk-dongle/include/periph_conf.h | 62 ++++++++++++ boards/nrf52840-mdk-dongle/reset.c | 39 ++++++++ 11 files changed, 418 insertions(+) create mode 100644 boards/nrf52840-mdk-dongle/Kconfig create mode 100644 boards/nrf52840-mdk-dongle/Makefile create mode 100644 boards/nrf52840-mdk-dongle/Makefile.dep create mode 100644 boards/nrf52840-mdk-dongle/Makefile.features create mode 100644 boards/nrf52840-mdk-dongle/Makefile.include create mode 100644 boards/nrf52840-mdk-dongle/board.c create mode 100644 boards/nrf52840-mdk-dongle/doc.txt create mode 100644 boards/nrf52840-mdk-dongle/include/board.h create mode 100644 boards/nrf52840-mdk-dongle/include/gpio_params.h create mode 100644 boards/nrf52840-mdk-dongle/include/periph_conf.h create mode 100644 boards/nrf52840-mdk-dongle/reset.c diff --git a/boards/nrf52840-mdk-dongle/Kconfig b/boards/nrf52840-mdk-dongle/Kconfig new file mode 100644 index 0000000000..0b1a192707 --- /dev/null +++ b/boards/nrf52840-mdk-dongle/Kconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2020 HAW Hamburg +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +config BOARD + default "nrf52840-mdk-dongle" if BOARD_NRF52840_MDK_DONGLE + +config BOARD_NRF52840_MDK_DONGLE + bool + default y + select BOARD_COMMON_NRF52 + select CPU_MODEL_NRF52840XXAA + select HAS_PERIPH_UART + select HAS_PERIPH_USBDEV + select HAS_HIGHLEVEL_STDIO + +source "$(RIOTBOARD)/common/nrf52/Kconfig" diff --git a/boards/nrf52840-mdk-dongle/Makefile b/boards/nrf52840-mdk-dongle/Makefile new file mode 100644 index 0000000000..f8fcbb53a0 --- /dev/null +++ b/boards/nrf52840-mdk-dongle/Makefile @@ -0,0 +1,3 @@ +MODULE = board + +include $(RIOTBASE)/Makefile.base diff --git a/boards/nrf52840-mdk-dongle/Makefile.dep b/boards/nrf52840-mdk-dongle/Makefile.dep new file mode 100644 index 0000000000..b72178a1f7 --- /dev/null +++ b/boards/nrf52840-mdk-dongle/Makefile.dep @@ -0,0 +1,6 @@ +ifneq (,$(filter saul_default,$(USEMODULE))) + USEMODULE += saul_gpio +endif + +include $(RIOTBOARD)/common/nrf52/bootloader_nrfutil.dep.mk +include $(RIOTBOARD)/common/nrf52/Makefile.dep diff --git a/boards/nrf52840-mdk-dongle/Makefile.features b/boards/nrf52840-mdk-dongle/Makefile.features new file mode 100644 index 0000000000..bf752d2741 --- /dev/null +++ b/boards/nrf52840-mdk-dongle/Makefile.features @@ -0,0 +1,10 @@ +CPU_MODEL = nrf52840xxaa + +# Put defined MCU peripherals here (in alphabetical order) +FEATURES_PROVIDED += periph_uart +FEATURES_PROVIDED += periph_usbdev + +# Various other features (if any) +FEATURES_PROVIDED += highlevel_stdio + +include $(RIOTBOARD)/common/nrf52/Makefile.features diff --git a/boards/nrf52840-mdk-dongle/Makefile.include b/boards/nrf52840-mdk-dongle/Makefile.include new file mode 100644 index 0000000000..d2356761f5 --- /dev/null +++ b/boards/nrf52840-mdk-dongle/Makefile.include @@ -0,0 +1,19 @@ +# This board uses the vendor's serial bootloader + +PROGRAMMER ?= uf2conv + +ifeq (uf2conv,$(PROGRAMMER)) + + # Using uf2conv implies using the UF2 bootloader + # + # It has a static MBR at the first 4k, and a 48k UF2 Bootloader at + # the end, leaving 972k for the application. This overwrites any SoftDevice, + # but that's what the minimal working example for the dongle does as well. + ROM_OFFSET = 0x1000 + ROM_LEN = 0xf3000 + + FFLAGS_OPTS = -f 0xADA52840 + include $(RIOTMAKE)/tools/usb_board_reset.mk +endif + +include $(RIOTBOARD)/common/nrf52/Makefile.include diff --git a/boards/nrf52840-mdk-dongle/board.c b/boards/nrf52840-mdk-dongle/board.c new file mode 100644 index 0000000000..be2d183202 --- /dev/null +++ b/boards/nrf52840-mdk-dongle/board.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 Benjamin Valentin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_nrf52840-mdk-dongle + * @{ + * + * @file + * @brief Board initialization for the nRF52840-dongle + * + * @author Benjamin Valentin + * + * @} + */ + +#include "cpu.h" +#include "board.h" + +#include "periph/gpio.h" + +void board_init(void) +{ + /* initialize the board's RGB LED */ + gpio_init(LED0_PIN, GPIO_OUT); + gpio_set(LED0_PIN); + gpio_init(LED1_PIN, GPIO_OUT); + gpio_set(LED1_PIN); + gpio_init(LED2_PIN, GPIO_OUT); + gpio_set(LED2_PIN); + + /* initialize the CPU */ + cpu_init(); +} diff --git a/boards/nrf52840-mdk-dongle/doc.txt b/boards/nrf52840-mdk-dongle/doc.txt new file mode 100644 index 0000000000..527ff089ca --- /dev/null +++ b/boards/nrf52840-mdk-dongle/doc.txt @@ -0,0 +1,62 @@ +/** +@defgroup boards_nrf52840-mdk-dongle nRF52840 MDK USB Dongle +@ingroup boards +@brief Support for the nRF52840 MDK USB Dongle + +### General information + +Refer to [The makerdiary Github repo](https://github.com/makerdiary/nrf52840-mdk-usb-dongle) +or [The nrf52840-mdk-usb-dongle wiki](https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle/) +for more details about the device. + +This is pretty much just the nRF52840 with a useful number of pins exposed for +your pleasure along with one RGB LED and an onboard antenna in a USB stick form +factor with room for headers on the sides. + +Unlike similar sticks (like the @ref boards_nrf52840-mdk), it features no +dedicated programmer hardware but relies on direct USB communication with a +built-in bootloader. + +The board features an RGB LED, a user/reset button as well as 12 configurable external pins. + +### Pinout + +\image html https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle/assets/images/nrf52840-mdk-usb-dongle-pinout.png width=66% + +### Links + +- [nRF52840 documentation](https://infocenter.nordicsemi.com/topic/struct_nrf52/struct/nrf52840.html) +- [Schematic](https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle/hardware/nrf52840-mdk-usb-dongle-sch_v1_0.pdf) + +### Flash the board + +The board is flashed using its on-board UF2 boot loader. +The boot loader will present a mass storage device that has to be mounted to /media/MDK-DONGLE so +`uf2conv.py` can find it. If you have an auto-mounter installed this will happen automatically. + +The rest of the process is automated in the usual `make flash` target. + +If RIOT is already running on the board, it will automatically reset the CPU and enter +the bootloader. +If some other firmware is running or RIOT crashed, you need to enter the bootloader +manually by pressing the board's reset button while plugging the device into the USB port. + +Readiness of the bootloader is indicated by the LED glowing green. + +### Accessing STDIO + +The usual way to obtain a console on this board is using an emulated USB serial port (CDC-ACM). +This is available automatically using the `stdio_cdc_acm` module, +unless any other stdio module is enabled. + +On Linux systems with ModemManager < 1.10 installed, +`make term` will, in some setups, fail for a few seconds after the device has come up. +This is [fixed in its 1.12.4 version](https://gitlab.freedesktop.org/mobile-broadband/ModemManager/issues/164), +but should not be more than a short annoyance in earlier versions. + +To ease debugging, +pins 0.6 and 0.7 are configured as RX and TX, respectively. +They provide stdio if no CDC-ACM is disabled, +and can be used as a custom UART otherwise. + + */ diff --git a/boards/nrf52840-mdk-dongle/include/board.h b/boards/nrf52840-mdk-dongle/include/board.h new file mode 100644 index 0000000000..fecaa30af5 --- /dev/null +++ b/boards/nrf52840-mdk-dongle/include/board.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2020 Benjamin Valentin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_nrf52840-mdk-dongle + * @{ + * + * @file + * @brief Board specific configuration for the nRF52840 MDK USB Dongle + * + * @author Benjamin Valentin + */ + +#ifndef BOARD_H +#define BOARD_H + +#include "cpu.h" +#include "board_common.h" +#include "periph/gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name USB configuration + * @{ + */ +#define INTERNAL_PERIPHERAL_VID (0x239a) +#define INTERNAL_PERIPHERAL_PID (0x0029) +/** @} */ + +/** + * @name LED pin configuration + * @{ + */ + /** @brief The red channel of the LED */ +#define LED0_PIN GPIO_PIN(0, 23) + /** @brief The green channel of the LED */ +#define LED1_PIN GPIO_PIN(0, 22) + /** @brief The blue channel of the LED */ +#define LED2_PIN GPIO_PIN(0, 24) + +/** @} */ + +/** + * @name LED access macros + * @{ + */ + +/** Enable LED's red channel */ +#define LED0_ON gpio_clear(LED0_PIN) +/** Disable LED's red channel */ +#define LED0_OFF gpio_set(LED0_PIN) +/** Toggle LED's red channel */ +#define LED0_TOGGLE gpio_toggle(LED0_PIN) + +/** Enable LED's green channel */ +#define LED1_ON gpio_clear(LED1_PIN) +/** Disable LED's green channel */ +#define LED1_OFF gpio_set(LED1_PIN) +/** Toggle LED's green channel */ +#define LED1_TOGGLE gpio_toggle(LED1_PIN) + +/** Enable LED's blue channel */ +#define LED2_ON gpio_clear(LED2_PIN) +/** Disable LED's blue channel */ +#define LED2_OFF gpio_set(LED2_PIN) +/** Toggle LED's blue channel */ +#define LED2_TOGGLE gpio_toggle(LED2_PIN) + +/** @} */ + +/** + * @name Button pin configuration + * @{ + */ +/** @brief The button labelled RESET */ +#define BTN0_PIN GPIO_PIN(0, 18) +/** @brief The GPIO pin mode of the button labelled RESET */ +#define BTN0_MODE GPIO_IN_PU +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H */ +/** @} */ diff --git a/boards/nrf52840-mdk-dongle/include/gpio_params.h b/boards/nrf52840-mdk-dongle/include/gpio_params.h new file mode 100644 index 0000000000..46dc3ccaa5 --- /dev/null +++ b/boards/nrf52840-mdk-dongle/include/gpio_params.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 Benjamin Valentin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_nrf52840-mdk-dongle + * @{ + * + * @file + * @brief Configuration of SAUL mapped GPIO pins + * + * @author Benjamin Valentin + */ + +#ifndef GPIO_PARAMS_H +#define GPIO_PARAMS_H + +#include "board.h" +#include "saul/periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LED and button configuration for SAUL + */ +static const saul_gpio_params_t saul_gpio_params[] = +{ + { + .name = "LED Red", + .pin = LED0_PIN, + .mode = GPIO_OUT, + .flags = (SAUL_GPIO_INVERTED | SAUL_GPIO_INIT_CLEAR), + }, + { + .name = "LED Green", + .pin = LED1_PIN, + .mode = GPIO_OUT, + .flags = (SAUL_GPIO_INVERTED | SAUL_GPIO_INIT_CLEAR), + }, + { + .name = "LED Blue", + .pin = LED2_PIN, + .mode = GPIO_OUT, + .flags = (SAUL_GPIO_INVERTED | SAUL_GPIO_INIT_CLEAR), + }, + { + .name = "Reset", + .pin = BTN0_PIN, + .mode = GPIO_IN_PU, + .flags = SAUL_GPIO_INVERTED, + }, +}; + + +#ifdef __cplusplus +} +#endif + +#endif /* GPIO_PARAMS_H */ +/** @} */ diff --git a/boards/nrf52840-mdk-dongle/include/periph_conf.h b/boards/nrf52840-mdk-dongle/include/periph_conf.h new file mode 100644 index 0000000000..b933de4842 --- /dev/null +++ b/boards/nrf52840-mdk-dongle/include/periph_conf.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 Benjamin Valentin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_nrf52840-mdk-dongle + * @{ + * + * @file + * @brief Peripheral configuration for the nRF52840 MDK USB Dongle + * + * @author Benjamin Valentin + * + */ + +#ifndef PERIPH_CONF_H +#define PERIPH_CONF_H + +#include "periph_cpu.h" +#include "cfg_clock_32_1.h" +#include "cfg_rtt_default.h" +#include "cfg_timer_default.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name UART configuration + * + * This board does not have explicit UART pins. These are set as UART 0 to + * provide an easy serial debug port when not using (or debugging) USB. + * + * @{ + */ +static const uart_conf_t uart_config[] = { + { + .dev = NRF_UARTE0, + .rx_pin = GPIO_PIN(0, 6), + .tx_pin = GPIO_PIN(0, 7), +#ifdef MODULE_PERIPH_UART_HW_FC + .rts_pin = GPIO_UNDEF, + .cts_pin = GPIO_UNDEF, +#endif + .irqn = UARTE0_UART0_IRQn, + }, +}; + +#define UART_0_ISR isr_uart0 + +#define UART_NUMOF ARRAY_SIZE(uart_config) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CONF_H */ diff --git a/boards/nrf52840-mdk-dongle/reset.c b/boards/nrf52840-mdk-dongle/reset.c new file mode 100644 index 0000000000..7440faba3b --- /dev/null +++ b/boards/nrf52840-mdk-dongle/reset.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 Benjamin Valentin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_nrf52840-mdk-dongle + * @{ + * @file + * @brief Implementation for managing the UF2 bootloader + * + * @author Benjamin Valentin + * + * @} + */ + +#ifdef MODULE_USB_BOARD_RESET + +#define USB_H_USER_IS_RIOT_INTERNAL + +#include "cpu.h" +#include "usb_board_reset.h" + +/* from uf2-bootloader src/main.c */ +#define DFU_MAGIC_UF2_RESET 0x57 + +void usb_board_reset_in_bootloader(void) +{ + NRF_POWER->GPREGRET = DFU_MAGIC_UF2_RESET; + + usb_board_reset_in_application(); +} + +#else +typedef int dont_be_pedantic; +#endif /* MODULE_USB_BOARD_RESET */