From 337e9d80f2f015c45c53cd8d520de5004e5b8d83 Mon Sep 17 00:00:00 2001
From: Alexandre Abadie <alexandre.abadie@inria.fr>
Date: Thu, 24 Aug 2017 11:44:56 +0200
Subject: [PATCH] boards/feather-m0: initial support

---
 boards/feather-m0/Makefile                    |   3 +
 boards/feather-m0/Makefile.dep                |   3 +
 boards/feather-m0/Makefile.features           |  15 ++
 boards/feather-m0/Makefile.include            |  25 ++
 boards/feather-m0/board.c                     |  31 +++
 boards/feather-m0/doc.txt                     |  45 ++++
 boards/feather-m0/include/board.h             |  56 ++++
 boards/feather-m0/include/gpio_params.h       |  46 ++++
 boards/feather-m0/include/periph_conf.h       | 255 ++++++++++++++++++
 boards/feather-m0/include/sdcard_spi_params.h |  53 ++++
 10 files changed, 532 insertions(+)
 create mode 100644 boards/feather-m0/Makefile
 create mode 100644 boards/feather-m0/Makefile.dep
 create mode 100644 boards/feather-m0/Makefile.features
 create mode 100644 boards/feather-m0/Makefile.include
 create mode 100644 boards/feather-m0/board.c
 create mode 100644 boards/feather-m0/doc.txt
 create mode 100644 boards/feather-m0/include/board.h
 create mode 100644 boards/feather-m0/include/gpio_params.h
 create mode 100644 boards/feather-m0/include/periph_conf.h
 create mode 100644 boards/feather-m0/include/sdcard_spi_params.h

