From 2d53178cc5b8a1d4779fc1c06f530ebc3545f1fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= <joakim.nohlgard@eistec.se>
Date: Mon, 1 May 2017 15:40:12 +0200
Subject: [PATCH] boards/frdm-kw41z: Add NXP FRDM-KW41Z

https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/kinetis-cortex-m-mcus/w-serieswireless-conn.m0-plus-m4/freedom-development-kit-for-kinetis-kw41z-31z-21z-mcus:FRDM-KW41Z
---
 boards/frdm-kw41z/Makefile              |   3 +
 boards/frdm-kw41z/Makefile.dep          |   6 +
 boards/frdm-kw41z/Makefile.features     |  15 ++
 boards/frdm-kw41z/Makefile.include      |  13 +
 boards/frdm-kw41z/board.c               |  44 ++++
 boards/frdm-kw41z/include/adc_params.h  |  81 +++++++
 boards/frdm-kw41z/include/board.h       |  99 ++++++++
 boards/frdm-kw41z/include/gpio_params.h |  80 +++++++
 boards/frdm-kw41z/include/periph_conf.h | 306 ++++++++++++++++++++++++
 tests/unittests/Makefile                |   1 +
 10 files changed, 648 insertions(+)
 create mode 100644 boards/frdm-kw41z/Makefile
 create mode 100644 boards/frdm-kw41z/Makefile.dep
 create mode 100644 boards/frdm-kw41z/Makefile.features
 create mode 100644 boards/frdm-kw41z/Makefile.include
 create mode 100644 boards/frdm-kw41z/board.c
 create mode 100644 boards/frdm-kw41z/include/adc_params.h
 create mode 100644 boards/frdm-kw41z/include/board.h
 create mode 100644 boards/frdm-kw41z/include/gpio_params.h
 create mode 100644 boards/frdm-kw41z/include/periph_conf.h

