From bf3e471fdbf46c3a719f8ab2b3313317cc2eaf51 Mon Sep 17 00:00:00 2001 From: Alexandre Abadie Date: Wed, 8 May 2019 16:54:49 +0200 Subject: [PATCH 1/4] boards/lsn50: add initial support --- boards/lsn50/Makefile | 3 + boards/lsn50/Makefile.dep | 3 + boards/lsn50/Makefile.features | 16 ++ boards/lsn50/Makefile.include | 19 +++ boards/lsn50/board.c | 29 ++++ boards/lsn50/doc.txt | 51 +++++++ boards/lsn50/include/board.h | 64 ++++++++ boards/lsn50/include/periph_conf.h | 231 +++++++++++++++++++++++++++++ 8 files changed, 416 insertions(+) create mode 100644 boards/lsn50/Makefile create mode 100644 boards/lsn50/Makefile.dep create mode 100644 boards/lsn50/Makefile.features create mode 100644 boards/lsn50/Makefile.include create mode 100644 boards/lsn50/board.c create mode 100644 boards/lsn50/doc.txt create mode 100644 boards/lsn50/include/board.h create mode 100644 boards/lsn50/include/periph_conf.h diff --git a/boards/lsn50/Makefile b/boards/lsn50/Makefile new file mode 100644 index 000000000..f8fcbb53a --- /dev/null +++ b/boards/lsn50/Makefile @@ -0,0 +1,3 @@ +MODULE = board + +include $(RIOTBASE)/Makefile.base diff --git a/boards/lsn50/Makefile.dep b/boards/lsn50/Makefile.dep new file mode 100644 index 000000000..4ab749e2d --- /dev/null +++ b/boards/lsn50/Makefile.dep @@ -0,0 +1,3 @@ +ifneq (,$(filter netdev_default,$(USEMODULE))) + USEMODULE += sx1276 +endif diff --git a/boards/lsn50/Makefile.features b/boards/lsn50/Makefile.features new file mode 100644 index 000000000..dfaf64797 --- /dev/null +++ b/boards/lsn50/Makefile.features @@ -0,0 +1,16 @@ +# Put defined MCU peripherals here (in alphabetical order) +FEATURES_PROVIDED += periph_dma +FEATURES_PROVIDED += periph_i2c +FEATURES_PROVIDED += periph_rtc +FEATURES_PROVIDED += periph_rtt +FEATURES_PROVIDED += periph_spi +FEATURES_PROVIDED += periph_timer +FEATURES_PROVIDED += periph_uart + +# Put other features for this board (in alphabetical order) +# For riotboot you need an openocd that supports dualbank flashing. +# The 0.10.0 openocd version in Ubuntu Bionic doesn't work. The change was +# introduced after Jun 8, 2017 - v0.10.0-1-20170607-2132-dev. +FEATURES_PROVIDED += riotboot + +include $(RIOTCPU)/stm32l0/Makefile.features diff --git a/boards/lsn50/Makefile.include b/boards/lsn50/Makefile.include new file mode 100644 index 000000000..0b4a8e989 --- /dev/null +++ b/boards/lsn50/Makefile.include @@ -0,0 +1,19 @@ +## the cpu to build for +export CPU = stm32l0 +export CPU_MODEL = stm32l072cz + +# define the default port depending on the host OS +PORT_LINUX ?= /dev/ttyACM0 +PORT_DARWIN ?= $(firstword $(sort $(wildcard /dev/tty.usbmodem*))) + +# setup serial terminal +include $(RIOTMAKE)/tools/serial.inc.mk + +# By default, flash this board using an ST-link adapter +export DEBUG_ADAPTER ?= stlink + +# call a 'reset halt' command before starting the debugger +export OPENOCD_DBG_START_CMD = -c 'reset halt' + +# this board uses openocd +include $(RIOTMAKE)/tools/openocd.inc.mk diff --git a/boards/lsn50/board.c b/boards/lsn50/board.c new file mode 100644 index 000000000..2e2dfeb31 --- /dev/null +++ b/boards/lsn50/board.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2019 Inria + * + * 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_lsn50 + * @{ + * + * @file + * @brief Board specific implementations for the LSN50 board + * + * @author Alexandre Abadie + * + * @} + */ + +#include "board.h" +#include "periph/gpio.h" + + +void board_init(void) +{ + /* initialize the CPU */ + cpu_init(); +} diff --git a/boards/lsn50/doc.txt b/boards/lsn50/doc.txt new file mode 100644 index 000000000..de0ced1d8 --- /dev/null +++ b/boards/lsn50/doc.txt @@ -0,0 +1,51 @@ +/** +@defgroup boards_lsn50 Dragino LSN50 LoRa Sensor Node +@ingroup boards +@brief Support for the Dragino LSN50 LoRa Sensor Node + +### Introduction + +This board is a waterproof board with a LoRa SX1276 radio. + +![LSN50](https://wiki.dragino.com/images/thumb/e/e9/Introdution.png/600px-Introdution.png) + +Documentation of the board is available +[here](https://wiki.dragino.com/index.php?title=Lora_Sensor_Node-LSN50). + +More documentation is available +[here](http://wiki.dragino.com/index.php?title=Lora_Sensor_Node-LSN50#Resource). + +The datasheet can be downloaded +[here](https://www.dragino.com/downloads/index.php?dir=datasheet/EN/&file=Datasheet_LoRaSensorNode.pdf). + +Detailed schematics are available on GitHub: +- Board schematics are [here](https://github.com/dragino/Lora/tree/master/LSN50) +- Radio connection schematics are [here](https://github.com/dragino/Lora/tree/master/LoRaST) + +### Flashing the board + +To flash the board, use an external ST-Link programmer/debugger, plugged on +available SWD pins: PA13 (SWDIO), PA14 (SWCLK) and NRST (this pin is not +exposed with v1.0). +Ensure SW1 is on `flash` position. +Then use the following command: + + make BOARD=lsn50 -C examples/hello-world flash + +On the v1.0 version of the board, no NRST pin is exposed so one has to press the +reset button during flash and release it when OpenOCD prints `adapter speed: 240 kHz` +the first time. +The reset button must also be pressed a second time after flashing to start the new +application. + +### STDIO + +STDIO is connected to pins PA9 (TX) and PA10 (RX) so an USB to UART adapter is +required. Use the `term` targed to open a terminal: + + make BOARD=lsn50 -C examples/hello-world term + +If an external ST-Link adapter is used, RX and TX pins can be directly connected +to it. In this case, STDIO is available on /dev/ttyACMx (Linux case). + + */ diff --git a/boards/lsn50/include/board.h b/boards/lsn50/include/board.h new file mode 100644 index 000000000..989887613 --- /dev/null +++ b/boards/lsn50/include/board.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2019 Inria + * + * 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_lsn50 + * @{ + * + * @file + * @brief Board specific definitions for the LSN50 board + * + * @author Alexandre Abadie + */ + +#ifndef BOARD_H +#define BOARD_H + +#include + +#include "cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name xtimer configuration + * @{ + */ +#define XTIMER_WIDTH (16) +/** @} */ + +/** + * @name sx1276 configuration + * @{ + */ +#define SX127X_PARAM_SPI SPI_DEV(0) +#define SX127X_PARAM_SPI_NSS GPIO_PIN(PORT_A, 15) + +#define SX127X_PARAM_RESET GPIO_PIN(PORT_B, 0) +#define SX127X_PARAM_DIO0 GPIO_PIN(PORT_C, 13) +#define SX127X_PARAM_DIO1 GPIO_PIN(PORT_B, 10) +#define SX127X_PARAM_DIO2 GPIO_PIN(PORT_B, 11) +#define SX127X_PARAM_DIO3 GPIO_PIN(PORT_B, 8) +#define SX127X_PARAM_DIO4 GPIO_PIN(PORT_B, 9) +#define SX127X_PARAM_DIO5 GPIO_PIN(PORT_B, 1) +#define SX127X_PARAM_PASELECT (SX127X_PA_BOOST) +/** @} */ + +/** + * @brief Initialize board specific hardware + */ +void board_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H */ +/** @} */ diff --git a/boards/lsn50/include/periph_conf.h b/boards/lsn50/include/periph_conf.h new file mode 100644 index 000000000..9c1d32808 --- /dev/null +++ b/boards/lsn50/include/periph_conf.h @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2019 Inria + * + * 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_lsn50 + * @{ + * + * @file + * @brief Peripheral MCU configuration for the LSN50 board + * + * @author Alexandre Abadie + */ + +#ifndef PERIPH_CONF_H +#define PERIPH_CONF_H + +#include "periph_cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Clock system configuration + * @{ + */ +#define CLOCK_HSI (16000000U) /* internal oscillator */ +#define CLOCK_CORECLOCK (32000000U) /* desired core clock frequency */ +#define CLOCK_LSE (1) /* enable low speed external oscillator */ + +/* configuration of PLL prescaler and multiply values */ +/* CORECLOCK := HSI / CLOCK_PLL_DIV * CLOCK_PLL_MUL */ +#define CLOCK_PLL_DIV RCC_CFGR_PLLDIV2 +#define CLOCK_PLL_MUL RCC_CFGR_PLLMUL4 +/* configuration of peripheral bus clock prescalers */ +#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1 /* AHB clock -> 32MHz */ +#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV1 /* APB2 clock -> 32MHz */ +#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV1 /* APB1 clock -> 32MHz */ +/* configuration of flash access cycles */ +#define CLOCK_FLASH_LATENCY FLASH_ACR_LATENCY + +/* bus clocks for simplified peripheral initialization, UPDATE MANUALLY! */ +#define CLOCK_AHB (CLOCK_CORECLOCK / 1) +#define CLOCK_APB2 (CLOCK_CORECLOCK / 1) +#define CLOCK_APB1 (CLOCK_CORECLOCK / 1) +/** @} */ + +/** + * @name DMA streams configuration + * @{ + */ +#ifdef MODULE_PERIPH_DMA +static const dma_conf_t dma_config[] = { + { .stream = 1 }, /* channel 2 */ + { .stream = 2 }, /* channel 3 */ + { .stream = 3 }, /* channel 4 */ + { .stream = 4 }, /* channel 5 */ + { .stream = 5 }, /* channel 6 */ +}; + +#define DMA_SHARED_ISR_0 isr_dma1_channel2_3 +#define DMA_SHARED_ISR_0_STREAMS { 0, 1 } /* Indexes 0 and 1 of dma_config share the same isr */ +#define DMA_SHARED_ISR_1 isr_dma1_channel4_5_6_7 +#define DMA_SHARED_ISR_1_STREAMS { 2, 3, 4 } /* Indexes 2, 3 and 4 of dma_config share the same isr */ + +#define DMA_NUMOF (sizeof(dma_config) / sizeof(dma_config[0])) +#endif +/** @} */ + +/** + * @name Timer configuration + * @{ + */ +static const timer_conf_t timer_config[] = { + { + .dev = TIM2, + .max = 0x0000ffff, + .rcc_mask = RCC_APB1ENR_TIM2EN, + .bus = APB1, + .irqn = TIM2_IRQn + } +}; + +#define TIMER_0_ISR isr_tim2 + +#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0])) +/** @} */ + +/** + * @name UART configuration + * @{ + */ +static const uart_conf_t uart_config[] = { + { + .dev = USART1, + .rcc_mask = RCC_APB2ENR_USART1EN, + .rx_pin = GPIO_PIN(PORT_A, 10), + .tx_pin = GPIO_PIN(PORT_A, 9), + .rx_af = GPIO_AF4, + .tx_af = GPIO_AF4, + .bus = APB2, + .irqn = USART1_IRQn, + .type = STM32_USART, + .clk_src = 0, /* Use APB clock */ +#ifdef MODULE_PERIPH_DMA + .dma = 0, + .dma_chan = 3, +#endif + }, + { + .dev = USART2, + .rcc_mask = RCC_APB1ENR_USART2EN, + .rx_pin = GPIO_PIN(PORT_A, 3), + .tx_pin = GPIO_PIN(PORT_A, 2), + .rx_af = GPIO_AF4, + .tx_af = GPIO_AF4, + .bus = APB1, + .irqn = USART2_IRQn, + .type = STM32_USART, + .clk_src = 0, /* Use APB clock */ +#ifdef MODULE_PERIPH_DMA + .dma = 2, + .dma_chan = 4, +#endif + }, +}; + +#define UART_0_ISR (isr_usart1) +#define UART_1_ISR (isr_usart2) + +#define UART_NUMOF (sizeof(uart_config) / sizeof(uart_config[0])) +/** @} */ + +/** + * @name SPI configuration + * + * @note The spi_divtable is auto-generated from + * `cpu/stm32_common/dist/spi_divtable/spi_divtable.c` + * @{ + */ +static const uint8_t spi_divtable[2][5] = { + { /* for APB1 @ 32000000Hz */ + 7, /* -> 125000Hz */ + 5, /* -> 500000Hz */ + 4, /* -> 1000000Hz */ + 2, /* -> 4000000Hz */ + 1 /* -> 8000000Hz */ + }, + { /* for APB2 @ 32000000Hz */ + 7, /* -> 125000Hz */ + 5, /* -> 500000Hz */ + 4, /* -> 1000000Hz */ + 2, /* -> 4000000Hz */ + 1 /* -> 8000000Hz */ + } +}; + +static const spi_conf_t spi_config[] = { + { + .dev = SPI1, /* connected to SX1276 */ + .mosi_pin = GPIO_PIN(PORT_A, 7), + .miso_pin = GPIO_PIN(PORT_A, 6), + .sclk_pin = GPIO_PIN(PORT_A, 5), + .cs_pin = GPIO_UNDEF, + .af = GPIO_AF0, + .rccmask = RCC_APB2ENR_SPI1EN, + .apbbus = APB2, +#ifdef MODULE_PERIPH_DMA + .tx_dma = 1, + .tx_dma_chan = 1, + .rx_dma = 0, + .rx_dma_chan = 1, +#endif + }, +}; + +#define SPI_NUMOF (sizeof(spi_config) / sizeof(spi_config[0])) +/** @} */ + +/** + * @name I2C configuration + * @{ + */ +static const i2c_conf_t i2c_config[] = { + { + .dev = I2C1, + .speed = I2C_SPEED_NORMAL, + .scl_pin = GPIO_PIN(PORT_B, 6), + .sda_pin = GPIO_PIN(PORT_B, 7), + .scl_af = GPIO_AF4, + .sda_af = GPIO_AF4, + .bus = APB1, + .rcc_mask = RCC_APB1ENR_I2C1EN, + .irqn = I2C1_IRQn + } +}; + +#define I2C_0_ISR isr_i2c1 + +#define I2C_NUMOF (sizeof(i2c_config) / sizeof(i2c_config[0])) +/** @} */ + +/** + * @name RTT configuration + * + * On the STM32Lx platforms, we always utilize the LPTIM1. + * @{ + */ +#define RTT_NUMOF (1) +#define RTT_FREQUENCY (1024U) /* 32768 / 2^n */ +#define RTT_MAX_VALUE (0x0000ffff) /* 16-bit timer */ +/** @} */ + +/** + * @name RTC configuration + * @{ + */ +#define RTC_NUMOF (1U) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CONF_H */ +/** @} */ From 14cd77b277ed3f55392ddb1775c39e0385e24697 Mon Sep 17 00:00:00 2001 From: Alexandre Abadie Date: Tue, 14 May 2019 07:42:26 +0200 Subject: [PATCH 2/4] examples/default: add lsn50 to boards providing netif --- examples/default/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/default/Makefile b/examples/default/Makefile index 53ec584e6..3af51cf2c 100644 --- a/examples/default/Makefile +++ b/examples/default/Makefile @@ -36,8 +36,9 @@ USEMODULE += ps # include and auto-initialize all available sensors USEMODULE += saul_default -BOARD_PROVIDES_NETIF := acd52832 airfy-beacon b-l072z-lrwan1 cc2538dk fox iotlab-m3 iotlab-a8-m3 mulle \ - microbit native nrf51dk nrf51dongle nrf52dk nrf52840dk nrf52840-mdk nrf6310 \ +BOARD_PROVIDES_NETIF := acd52832 airfy-beacon b-l072z-lrwan1 cc2538dk fox \ + iotlab-m3 iotlab-a8-m3 lsn50 mulle microbit native nrf51dk \ + nrf51dongle nrf52dk nrf52840dk nrf52840-mdk nrf6310 \ openmote-cc2538 pba-d-01-kw2x remote-pa remote-reva samr21-xpro \ spark-core telosb yunjia-nrf51822 z1 From 97b4ac0e98be8de5c4709479dd0280ada877af35 Mon Sep 17 00:00:00 2001 From: Alexandre Abadie Date: Tue, 14 May 2019 11:02:06 +0200 Subject: [PATCH 3/4] examples: add lsn50 to insufficient memory boards --- examples/dtls-echo/Makefile | 2 +- examples/gnrc_border_router/Makefile | 2 +- examples/javascript/Makefile | 2 +- examples/lua_REPL/Makefile | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/dtls-echo/Makefile b/examples/dtls-echo/Makefile index 78ff942c3..3a6066fea 100644 --- a/examples/dtls-echo/Makefile +++ b/examples/dtls-echo/Makefile @@ -14,7 +14,7 @@ BOARD_BLACKLIST := arduino-duemilanove arduino-mega2560 arduino-nano \ wsn430-v1_4 z1 BOARD_INSUFFICIENT_MEMORY := airfy-beacon b-l072z-lrwan1 blackpill bluepill calliope-mini \ - cc2650-launchpad cc2650stk hifive1 maple-mini \ + cc2650-launchpad cc2650stk hifive1 lsn50 maple-mini \ microbit nrf51dk nrf51dongle nrf6310 nucleo-f031k6 \ nucleo-f042k6 nucleo-f303k8 nucleo-l031k6 nucleo-f030r8 \ nucleo-f070rb nucleo-f072rb nucleo-f103rb nucleo-f302r8 nucleo-f334r8 \ diff --git a/examples/gnrc_border_router/Makefile b/examples/gnrc_border_router/Makefile index 35f2dbe82..58d3e11f8 100644 --- a/examples/gnrc_border_router/Makefile +++ b/examples/gnrc_border_router/Makefile @@ -10,7 +10,7 @@ RIOTBASE ?= $(CURDIR)/../.. BOARD_INSUFFICIENT_MEMORY := airfy-beacon arduino-duemilanove arduino-mega2560 \ arduino-nano arduino-uno b-l072z-lrwan1 blackpill \ bluepill calliope-mini cc2650-launchpad cc2650stk \ - hifive1 maple-mini mega-xplained microbit msb-430 \ + hifive1 lsn50 maple-mini mega-xplained microbit msb-430 \ msb-430h nrf51dk nrf51dongle nrf6310 \ nucleo-f031k6 nucleo-f042k6 \ nucleo-f303k8 nucleo-l031k6 nucleo-f030r8 \ diff --git a/examples/javascript/Makefile b/examples/javascript/Makefile index 36c2bd454..cae0e3cba 100644 --- a/examples/javascript/Makefile +++ b/examples/javascript/Makefile @@ -8,7 +8,7 @@ BOARD ?= native RIOTBASE ?= $(CURDIR)/../.. BOARD_INSUFFICIENT_MEMORY := airfy-beacon b-l072z-lrwan1 blackpill bluepill calliope-mini \ - cc2650-launchpad cc2650stk hifive1 lobaro-lorabox \ + cc2650-launchpad cc2650stk hifive1 lobaro-lorabox lsn50 \ maple-mini microbit nrf51dk nrf51dongle nrf6310 \ nucleo-f030r8 nucleo-f070rb nucleo-f072rb \ nucleo-f103rb nucleo-f302r8 nucleo-f334r8 \ diff --git a/examples/lua_REPL/Makefile b/examples/lua_REPL/Makefile index 0cafbef38..c04ac5276 100644 --- a/examples/lua_REPL/Makefile +++ b/examples/lua_REPL/Makefile @@ -7,7 +7,8 @@ BOARD ?= native RIOTBASE ?= $(CURDIR)/../.. BOARD_INSUFFICIENT_MEMORY := blackpill bluepill calliope-mini cc2650-launchpad \ - cc2650stk hamilton maple-mini microbit nrf51dk nrf51dongle \ + cc2650stk hamilton lsn50 \ + maple-mini microbit nrf51dk nrf51dongle \ nucleo-f030r8 nucleo-f031k6 nucleo-f042k6 \ nucleo-f070rb nucleo-f072rb nucleo-f103rb \ nucleo-f302r8 nucleo-f303k8 nucleo-f334r8 \ From ea2988c057afe8b1ec8fd9c205c7c06a10e93200 Mon Sep 17 00:00:00 2001 From: Alexandre Abadie Date: Tue, 14 May 2019 11:03:27 +0200 Subject: [PATCH 4/4] tests: add lsn50 to insufficient memory boards --- tests/gnrc_netif/Makefile | 2 +- tests/unittests/Makefile | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/gnrc_netif/Makefile b/tests/gnrc_netif/Makefile index 0dd0e416b..d656ff80f 100644 --- a/tests/gnrc_netif/Makefile +++ b/tests/gnrc_netif/Makefile @@ -3,7 +3,7 @@ include ../Makefile.tests_common BOARD_INSUFFICIENT_MEMORY := airfy-beacon arduino-duemilanove arduino-mega2560 \ arduino-nano arduino-uno b-l072z-lrwan1 blackpill \ bluepill calliope-mini cc2650-launchpad cc2650stk \ - chronos hifive1 maple-mini mega-xplained microbit \ + chronos hifive1 lsn50 maple-mini mega-xplained microbit \ msb-430 msb-430h nrf51dk nrf51dongle nrf6310 \ nucleo-f030r8 nucleo-f070rb nucleo-f072rb \ nucleo-f103rb nucleo-f302r8 nucleo-f334r8 \ diff --git a/tests/unittests/Makefile b/tests/unittests/Makefile index 03605f2a5..6acd7a260 100644 --- a/tests/unittests/Makefile +++ b/tests/unittests/Makefile @@ -26,6 +26,7 @@ BOARD_INSUFFICIENT_MEMORY := airfy-beacon \ ikea-tradfri \ limifrog-v1 maple-mini \ lobaro-lorabox \ + lsn50 \ mbed_lpc1768 \ mega-xplained \ microbit \ @@ -125,6 +126,7 @@ ARM_CORTEX_M_BOARDS := airfy-beacon \ iotlab-a8-m3 \ iotlab-m3 \ limifrog-v1 \ + lsn50 \ maple-mini \ mbed_lpc1768 \ microbit \