From 4bfce892d3cbb12fb6c99ee6cc1ef48490c548d3 Mon Sep 17 00:00:00 2001
From: Hauke Petersen <hauke.petersen@fu-berlin.de>
Date: Fri, 20 Jan 2017 11:18:38 +0100
Subject: [PATCH] drivers/periph&cpu: add and use common periph_init()

---
 cpu/atmega1281/cpu.c          |  5 ++--
 cpu/atmega2560/cpu.c          |  5 ++--
 cpu/atmega328p/cpu.c          |  5 ++--
 cpu/cc2538/cpu.c              |  3 +++
 cpu/cc26x0/cpu.c              |  8 ++++--
 cpu/ezr32wg/cpu.c             |  3 +++
 cpu/k60/cpu.c                 |  3 +++
 cpu/k64f/cpu.c                |  3 +++
 cpu/kw2x/cpu.c                |  3 +++
 cpu/lm4f120/cpu.c             |  4 +++
 cpu/lpc11u34/cpu.c            |  3 +++
 cpu/lpc1768/cpu.c             |  3 +++
 cpu/nrf51/cpu.c               |  3 +++
 cpu/nrf52/cpu.c               |  4 +++
 cpu/sam3/cpu.c                |  4 +++
 cpu/samd21/cpu.c              |  1 +
 cpu/saml21/cpu.c              |  4 +++
 cpu/stm32f0/cpu.c             |  3 +++
 cpu/stm32f1/cpu.c             |  3 +++
 cpu/stm32f2/cpu.c             |  3 +++
 cpu/stm32f3/cpu.c             |  3 +++
 cpu/stm32f4/cpu.c             |  3 +++
 cpu/stm32l1/cpu.c             |  3 +++
 drivers/include/periph/init.h | 47 +++++++++++++++++++++++++++++++++++
 drivers/periph_common/init.c  | 31 +++++++++++++++++++++++
 25 files changed, 152 insertions(+), 8 deletions(-)
 create mode 100644 drivers/include/periph/init.h
 create mode 100644 drivers/periph_common/init.c

diff --git a/cpu/atmega1281/cpu.c b/cpu/atmega1281/cpu.c
index 0159ec5b8c..2d184cf544 100644
--- a/cpu/atmega1281/cpu.c
+++ b/cpu/atmega1281/cpu.c
@@ -18,12 +18,13 @@
  */
 
 #include "cpu.h"
+#include "periph/init.h"
 
 /**
  * @brief Initialize the CPU, set IRQ priorities
  */
 void cpu_init(void)
 {
-    /* Right now we need to do nothing here */
-    ;
+    /* trigger static peripheral initialization */
+    periph_init();
 }
diff --git a/cpu/atmega2560/cpu.c b/cpu/atmega2560/cpu.c
index e79c67dc6b..8ea4e28b5f 100644
--- a/cpu/atmega2560/cpu.c
+++ b/cpu/atmega2560/cpu.c
@@ -18,12 +18,13 @@
  */
 
 #include "cpu.h"
+#include "periph/init.h"
 
 /**
  * @brief Initialize the CPU, set IRQ priorities
  */
 void cpu_init(void)
 {
-    /* Right now we need to do nothing here */
-    ;
+    /* trigger static peripheral initialization */
+    periph_init();
 }
diff --git a/cpu/atmega328p/cpu.c b/cpu/atmega328p/cpu.c
index 3de168ab4f..ed865bd42a 100644
--- a/cpu/atmega328p/cpu.c
+++ b/cpu/atmega328p/cpu.c
@@ -18,12 +18,13 @@
  */
 
 #include "cpu.h"
+#include "periph/init.h"
 
 /**
  * @brief Initialize the CPU, set IRQ priorities
  */
 void cpu_init(void)
 {
-    /* Right now we need to do nothing here */
-    ;
+    /* trigger static peripheral initialization */
+    periph_init();
 }