diff --git a/boards/frdm-kw41z/Makefile b/boards/frdm-kw41z/Makefile
new file mode 100644
index 0000000000..f8fcbb53a0
--- /dev/null
+++ b/boards/frdm-kw41z/Makefile
@@ -0,0 +1,3 @@
+MODULE = board
+
+include $(RIOTBASE)/Makefile.base
diff --git a/boards/frdm-kw41z/Makefile.dep b/boards/frdm-kw41z/Makefile.dep
new file mode 100644
index 0000000000..a73981801a
--- /dev/null
+++ b/boards/frdm-kw41z/Makefile.dep
@@ -0,0 +1,6 @@
+ifneq (,$(filter saul_default,$(USEMODULE)))
+  USEMODULE += saul_gpio
+  USEMODULE += saul_adc
+endif
+
+include $(RIOTCPU)/kinetis/Makefile.dep
diff --git a/boards/frdm-kw41z/Makefile.features b/boards/frdm-kw41z/Makefile.features
new file mode 100644
index 0000000000..5cc311ad95
--- /dev/null
+++ b/boards/frdm-kw41z/Makefile.features
@@ -0,0 +1,15 @@
+# Put defined MCU peripherals here (in alphabetical order)
+FEATURES_PROVIDED += periph_adc
+FEATURES_PROVIDED += periph_i2c
+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)/kinetis/Makefile.features
+# Remove this line after TRNG driver is implemented
+FEATURES_PROVIDED := $(filter-out periph_hwrng,$(FEATURES_PROVIDED))
diff --git a/boards/frdm-kw41z/Makefile.include b/boards/frdm-kw41z/Makefile.include
new file mode 100644
index 0000000000..730c8887d3
--- /dev/null
+++ b/boards/frdm-kw41z/Makefile.include
@@ -0,0 +1,13 @@
+# define the cpu used by the board
+export CPU = kinetis
+export CPU_MODEL = mkw41z512vht4
+
+# OpenOCD v0.10.0-dev (current development version) or later is required for
+# flashing KW41Z devices
+# See http://openocd.zylin.com/#/c/4104/ for the upstreaming process
+export USE_OLD_OPENOCD ?= 0
+# This board comes with OpenSDA configured for JLink compatibility
+export DEBUG_ADAPTER ?= jlink
+
+# Include default FRDM board config
+include $(RIOTBOARD)/common/frdm/Makefile.include
diff --git a/boards/frdm-kw41z/board.c b/boards/frdm-kw41z/board.c
new file mode 100644
index 0000000000..31153834be
--- /dev/null
+++ b/boards/frdm-kw41z/board.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 Eistec AB
+ *
+ * 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_frdm-kw41z
+ * @{
+ *
+ * @file
+ * @brief       Board specific initialization for the FRDM-KW41Z
+ *
+ * @author      Joakim Nohlgård <joakim.nohlgard@eistec.se>
+ *
+ * @}
+ */
+
+#include "board.h"
+#include "periph/gpio.h"
+#include "periph/rtt.h"
+
+void board_init(void)
+{
+    /* initialize the CPU core */
+    cpu_init();
+
+#if MODULE_XTIMER && !(KINETIS_XTIMER_SOURCE_PIT)
+    /* Start the RTT, used as time base for xtimer when using LPTMR backend */
+    rtt_init();
+#endif
+
+    /* initialize and turn off LEDs */
+    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);
+    gpio_init(LED3_PIN, GPIO_OUT);
+    gpio_set(LED3_PIN);
+}
diff --git a/boards/frdm-kw41z/include/adc_params.h b/boards/frdm-kw41z/include/adc_params.h
new file mode 100644
index 0000000000..0c4a109e2e
--- /dev/null
+++ b/boards/frdm-kw41z/include/adc_params.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2017 Eistec AB
+ *
+ * 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_frdm_kw41z
+ * @{
+ *
+ * @file
+ * @brief     Board specific configuration of direct mapped ADC
+ *
+ * @author    Joakim Nohlgård <joakim.nohlgard@eistec.se>
+ */
+
+#ifndef ADC_PARAMS_H
+#define ADC_PARAMS_H
+
+#include "board.h"
+#include "saul/periph.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief    ADC configuration
+ */
+static const  saul_adc_params_t saul_adc_params[] =
+{
+    {
+        .name = "coretemp",
+        .line = ADC_LINE(0),
+        .res  = ADC_RES_16BIT,
+    },
+    {
+        .name = "corebandgap",
+        .line = ADC_LINE(1),
+        .res  = ADC_RES_16BIT,
+    },
+    {
+        .name = "corevrefh",
+        .line = ADC_LINE(2),
+        .res  = ADC_RES_16BIT,
+    },
+    {
+        .name = "corevrefl",
+        .line = ADC_LINE(3),
+        .res  = ADC_RES_16BIT,
+    },
+    {
+        .name = "dcdcvbat",
+        .line = ADC_LINE(4),
+        .res  = ADC_RES_16BIT,
+    },
+    {
+        .name = "ADC0_DP-DM",
+        .line = ADC_LINE(5),
+        .res  = ADC_RES_16BIT,
+    },
+    {
+        .name = "ADC0_SE2",
+        .line = ADC_LINE(6),
+        .res  = ADC_RES_16BIT,
+    },
+    {
+        .name = "ADC0_SE3",
+        .line = ADC_LINE(7),
+        .res  = ADC_RES_16BIT,
+    },
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ADC_PARAMS_H */
+/** @} */
diff --git a/boards/frdm-kw41z/include/board.h b/boards/frdm-kw41z/include/board.h
new file mode 100644
index 0000000000..b15907b6c3
--- /dev/null
+++ b/boards/frdm-kw41z/include/board.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 Eistec AB
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup    boards_frdm-kw41z Freescale FRDM-KW41Z Board
+ * @ingroup     boards
+ * @brief       Board specific implementations for the FRDM-KW41Z
+ * @{
+ *
+ * @file
+ * @brief       Board specific definitions for the FRDM-KW41Z
+ *
+ * @author      Joakim Nohlgård <joakim.nohlgard@eistec.se>
+ */
+
+#ifndef BOARD_H
+#define BOARD_H
+
+#include "cpu.h"
+#include "periph_conf.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @name    LED pin definitions and handlers
+ * @{
+ */
+#define LED0_PIN            GPIO_PIN(PORT_B,  0)
+#define LED0_MASK           (1 << 0)
+#define LED0_ON             (GPIOB->PCOR = LED0_MASK)
+#define LED0_OFF            (GPIOB->PSOR = LED0_MASK)
+#define LED0_TOGGLE         (GPIOB->PTOR = LED0_MASK)
+#define LED1_PIN            GPIO_PIN(PORT_C,  1)
+#define LED1_MASK           (1 << 1)
+#define LED1_ON             (GPIOC->PCOR = LED1_MASK)
+#define LED1_OFF            (GPIOC->PSOR = LED1_MASK)
+#define LED1_TOGGLE         (GPIOC->PTOR = LED1_MASK)
+#define LED2_PIN            GPIO_PIN(PORT_A, 19)
+#define LED2_MASK           (1 << 19)
+#define LED2_ON             (GPIOA->PCOR = LED2_MASK)
+#define LED2_OFF            (GPIOA->PSOR = LED2_MASK)
+#define LED2_TOGGLE         (GPIOA->PTOR = LED2_MASK)
+#define LED3_PIN            GPIO_PIN(PORT_A, 18)
+#define LED3_MASK           (1 << 18)
+#define LED3_ON             (GPIOA->PCOR = LED3_MASK)
+#define LED3_OFF            (GPIOA->PSOR = LED3_MASK)
+#define LED3_TOGGLE         (GPIOA->PTOR = LED3_MASK)
+/** @} */
+
+/**
+ * @name    xtimer configuration
+ * @{
+ */
+#if KINETIS_XTIMER_SOURCE_PIT
+/* PIT xtimer configuration */
+#define XTIMER_DEV                  (TIMER_PIT_DEV(0))
+#define XTIMER_CHAN                 (0)
+/* Default xtimer settings should work on the PIT */
+#else
+/* LPTMR xtimer configuration */
+#define XTIMER_DEV                  (TIMER_LPTMR_DEV(0))
+#define XTIMER_CHAN                 (0)
+/* LPTMR is 16 bits wide and runs at 32768 Hz (clocked by the RTC) */
+#define XTIMER_WIDTH                (16)
+#define XTIMER_BACKOFF              (5)
+#define XTIMER_ISR_BACKOFF          (5)
+#define XTIMER_OVERHEAD             (4)
+#define XTIMER_HZ                   (32768ul)
+#endif
+/** @} */
+
+/**
+ * @name    NOR flash hardware configuration
+ * @{
+ */
+#define FRDM_NOR_SPI_DEV               SPI_DEV(0)
+#define FRDM_NOR_SPI_CLK               SPI_CLK_5MHZ
+#define FRDM_NOR_SPI_CS                SPI_HWCS(0) /**< Flash CS pin */
+/** @} */
+
+/**
+ * @brief   Initialize board specific hardware, including clock, LEDs and standard I/O
+ */
+void board_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BOARD_H */
+/** @} */
diff --git a/boards/frdm-kw41z/include/gpio_params.h b/boards/frdm-kw41z/include/gpio_params.h
new file mode 100644
index 0000000000..b5c717cd6c
--- /dev/null
+++ b/boards/frdm-kw41z/include/gpio_params.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2017 SKF AB
+ *
+ * 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_frdm_kw41z
+ * @{
+ *
+ * @file
+ * @brief     Board specific configuration of direct mapped GPIOs
+ *
+ * @author    Joakim Nohlgård <joakim.nohlgard@eistec.se>
+ */
+
+#ifndef GPIO_PARAMS_H
+#define GPIO_PARAMS_H
+
+#include "board.h"
+#include "saul/periph.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief    LED configuration
+ */
+static const  saul_gpio_params_t saul_gpio_params[] =
+{
+    /* These LEDs are marked on the board silkscreen with "LED3" for the red LED,
+     * and "LED4" for the RGB LED, hence the names for the SAUL actuators don't
+     * match the LEDx_PIN macros in board.h */
+    /* LED1 and LED2 on the board are wired to the target CPU reset pin, and the
+     * power supply line and are not software controllable */
+    {
+        .name = "LED3",
+        .pin = LED0_PIN,
+        .mode = GPIO_OUT,
+        .flags = (SAUL_GPIO_INVERTED | SAUL_GPIO_INIT_CLEAR),
+    },
+    {
+        .name = "LED4_R",
+        .pin = LED1_PIN,
+        .mode = GPIO_OUT,
+        .flags = (SAUL_GPIO_INVERTED | SAUL_GPIO_INIT_CLEAR),
+    },
+    {
+        .name = "LED4_G",
+        .pin = LED2_PIN,
+        .mode = GPIO_OUT,
+        .flags = (SAUL_GPIO_INVERTED | SAUL_GPIO_INIT_CLEAR),
+    },
+    {
+        .name = "LED4_B",
+        .pin = LED3_PIN,
+        .mode = GPIO_OUT,
+        .flags = (SAUL_GPIO_INVERTED | SAUL_GPIO_INIT_CLEAR),
+    },
+    {
+        .name = "SW3",
+        .pin = GPIO_PIN(PORT_C, 4),
+        .mode = GPIO_IN_PU
+    },
+    {
+        .name = "SW4",
+        .pin = GPIO_PIN(PORT_C, 5),
+        .mode = GPIO_IN_PU
+    },
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GPIO_PARAMS_H */
+/** @} */
diff --git a/boards/frdm-kw41z/include/periph_conf.h b/boards/frdm-kw41z/include/periph_conf.h
new file mode 100644
index 0000000000..a021cef6de
--- /dev/null
+++ b/boards/frdm-kw41z/include/periph_conf.h
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2017 Eistec AB
+ *
+ * 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_frdm-kw41z
+ * @{
+ *
+ * @file
+ * @name        Peripheral MCU configuration for the FRDM-KW41Z
+ *
+ * @author      Joakim Nohlgård <joakim.nohlgard@eistec.se>
+ */
+
+#ifndef PERIPH_CONF_H
+#define PERIPH_CONF_H
+
+#include "periph_cpu.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @name Clock system configuration
+ * @{
+ */
+static const clock_config_t clock_config = {
+    /*
+     * This configuration results in the system running with the internal clock
+     * with the following clock frequencies:
+     * Core:  48 MHz
+     * Bus:   24 MHz
+     * Flash: 24 MHz
+     */
+    .clkdiv1            = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV4(1),
+    /* Using FEI mode by default, the external crystal settings below are only
+     * used if mode is changed to an external mode (PEE, FBE, or FEE) */
+    .default_mode       = KINETIS_MCG_MODE_FEI,
+    /* The crystal connected to RSIM OSC is 32 MHz */
+    .erc_range          = KINETIS_MCG_ERC_RANGE_VERY_HIGH,
+    .fcrdiv             = 0, /* Fast IRC divide by 1 => 4 MHz */
+    .oscsel             = 0, /* Use RSIM for external clock */
+    .clc                = 0, /* no load cap configuration */
+    .fll_frdiv          = 0b101, /* Divide by 1024 */
+    .fll_factor_fei     = KINETIS_MCG_FLL_FACTOR_1464, /* FEI FLL freq = 48 MHz */
+    .fll_factor_fee     = KINETIS_MCG_FLL_FACTOR_1280, /* FEE FLL freq = 40 MHz */
+    .enable_oscillator  = true, /* Use RF module oscillator */
+    .select_fast_irc    = true,
+    .enable_mcgirclk    = true, /* Used for LPUART clocking */
+};
+/* Radio xtal frequency, either 32 MHz or 26 MHz */
+#define CLOCK_RADIOXTAL              (32000000ul)
+/* CPU core clock, the MCG clock output frequency */
+#define CLOCK_CORECLOCK              (48000000ul)
+#define CLOCK_BUSCLOCK               (CLOCK_CORECLOCK / 2)
+#define CLOCK_MCGIRCLK               (4000000ul)
+/** @} */
+
+/**
+ * @name Timer configuration
+ * @{
+ */
+#define PIT_NUMOF               (1U)
+#define PIT_CONFIG {                 \
+        {                            \
+            .prescaler_ch = 0,       \
+            .count_ch = 1,           \
+        },                           \
+    }
+#define LPTMR_NUMOF             (1U)
+#define LPTMR_CONFIG { \
+        { \
+            .dev = LPTMR0, \
+            .irqn = LPTMR0_IRQn, \
+        } \
+    }
+#define TIMER_NUMOF             ((PIT_NUMOF) + (LPTMR_NUMOF))
+#define PIT_BASECLOCK           (CLOCK_BUSCLOCK)
+#define LPTMR_ISR_0             isr_lptmr0
+/** @} */
+
+/**
+ * @name UART configuration
+ * @{
+ */
+static const uart_conf_t uart_config[] = {
+    {
+        .dev    = LPUART0,
+        .freq   = CLOCK_MCGIRCLK,
+        .pin_rx = GPIO_PIN(PORT_C,  6),
+        .pin_tx = GPIO_PIN(PORT_C,  7),
+        .pcr_rx = PORT_PCR_MUX(4),
+        .pcr_tx = PORT_PCR_MUX(4),
+        .irqn   = LPUART0_IRQn,
+        .scgc_addr = &SIM->SCGC5,
+        .scgc_bit = SIM_SCGC5_LPUART0_SHIFT,
+        .mode   = UART_MODE_8N1,
+        .type   = KINETIS_LPUART,
+    },
+};
+#define UART_NUMOF          (sizeof(uart_config) / sizeof(uart_config[0]))
+#define LPUART_0_ISR        isr_lpuart0
+/* Use MCGIRCLK (internal reference 4 MHz clock) */
+#define LPUART_0_SRC        3
+/** @} */
+
+/**
+ * @name ADC configuration
+ * @{
+ */
+static const adc_conf_t adc_config[] = {
+    /* dev, pin, channel */
+    [ 0] = { ADC0, GPIO_UNDEF, 26 },       /* internal: temperature sensor */
+    /* Note: the band gap buffer uses a bit of current and is turned off by default,
+     * Set PMC->REGSC |= PMC_REGSC_BGBE_MASK before reading or the input will be floating */
+    [ 1] = { ADC0, GPIO_UNDEF, 27 },       /* internal: band gap */
+    [ 2] = { ADC0, GPIO_UNDEF, 29 },       /* internal: V_REFH */
+    [ 3] = { ADC0, GPIO_UNDEF, 30 },       /* internal: V_REFL */
+    [ 4] = { ADC0, GPIO_UNDEF, 23 },       /* internal: DCDC divided battery level */
+    [ 5] = { ADC0, GPIO_UNDEF,  0 | ADC_SC1_DIFF_MASK }, /* ADC0_DP-ADC0_DM differential reading */
+    [ 6] = { ADC0, GPIO_PIN(PORT_B,  3),  2 }, /* ADC0_SE2 */
+    [ 7] = { ADC0, GPIO_PIN(PORT_B,  2),  3 }, /* ADC0_SE3 */
+};
+#define ADC_NUMOF           (sizeof(adc_config) / sizeof(adc_config[0]))
+/*
+ * KW41Z ADC reference settings:
+ * 0: VREFH external pin or VREF_OUT 1.2 V signal (if VREF module is enabled)
+ * 1: VDDA (analog supply input voltage)
+ * 2-3: reserved
+ *
+ * VREF_OUT and VREFH shares the pin on KW41Z and is only connected to a 100 nF
+ * capacitor on the FRDM-KW41Z board. So use VDDA by default on this board
+ * unless the application enables the VREF module.
+ */
+#define ADC_REF_SETTING     1
+/** @} */
+
+/**
+ * @name   SPI configuration
+ *
+ * Clock configuration values based on the configured 16Mhz module clock.
+ *
+ * Auto-generated by:
+ * cpu/kinetis/dist/calc_spi_scalers/calc_spi_scalers.c
+ *
+* @{
+*/
+static const uint32_t spi_clk_config[] = {
+    (
+        SPI_CTAR_PBR(2) | SPI_CTAR_BR(5) |          /* -> 100000Hz */
+        SPI_CTAR_PCSSCK(2) | SPI_CTAR_CSSCK(4) |
+        SPI_CTAR_PASC(2) | SPI_CTAR_ASC(4) |
+        SPI_CTAR_PDT(2) | SPI_CTAR_DT(4)
+    ),
+    (
+        SPI_CTAR_PBR(2) | SPI_CTAR_BR(3) |          /* -> 400000Hz */
+        SPI_CTAR_PCSSCK(2) | SPI_CTAR_CSSCK(2) |
+        SPI_CTAR_PASC(2) | SPI_CTAR_ASC(2) |
+        SPI_CTAR_PDT(2) | SPI_CTAR_DT(2)
+    ),
+    (
+        SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) |          /* -> 1000000Hz */
+        SPI_CTAR_PCSSCK(0) | SPI_CTAR_CSSCK(3) |
+        SPI_CTAR_PASC(0) | SPI_CTAR_ASC(3) |
+        SPI_CTAR_PDT(0) | SPI_CTAR_DT(3)
+    ),
+    (
+        SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) |          /* -> 4000000Hz */
+        SPI_CTAR_PCSSCK(0) | SPI_CTAR_CSSCK(1) |
+        SPI_CTAR_PASC(0) | SPI_CTAR_ASC(1) |
+        SPI_CTAR_PDT(0) | SPI_CTAR_DT(1)
+    ),
+    (
+        SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) |          /* -> 4000000Hz */
+        SPI_CTAR_PCSSCK(0) | SPI_CTAR_CSSCK(0) |
+        SPI_CTAR_PASC(0) | SPI_CTAR_ASC(0) |
+        SPI_CTAR_PDT(0) | SPI_CTAR_DT(0)
+    )
+};
+
+static const spi_conf_t spi_config[] = {
+    {
+        .dev      = SPI0,
+        .pin_miso = GPIO_PIN(PORT_C, 18),
+        .pin_mosi = GPIO_PIN(PORT_C, 17),
+        .pin_clk  = GPIO_PIN(PORT_C, 16),
+        .pin_cs   = {
+            GPIO_PIN(PORT_C, 19),
+            GPIO_UNDEF,
+            GPIO_UNDEF,
+            GPIO_UNDEF,
+            GPIO_UNDEF
+        },
+        .pcr      = GPIO_AF_2,
+        .simmask  = SIM_SCGC6_SPI0_MASK
+    },
+    {
+        .dev      = SPI1,
+        .pin_miso = GPIO_PIN(PORT_A, 17),
+        .pin_mosi = GPIO_PIN(PORT_A, 16),
+        .pin_clk  = GPIO_PIN(PORT_A, 18),
+        .pin_cs   = {
+            GPIO_PIN(PORT_A, 19),
+            GPIO_UNDEF,
+            GPIO_UNDEF,
+            GPIO_UNDEF,
+            GPIO_UNDEF
+        },
+        .pcr      = GPIO_AF_2,
+        .simmask  = SIM_SCGC6_SPI1_MASK
+    }
+};
+#define SPI_NUMOF           (sizeof(spi_config) / sizeof(spi_config[0]))
+/** @} */
+
+
+/**
+* @name I2C configuration
+* @{
+*/
+/* This CPU has I2C0 clocked by the bus clock and I2C1 clocked by the system
+ * clock. This causes trouble with the current implementation in kinetis
+ * which only supports one set of frequency dividers at a time */
+/* The current configuration sets the dividers so that the I2C0 bus will run at
+ * half the requested speed, to avoid exceeding the requested speed on I2C1 with
+ * the same configuration */
+#define I2C_NUMOF                    (2U)
+#define I2C_0_EN                     1
+/* Disabled while waiting for a rewritten i2c driver which supports different
+ * clock sources for each i2c module */
+#define I2C_1_EN                     1
+/* Low (10 kHz): MUL = 2, SCL divider = 1792, total: 3584 */
+#define KINETIS_I2C_F_ICR_LOW        (0x3A)
+#define KINETIS_I2C_F_MULT_LOW       (1)
+/* Normal (100 kHz): MUL = 1, SCL divider = 320, total: 320 */
+#define KINETIS_I2C_F_ICR_NORMAL     (0x25)
+#define KINETIS_I2C_F_MULT_NORMAL    (0)
+/* Fast (400 kHz): MUL = 1, SCL divider = 80, total: 80 */
+#define KINETIS_I2C_F_ICR_FAST       (0x14)
+#define KINETIS_I2C_F_MULT_FAST      (0)
+/* Fast plus (1000 kHz): MUL = 1, SCL divider = 32, total: 32 */
+#define KINETIS_I2C_F_ICR_FAST_PLUS  (0x09)
+#define KINETIS_I2C_F_MULT_FAST_PLUS (0)
+
+/* I2C 0 device configuration */
+#define I2C_0_DEV                    I2C0
+#define I2C_0_CLKEN()                (bit_set32(&SIM->SCGC4, SIM_SCGC4_I2C0_SHIFT))
+#define I2C_0_CLKDIS()               (bit_clear32(&SIM->SCGC4, SIM_SCGC4_I2C0_SHIFT))
+#define I2C_0_IRQ                    I2C0_IRQn
+#define I2C_0_IRQ_HANDLER            isr_i2c0
+/* I2C 0 pin configuration */
+#define I2C_0_PORT                   PORTB
+#define I2C_0_PORT_CLKEN()           (bit_set32(&SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT))
+#define I2C_0_PIN_AF                 3
+#define I2C_0_SDA_PIN                1
+#define I2C_0_SCL_PIN                0
+#define I2C_0_PORT_CFG               (PORT_PCR_MUX(I2C_0_PIN_AF))
+/* I2C 1 device configuration */
+#define I2C_1_DEV                    I2C1
+#define I2C_1_CLKEN()                (bit_set32(&SIM->SCGC4, SIM_SCGC4_I2C1_SHIFT))
+#define I2C_1_CLKDIS()               (bit_clear32(&SIM->SCGC4, SIM_SCGC4_I2C1_SHIFT))
+#define I2C_1_IRQ                    I2C1_IRQn
+#define I2C_1_IRQ_HANDLER            isr_i2c1
+/* I2C 1 pin configuration */
+#define I2C_1_PORT                   PORTC
+#define I2C_1_PORT_CLKEN()           (bit_set32(&SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT))
+#define I2C_1_PIN_AF                 3
+#define I2C_1_SDA_PIN                3
+#define I2C_1_SCL_PIN                2
+#define I2C_1_PORT_CFG               (PORT_PCR_MUX(I2C_0_PIN_AF))
+/** @} */
+
+/**
+* @name RTT and RTC configuration
+* @{
+*/
+#define RTT_NUMOF                    (1U)
+#define RTC_NUMOF                    (1U)
+#define RTT_DEV                      RTC
+#define RTT_IRQ                      RTC_IRQn
+#define RTT_IRQ_PRIO                 10
+#define RTT_UNLOCK()                 (bit_set32(&SIM->SCGC6, SIM_SCGC6_RTC_SHIFT))
+#define RTT_ISR                      isr_rtc
+#define RTT_FREQUENCY                (1)
+#define RTT_MAX_VALUE                (0xffffffff)
+/** @} */
+
+/**
+ * @name Random Number Generator configuration
+ * @{
+ */
+#define KINETIS_TRNG                TRNG
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PERIPH_CONF_H */
+/** @} */
diff --git a/tests/unittests/Makefile b/tests/unittests/Makefile
index 10a7de7d14..5039ea78f5 100644
--- a/tests/unittests/Makefile
+++ b/tests/unittests/Makefile
@@ -99,6 +99,7 @@ ARM_CORTEX_M_BOARDS := airfy-beacon \
                        fox \
                        frdm-k22f \
                        frdm-k64f \
+                       frdm-kw41z \
                        iotlab-a8-m3 \
                        iotlab-m3 \
                        limifrog-v1 \
-- 
GitLab