From 4618a5ce0e630789498d50f9338af1cf601fd738 Mon Sep 17 00:00:00 2001 From: francisco Date: Fri, 8 Mar 2019 16:35:44 +0100 Subject: [PATCH] boards/im880b: add initial support --- boards/im880b/Makefile | 3 + boards/im880b/Makefile.dep | 3 + boards/im880b/Makefile.features | 11 ++ boards/im880b/Makefile.include | 14 ++ boards/im880b/board.c | 28 ++++ boards/im880b/doc.txt | 73 ++++++++++ boards/im880b/include/board.h | 68 +++++++++ boards/im880b/include/periph_conf.h | 209 ++++++++++++++++++++++++++++ 8 files changed, 409 insertions(+) create mode 100644 boards/im880b/Makefile create mode 100644 boards/im880b/Makefile.dep create mode 100644 boards/im880b/Makefile.features create mode 100644 boards/im880b/Makefile.include create mode 100644 boards/im880b/board.c create mode 100644 boards/im880b/doc.txt create mode 100644 boards/im880b/include/board.h create mode 100644 boards/im880b/include/periph_conf.h diff --git a/boards/im880b/Makefile b/boards/im880b/Makefile new file mode 100644 index 0000000000..f8fcbb53a0 --- /dev/null +++ b/boards/im880b/Makefile @@ -0,0 +1,3 @@ +MODULE = board + +include $(RIOTBASE)/Makefile.base diff --git a/boards/im880b/Makefile.dep b/boards/im880b/Makefile.dep new file mode 100644 index 0000000000..127d32fd6f --- /dev/null +++ b/boards/im880b/Makefile.dep @@ -0,0 +1,3 @@ +ifneq (,$(filter netdev_default,$(USEMODULE))) + USEMODULE += sx1272 +endif diff --git a/boards/im880b/Makefile.features b/boards/im880b/Makefile.features new file mode 100644 index 0000000000..68d9a831c5 --- /dev/null +++ b/boards/im880b/Makefile.features @@ -0,0 +1,11 @@ +## the cpu to build for +CPU = stm32l1 +CPU_MODEL = stm32l151cb + +# Put defined MCU peripherals here (in alphabetical order) +FEATURES_PROVIDED += periph_adc +FEATURES_PROVIDED += periph_i2c +FEATURES_PROVIDED += periph_rtc +FEATURES_PROVIDED += periph_spi +FEATURES_PROVIDED += periph_timer +FEATURES_PROVIDED += periph_uart diff --git a/boards/im880b/Makefile.include b/boards/im880b/Makefile.include new file mode 100644 index 0000000000..acda956bed --- /dev/null +++ b/boards/im880b/Makefile.include @@ -0,0 +1,14 @@ +# define the default port depending on the host OS +PORT_LINUX ?= /dev/ttyUSB0 +PORT_DARWIN ?= $(firstword $(sort $(wildcard /dev/tty.SLAB_USBtoUART*))) + +# setup serial terminal +include $(RIOTMAKE)/tools/serial.inc.mk + +DEBUG_ADAPTER ?= stlink + +CFLAGS+=-DSX127X_TX_SWITCH +CFLAGS+=-DSX127X_RX_SWITCH + +# this board uses openocd +include $(RIOTMAKE)/tools/openocd.inc.mk diff --git a/boards/im880b/board.c b/boards/im880b/board.c new file mode 100644 index 0000000000..0a834d9555 --- /dev/null +++ b/boards/im880b/board.c @@ -0,0 +1,28 @@ +/* + * 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_im880b + * @{ + * + * @file + * @brief Board specific implementations for the im880b board + * + * @author Francisco Molina + * + * @} + */ + +#include "board.h" +#include "periph/gpio.h" + +void board_init(void) +{ + /* initialize the CPU */ + cpu_init(); +} diff --git a/boards/im880b/doc.txt b/boards/im880b/doc.txt new file mode 100644 index 0000000000..a741b97965 --- /dev/null +++ b/boards/im880b/doc.txt @@ -0,0 +1,73 @@ +/** +@defgroup boards_im880b im880b +@ingroup boards +@brief Support for the im880b with stm32l151cb-a + +## Hardware + +![LoraBox](https://www.wireless-solutions.de/images/stories/products/im880a.png) + + +### MCU +| MCU | stm32l151cb-a | +|:------------- |:--------------------- | +| Family | ARM Cortex-M3 | +| Vendor | ST Microelectronics | +| RAM | 16Kb | +| Flash | 128Kb | +| Frequency | 32MHz (no external oscilator connected) | +| FPU | no | +| Timers | 10 (8x 16-bit, 2x watchdog timers) | +| ADCs | 1x 24-channel 12-bit | +| UARTs | 3 | +| SPIs | 2 | +| I2Cs | 2 | +| Vcc | 1.65V - 3.6V | +| Datasheet | [Datasheet](https://www.st.com/resource/en/datasheet/stm32l151cb-a.pdf) | +| Reference Manual | [Reference Manual](https://www.st.com/content/ccc/resource/technical/document/reference_manual/cc/f9/93/b2/f0/82/42/57/CD00240193.pdf/files/CD00240193.pdf/jcr:content/translations/en.CD00240193.pdf) | +| Programming Manual | [Programming Manual](https://www.st.com/content/ccc/resource/technical/document/programming_manual/5b/ca/8d/83/56/7f/40/08/CD00228163.pdf/files/CD00228163.pdf/jcr:content/translations/en.CD00228163.pdf) | +| Board Manual | [Board Manual](https://cdn.sos.sk/productdata/29/eb/a68245ed/im880b-l-lorawan.pdf)| + +### User Interface + +## Flashing +As no usb connector is present on the device an external programmer must +be connected to the board for flashing. You can use JTAG or STLINK programmer. + + * JTAG: + * - JTDO: PB_3 / P39 + * - JTDI: PA_15 / P38 + * - JTCK: PA_14 / P37 + * - JTMS: PA_13 / P34 + + * STLINK: + * - NRST: NRST / P7 + * - SWCLK: PA_14 / P37 + * - SWDAT: PA_13 / P34 + +### STM32 Loader +To flash RIOT on the board, after connecting the UART-USB bridge, just run: +``` +BOARD=im880b make flash +``` +This uses the stm32loader script to erase the memory and flash it interfacing +with the STM32 ROM bootloader. + +## Connecting via Serial +The default UART port is the USART1, there is no usb connection a USB/TTL +converter must be used to connect to the board TX & RX pins. The default +port is /dev/ttyUSB0. The pin connections are: + + * USART1: + * - TX: PA_9 / P30 + * - RX: PA_10 / P31 + +``` +BOARD=im880b make term +``` + */ + +## SX1272 radio +Please note that the board has a Semtech SX1272 radio. This means that when the +semtech-loramac package or the sx127x driver are used the correct driver version +(sx1272) must be selected. \ No newline at end of file diff --git a/boards/im880b/include/board.h b/boards/im880b/include/board.h new file mode 100644 index 0000000000..59f5c5d214 --- /dev/null +++ b/boards/im880b/include/board.h @@ -0,0 +1,68 @@ +/* + * 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_im880b + * @brief Support for im880b + * @{ + * + * @file + * @brief Board specific definitions for the im880b board. + * + * @author Francisco Molina + */ + +#ifndef BOARD_H +#define BOARD_H + +#include + +#include "cpu.h" +#include "periph_conf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name xtimer configuration + * @{ + */ +#define XTIMER_BACKOFF (11) +#define XTIMER_WIDTH (16) +/** @} */ + +/** + * @name sx1272 configuration + * @{ + */ +#define SX127X_PARAM_SPI_NSS GPIO_PIN(PORT_B, 0) + +#define SX127X_PARAM_RESET GPIO_PIN(PORT_A, 2) +#define SX127X_PARAM_DIO0 GPIO_PIN(PORT_B, 1) +#define SX127X_PARAM_DIO1 GPIO_PIN(PORT_B, 10) +#define SX127X_PARAM_DIO2 GPIO_PIN(PORT_B, 11) +/* stm32l1xxx Errata: Pull-up on PB7 when configured in analog mode */ +#define SX127X_PARAM_DIO3 GPIO_PIN(PORT_B, 7) + +#define SX127X_PARAM_RX_SWITCH GPIO_PIN(PORT_C, 13) +#define SX127X_PARAM_TX_SWITCH GPIO_PIN(PORT_A, 4) +/** @} */ + + +/** + * @brief Initialize board specific hardware, including clock, LEDs and std-IO + */ +void board_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H */ +/** @} */ diff --git a/boards/im880b/include/periph_conf.h b/boards/im880b/include/periph_conf.h new file mode 100644 index 0000000000..56c0fde7bf --- /dev/null +++ b/boards/im880b/include/periph_conf.h @@ -0,0 +1,209 @@ +/* + * 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_im880b + * @{ + * + * @file + * @brief Peripheral MCU configuration for the im808b board + * + * @author Francisco Molina + */ + +#ifndef PERIPH_CONF_H +#define PERIPH_CONF_H + +#include "periph_cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Clock system configuration + * @{ + **/ +#define CLOCK_HSE (16000000U) /* external oscillator */ +#define CLOCK_CORECLOCK (32000000U) /* desired core clock frequency */ + +/* + * 0: no external low speed crystal available, + * 1: external crystal available (always 32.768kHz) + */ +#ifndef CLOCK_LSE +#define CLOCK_LSE (1) +#endif +/* configuration of PLL prescaler and multiply values */ +/* CORECLOCK := HSE / 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_APB1 (CLOCK_CORECLOCK / 1) +#define CLOCK_APB2 (CLOCK_CORECLOCK / 1) +/** @} */ + +/** + * @name Timer configuration + * @{ + */ +static const timer_conf_t timer_config[] = { + { + .dev = TIM3, + .max = 0x0000ffff, + .rcc_mask = RCC_APB1ENR_TIM3EN, + .bus = APB1, + .irqn = TIM3_IRQn + } +}; + +#define TIMER_0_ISR (isr_tim3) + +#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_AF7, + .tx_af = GPIO_AF7, + .bus = APB2, + .irqn = USART1_IRQn + }, +}; + +#define UART_0_ISR (isr_usart1) + +#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, + .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, + .mosi_af = GPIO_AF5, + .miso_af = GPIO_AF5, + .sclk_af = GPIO_AF5, + .cs_af = GPIO_AF5, + .rccmask = RCC_APB2ENR_SPI1EN, + .apbbus = APB2 + }, + { + .dev = SPI2, + .mosi_pin = GPIO_PIN(PORT_B, 14), + .miso_pin = GPIO_PIN(PORT_B, 15), + .sclk_pin = GPIO_PIN(PORT_B, 13), + .cs_pin = GPIO_PIN(PORT_B, 12), + .mosi_af = GPIO_AF5, + .miso_af = GPIO_AF5, + .sclk_af = GPIO_AF5, + .cs_af = GPIO_AF5, + .rccmask = RCC_APB1ENR_SPI2EN, + .apbbus = APB1 + } +}; + +#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, 8), + .sda_pin = GPIO_PIN(PORT_B, 9), + .scl_af = GPIO_AF4, + .sda_af = GPIO_AF4, + .bus = APB1, + .rcc_mask = RCC_APB1ENR_I2C1EN, + .clk = CLOCK_APB1, + .irqn = I2C1_EV_IRQn + } +}; + +#define I2C_0_ISR isr_i2c1_ev + +#define I2C_NUMOF (sizeof(i2c_config) / sizeof(i2c_config[0])) +/** @} */ + +/** + * @name RTC configuration + * @{ + */ +#define RTC_NUMOF (1U) +/** @} */ + +/** + * @name ADC configuration + * @{ + */ +#define ADC_CONFIG { \ + { GPIO_PIN(PORT_A, 0), 0 }, /* P14 */ \ + { GPIO_PIN(PORT_A, 1), 1 }, /* P15 */ \ + { GPIO_PIN(PORT_A, 3), 3 }, /* P17 */ \ + /* ADC Temperature channel */ \ + { GPIO_UNDEF, 16 }, \ + /* ADC VREF channel */ \ + { GPIO_UNDEF, 17 }, \ +} + +#define ADC_NUMOF (5) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CONF_H */ +/** @} */