diff --git a/cpu/cc2538/cpu.c b/cpu/cc2538/cpu.c
index 68c7b39e91..60bf9342bf 100644
--- a/cpu/cc2538/cpu.c
+++ b/cpu/cc2538/cpu.c
@@ -20,6 +20,7 @@
 #include <assert.h>
 
 #include "cpu.h"
+#include "periph/init.h"
 
 #define BIT(n)          ( 1UL << (n) )
 
@@ -47,6 +48,8 @@ void cpu_init(void)
     SYS_CTRL->I_MAP = 1;
     /* initialize the clock system */
     cpu_clock_init();
+    /* trigger static peripheral initialization */
+    periph_init();
 }
 
 /**
diff --git a/cpu/cc26x0/cpu.c b/cpu/cc26x0/cpu.c
index 2f4f55ecd2..232bdc343e 100644
--- a/cpu/cc26x0/cpu.c
+++ b/cpu/cc26x0/cpu.c
@@ -17,8 +17,9 @@
  * @}
  */
 
- #include "cpu.h"
- #include "periph_conf.h"
+#include "cpu.h"
+#include "periph_conf.h"
+#include "periph/init.h"
 
 #ifndef HF_CLOCK_SOURCE
 #define HF_CLOCK_SOURCE DDI_0_OSC_CTL0_SCLK_HF_SRC_SEL_RCOSC /* set 48MHz RCOSC */
@@ -42,6 +43,9 @@ void cpu_init(void)
 
     /* initialize the system clock */
     cpu_clock_init();
+
+    /* trigger static peripheral initialization */
+    periph_init();
 }
 
 static void cpu_clock_init(void)
diff --git a/cpu/ezr32wg/cpu.c b/cpu/ezr32wg/cpu.c
index d48dc6e346..afa1927184 100644
--- a/cpu/ezr32wg/cpu.c
+++ b/cpu/ezr32wg/cpu.c
@@ -19,6 +19,7 @@
 
 #include "cpu.h"
 #include "periph_conf.h"
+#include "periph/init.h"
 
 /**
  * @brief   Configure clock sources and the CPU frequency
@@ -59,4 +60,6 @@ void cpu_init(void)
     cortexm_init();
     /* Initialise clock sources and generic clocks */
     clk_init();
+    /* trigger static peripheral initialization */
+    periph_init();
 }
diff --git a/cpu/k60/cpu.c b/cpu/k60/cpu.c
index f25d4056cc..327100e9b1 100644
--- a/cpu/k60/cpu.c
+++ b/cpu/k60/cpu.c
@@ -9,6 +9,7 @@
 #include <stdint.h>
 #include "cpu.h"
 #include "board.h"
+#include "periph/init.h"
 
 /**
  * @ingroup     cpu_k60
@@ -48,6 +49,8 @@ void cpu_init(void)
     cortexm_init();
     /* Check that we are running on the CPU that this code was built for */
     check_running_cpu_revision();
+    /* trigger static peripheral initialization */
+    periph_init();
 }
 
 static void check_running_cpu_revision(void)
diff --git a/cpu/k64f/cpu.c b/cpu/k64f/cpu.c
index 567ce64e42..cfb6583bc6 100644
--- a/cpu/k64f/cpu.c
+++ b/cpu/k64f/cpu.c
@@ -23,6 +23,7 @@
 #include "cpu.h"
 #include "mcg.h"
 #include "cpu_conf.h"
+#include "periph/init.h"
 
 #define SIM_CLKDIV1_60MHZ      (SIM_CLKDIV1_OUTDIV1(0) | \
                                 SIM_CLKDIV1_OUTDIV2(0) | \
@@ -40,6 +41,8 @@ void cpu_init(void)
     cortexm_init();
     /* initialize the clock system */
     cpu_clock_init();
+    /* trigger static peripheral initialization */
+    periph_init();
 }
 
 /**
diff --git a/cpu/kw2x/cpu.c b/cpu/kw2x/cpu.c
index 41f95e6c16..bcbffa75b8 100644
--- a/cpu/kw2x/cpu.c
+++ b/cpu/kw2x/cpu.c
@@ -23,6 +23,7 @@
 #include "cpu.h"
 #include "mcg.h"
 #include "cpu_conf.h"
+#include "periph/init.h"
 
 #define FLASH_BASE          (0x00000000)
 
@@ -37,6 +38,8 @@ void cpu_init(void)
     cortexm_init();
     /* initialize the clock system */
     cpu_clock_init();
