diff --git a/boards/common/silabs/Makefile b/boards/common/silabs/Makefile new file mode 100644 index 0000000000..dd0591967c --- /dev/null +++ b/boards/common/silabs/Makefile @@ -0,0 +1,15 @@ +MODULE = boards_common_silabs + +ifneq (,$(filter silabs_aem,$(USEMODULE))) + DIRS += drivers/aem +endif + +ifneq (,$(filter silabs_bc,$(USEMODULE))) + DIRS += drivers/bc +endif + +ifneq (,$(filter silabs_pic,$(USEMODULE))) + DIRS += drivers/pic +endif + +include $(RIOTBASE)/Makefile.base diff --git a/boards/common/silabs/Makefile.dep b/boards/common/silabs/Makefile.dep new file mode 100644 index 0000000000..1bedf26010 --- /dev/null +++ b/boards/common/silabs/Makefile.dep @@ -0,0 +1,3 @@ +ifneq (,$(filter silabs_pic,$(USEMODULE))) + USEMODULE += periph_i2c +endif diff --git a/boards/common/silabs/Makefile.include b/boards/common/silabs/Makefile.include new file mode 100644 index 0000000000..f62e5fec7f --- /dev/null +++ b/boards/common/silabs/Makefile.include @@ -0,0 +1,2 @@ +export INCLUDES += -I$(RIOTBOARD)/common/silabs/include +export INCLUDES += -I$(RIOTBOARD)/common/silabs/drivers/include diff --git a/boards/common/silabs/board_common.c b/boards/common/silabs/board_common.c new file mode 100644 index 0000000000..94864a9848 --- /dev/null +++ b/boards/common/silabs/board_common.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2018 Bas Stottelaar + * + * 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_common_silabs + * @{ + * + * @file + * @brief Implementations of the common board features. + * + * @author Bas Stottelaar + * + * @} + */ + +#include "board_common.h" + +#include "aem.h" +#include "bc.h" +#include "pic.h" + +void board_common_init(void) +{ + /* initialize the advanced energy monitor */ +#ifdef MODULE_SILABS_AEM + aem_init(); +#endif + + /* initialize the board controller (to enable serial output) */ +#ifdef MODULE_SILABS_BC + bc_init(); +#endif + + /* initialize the LEDs */ + gpio_init(LED0_PIN, GPIO_OUT); + gpio_init(LED1_PIN, GPIO_OUT); + + /* initialize the push buttons */ + gpio_init(PB0_PIN, GPIO_IN); + gpio_init(PB1_PIN, GPIO_IN); + + /* enable power and interrupt controller (for sensors) */ +#ifdef MODULE_SILABS_PIC + pic_init(); +#endif +} diff --git a/boards/common/silabs/doc.txt b/boards/common/silabs/doc.txt new file mode 100644 index 0000000000..68517c8353 --- /dev/null +++ b/boards/common/silabs/doc.txt @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2018 Bas Stottelaar + * + * 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_common_silabs Silicon Labs Common + * @ingroup boards_common + * @brief Shared files and configuration for the Silicon Labs boards. + */ diff --git a/boards/common/silabs/drivers/aem/Makefile b/boards/common/silabs/drivers/aem/Makefile new file mode 100644 index 0000000000..280864279c --- /dev/null +++ b/boards/common/silabs/drivers/aem/Makefile @@ -0,0 +1,7 @@ +MODULE = silabs_aem + +ifeq ($(CPU_ARCH),cortex-m0plus) + $(error AEM is not available for the Cortex M0+) +endif + +include $(RIOTBASE)/Makefile.base diff --git a/boards/common/silabs/drivers/aem/aem.c b/boards/common/silabs/drivers/aem/aem.c new file mode 100644 index 0000000000..e823c9e775 --- /dev/null +++ b/boards/common/silabs/drivers/aem/aem.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2018 Bas Stottelaar + * + * 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_common_silabs_drivers_aem + * @{ + * + * @file + * @brief Implementations of the advanced energy monitor driver. + * + * @author Bas Stottelaar + * + * @} + */ + +#include "aem.h" + +#include "em_dbg.h" +#include "em_gpio.h" + +void aem_init(void) +{ + /* do not initialize if debugger is not connected */ + if (!DBG_Connected()) { + return; + } + + /* enable GPIO clock for configuring SWO pins */ + CMU_ClockEnable(cmuClock_HFPER, true); + CMU_ClockEnable(cmuClock_GPIO, true); + + /* enable debug peripheral via SWO */ +#ifdef _SILICON_LABS_32B_SERIES_0 + DBG_SWOEnable(GPIO_ROUTE_SWLOCATION_LOC0); +#else + DBG_SWOEnable(GPIO_ROUTELOC0_SWVLOC_LOC0); +#endif + + /* enable trace in core debug */ + CoreDebug->DHCSR |= CoreDebug_DHCSR_C_DEBUGEN_Msk; + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + + /* enable PC and IRQ sampling output */ + DWT->CTRL = AEM_DWT_CTRL; + + /* set TPIU prescaler to 16 */ + TPI->ACPR = AEM_TPI_ACPR; + + /* set protocol to NRZ */ + TPI->SPPR = AEM_TPI_SPPR; + + /* disable continuous formatting */ + TPI->FFCR = AEM_TPI_FFCR; + + /* unlock ITM and output data */ + ITM->LAR = AEM_ITM_LAR; + ITM->TCR = AEM_ITM_TCR; +} diff --git a/boards/common/silabs/drivers/bc/Makefile b/boards/common/silabs/drivers/bc/Makefile new file mode 100644 index 0000000000..25989670ff --- /dev/null +++ b/boards/common/silabs/drivers/bc/Makefile @@ -0,0 +1,3 @@ +MODULE = silabs_bc + +include $(RIOTBASE)/Makefile.base diff --git a/boards/common/silabs/drivers/bc/bc.c b/boards/common/silabs/drivers/bc/bc.c new file mode 100644 index 0000000000..9deddb211f --- /dev/null +++ b/boards/common/silabs/drivers/bc/bc.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2018 Bas Stottelaar + * + * 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_common_silabs_drivers_bc + * @{ + * + * @file + * @brief Implementations of the board controller driver. + * + * @author Bas Stottelaar + * + * @} + */ + +#include "bc.h" + +#include "uart_stdio.h" + +#include "periph/gpio.h" +#include "periph/uart.h" + +/** + * @brief Ensure that the BC_PIN is defined + */ +#ifndef BC_PIN +#error "BC_PIN is not defined by the board." +#endif + +/** + * @brief Ensure that the correct UART is used. + */ +#if ((UART_STDIO_DEV) != (UART_DEV(0))) +#error "The BC requires UART_DEV(0)." +#endif + +/** + * @brief Ensure that the correct baud rate is used. + */ +#if ((UART_STDIO_BAUDRATE) != 115200) +#error "The BC requires a baud rate of 115200." +#endif + +void bc_init(void) +{ + gpio_init(BC_PIN, GPIO_OUT); + gpio_set(BC_PIN); +} diff --git a/boards/common/silabs/drivers/doc.txt b/boards/common/silabs/drivers/doc.txt new file mode 100644 index 0000000000..9cf91be665 --- /dev/null +++ b/boards/common/silabs/drivers/doc.txt @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2018 Bas Stottelaar + * + * 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_common_silabs_drivers Silicon Labs Common Drivers + * @ingroup boards_common_silabs + * @brief Silicon Labs board specific drivers + * + * This module contains drivers specific for the Silicon Labs development + * boards. + */ diff --git a/boards/common/silabs/drivers/include/aem.h b/boards/common/silabs/drivers/include/aem.h new file mode 100644 index 0000000000..77d6fcdd45 --- /dev/null +++ b/boards/common/silabs/drivers/include/aem.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2018 Bas Stottelaar + * + * 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_common_silabs_drivers_aem Advanced energy monitor driver + * @ingroup boards_common_silabs_drivers + * @{ + * + * @file + * @brief Implementations of the advanced energy monitor driver. + * + * @author Bas Stottelaar + */ + +#ifndef AEM_H +#define AEM_H + +#include "board.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief AEM specific values for the Data Watchpoint and Trace (DWT). + */ +#define AEM_DWT_CTRL (0x400113FF) + +/** + * @name AEM specific values for theTrace Port Interface Unit (TPIU). + * @{ + */ +#define AEM_TPI_ACPR (0xf) +#define AEM_TPI_SPPR (0x2) +#define AEM_TPI_FFCR (0x100) +/** @} */ + +/** + * @name AEM specific values for the Instrumentation Trace Microcel (ITM). + * @{ + */ +#define AEM_ITM_LAR (0xc5acce55) +#define AEM_ITM_TCR (0x10009) +/** @} */ + +/** + * @brief Initialize the advanced energy monitor. + * + * This must be performed as one of the first initializations, to provide + * output as soon as possible. + */ +void aem_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* AEM_H */ +/** @} */ diff --git a/boards/common/silabs/drivers/include/bc.h b/boards/common/silabs/drivers/include/bc.h new file mode 100644 index 0000000000..8dcce24353 --- /dev/null +++ b/boards/common/silabs/drivers/include/bc.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2018 Bas Stottelaar + * + * 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_common_silabs_drivers_bc Board communication controller + * @ingroup boards_common_silabs_drivers + * @{ + * + * @file + * @brief Implementations of the board controller driver. + * + * @author Bas Stottelaar + */ + +#ifndef BC_H +#define BC_H + +#include "board.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the board controller. + * + * The following values must be defined: + * + * - BC_PIN + */ +void bc_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BC_H */ +/** @} */ diff --git a/boards/common/silabs/drivers/include/pic.h b/boards/common/silabs/drivers/include/pic.h new file mode 100644 index 0000000000..17d8a5737d --- /dev/null +++ b/boards/common/silabs/drivers/include/pic.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2018 Bas Stottelaar + * + * 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_common_silabs_drivers_pic Power-and-interrupt driver + * @ingroup boards_common_silabs_drivers + * @{ + * + * @file + * @brief Implementations of the power-and-interrupt controller. + * + * @author Bas Stottelaar + */ + +#ifndef PIC_H +#define PIC_H + +#include "board.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the power-and-interrupt controller. + * + * The following values must be defined: + * + * - PIC_INT_WAKE_PIN + * - PIC_I2C + * - PIC_I2C_ADDR + */ +void pic_init(void); + +/** + * @brief Write data to the power-and-interrupt controller. + * + * @param[in] addr Address of the peripheral to write to. + * @param[in] value Value to write. + */ +void pic_write(uint8_t addr, uint8_t value); + +#ifdef __cplusplus +} +#endif + +#endif /* PIC_H */ +/** @} */ diff --git a/boards/common/silabs/drivers/pic/Makefile b/boards/common/silabs/drivers/pic/Makefile new file mode 100644 index 0000000000..ecddcff597 --- /dev/null +++ b/boards/common/silabs/drivers/pic/Makefile @@ -0,0 +1,3 @@ +MODULE = silabs_pic + +include $(RIOTBASE)/Makefile.base diff --git a/boards/common/silabs/drivers/pic/pic.c b/boards/common/silabs/drivers/pic/pic.c new file mode 100644 index 0000000000..2d4fb58b77 --- /dev/null +++ b/boards/common/silabs/drivers/pic/pic.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2018 Bas Stottelaar + * + * 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_common_silabs_drivers_pic + * @{ + * + * @file + * @brief Implementations of the power-and-interrupt controller. + * + * @author Bas Stottelaar + * + * @} + */ + +#include "pic.h" + +#include "periph/gpio.h" +#include "periph/i2c.h" + +/** + * @brief Ensure the interrupt wake pin is defined. + */ +#ifndef PIC_INT_WAKE_PIN +#error "PIC_I2C_WAKE_PIN is not defined by the board." +#endif + +/** + * @brief Ensure the PIC I2C device is defined. + */ +#ifndef PIC_I2C +#error "PIC_I2C is not defined by the board." +#endif + +/** + * @brief Ensure the I2C address of the PIC is defined. + */ +#ifndef PIC_I2C_ADDR +#error "PIC_I2C_ADDR is not defined by the board." +#endif + +/** + * @brief Microsecond sleep method, which does not rely on xtimer. + * + * @param[in] delay Amount of microseconds to delay. + */ +static inline void _usleep(uint32_t delay) +{ + /* decrement + compare take two cycles, therefore divide by two */ + uint32_t count = (delay * (SystemCoreClock / 1000 / 1000)) / 2; + + while (count--) {} +} + +void pic_init(void) +{ + gpio_init(PIC_INT_WAKE_PIN, GPIO_OD); + gpio_set(PIC_INT_WAKE_PIN); + + i2c_init_master(PIC_I2C, I2C_SPEED_NORMAL); +} + +void pic_write(uint8_t addr, uint8_t value) +{ + /* toggle the pin for 4 us */ + gpio_clear(PIC_INT_WAKE_PIN); + _usleep(4); + + /* write to gpio expander */ + i2c_acquire(PIC_I2C); + uint8_t bytes[] = { addr, value }; + i2c_write_bytes(PIC_I2C, PIC_I2C_ADDR, bytes, 2); + i2c_release(PIC_I2C); + + /* put PIC in sleep mode again */ + gpio_set(PIC_INT_WAKE_PIN); +} diff --git a/boards/common/silabs/include/board_common.h b/boards/common/silabs/include/board_common.h new file mode 100644 index 0000000000..42a30e9749 --- /dev/null +++ b/boards/common/silabs/include/board_common.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2018 Bas Stottelaar + * + * 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_common_silabs + * + * @{ + * + * @file + * @brief Common board definitions for the Silicon Labs developtment + * boards. + * + * @author Bas Stottelaar + */ + +#ifndef BOARD_COMMON_H +#define BOARD_COMMON_H + +#include "board.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize common board features. + * + * It currently initializes (if available) the AEM, BC, LEDs and PIC. + */ +void board_common_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_COMMON_H */ +/** @} */