diff --git a/boards/feather-m0/Makefile b/boards/feather-m0/Makefile
new file mode 100644
index 0000000000..f8fcbb53a0
--- /dev/null
+++ b/boards/feather-m0/Makefile
@@ -0,0 +1,3 @@
+MODULE = board
+
+include $(RIOTBASE)/Makefile.base
diff --git a/boards/feather-m0/Makefile.dep b/boards/feather-m0/Makefile.dep
new file mode 100644
index 0000000000..5472bf8b8d
--- /dev/null
+++ b/boards/feather-m0/Makefile.dep
@@ -0,0 +1,3 @@
+ifneq (,$(filter saul_default,$(USEMODULE)))
+  USEMODULE += saul_gpio
+endif
diff --git a/boards/feather-m0/Makefile.features b/boards/feather-m0/Makefile.features
new file mode 100644
index 0000000000..79f3ed861c
--- /dev/null
+++ b/boards/feather-m0/Makefile.features
@@ -0,0 +1,15 @@
+# Put defined MCU peripherals here (in alphabetical order)
+FEATURES_PROVIDED += periph_adc
+FEATURES_PROVIDED += periph_gpio
+FEATURES_PROVIDED += periph_i2c
+FEATURES_PROVIDED += periph_pwm
+FEATURES_PROVIDED += periph_rtc
+FEATURES_PROVIDED += periph_rtt
+FEATURES_PROVIDED += periph_spi
+FEATURES_PROVIDED += periph_timer
+FEATURES_PROVIDED += periph_uart
+
+# The board MPU family (used for grouping by the CI system)
+FEATURES_MCU_GROUP = cortex_m0_2
+
+-include $(RIOTCPU)/samd21/Makefile.features
diff --git a/boards/feather-m0/Makefile.include b/boards/feather-m0/Makefile.include
new file mode 100644
index 0000000000..2c71b756e8
--- /dev/null
+++ b/boards/feather-m0/Makefile.include
@@ -0,0 +1,25 @@
+# define the cpu used by Adafruit Feather M0 boards
+export CPU = samd21
+export CPU_MODEL = samd21g18a
+
+#export needed for flash rule
+export PORT_LINUX ?= /dev/ttyACM0
+export PORT_DARWIN ?= $(firstword $(sort $(wildcard /dev/tty.usbmodem*)))
+
+# setup serial terminal
+include $(RIOTMAKE)/tools/serial.inc.mk
+
+# setup the flash tool used
+ifeq ($(PROGRAMMER),jlink)
+  # in case J-Link is attached to SWD pins, use a plain CPU memory model
+  export JLINK_DEVICE := atsamd21
+  include $(RIOTMAKE)/tools/jlink.inc.mk
+else
+  # by default, we use BOSSA to flash this board to take into account the
+  # pre-flashed Arduino bootloader
+  export LINKER_SCRIPT ?= $(RIOTCPU)/sam0_common/ldscripts/$(CPU_MODEL)_arduino_bootloader.ld
+  include $(RIOTMAKE)/tools/bossa.inc.mk
+endif
+
+# setup the boards dependencies
+include $(RIOTBOARD)/$(BOARD)/Makefile.dep
diff --git a/boards/feather-m0/board.c b/boards/feather-m0/board.c
new file mode 100644
index 0000000000..34c8711dbd
--- /dev/null
+++ b/boards/feather-m0/board.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C)  2017 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_feather-m0
+ * @{
+ *
+ * @file
+ * @brief       Board specific implementations for the Adafruit Feather M0 boards
+ *
+ * @author      Alexandre Abadie <alexandre.abadie@inria.fr>
+ *
+ * @}
+ */
+
+#include "cpu.h"
+#include "board.h"
+#include "periph/gpio.h"
+
+void board_init(void)
+{
+    /* initialize the CPU */
+    cpu_init();
+    /* initialize the on-board red LED on pin PA17 */
+    gpio_init(LED0_PIN, GPIO_OUT);
+}
diff --git a/boards/feather-m0/doc.txt b/boards/feather-m0/doc.txt
new file mode 100644
index 0000000000..c679acc62d
--- /dev/null
+++ b/boards/feather-m0/doc.txt
@@ -0,0 +1,45 @@
+/**
+ * @defgroup    boards_feather-m0 Adafruit Feather M0
+ * @ingroup     boards
+ * @brief       Support for the Adafruit Feather M0.
+ *
+ * ### General information
+ *
+ * Feather M0 boards are development boards shipped by
+ * [Adafruit](https://learn.adafruit.com/adafruit-feather-m0-basic-proto/).
+ *
+ * All the feather M0 boards are built based on the same Atmel SAMD21G18A
+ * microcontroller. See @ref cpu_samd21.
+ *
+ * Several types of Feather M0 boards exist:
+ * * [Feather M0 WiFi](https://learn.adafruit.com/adafruit-feather-m0-wifi-atwinc1500/)
+ * * [Feather M0 BLE](https://learn.adafruit.com/adafruit-feather-m0-bluefruit-le/overview)
+ * * [Feather M0 Adalogger](https://learn.adafruit.com/adafruit-feather-m0-adalogger/)
+ * * [Feather M0 LoRa](https://learn.adafruit.com/adafruit-feather-m0-radio-with-lora-radio-module)
+ *
+ * The different modules used to differenciate the boards (ATWINC1500 WiFi,
+ * Bluefruit LE, SD card, LoRa) are connected via SPI (SPI_DEV(0)) to the
+ * SAMD21 mcu.
+ *
+ * ### Pinout
+ *
+ * <img src="https://cdn-learn.adafruit.com/assets/assets/000/030/921/original/adafruit_products_2772_pinout_v1_0.png"
+ *      alt="Adafruit Feather M0 proto pinout" style="width:800px;"/>
+ *
+ * ### Flash the board
+ *
+ * 1. Put the board in bootloader mode by double tapping the reset button.<br/>
+ *    When the board is in bootloader mode, the user led (red) oscillates smoothly.
+ *
+ *
+ * 2. Use `BOARD=feather-m0` with the `make` command.<br/>
+ *    Example with `hello-world` application:
+ * ```
+ *      make BOARD=feather-m0 -C examples/hello-world flash
+ * ```
+ *
+ * ### Accessing STDIO via UART
+ *
+ * To access the STDIO of RIOT, a FTDI to USB converted needs to be plugged to
+ * the RX/TX pins on the board.
+ */
\ No newline at end of file
diff --git a/boards/feather-m0/include/board.h b/boards/feather-m0/include/board.h
new file mode 100644
index 0000000000..2c93ae2d18
--- /dev/null
+++ b/boards/feather-m0/include/board.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 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_feather-m0
+ * @brief       Board specific configuration of the Adafruit Feather M0.
+ *
+ * @{
+ *
+ * @file
+ * @brief       Board specific configuration for the Adafruit Feather M0
+ *
+ * @author      Alexandre Abadie <alexandre.abadie@inria.fr>
+ */
+
+#ifndef BOARD_H
+#define BOARD_H
+
+#include "cpu.h"
+#include "periph_conf.h"
+#include "periph_cpu.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @name   LED pin definitions and handlers
+ * @{
+ */
+#define LED0_PIN            GPIO_PIN(PA, 17)
+
+#define LED_PORT            PORT->Group[PA]
+#define LED0_MASK           (1 << 17)
+
+#define LED0_ON             (LED_PORT.OUTSET.reg = LED0_MASK)
+#define LED0_OFF            (LED_PORT.OUTCLR.reg = LED0_MASK)
+#define LED0_TOGGLE         (LED_PORT.OUTTGL.reg = LED0_MASK)
+/** @} */
+
+/**
+ * @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/feather-m0/include/gpio_params.h b/boards/feather-m0/include/gpio_params.h
new file mode 100644
index 0000000000..9938463489
--- /dev/null
+++ b/boards/feather-m0/include/gpio_params.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C)  2017 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_feather-m0
+ * @{
+ *
+ * @file
+ * @brief       Board specific configuration of direct mapped GPIOs
+ *
+ * @author      Alexandre Abadie <alexandre.abadie@inria.fr>
+ */
+
+#ifndef GPIO_PARAMS_H
+#define GPIO_PARAMS_H
+
+#include "board.h"
+#include "saul/periph.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief    GPIO pin configuration
+ */
+static const  saul_gpio_params_t saul_gpio_params[] =
+{
+    {
+        .name = "LED(Red)",
+        .pin = LED0_PIN,
+        .mode = GPIO_OUT
+    },
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GPIO_PARAMS_H */
+/** @} */
diff --git a/boards/feather-m0/include/periph_conf.h b/boards/feather-m0/include/periph_conf.h
new file mode 100644
index 0000000000..07498a6345
--- /dev/null
+++ b/boards/feather-m0/include/periph_conf.h
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C)  2017 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_feather-m0
+ * @{
+ *
+ * @file
+ * @brief       Configuration of CPU peripherals for Adafruit Feather M0
+ *
+ * @author      Alexandre Abadie <alexandre.abadie@inria.fr>
+ */
+
+#ifndef PERIPH_CONF_H
+#define PERIPH_CONF_H
+
+#include <stdint.h>
+
+#include "cpu.h"
+#include "periph_cpu.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @name    External oscillator and clock configuration
+ *
+ * For selection of the used CORECLOCK, we have implemented two choices:
+ *
+ * - usage of the PLL fed by the internal 8MHz oscillator divided by 8
+ * - usage of the internal 8MHz oscillator directly, divided by N if needed
+ *
+ *
+ * The PLL option allows for the usage of a wider frequency range and a more
+ * stable clock with less jitter. This is why we use this option as default.
+ *
+ * The target frequency is computed from the PLL multiplier and the PLL divisor.
+ * Use the following formula to compute your values:
+ *
+ * CORECLOCK = ((PLL_MUL + 1) * 1MHz) / PLL_DIV
+ *
+ * NOTE: The PLL circuit does not run with less than 32MHz while the maximum PLL
+ *       frequency is 96MHz. So PLL_MULL must be between 31 and 95!
+ *
+ *
+ * The internal Oscillator used directly can lead to a slightly better power
+ * efficiency to the cost of a less stable clock. Use this option when you know
+ * what you are doing! The actual core frequency is adjusted as follows:
+ *
+ * CORECLOCK = 8MHz / DIV
+ *
+ * NOTE: A core clock frequency below 1MHz is not recommended
+ *
+ * @{
+ */
+#define CLOCK_USE_PLL       (1)
+
+#if CLOCK_USE_PLL
+/* edit these values to adjust the PLL output frequency */
+#define CLOCK_PLL_MUL       (47U)               /* must be >= 31 & <= 95 */
+#define CLOCK_PLL_DIV       (1U)                /* adjust to your needs */
+#define CLOCK_CORECLOCK     (((CLOCK_PLL_MUL + 1) * 1000000U) / CLOCK_PLL_DIV)
+#else
+/* edit this value to your needs */
+#define CLOCK_DIV           (1U)
+/* generate the actual core clock frequency */
+#define CLOCK_CORECLOCK     (8000000 / CLOCK_DIV)
+#endif
+/** @} */
+
+/**
+ * @name    Timer peripheral configuration
+ * @{
+ */
+#define TIMER_NUMOF         (2U)
+#define TIMER_0_EN          1
+#define TIMER_1_EN          1
+
+/* Timer 0 configuration */
+#define TIMER_0_DEV         TC3->COUNT16
+#define TIMER_0_CHANNELS    2
+#define TIMER_0_MAX_VALUE   (0xffff)
+#define TIMER_0_ISR         isr_tc3
+
+/* Timer 1 configuration */
+#define TIMER_1_DEV         TC4->COUNT32
+#define TIMER_1_CHANNELS    2
+#define TIMER_1_MAX_VALUE   (0xffffffff)
+#define TIMER_1_ISR         isr_tc4
+/** @} */
+
+/**
+ * @name    UART configuration
+ * @{
+ */
+static const uart_conf_t uart_config[] = {
+    {
+        .dev    = &SERCOM0->USART,
+        .rx_pin = GPIO_PIN(PA, 11), /* RX pin */
+        .tx_pin = GPIO_PIN(PA, 10), /* TX pin */
+        .mux    = GPIO_MUX_C,
+        .rx_pad = UART_PAD_RX_3,
+        .tx_pad = UART_PAD_TX_2
+    }
+};
+
+/* interrupt function name mapping */
+#define UART_0_ISR          isr_sercom0
+
+#define UART_NUMOF          (sizeof(uart_config) / sizeof(uart_config[0]))
+/** @} */
+
+/**
+ * @name    PWM configuration
+ * @{
+ */
+#define PWM_0_EN            1
+#define PWM_1_EN            1
+#define PWM_MAX_CHANNELS    2
+/* for compatibility with test application */
+#define PWM_0_CHANNELS      PWM_MAX_CHANNELS
+#define PWM_1_CHANNELS      PWM_MAX_CHANNELS
+
+/* PWM device configuration */
+static const pwm_conf_t pwm_config[] = {
+#if PWM_0_EN
+    {TCC0, {
+        /* GPIO pin, MUX value, TCC channel */
+        { GPIO_UNDEF, (gpio_mux_t)0,  0 },
+        { GPIO_PIN(PA, 7), GPIO_MUX_E, 1 }, /* ~9 */
+    }},
+#endif
+#if PWM_1_EN
+    {TCC2, {
+        /* GPIO pin, MUX value, TCC channel */
+        { GPIO_PIN(PA, 16), GPIO_MUX_E, 0 }, /* ~11 */
+        { GPIO_UNDEF, (gpio_mux_t)0, 1 },
+    }},
+#endif
+};
+
+/* number of devices that are actually defined */
+#define PWM_NUMOF           (2U)
+/** @} */
+
+/**
+ * @name    ADC configuration
+ * @{
+ */
+#define ADC_0_EN                           1
+#define ADC_MAX_CHANNELS                   14
+/* ADC 0 device configuration */
+#define ADC_0_DEV                          ADC
+#define ADC_0_IRQ                          ADC_IRQn
+
+/* ADC 0 Default values */
+#define ADC_0_CLK_SOURCE                   0 /* GCLK_GENERATOR_0 */
+#define ADC_0_PRESCALER                    ADC_CTRLB_PRESCALER_DIV512
+
+#define ADC_0_NEG_INPUT                    ADC_INPUTCTRL_MUXNEG_GND
+#define ADC_0_GAIN_FACTOR_DEFAULT          ADC_INPUTCTRL_GAIN_1X
+#define ADC_0_REF_DEFAULT                  ADC_REFCTRL_REFSEL_INT1V
+
+static const adc_conf_chan_t adc_channels[] = {
+    /* port, pin, muxpos */
+    { GPIO_PIN(PA, 2), ADC_INPUTCTRL_MUXPOS_PIN0 },     /* A0 */
+    { GPIO_PIN(PB, 8), ADC_INPUTCTRL_MUXPOS_PIN2 },     /* A1 */
+    { GPIO_PIN(PB, 9), ADC_INPUTCTRL_MUXPOS_PIN3 },     /* A2 */
+    { GPIO_PIN(PA, 4), ADC_INPUTCTRL_MUXPOS_PIN4 },     /* A3 */
+    { GPIO_PIN(PA, 5), ADC_INPUTCTRL_MUXPOS_PIN5 },     /* A4 */
+    { GPIO_PIN(PB, 2), ADC_INPUTCTRL_MUXPOS_PIN10 },    /* A5 */
+};
+
+#define ADC_0_CHANNELS                     (6U)
+#define ADC_NUMOF                          ADC_0_CHANNELS
+/** @} */
+
+/**
+ * @name    SPI configuration
+ * @{
+ */
+static const spi_conf_t spi_config[] = {
+    {
+        .dev      = &SERCOM4->SPI,
+        .miso_pin = GPIO_PIN(PA, 12),
+        .mosi_pin = GPIO_PIN(PB, 10),
+        .clk_pin  = GPIO_PIN(PB, 11),
+        .miso_mux = GPIO_MUX_D,
+        .mosi_mux = GPIO_MUX_D,
+        .clk_mux  = GPIO_MUX_D,
+        .miso_pad = SPI_PAD_MISO_0,
+        .mosi_pad = SPI_PAD_MOSI_2_SCK_3
+    }
+};
+
+#define SPI_NUMOF           (sizeof(spi_config) / sizeof(spi_config[0]))
+/** @} */
+
+/**
+ * @name    I2C configuration
+ * @{
+ */
+#define I2C_NUMOF           (1U)
+#define I2C_0_EN            1
+#define I2C_1_EN            0
+#define I2C_2_EN            0
+#define I2C_3_EN            0
+#define I2C_IRQ_PRIO        1
+
+#define I2C_0_DEV           SERCOM3->I2CM
+#define I2C_0_IRQ           SERCOM3_IRQn
+#define I2C_0_ISR           isr_sercom3
+/* I2C 0 GCLK */
+#define I2C_0_GCLK_ID       SERCOM3_GCLK_ID_CORE
+#define I2C_0_GCLK_ID_SLOW  SERCOM3_GCLK_ID_SLOW
+/* I2C 0 pin configuration */
+#define I2C_0_SDA           GPIO_PIN(PA, 22) /* SDA pin */
+#define I2C_0_SCL           GPIO_PIN(PA, 23) /* SCL pin */
+#define I2C_0_MUX           GPIO_MUX_C
+/** @} */
+
+/**
+ * @name    RTC configuration
+ * @{
+ */
+#define RTC_NUMOF           (1U)
+#define RTC_DEV             RTC->MODE2
+/** @} */
+
+/**
+ * @name    RTT configuration
+ * @{
+ */
+#define RTT_NUMOF           (1U)
+#define RTT_DEV             RTC->MODE0
+#define RTT_IRQ             RTC_IRQn
+#define RTT_IRQ_PRIO        10
+#define RTT_ISR             isr_rtc
+#define RTT_MAX_VALUE       (0xffffffff)
+#define RTT_FREQUENCY       (32768U)    /* in Hz. For changes see `rtt.c` */
+#define RTT_RUNSTDBY        (1)         /* Keep RTT running in sleep states */
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PERIPH_CONF_H */
+/** @} */
diff --git a/boards/feather-m0/include/sdcard_spi_params.h b/boards/feather-m0/include/sdcard_spi_params.h
new file mode 100644
index 0000000000..9d057fdca8
--- /dev/null
+++ b/boards/feather-m0/include/sdcard_spi_params.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 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_feather-m0
+ * @{
+ *
+ * @file
+ * @brief       SD card configuration for the Adafruit Feather M0 Adalogger
+ *
+ * @author      Alexandre Abadie <alexandre.abadie@inria.fr>
+ */
+
+#ifndef SDCARD_SPI_PARAMS_H
+#define SDCARD_SPI_PARAMS_H
+
+#include "board.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   Card detect pin
+ */
+ #define CARD_DETECT_PIN              (GPIO_PIN(PA, 21))
+
+/**
+ * @brief   sdcard_spi configuration
+ */
+static const  sdcard_spi_params_t sdcard_spi_params[] = {
+    {
+        .spi_dev        = SPI_DEV(0),
+        .cs             = GPIO_PIN(PA, 8),
+        .clk            = GPIO_PIN(PB, 11),
+        .mosi           = GPIO_PIN(PB, 10),
+        .miso           = GPIO_PIN(PA, 12),
+        .power          = GPIO_UNDEF,
+        .power_act_high = true
+    },
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDCARD_SPI_PARAMS_H */
+/** @} */
-- 
GitLab