+    /* trigger static peripheral initialization */
+    periph_init();
 }
 
 static inline void modem_clock_init(void)
diff --git a/cpu/lm4f120/cpu.c b/cpu/lm4f120/cpu.c
index 05ffbdaa11..a4b1598381 100644
--- a/cpu/lm4f120/cpu.c
+++ b/cpu/lm4f120/cpu.c
@@ -23,6 +23,7 @@
 #include "thread.h"
 #include "arch/thread_arch.h"
 #include "arch/irq_arch.h"
+#include "periph/init.h"
 
 /**
  * @brief Initialize the CPU, set IRQ priorities
@@ -34,6 +35,9 @@ void cpu_init(void)
 
     /* initialize the clock system */
     cpu_clock_init(CLOCK_SOURCE);
+
+    /* trigger static peripheral initialization */
+    periph_init();
 }
 
 void setup_fpu(void)
diff --git a/cpu/lpc11u34/cpu.c b/cpu/lpc11u34/cpu.c
index a41832e254..561aefd2bb 100644
--- a/cpu/lpc11u34/cpu.c
+++ b/cpu/lpc11u34/cpu.c
@@ -18,6 +18,7 @@
  */
 
 #include "cpu.h"
+#include "periph/init.h"
 
 
 #define SYSOSCCTRL_Val    0x00000000 /* Reset: 0x000 */
@@ -111,4 +112,6 @@ void cpu_init(void)
     cortexm_init();
     /* initialize the clock */
     clk_init();
+    /* trigger static peripheral initialization */
+    periph_init();
 }
diff --git a/cpu/lpc1768/cpu.c b/cpu/lpc1768/cpu.c
index 69b856f611..9018d8b756 100644
--- a/cpu/lpc1768/cpu.c
+++ b/cpu/lpc1768/cpu.c
@@ -18,6 +18,7 @@
  */
 
 #include "cpu.h"
+#include "periph/init.h"
 
 /**
  * @brief Initialize the CPU, set IRQ priorities
@@ -26,4 +27,6 @@ void cpu_init(void)
 {
     /* initialize the Cortex-M core */
     cortexm_init();
+    /* trigger static peripheral initialization */
+    periph_init();
 }
diff --git a/cpu/nrf51/cpu.c b/cpu/nrf51/cpu.c
index 1d00dc7a40..db19c2681a 100644
--- a/cpu/nrf51/cpu.c
+++ b/cpu/nrf51/cpu.c
@@ -19,6 +19,7 @@
 
 #include "cpu.h"
 #include "periph_conf.h"
+#include "periph/init.h"
 
 /**
  * @brief Initialize the CPU, set IRQ priorities
@@ -39,4 +40,6 @@ void cpu_init(void)
     NRF_CLOCK->TASKS_HFCLKSTART = 1;
     while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {}
 #endif
+    /* trigger static peripheral initialization */
+    periph_init();
 }
diff --git a/cpu/nrf52/cpu.c b/cpu/nrf52/cpu.c
index 173531915d..85687fb9d8 100644
--- a/cpu/nrf52/cpu.c
+++ b/cpu/nrf52/cpu.c
@@ -24,6 +24,7 @@
 
 #include "cpu.h"
 #include "periph_conf.h"
+#include "periph/init.h"
 
 /* FTPAN helper functions */
 static bool ftpan_32(void);
@@ -82,6 +83,9 @@ void cpu_init(void)
     NVIC_EnableIRQ(SWI0_EGU0_IRQn);
     NVIC_SetPriority(SWI0_EGU0_IRQn, 6);
 #endif
+
+    /* trigger static peripheral initialization */
+    periph_init();
 }
 
 /**
diff --git a/cpu/sam3/cpu.c b/cpu/sam3/cpu.c
index aaa18578b6..2b7ff7db4d 100644
--- a/cpu/sam3/cpu.c
+++ b/cpu/sam3/cpu.c
@@ -19,6 +19,7 @@
 
 #include "cpu.h"
 #include "periph_conf.h"
+#include "periph/init.h"
 
 /**
  * @brief   Keys needed for editing certain PMC registers
@@ -88,4 +89,7 @@ void cpu_init(void)
     PMC->PMC_MCKR = PMC_MCKR_CSS_PLLA_CLK;
     /* wait for master clock to be ready */
     while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
+
+    /* trigger static peripheral initialization */
+    periph_init();
 }
diff --git a/cpu/samd21/cpu.c b/cpu/samd21/cpu.c
index 8f0ebff4fc..a4a80864c7 100644
--- a/cpu/samd21/cpu.c
+++ b/cpu/samd21/cpu.c
@@ -20,6 +20,7 @@
 
 #include "cpu.h"
 #include "periph_conf.h"
+#include "periph/init.h"
 
 /**
  * @brief   Configure clock sources and the cpu frequency
diff --git a/cpu/saml21/cpu.c b/cpu/saml21/cpu.c
index 75a945165f..e5ea27fa2c 100644
--- a/cpu/saml21/cpu.c
+++ b/cpu/saml21/cpu.c
@@ -19,6 +19,7 @@
  */
 
 #include "cpu.h"
+#include "periph/init.h"
 
 static void _gclk_setup(int gclk, uint32_t reg)
 {
@@ -77,4 +78,7 @@ void cpu_init(void)
      */
     SUPC->BOD33.bit.ENABLE=0;
 #endif
+
+    /* trigger static peripheral initialization */
+    periph_init();
 }
diff --git a/cpu/stm32f0/cpu.c b/cpu/stm32f0/cpu.c
index 557176afa5..88884d123c 100644
--- a/cpu/stm32f0/cpu.c
+++ b/cpu/stm32f0/cpu.c
@@ -19,6 +19,7 @@
 
 #include "cpu.h"
 #include "periph_conf.h"
+#include "periph/init.h"
 
 /* Check the source to be used for the PLL */
 #if defined(CLOCK_HSI) && defined(CLOCK_HSE)
@@ -54,6 +55,8 @@ void cpu_init(void)
     cortexm_init();
     /* initialize the clock system */
     clock_init();
+    /* trigger static peripheral initialization */
+    periph_init();
 }
 
 /**
diff --git a/cpu/stm32f1/cpu.c b/cpu/stm32f1/cpu.c
index b611b228cf..c2d465a640 100644
--- a/cpu/stm32f1/cpu.c
+++ b/cpu/stm32f1/cpu.c
@@ -27,6 +27,7 @@
 
 #include "cpu.h"
 #include "periph_conf.h"
+#include "periph/init.h"
 
 /* Configuration of flash access cycles */
 #if CLOCK_CORECLOCK <= 24000000
@@ -103,6 +104,8 @@ void cpu_init(void)
     cortexm_init();
     /* initialize system clocks */
     clk_init();
+    /* trigger static peripheral initialization */
+    periph_init();
 }
 
 /**
diff --git a/cpu/stm32f2/cpu.c b/cpu/stm32f2/cpu.c
index 8304176755..2437e6ddb6 100644
--- a/cpu/stm32f2/cpu.c
+++ b/cpu/stm32f2/cpu.c
@@ -19,6 +19,7 @@
 
 #include "cpu.h"
 #include "periph_conf.h"
+#include "periph/init.h"
 
 #ifdef HSI_VALUE
 # define RCC_CR_SOURCE          RCC_CR_HSION
@@ -38,6 +39,8 @@ void cpu_init(void)
     cortexm_init();
     /* initialize system clocks */
     clk_init();
+    /* trigger static peripheral initialization */
+    periph_init();
 }
 
 /**
diff --git a/cpu/stm32f3/cpu.c b/cpu/stm32f3/cpu.c
index 969a5c5a69..66bb7763a7 100644
--- a/cpu/stm32f3/cpu.c
+++ b/cpu/stm32f3/cpu.c
@@ -21,6 +21,7 @@
 #include <stdint.h>
 #include "cpu.h"
 #include "periph_conf.h"
+#include "periph/init.h"
 
 /* Check the source to be used for the PLL */
 #if defined(CLOCK_HSI) && defined(CLOCK_HSE)
@@ -57,6 +58,8 @@ void cpu_init(void)
     cortexm_init();
     /* initialize the clock system */
     cpu_clock_init();
+    /* trigger static peripheral initialization */
+    periph_init();
 }
 
 /**
diff --git a/cpu/stm32f4/cpu.c b/cpu/stm32f4/cpu.c
index b2e50c6988..09e2b71e1c 100644
--- a/cpu/stm32f4/cpu.c
+++ b/cpu/stm32f4/cpu.c
@@ -21,6 +21,7 @@
 #include <stdint.h>
 #include "cpu.h"
 #include "periph_conf.h"
+#include "periph/init.h"
 
 /* Check the source to be used for the PLL */
 #if defined(CLOCK_HSI) && defined(CLOCK_HSE)
@@ -50,6 +51,8 @@ void cpu_init(void)
     cortexm_init();
     /* initialize the clock system */
     cpu_clock_init();
+    /* trigger static peripheral initialization */
+    periph_init();
 }
 
 /**
diff --git a/cpu/stm32l1/cpu.c b/cpu/stm32l1/cpu.c
index bf092531d6..f0ebc74e62 100644
--- a/cpu/stm32l1/cpu.c
+++ b/cpu/stm32l1/cpu.c
@@ -22,6 +22,7 @@
 #include "cpu.h"
 #include "board.h"
 #include "periph_conf.h"
+#include "periph/init.h"
 
 /* Check the source to be used for the PLL */
 #if defined(CLOCK_HSI) && defined(CLOCK_HSE)
@@ -46,6 +47,8 @@ void cpu_init(void)
     cortexm_init();
     /* initialize system clocks */
     clk_init();
+    /* trigger static peripheral initialization */
+    periph_init();
 }
 
 /**
diff --git a/drivers/include/periph/init.h b/drivers/include/periph/init.h
new file mode 100644
index 0000000000..3e74d35ba7
--- /dev/null
+++ b/drivers/include/periph/init.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 Freie Universität Berlin
+ *
+ * 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    drivers_periph_init Common peripheral initialization
+ * @ingroup     drivers_periph
+ * @brief       Common static peripheral driver initialization
+ *
+ * This interface provides a central hook for any static peripheral
+ * initialization that might be needed. Typical drivers that need this are
+ * shared peripherals like SPI and I2C.
+ *
+ * @{
+ * @file
+ * @brief       Common peripheral driver initialization interface
+ *
+ * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
+ */
+
+#ifndef PERIPH_INIT_H
+#define PERIPH_INIT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   Common peripheral initialization function
+ *
+ * This function should call all needed static initialization functions for
+ * configured peripheral drivers like SPI or I2C. This function SHOULD be called
+ * early in the boot process, e.g. before the actual kernel initialization is
+ * started.
+ */
+void periph_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PERIPH_INIT_H */
+/** @} */
diff --git a/drivers/periph_common/init.c b/drivers/periph_common/init.c
new file mode 100644
index 0000000000..3c13f15120
--- /dev/null
+++ b/drivers/periph_common/init.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 Freie Universität Berlin
+ *
+ * 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     drivers_periph_init
+ * @{
+ *
+ * @file
+ * @brief       Common static peripheral driver initialization implementation
+ *
+ * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
+ *
+ * @}
+ */
+
+#include "periph/spi.h"
+
+void periph_init(void)
+{
+    /* initialize configured SPI devices */
+#ifdef SPI_NUMOF
+    for (unsigned i = 0; i < SPI_NUMOF; i++) {
+        spi_init(SPI_DEV(i));
+    }
+#endif
+}
-- 
GitLab