diff --git a/boards/f4vi1/include/periph_conf.h b/boards/f4vi1/include/periph_conf.h
index ccf2dbb455e19bab305584fd905357d9ae91a8fa..1722444c1d5de12b4fc41b576a158e46de5837d1 100644
--- a/boards/f4vi1/include/periph_conf.h
+++ b/boards/f4vi1/include/periph_conf.h
@@ -28,25 +28,34 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 168MHz */
+#define CLOCK_CORECLOCK     (168000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (16000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (0)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 168MHz */
-#define CLOCK_CORECLOCK     (168000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV4     /* max 42MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 4)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV2     /* max 84MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 2)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (8)
+#define CLOCK_PLL_N          (168)
+#define CLOCK_PLL_P          (2)
+#define CLOCK_PLL_Q          (7)
 /** @} */
 
 /**
diff --git a/boards/msbiot/include/periph_conf.h b/boards/msbiot/include/periph_conf.h
index e3045332e6391e7f726c1e092937d9c77fadc132..52629ab8d4a915f10d9e882027a1de25fa3bc162 100644
--- a/boards/msbiot/include/periph_conf.h
+++ b/boards/msbiot/include/periph_conf.h
@@ -26,25 +26,34 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 168MHz */
+#define CLOCK_CORECLOCK     (168000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (16000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (0)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 168MHz */
-#define CLOCK_CORECLOCK     (168000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV4     /* max 42MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 4)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV2     /* max 84MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 2)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (8)
+#define CLOCK_PLL_N          (168)
+#define CLOCK_PLL_P          (2)
+#define CLOCK_PLL_Q          (7)
 /** @} */
 
 /**
diff --git a/boards/nucleo-f401/include/periph_conf.h b/boards/nucleo-f401/include/periph_conf.h
index ae5ce5ccfbfea82d5b2b6b5f589393265353cf32..6bcfe0c61076a9b9fb398bdee8a6703575cda8b1 100644
--- a/boards/nucleo-f401/include/periph_conf.h
+++ b/boards/nucleo-f401/include/periph_conf.h
@@ -26,27 +26,34 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 84MHz */
+#define CLOCK_CORECLOCK     (84000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (8000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (1)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 84MHz */
-#define CLOCK_CORECLOCK     (84000000U)
-/* PLL Output divisor */
-#define P                   (4U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV2     /* max 42MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 2)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV1     /* max 84MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 1)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (4)
+#define CLOCK_PLL_N          (168)
+#define CLOCK_PLL_P          (4)
+#define CLOCK_PLL_Q          (7)
 /** @} */
 
 /**
diff --git a/boards/nucleo-f410/include/periph_conf.h b/boards/nucleo-f410/include/periph_conf.h
index 1f2f29edb86e7a8f31dcdd4fcd7069675748535c..0c8fb5a590c5b8d558bcaef586e59be154660a3c 100644
--- a/boards/nucleo-f410/include/periph_conf.h
+++ b/boards/nucleo-f410/include/periph_conf.h
@@ -26,25 +26,34 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 100MHz */
+#define CLOCK_CORECLOCK     (96000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (8000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (1)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 100MHz */
-#define CLOCK_CORECLOCK     (96000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV2     /* max 50MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 2)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV1     /* max 100MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 1)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (4)
+#define CLOCK_PLL_N          (192)
+#define CLOCK_PLL_P          (4)
+#define CLOCK_PLL_Q          (8)
 /** @} */
 
 /**
@@ -119,19 +128,19 @@ static const uart_conf_t uart_config[] = {
  * @{
  */
 static const uint8_t spi_divtable[2][5] = {
-    {       /* for APB1 @ 50000000Hz */
-        7,  /* -> 195312Hz */
-        6,  /* -> 390625Hz */
-        5,  /* -> 781250Hz */
-        2,  /* -> 6250000Hz */
-        1   /* -> 12500000Hz */
+    {       /* for APB1 @ 48000000Hz */
+        7,  /* -> 187500Hz */
+        6,  /* -> 375000Hz */
+        5,  /* -> 750000Hz */
+        2,  /* -> 6000000Hz */
+        1   /* -> 12000000Hz */
     },
-    {       /* for APB2 @ 100000000Hz */
-        7,  /* -> 390625Hz */
-        7,  /* -> 390625Hz */
-        6,  /* -> 781250Hz */
-        3,  /* -> 6250000Hz */
-        2   /* -> 12500000Hz */
+    {       /* for APB2 @ 96000000Hz */
+        7,  /* -> 375000Hz */
+        7,  /* -> 375000Hz */
+        6,  /* -> 750000Hz */
+        3,  /* -> 6000000Hz */
+        2   /* -> 12000000Hz */
     }
 };
 
diff --git a/boards/nucleo-f411/include/periph_conf.h b/boards/nucleo-f411/include/periph_conf.h
index 4ce6b7fb125152187e35a4a9e62be4c4dccee0fb..05077cc2c862bc4df168ce087e2a6973909cbc57 100644
--- a/boards/nucleo-f411/include/periph_conf.h
+++ b/boards/nucleo-f411/include/periph_conf.h
@@ -26,25 +26,34 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 100MHz */
+#define CLOCK_CORECLOCK     (96000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (8000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (1)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 100MHz */
-#define CLOCK_CORECLOCK     (96000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV2     /* max 50MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 2)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV1     /* max 100MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 1)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (4)
+#define CLOCK_PLL_N          (192)
+#define CLOCK_PLL_P          (4)
+#define CLOCK_PLL_Q          (8)
 /** @} */
 
 /**
@@ -165,19 +174,19 @@ static const pwm_conf_t pwm_config[] = {
  * @{
  */
 static const uint8_t spi_divtable[2][5] = {
-    {       /* for APB1 @ 50000000Hz */
-        7,  /* -> 195312Hz */
-        6,  /* -> 390625Hz */
-        5,  /* -> 781250Hz */
-        2,  /* -> 6250000Hz */
-        1   /* -> 12500000Hz */
+    {       /* for APB1 @ 48000000Hz */
+        7,  /* -> 187500Hz */
+        6,  /* -> 375000Hz */
+        5,  /* -> 750000Hz */
+        2,  /* -> 6000000Hz */
+        1   /* -> 12000000Hz */
     },
-    {       /* for APB2 @ 100000000Hz */
-        7,  /* -> 390625Hz */
-        7,  /* -> 390625Hz */
-        6,  /* -> 781250Hz */
-        3,  /* -> 6250000Hz */
-        2   /* -> 12500000Hz */
+    {       /* for APB2 @ 96000000Hz */
+        7,  /* -> 375000Hz */
+        7,  /* -> 375000Hz */
+        6,  /* -> 750000Hz */
+        3,  /* -> 6000000Hz */
+        2   /* -> 12000000Hz */
     }
 };
 
diff --git a/boards/nucleo-f446/include/periph_conf.h b/boards/nucleo-f446/include/periph_conf.h
index 62ba179169ec741a02ea3f6c7ee306a6c044c9e5..2ce1f9526ad5eb0ef99bfb73dd20e62e1773ad86 100644
--- a/boards/nucleo-f446/include/periph_conf.h
+++ b/boards/nucleo-f446/include/periph_conf.h
@@ -26,25 +26,44 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 180MHz */
+#define CLOCK_CORECLOCK     (180000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (8000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (1)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 180MHz */
-#define CLOCK_CORECLOCK     (168000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV4     /* max 45MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 4)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV2     /* max 90MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 2)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (4)
+#define CLOCK_PLL_N          (180)
+#define CLOCK_PLL_P          (2)
+#define CLOCK_PLL_Q          (0)
+
+/* PLL SAI configuration */
+#define CLOCK_ENABLE_PLL_SAI (1)
+#define CLOCK_PLL_SAI_M      (4)
+#define CLOCK_PLL_SAI_N      (192)
+#define CLOCK_PLL_SAI_P      (8)
+#define CLOCK_PLL_SAI_Q      (0)
+
+/* Use alternative source for 48MHz clock */
+#define CLOCK_USE_ALT_48MHZ  (1)
 /** @} */
 
 /**
diff --git a/boards/nucleo144-f207/include/periph_conf.h b/boards/nucleo144-f207/include/periph_conf.h
index 47b12acd23ceccfc7145cb623625ab30e2db1488..9735c5d2cbd363a48208f5dab7996026102819d5 100644
--- a/boards/nucleo144-f207/include/periph_conf.h
+++ b/boards/nucleo144-f207/include/periph_conf.h
@@ -28,25 +28,34 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 120MHz */
+#define CLOCK_CORECLOCK     (120000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (8000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (1)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 120MHz */
-#define CLOCK_CORECLOCK     (120000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV4     /* max 30MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 4)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV2     /* max 60MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 2)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (4)
+#define CLOCK_PLL_N          (120)
+#define CLOCK_PLL_P          (2)
+#define CLOCK_PLL_Q          (5)
 /** @} */
 
 /**
diff --git a/boards/nucleo144-f412/include/periph_conf.h b/boards/nucleo144-f412/include/periph_conf.h
index 842baa7fb2ad440e7e27b3408c83c7df0507d893..980ebd06299322984baa6e7b2877d488ff92d5ae 100644
--- a/boards/nucleo144-f412/include/periph_conf.h
+++ b/boards/nucleo144-f412/include/periph_conf.h
@@ -28,25 +28,45 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 100MHz */
+#define CLOCK_CORECLOCK     (100000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (8000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (1)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 100MHz */
-#define CLOCK_CORECLOCK     (96000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV2     /* max 50MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 2)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV1     /* max 100MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 1)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (4)
+#define CLOCK_PLL_N          (200)
+#define CLOCK_PLL_P          (4)
+#define CLOCK_PLL_Q          (0)
+
+/* PLL I2S configuration */
+#define CLOCK_ENABLE_PLL_I2S (1)
+#define CLOCK_PLL_I2S_SRC    (0)
+#define CLOCK_PLL_I2S_M      (4)
+#define CLOCK_PLL_I2S_N      (216)
+#define CLOCK_PLL_I2S_P      (0)
+#define CLOCK_PLL_I2S_Q      (9)
+
+/* Use alternative source for 48MHz clock */
+#define CLOCK_USE_ALT_48MHZ  (1)
 /** @} */
 
 /**
diff --git a/boards/nucleo144-f413/include/periph_conf.h b/boards/nucleo144-f413/include/periph_conf.h
index c47822189064f2bdff2e0304bdb2e8b5af11b166..69d4aed14da0823ff91b7594423bec60918f6dcf 100644
--- a/boards/nucleo144-f413/include/periph_conf.h
+++ b/boards/nucleo144-f413/include/periph_conf.h
@@ -28,25 +28,45 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 100MHz */
+#define CLOCK_CORECLOCK     (100000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (8000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (1)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 100MHz */
-#define CLOCK_CORECLOCK     (96000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV2     /* max 50MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 2)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV1     /* max 100MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 1)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (4)
+#define CLOCK_PLL_N          (200)
+#define CLOCK_PLL_P          (4)
+#define CLOCK_PLL_Q          (0)
+
+/* PLL I2S configuration */
+#define CLOCK_ENABLE_PLL_I2S (1)
+#define CLOCK_PLL_I2S_SRC    (0)
+#define CLOCK_PLL_I2S_M      (4)
+#define CLOCK_PLL_I2S_N      (216)
+#define CLOCK_PLL_I2S_P      (0)
+#define CLOCK_PLL_I2S_Q      (9)
+
+/* Use alternative source for 48MHz clock */
+#define CLOCK_USE_ALT_48MHZ  (1)
 /** @} */
 
 /**
diff --git a/boards/nucleo144-f429/include/periph_conf.h b/boards/nucleo144-f429/include/periph_conf.h
index 3679d69232bfb73378dbf86c576d33f8a32db88b..230793cbc20c72e308dd86b610aa62f53adf61ad 100644
--- a/boards/nucleo144-f429/include/periph_conf.h
+++ b/boards/nucleo144-f429/include/periph_conf.h
@@ -26,25 +26,34 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 180MHz */
+#define CLOCK_CORECLOCK     (168000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (8000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (1)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 180MHz */
-#define CLOCK_CORECLOCK     (168000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV4     /* max 45MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 4)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV2     /* max 90MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 2)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (4)
+#define CLOCK_PLL_N          (168)
+#define CLOCK_PLL_P          (2)
+#define CLOCK_PLL_Q          (7)
 /** @} */
 
 /**
diff --git a/boards/nucleo144-f446/include/periph_conf.h b/boards/nucleo144-f446/include/periph_conf.h
index 70905380ed220bd9230fee6087193d5825c8c83d..56d42da52d548714417e061a690a6a056bec9c96 100644
--- a/boards/nucleo144-f446/include/periph_conf.h
+++ b/boards/nucleo144-f446/include/periph_conf.h
@@ -26,25 +26,44 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 180MHz */
+#define CLOCK_CORECLOCK     (180000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (8000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (1)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 100MHz */
-#define CLOCK_CORECLOCK     (168000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV4     /* max 45MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 4)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV2     /* max 90MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 2)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (4)
+#define CLOCK_PLL_N          (180)
+#define CLOCK_PLL_P          (2)
+#define CLOCK_PLL_Q          (0)
+
+/* PLL SAI configuration */
+#define CLOCK_ENABLE_PLL_SAI (1)
+#define CLOCK_PLL_SAI_M      (4)
+#define CLOCK_PLL_SAI_N      (192)
+#define CLOCK_PLL_SAI_P      (8)
+#define CLOCK_PLL_SAI_Q      (0)
+
+/* Use alternative source for 48MHz clock */
+#define CLOCK_USE_ALT_48MHZ  (1)
 /** @} */
 
 /**
diff --git a/boards/nucleo144-f722/include/periph_conf.h b/boards/nucleo144-f722/include/periph_conf.h
index e93c86811aae5c1e6ab790f8b21ba2c140d3b344..67f6b9cc816480bddbc68e201f36cd52d3fbb1dc 100644
--- a/boards/nucleo144-f722/include/periph_conf.h
+++ b/boards/nucleo144-f722/include/periph_conf.h
@@ -26,25 +26,34 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 216MHz */
+#define CLOCK_CORECLOCK     (216000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (8000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (1)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 216MHz, min: 96MHz, must be multiple of 24MHz */
-#define CLOCK_CORECLOCK     (216000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV4     /* max 54MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 4)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV2     /* max 108MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 2)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (4)
+#define CLOCK_PLL_N          (216)
+#define CLOCK_PLL_P          (2)
+#define CLOCK_PLL_Q          (9)
 /** @} */
 
 /**
diff --git a/boards/nucleo144-f746/include/periph_conf.h b/boards/nucleo144-f746/include/periph_conf.h
index 46cc3540c6af1332cc309ad7bc995335450bd83c..b74fc078067b715c5431f498968254390b8c6c4b 100644
--- a/boards/nucleo144-f746/include/periph_conf.h
+++ b/boards/nucleo144-f746/include/periph_conf.h
@@ -26,25 +26,34 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 216MHz */
+#define CLOCK_CORECLOCK     (216000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (8000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (1)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 216MHz, min: 96MHz, must be multiple of 24MHz */
-#define CLOCK_CORECLOCK     (216000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV4     /* max 54MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 4)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV2     /* max 108MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 2)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (4)
+#define CLOCK_PLL_N          (216)
+#define CLOCK_PLL_P          (2)
+#define CLOCK_PLL_Q          (9)
 /** @} */
 
 /**
diff --git a/boards/nucleo144-f767/include/periph_conf.h b/boards/nucleo144-f767/include/periph_conf.h
index 0242bc2c45a206471b8d991700e527e193290205..ec67f3c8a820f054b3be2c518e5f7013960bdb24 100644
--- a/boards/nucleo144-f767/include/periph_conf.h
+++ b/boards/nucleo144-f767/include/periph_conf.h
@@ -26,25 +26,34 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 216MHz */
+#define CLOCK_CORECLOCK     (216000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (8000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (1)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 216MHz, min: 96MHz, must be multiple of 24MHz */
-#define CLOCK_CORECLOCK     (216000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV4     /* max 54MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 4)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV2     /* max 108MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 2)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (4)
+#define CLOCK_PLL_N          (216)
+#define CLOCK_PLL_P          (2)
+#define CLOCK_PLL_Q          (9)
 /** @} */
 
 /**
diff --git a/boards/stm32f4discovery/include/periph_conf.h b/boards/stm32f4discovery/include/periph_conf.h
index c1ab8c8afb8e66bf5ebdfb209c75b80bfd8ca2ab..9bc1f93e2d2b2f1b682b358d5cdb7539d8033694 100644
--- a/boards/stm32f4discovery/include/periph_conf.h
+++ b/boards/stm32f4discovery/include/periph_conf.h
@@ -27,25 +27,34 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 168MHz */
+#define CLOCK_CORECLOCK     (168000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (8000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (1)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 168MHz */
-#define CLOCK_CORECLOCK     (168000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV4     /* max 42MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 4)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV2     /* max 84MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 2)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (4)
+#define CLOCK_PLL_N          (168)
+#define CLOCK_PLL_P          (2)
+#define CLOCK_PLL_Q          (7)
 /** @} */
 
 /**
diff --git a/boards/stm32f7discovery/include/periph_conf.h b/boards/stm32f7discovery/include/periph_conf.h
index 95eaaf5f986dec11500681fe35eb3582a23b10f5..759d56acedc99891ade0c4ece6467280c0122e18 100644
--- a/boards/stm32f7discovery/include/periph_conf.h
+++ b/boards/stm32f7discovery/include/periph_conf.h
@@ -26,25 +26,34 @@ extern "C" {
 #endif
 
 /**
- * @name    Clock system configuration
+ * @name    Clock settings
+ *
+ * @note    This is auto-generated from
+ *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`
  * @{
  */
+/* give the target core clock (HCLK) frequency [in Hz],
+ * maximum: 216MHz */
+#define CLOCK_CORECLOCK     (216000000U)
 /* 0: no external high speed crystal available
  * else: actual crystal frequency [in Hz] */
 #define CLOCK_HSE           (25000000U)
 /* 0: no external low speed crystal available,
  * 1: external crystal available (always 32.768kHz) */
 #define CLOCK_LSE           (1)
-/* give the target core clock (HCLK) frequency [in Hz],
- * maximum: 216MHz, min: 96MHz, must be multiple of 48MHz */
-#define CLOCK_CORECLOCK     (216000000U)
 /* peripheral clock setup */
-#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1      /* min 25MHz */
+#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1
 #define CLOCK_AHB           (CLOCK_CORECLOCK / 1)
 #define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV4     /* max 54MHz */
 #define CLOCK_APB1          (CLOCK_CORECLOCK / 4)
 #define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV2     /* max 108MHz */
 #define CLOCK_APB2          (CLOCK_CORECLOCK / 2)
+
+/* Main PLL factors */
+#define CLOCK_PLL_M          (25)
+#define CLOCK_PLL_N          (432)
+#define CLOCK_PLL_P          (2)
+#define CLOCK_PLL_Q          (9)
 /** @} */
 
 /**
diff --git a/cpu/stm32_common/dist/.gitignore b/cpu/stm32_common/dist/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e0afe360f45a149ece8f68d555e8b573cf69378c
--- /dev/null
+++ b/cpu/stm32_common/dist/.gitignore
@@ -0,0 +1,2 @@
+clk_conf
+spi_divtable
diff --git a/cpu/stm32_common/dist/clk_conf/Makefile b/cpu/stm32_common/dist/clk_conf/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..bfe565640a23471f293b87a775b1a2af37a3e0e3
--- /dev/null
+++ b/cpu/stm32_common/dist/clk_conf/Makefile
@@ -0,0 +1,12 @@
+NAME        = clk_conf
+CC          = gcc
+CFLAGS      = -std=c99 -Wall
+SRC         = $(wildcard *.c)
+
+.PHONY: all clean
+
+all:
+	$(CC) $(CFLAGS) -o $(NAME) $(SRC)
+
+clean:
+	rm -f $(NAME)
diff --git a/cpu/stm32_common/dist/clk_conf/clk_conf.c b/cpu/stm32_common/dist/clk_conf/clk_conf.c
new file mode 100644
index 0000000000000000000000000000000000000000..6d51b487a1be41b048a02316af54d2835913077e
--- /dev/null
+++ b/cpu/stm32_common/dist/clk_conf/clk_conf.c
@@ -0,0 +1,483 @@
+/*
+ * Copyright (C) 2017 OTA keys S.A.
+ *
+ * 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.
+ */
+
+/**
+ * @brief       Compute clock constants for STM32F[2|4|7] CPUs
+ *
+ *
+ * @author      Vincent Dupont <vincent@otakeys.com>
+ *
+ * @}
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include "clk_conf.h"
+
+#define ENABLE_DEBUG (0)
+#if ENABLE_DEBUG
+#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
+#else
+#define DEBUG(...)
+#endif
+
+/**
+ * @brief Check if N/P pair is valid
+ *
+ * Check if N/P (alternatively N/Q or N/R) pair is valid with given @p vco_in and
+ * @p pll_out
+ *
+ * @param[in] n
+ * @param[in] p
+ * @param[in] vco_in
+ * @param[in] pll_out
+ *
+ * @return 1 if pair is valid, 0 otherwise
+ */
+static int is_n_ok(const pll_cfg_t *cfg, unsigned n, unsigned p,
+                   unsigned vco_in, unsigned pll_out)
+{
+    if (n >= cfg->min_n && n <= cfg->max_n &&
+            vco_in * n >= cfg->min_vco_output && vco_in * n <= cfg->max_vco_output &&
+            vco_in * n / p == pll_out) {
+        return 1;
+    }
+    else {
+        return 0;
+    }
+}
+
+/**
+ * @brief Compute PLL factors
+ *
+ * @param[in] pll_in      PLL input frequency
+ * @param[in] pll_p_out   PLL P output frequency (0 if P is not needed)
+ * @param[in] pll_q_out   PLL Q output frequency (0 if Q is not needed)
+ * @param[in] pll_r_out   PLL R output frequency (0 if R is not needed)
+ * @param[in,out] m       M factor, can be preset (0, if it has to be calculated)
+ * @param[out] n          N factor
+ * @param[out] p          P factor
+ * @param[out] q          Q factor
+ * @param[out] r          R factor
+ *
+ * @return -1 if no P,N pair can be computed with given @p pll_in and @p pll_p_out
+ * @return 1 if no Q can be computed, M, N and P are valid
+ * @return 2 if no R can be computed, M, M and P are valid
+ * @return 3 if no Q nor R can be computed, M, M and P are valid
+ * @return 0 if M, N, P, Q, R are valid
+ */
+static int compute_pll(const pll_cfg_t *cfg, unsigned pll_in,
+                       unsigned pll_p_out, unsigned pll_q_out, unsigned pll_r_out,
+                       unsigned *m, unsigned *n,
+                       unsigned *p, unsigned *q, unsigned *r)
+{
+    (void)pll_r_out;
+    (void)r;
+
+    int res = 0;
+    unsigned vco_in;
+
+    if (*m == 0) {
+        unsigned found_m = 0;
+        unsigned found_n;
+        unsigned found_p;
+        unsigned found_q;
+        unsigned found_r;
+        unsigned found_res;
+        *m = cfg->min_m;
+        while (*m <= cfg->max_m && (res = compute_pll(cfg, pll_in, pll_p_out,
+                                                      pll_q_out, pll_r_out,
+                                                      m, n, p, q, r)) != 0) {
+            if (res > 0 && !found_m) {
+                found_m = *m;
+                found_n = *n;
+                found_p = *p;
+                found_q = *q;
+                found_r = *r;
+                found_res = res;
+            }
+            *m += cfg->inc_m;
+        }
+        if (res == 0) {
+            return 0;
+        }
+        if (found_m) {
+            *m = found_m;
+            *n = found_n;
+            *p = found_p;
+            *q = found_q;
+            *r = found_r;
+            return found_res;
+        }
+        else {
+            return -1;
+        }
+    }
+    else {
+        vco_in = pll_in / *m;
+        DEBUG("M=%u, vco_in=%u\n", *m, vco_in);
+    }
+
+    if (*m < cfg->min_m || *m > cfg->max_m ||
+            vco_in < cfg->min_vco_input || vco_in > cfg->max_vco_input) {
+        DEBUG("Invalid M=%u\n", *m);
+        return -1;
+    }
+
+    if (pll_p_out) {
+        DEBUG("Computing P for freq=%u\n", pll_p_out);
+        for (*p = cfg->max_p; *p >= cfg->min_p; *p -= cfg->inc_p) {
+            *n = *p * pll_p_out / vco_in;
+            DEBUG("Trying P=%u: N=%u\n", *p, *n);
+            if (is_n_ok(cfg, *n, *p, vco_in, pll_p_out)) {
+                DEBUG("Found M=%u, N=%u, P=%u\n", *m, *n, *p);
+                break;
+            }
+        }
+        if (*p < cfg->min_p) {
+            *p += cfg->inc_p;
+        }
+        if (!is_n_ok(cfg, *n, *p, vco_in, pll_p_out)) {
+            return -1;
+        }
+    }
+
+    if (pll_q_out) {
+        DEBUG("Computing Q for freq=%u\n", pll_q_out);
+        for (*q = cfg->max_q; *q >= cfg->min_q; *q -= cfg->inc_q) {
+            if (!pll_p_out) {
+                *n = *q * pll_q_out / vco_in;
+            }
+            DEBUG("Trying Q=%u: N=%u\n", *q, *n);
+            if (is_n_ok(cfg, *n, *q, vco_in, pll_q_out)) {
+                DEBUG("Found M=%u, N=%u, Q=%u\n", *m, *n, *q);
+                break;
+            }
+        }
+        if (*q < cfg->min_q) {
+            *q += cfg->inc_q;
+        }
+        if (!is_n_ok(cfg, *n, *q, vco_in, pll_q_out)) {
+            *q = 0;
+            res |= 1;
+        }
+    }
+
+    /* todo, compute r */
+
+    return res;
+}
+
+static void usage(char **argv)
+{
+    fprintf(stderr, "usage: %s <cpu_model> <coreclock> <hse_freq> <lse> [pll_i2s_src] "
+                    "[pll_i2s_q_out] [pll_sai_q_out]\n", argv[0]);
+}
+
+#define HSI 0
+#define HSE 1
+
+int main(int argc, char **argv)
+{
+    if (argc < 2) {
+        usage(argv);
+        return 1;
+    }
+
+    if (strlen(argv[1]) < 9
+            || !isdigit(argv[1][6])
+            || !isdigit(argv[1][7])
+            || !isdigit(argv[1][8])
+            || ((argv[1][5] != 'f') && (argv[1][5] != 'F')
+                /* && (argv[1][5] != 'l') && (argv[1][5] != 'L') */)) {
+        fprintf(stderr, "Invalid model : %s\n", argv[1]);
+        return 1;
+    }
+
+    int model = atoi(argv[1] + 6);
+    int i;
+    for (i = 0; i < MODEL_MAX; i++) {
+        if (stm32_model[i] == model) {
+            break;
+        }
+    }
+    if (i == MODEL_MAX) {
+        fprintf(stderr, "Unsupported CPU model %s\n", argv[1]);
+        return 1;
+    }
+
+    const clk_cfg_t *cfg = &stm32_clk_cfg[i];
+
+    /* print help for given cpu */
+    if (argc < 5) {
+        usage(argv);
+        fprintf(stderr, "Max values for stm32f%03d:\n", model);
+        fprintf(stderr, "  Max coreclock: %u Hz\n"
+                        "  Max APB1:      %u Hz\n"
+                        "  Max APB2:      %u Hz\n",
+                cfg->max_coreclock, cfg->max_apb1, cfg->max_apb2);
+        fprintf(stderr, "Additional PLLs:\n"
+                        "  PLL I2S: %d\n"
+                        "  PLL SAI: %d\n"
+                        "  Alternate 48MHz source: ",
+                cfg->has_pll_i2s, cfg->has_pll_sai);
+        if (cfg->has_alt_48MHz & ALT_48MHZ_I2S) {
+            fprintf(stderr, "PLL I2S\n");
+        }
+        else if (cfg->has_alt_48MHz & ALT_48MHZ_SAI) {
+            fprintf(stderr, "PLL SAI\n");
+        }
+        else {
+            fprintf(stderr, "None\n");
+        }
+        return 0;
+    }
+
+    /* parse command line arguments */
+    unsigned coreclock = atoi(argv[2]);
+    unsigned pll_in = atoi(argv[3]);
+    int pll_src;
+    if (pll_in == 0) {
+        pll_in = cfg->hsi;
+        pll_src = HSI;
+    }
+    else {
+        pll_src = HSE;
+    }
+
+    unsigned is_lse = atoi(argv[4]) ? 1 : 0;
+
+    unsigned pll_i2s_input = 0;
+    if (argc > 5) {
+        pll_i2s_input = atoi(argv[5]);
+    }
+
+    unsigned pll_i2s_p_out = 0;
+    unsigned pll_i2s_q_out = 0;
+    if (argc > 6) {
+        pll_i2s_q_out = atoi(argv[6]);
+    }
+
+    unsigned pll_sai_p_out = 0;
+    unsigned pll_sai_q_out = 0;
+    if (argc > 7) {
+        pll_sai_q_out = atoi(argv[7]);
+    }
+
+    if (cfg->max_coreclock && coreclock > cfg->max_coreclock) {
+        fprintf(stderr, "Invalid coreclock (max=%u)\n", cfg->max_coreclock);
+        return 1;
+    }
+
+    fprintf(stderr, "Computing settings for stm32f%03d CPU...\n", model);
+
+    unsigned m = 0;
+    unsigned n = 0;
+    unsigned p = 0;
+    unsigned q = 0;
+    unsigned r = 0;
+
+    unsigned m_i2s = 0;
+    unsigned n_i2s = 0;
+    unsigned p_i2s = 0;
+    unsigned q_i2s = 0;
+    unsigned r_i2s = 0;
+
+    unsigned m_sai = 0;
+    unsigned n_sai = 0;
+    unsigned p_sai = 0;
+    unsigned q_sai = 0;
+    unsigned r_sai = 0;
+
+    bool use_alt_48MHz = false;
+    unsigned clock_48MHz = cfg->need_48MHz ? 48000000U : 0;
+
+    /* main PLL */
+    /* try to match coreclock with P output and 48MHz for Q output (USB) */
+    switch (compute_pll(&cfg->pll, pll_in, coreclock, clock_48MHz, 0,
+                        &m, &n, &p, &q, &r)) {
+    case -1:
+        /* no config available */
+        fprintf(stderr, "Unable to compute main PLL factors\n");
+        return 1;
+    case 1:
+        /* Q not OK */
+        fprintf(stderr, "Need to use an alternate 48MHz src...");
+        if (cfg->has_pll_i2s && (cfg->has_alt_48MHz & ALT_48MHZ_I2S) == ALT_48MHZ_I2S) {
+            puts("PLL I2S");
+            use_alt_48MHz = true;
+            if (pll_i2s_q_out != 0 && pll_i2s_q_out != 48000000U) {
+                fprintf(stderr, "Invalid PLL I2S Q output freq: %u\n", pll_i2s_q_out);
+                return 1;
+            }
+            pll_i2s_q_out = 48000000U;
+        }
+        else if (cfg->has_pll_sai && (cfg->has_alt_48MHz & ALT_48MHZ_SAI)) {
+            fprintf(stderr, "PLL SAI...");
+            use_alt_48MHz = true;
+            if ((cfg->has_alt_48MHz & ALT_48MHZ_P) &&
+                    (pll_sai_p_out == 0 || pll_sai_p_out == 48000000U)) {
+                fprintf(stderr, "P\n");
+                pll_sai_p_out = 48000000U;
+            }
+            else if (!(cfg->has_alt_48MHz & ALT_48MHZ_P) &&
+                     (pll_sai_q_out == 0 || pll_sai_q_out == 48000000U)) {
+                fprintf(stderr, "Q\n");
+                pll_sai_q_out = 48000000U;
+            }
+            else {
+                if (cfg->has_alt_48MHz & ALT_48MHZ_P) {
+                    fprintf(stderr, "Invalid PLL SAI P output freq: %u\n", pll_sai_p_out);
+                } else {
+                    fprintf(stderr, "Invalid PLL SAI Q output freq: %u\n", pll_sai_q_out);
+                }
+                return 1;
+            }
+        }
+        else {
+            fprintf(stderr, "No other source available\n");
+            return 1;
+        }
+        break;
+    default:
+        break;
+    }
+
+    /* PLL I2S */
+    if (pll_i2s_p_out || pll_i2s_q_out) {
+        unsigned *_m;
+        unsigned _in;
+        if (cfg->has_pll_i2s_m) {
+            _m = &m_i2s;
+        }
+        else {
+            _m = &m;
+        }
+        if (cfg->has_pll_i2s_alt_input && pll_i2s_input) {
+            _in = pll_i2s_input;
+        }
+        else {
+            _in = pll_in;
+        }
+        if (compute_pll(&cfg->pll, _in, pll_i2s_p_out, pll_i2s_q_out, 0,
+                        _m, &n_i2s, &p_i2s, &q_i2s, &r_i2s) != 0) {
+            fprintf(stderr, "Unable to compute 48MHz output using PLL I2S\n");
+            return 1;
+        }
+    }
+
+    /* PLL SAI */
+    if (pll_sai_p_out || pll_sai_q_out) {
+        if (compute_pll(&cfg->pll, pll_in, pll_sai_p_out, pll_sai_q_out, 0,
+                        &m_sai, &n_sai, &p_sai, &q_sai, &r_sai) != 0) {
+            puts("Unable to compute 48MHz output using PLL I2S");
+            return 1;
+        }
+        if (!cfg->has_pll_sai_m && m != m_sai) {
+            m = m_sai;
+            DEBUG("Retry to compute main PLL with M=%u\n", m);
+            if (compute_pll(&cfg->pll, pll_in, coreclock, clock_48MHz, 0,
+                            &m, &n, &p, &q, &r) < 0) {
+                fprintf(stderr, "Unable to compute 48MHz output using PLL I2S\n");
+                return 1;
+            }
+        }
+    }
+
+    /* APB prescalers */
+    unsigned apb1_pre;
+    unsigned apb2_pre;
+
+    for (apb1_pre = 1; apb1_pre <= 16; apb1_pre <<= 1) {
+        if (coreclock / apb1_pre <= cfg->max_apb1) {
+            break;
+        }
+    }
+    for (apb2_pre = 1; apb2_pre <= 16; apb2_pre <<= 1) {
+        if (coreclock / apb2_pre <= cfg->max_apb2) {
+            break;
+        }
+    }
+
+
+    /* Print constants */
+    fprintf(stderr, "==============================================================\n");
+    fprintf(stderr, "Please copy the following code into your board's periph_conf.h\n\n");
+
+    printf("/**\n"
+           " * @name    Clock settings\n"
+           " *\n"
+           " * @note    This is auto-generated from\n"
+           " *          `cpu/stm32_common/dist/clk_conf/clk_conf.c`\n"
+           " * @{\n"
+           " */\n");
+    printf("/* give the target core clock (HCLK) frequency [in Hz],\n"
+           " * maximum: %uMHz */\n", cfg->max_coreclock / 1000000U);
+    printf("#define CLOCK_CORECLOCK     (%uU)\n", coreclock);
+    printf("/* 0: no external high speed crystal available\n"
+           " * else: actual crystal frequency [in Hz] */\n"
+           "#define CLOCK_HSE           (%uU)\n", pll_src ? pll_in : 0);
+    printf("/* 0: no external low speed crystal available,\n"
+           " * 1: external crystal available (always 32.768kHz) */\n"
+           "#define CLOCK_LSE           (%uU)\n", is_lse);
+    printf("/* peripheral clock setup */\n");
+    printf("#define CLOCK_AHB_DIV       RCC_CFGR_HPRE_DIV1\n"
+           "#define CLOCK_AHB           (CLOCK_CORECLOCK / 1)\n");
+    printf("#define CLOCK_APB1_DIV      RCC_CFGR_PPRE1_DIV%u     /* max %uMHz */\n"
+           "#define CLOCK_APB1          (CLOCK_CORECLOCK / %u)\n",
+           apb1_pre, cfg->max_apb1 / 1000000U, apb1_pre);
+    printf("#define CLOCK_APB2_DIV      RCC_CFGR_PPRE2_DIV%u     /* max %uMHz */\n"
+           "#define CLOCK_APB2          (CLOCK_CORECLOCK / %u)\n",
+           apb2_pre, cfg->max_apb2 / 1000000U, apb2_pre);
+    printf("\n/* Main PLL factors */\n");
+    printf("#define CLOCK_PLL_M          (%u)\n", m);
+    printf("#define CLOCK_PLL_N          (%u)\n", n);
+    printf("#define CLOCK_PLL_P          (%u)\n", p);
+    printf("#define CLOCK_PLL_Q          (%u)\n", q);
+
+
+    if (pll_i2s_p_out || pll_i2s_q_out) {
+        printf("\n/* PLL I2S configuration */\n");
+        printf("#define CLOCK_ENABLE_PLL_I2S (1)\n");
+        if (cfg->has_pll_i2s_alt_input && pll_i2s_input) {
+            printf("#define CLOCK_PLL_I2S_SRC    (RCC_PLLI2SCFGR_PLLI2SSRC)\n");
+        }
+        else {
+            printf("#define CLOCK_PLL_I2S_SRC    (0)\n");
+        }
+        if (cfg->has_pll_i2s_m) {
+            printf("#define CLOCK_PLL_I2S_M      (%u)\n", m_i2s);
+        }
+        printf("#define CLOCK_PLL_I2S_N      (%u)\n", n_i2s);
+        printf("#define CLOCK_PLL_I2S_P      (%u)\n", p_i2s);
+        printf("#define CLOCK_PLL_I2S_Q      (%u)\n", q_i2s);
+    }
+
+    if (pll_sai_p_out || pll_sai_q_out) {
+        printf("\n/* PLL SAI configuration */\n");
+        printf("#define CLOCK_ENABLE_PLL_SAI (1)\n");
+        if (cfg->has_pll_sai_m) {
+            printf("#define CLOCK_PLL_SAI_M      (%u)\n", m_sai);
+        }
+        printf("#define CLOCK_PLL_SAI_N      (%u)\n", n_sai);
+        printf("#define CLOCK_PLL_SAI_P      (%u)\n", p_sai);
+        printf("#define CLOCK_PLL_SAI_Q      (%u)\n", q_sai);
+    }
+
+    if (use_alt_48MHz) {
+        printf("\n/* Use alternative source for 48MHz clock */\n");
+        printf("#define CLOCK_USE_ALT_48MHZ  (1)\n");
+    }
+    printf("/** @} */\n");
+
+    return 0;
+}
diff --git a/cpu/stm32_common/dist/clk_conf/clk_conf.h b/cpu/stm32_common/dist/clk_conf/clk_conf.h
new file mode 100644
index 0000000000000000000000000000000000000000..d335fb3420a7b88b4289d0bc2867b6edd704d356
--- /dev/null
+++ b/cpu/stm32_common/dist/clk_conf/clk_conf.h
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2017 OTA keys S.A.
+ *
+ * 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.
+ */
+
+/**
+ * @brief       Compute clock constants for STM32F[2|4|7] CPUs
+ *
+ *
+ * @author      Vincent Dupont <vincent@otakeys.com>
+ *
+ * @}
+ */
+
+#ifndef CLK_CONF_H
+#define CLK_CONF_H
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @name STM32 families
+ * @ {
+ */
+enum fam {
+    STM32F0,
+    STM32F1,
+    STM32F2,
+    STM32F3,
+    STM32F4,
+    STM32F7,
+    FAM_MAX,
+};
+/** @} */
+
+/**
+ * @name Supported models
+ * @{
+ */
+enum {
+    STM32F205,
+    STM32F207,
+    STM32F215,
+    STM32F217,
+
+    STM32F401,
+    STM32F405,
+    STM32F407,
+    STM32F410,
+    STM32F411,
+    STM32F412,
+    STM32F413,
+    STM32F415,
+    STM32F417,
+    STM32F423,
+    STM32F427,
+    STM32F429,
+    STM32F437,
+    STM32F439,
+    STM32F446,
+    STM32F469,
+    STM32F479,
+
+    STM32F722,
+    STM32F732,
+    STM32F746,
+    STM32F756,
+    STM32F767,
+    STM32F769,
+    STM32F777,
+    STM32F779,
+
+    MODEL_MAX,
+};
+/** @} */
+
+/**
+ * @brief PLL configuration parameters
+ *
+ * PLL configuration follows the model:
+ * ```
+ *
+ * pll_in  +----+  vco_in  +------------------------------+
+ * --------| /M |----------|\  +----+ vco_out     +----+  |
+ *         +----+          | --| xN |-------------| /P |--|-- pll_p_out
+ *                         |   +----+         \   +----+  |
+ *                         |                   |  +----+  |
+ *                         |                   ---| /Q |--|-- pll_q_out
+ *                         |                   |  +----+  |
+ *                         |                   |  +----+  |
+ *                         |                   ---| /R |--|-- pll_r_out
+ *                         |                      +----+  |
+ *                         +------------------------------+
+ * ```
+ *
+ * vco_in = pll_in / M;
+ * vco_out = vco_in * N;
+ * pll_p_out = vco_out / P;
+ * pll_q_out = vco_out / Q;
+ * pll_r_out = vco_out / R;
+ */
+typedef struct {
+    unsigned min_vco_input;  /**< Min VCO input */
+    unsigned max_vco_input;  /**< Max VCO input */
+    unsigned min_vco_output; /**< Min VCO output */
+    unsigned max_vco_output; /**< Max VCO output */
+
+    unsigned min_n; /**< Min N */
+    unsigned max_n; /**< Max N */
+    unsigned inc_n; /**< Increment between two values of N */
+
+    unsigned min_m; /**< Min M */
+    unsigned max_m; /**< Max M */
+    unsigned inc_m; /**< Increment between two values of M */
+
+    unsigned min_p; /**< Min P */
+    unsigned max_p; /**< Max P */
+    unsigned inc_p; /**< Increment between two values of P */
+
+    unsigned min_q; /**< Min Q */
+    unsigned max_q; /**< Max Q */
+    unsigned inc_q; /**< Increment between two values of Q */
+} pll_cfg_t;
+
+/**
+ * @brief Clock configuration
+ */
+typedef struct {
+    enum fam family; /**< Family */
+
+    unsigned max_coreclock; /**< Max coreclock */
+    unsigned max_apb1;      /**< Max APB1 clock */
+    unsigned max_apb2;      /**< Max APB2 clock */
+
+    unsigned hsi; /**< HSI frequency */
+
+    pll_cfg_t pll; /**< PLL configuration */
+
+    bool has_pll_i2s;   /**< PLL I2S available */
+    bool has_pll_sai;   /**< PLL SAI available */
+    bool has_pll_i2s_m; /**< PLL I2S has a M factor */
+    bool has_pll_sai_m; /**< PLL SAI has a M factor */
+    bool has_pll_i2s_alt_input; /**< PLL I2S has an external input available */
+
+    int has_alt_48MHz; /**< 48MHz can be generated by an alternate source */
+    bool need_48MHz;   /**< 48MHz is needed */
+} clk_cfg_t;
+
+/**
+ * @name Alternative 48MHz sources
+ * @{
+ */
+#define ALT_48MHZ_NO  0
+#define ALT_48MHZ_I2S 1
+#define ALT_48MHZ_SAI 2
+
+#define ALT_48MHZ_Q   0
+#define ALT_48MHZ_P   4
+/** @} */
+
+#define STM32F(x) [STM32F##x] = x
+
+/** List of supported models */
+static const unsigned stm32_model[] = {
+    STM32F(205),
+    STM32F(207),
+    STM32F(215),
+    STM32F(217),
+
+    STM32F(401),
+    STM32F(405),
+    STM32F(407),
+    STM32F(410),
+    STM32F(411),
+    STM32F(412),
+    STM32F(413),
+    STM32F(415),
+    STM32F(417),
+    STM32F(423),
+    STM32F(427),
+    STM32F(429),
+    STM32F(437),
+    STM32F(439),
+    STM32F(446),
+    STM32F(469),
+    STM32F(479),
+
+    STM32F(722),
+    STM32F(732),
+    STM32F(746),
+    STM32F(756),
+    STM32F(767),
+    STM32F(769),
+    STM32F(777),
+    STM32F(779),
+};
+
+/** STM32F2xx / STM32F401 PLL config */
+#define stm32f2_4_192_pll_cfg  { \
+    .min_vco_input = 1000000U, \
+    .max_vco_input = 2000000U, \
+    .min_vco_output = 192000000U, \
+    .max_vco_output = 432000000U, \
+    .min_n = 50, \
+    .max_n = 432, \
+    .inc_n = 1, \
+    .min_m = 2, \
+    .max_m = 63, \
+    .inc_m = 1, \
+    .min_p = 2, \
+    .max_p = 8, \
+    .inc_p = 2, \
+    .min_q = 2, \
+    .max_q = 15, \
+    .inc_q = 1, \
+}
+
+/** STM32F4 (except 401) / STM32F7 PLL config */
+#define stm32f4_7_pll_cfg  { \
+    .min_vco_input = 1000000U, \
+    .max_vco_input = 2000000U, \
+    .min_vco_output = 192000000U, \
+    .max_vco_output = 432000000U, \
+    .min_n = 50, \
+    .max_n = 432, \
+    .inc_n = 1, \
+    .min_m = 2, \
+    .max_m = 63, \
+    .inc_m = 1, \
+    .min_p = 2, \
+    .max_p = 8, \
+    .inc_p = 2, \
+    .min_q = 2, \
+    .max_q = 15, \
+    .inc_q = 1, \
+}
+
+/**
+ * @brief Clock config for supported cpu
+ */
+static const clk_cfg_t stm32_clk_cfg[] = {
+    [STM32F205 ... STM32F217] = {
+        .family = STM32F2,
+        .max_coreclock = 120000000U,
+        .max_apb1 = 30000000U,
+        .max_apb2 = 60000000U,
+        .hsi = 16000000U,
+        .pll = stm32f2_4_192_pll_cfg,
+        .has_pll_i2s = true,
+        .has_pll_sai = false,
+        .has_pll_i2s_alt_input = false,
+        .has_alt_48MHz = 0,
+        .need_48MHz = true,
+    },
+    [STM32F401] = {
+        .family = STM32F4,
+        .max_coreclock = 84000000U,
+        .max_apb1 = 42000000U,
+        .max_apb2 = 84000000U,
+        .hsi = 16000000U,
+        .pll = stm32f2_4_192_pll_cfg,
+        .has_pll_i2s = true,
+        .has_pll_sai = false,
+        .has_pll_i2s_m = false,
+        .has_pll_i2s_alt_input = false,
+        .has_alt_48MHz = 0,
+        .need_48MHz = true,
+    },
+    [STM32F405 ... STM32F407] = {
+        .family = STM32F4,
+        .max_coreclock = 168000000U,
+        .max_apb1 = 42000000U,
+        .max_apb2 = 84000000U,
+        .hsi = 16000000U,
+        .pll = stm32f4_7_pll_cfg,
+        .has_pll_i2s = true,
+        .has_pll_sai = false,
+        .has_pll_i2s_m = false,
+        .has_pll_i2s_alt_input = false,
+        .has_alt_48MHz = 0,
+        .need_48MHz = true,
+    },
+    [STM32F410] = {
+        .family = STM32F4,
+        .max_coreclock = 100000000U,
+        .max_apb1 = 50000000U,
+        .max_apb2 = 100000000U,
+        .hsi = 16000000U,
+        .pll = stm32f4_7_pll_cfg,
+        .has_pll_i2s = false,
+        .has_pll_sai = false,
+        .has_pll_i2s_m = false,
+        .has_pll_i2s_alt_input = false,
+        .has_alt_48MHz = 0,
+        .need_48MHz = true,
+    },
+    [STM32F411] = {
+        .family = STM32F4,
+        .max_coreclock = 100000000U,
+        .max_apb1 = 50000000U,
+        .max_apb2 = 100000000U,
+        .hsi = 16000000U,
+        .pll = stm32f4_7_pll_cfg,
+        .has_pll_i2s = true,
+        .has_pll_sai = false,
+        .has_pll_i2s_m = true,
+        .has_pll_i2s_alt_input = false,
+        .has_alt_48MHz = 0,
+        .need_48MHz = true,
+    },
+    [STM32F412 ... STM32F413] = {
+        .family = STM32F4,
+        .max_coreclock = 100000000U,
+        .max_apb1 = 50000000U,
+        .max_apb2 = 100000000U,
+        .hsi = 16000000U,
+        .pll = stm32f4_7_pll_cfg,
+        .has_pll_i2s = true,
+        .has_pll_sai = true,
+        .has_pll_i2s_m = true,
+        .has_pll_sai_m = false,
+        .has_pll_i2s_alt_input = true,
+        .has_alt_48MHz = ALT_48MHZ_I2S,
+        .need_48MHz = true,
+    },
+    [STM32F415 ... STM32F417] = {
+        .family = STM32F4,
+        .max_coreclock = 168000000U,
+        .max_apb1 = 42000000U,
+        .max_apb2 = 84000000U,
+        .hsi = 16000000U,
+        .pll = stm32f4_7_pll_cfg,
+        .has_pll_i2s = true,
+        .has_pll_sai = false,
+        .has_pll_i2s_m = false,
+        .has_pll_i2s_alt_input = false,
+        .has_alt_48MHz = 0,
+        .need_48MHz = true,
+    },
+    [STM32F423] = {
+        .family = STM32F4,
+        .max_coreclock = 100000000U,
+        .max_apb1 = 50000000U,
+        .max_apb2 = 100000000U,
+        .hsi = 16000000U,
+        .pll = stm32f4_7_pll_cfg,
+        .has_pll_i2s = true,
+        .has_pll_sai = true,
+        .has_pll_i2s_m = true,
+        .has_pll_sai_m = false,
+        .has_pll_i2s_alt_input = true,
+        .has_alt_48MHz = ALT_48MHZ_I2S,
+        .need_48MHz = true,
+    },
+    [STM32F427 ... STM32F439] = {
+        .family = STM32F4,
+        .max_coreclock = 180000000U,
+        .max_apb1 = 45000000U,
+        .max_apb2 = 90000000U,
+        .hsi = 16000000U,
+        .pll = stm32f4_7_pll_cfg,
+        .has_pll_i2s = true,
+        .has_pll_sai = true,
+        .has_pll_i2s_m = false,
+        .has_pll_sai_m = false,
+        .has_pll_i2s_alt_input = false,
+        .has_alt_48MHz = 0,
+        .need_48MHz = true,
+    },
+    [STM32F446] = {
+        .family = STM32F4,
+        .max_coreclock = 180000000U,
+        .max_apb1 = 45000000U,
+        .max_apb2 = 90000000U,
+        .hsi = 16000000U,
+        .pll = stm32f4_7_pll_cfg,
+        .has_pll_i2s = true,
+        .has_pll_sai = true,
+        .has_pll_i2s_m = true,
+        .has_pll_sai_m = true,
+        .has_pll_i2s_alt_input = false,
+        .has_alt_48MHz = ALT_48MHZ_SAI | ALT_48MHZ_P,
+        .need_48MHz = true,
+    },
+    [STM32F469 ... STM32F479] = {
+        .family = STM32F4,
+        .max_coreclock = 180000000U,
+        .max_apb1 = 45000000U,
+        .max_apb2 = 90000000U,
+        .hsi = 16000000U,
+        .pll = stm32f4_7_pll_cfg,
+        .has_pll_i2s = true,
+        .has_pll_sai = true,
+        .has_pll_i2s_m = false,
+        .has_pll_sai_m = false,
+        .has_pll_i2s_alt_input = false,
+        .has_alt_48MHz = ALT_48MHZ_SAI | ALT_48MHZ_P,
+        .need_48MHz = true,
+    },
+    [STM32F722 ... STM32F779] = {
+        .family = STM32F7,
+        .max_coreclock = 216000000U,
+        .max_apb1 = 54000000U,
+        .max_apb2 = 108000000U,
+        .hsi = 16000000U,
+        .pll = stm32f4_7_pll_cfg,
+        .has_pll_i2s = true,
+        .has_pll_sai = true,
+        .has_pll_i2s_m = false,
+        .has_pll_sai_m = false,
+        .has_pll_i2s_alt_input = false,
+        .has_alt_48MHz = ALT_48MHZ_SAI | ALT_48MHZ_P,
+        .need_48MHz = true,
+    },
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CLK_CONF_H */
diff --git a/cpu/stm32_common/doc.txt b/cpu/stm32_common/doc.txt
index a39cb647eb2354e6008a1535c46cc2db22d313c6..0827b1c627629b639ee81c4813a40ce6c28d1380 100644
--- a/cpu/stm32_common/doc.txt
+++ b/cpu/stm32_common/doc.txt
@@ -7,4 +7,39 @@
  * families supported by RIOT: @ref cpu_stm32f0, @ref cpu_stm32l0,
  * @ref cpu_stm32f1, @ref cpu_stm32f2, @ref cpu_stm32f3, @ref cpu_stm32f4,
  * @ref cpu_stm32l4, @ref cpu_stm32f7.
- */
\ No newline at end of file
+ *
+ * STM32F[2|4|7] Clock configuration
+ * =================================
+ *
+ * stm32f2, stm32f4 and stm32f7 cpus share clock configuration code and macro.
+ * It can be configured as described here.
+ *
+ * The following macro must be defined in the board's periph_conf.h:
+ *  - CLOCK_HSE: 0 if HSI must be used as PLL source, frequency in Hz otherwise,
+ *  - CLOCK_LSE: 0 if LSI must be used as low speed clock, 1 otherwise
+ * (the LSE is a 32.768kHz crytal)
+ *  - CLOCK_CORECLOCK: desired main clock frequency
+ *  - CLOCK_AHB_DIV, CLOCK_AHB: AHB prescaler in register value and AHB frequecny in Hz
+ *  - CLOCK_APB1_DIV, CLOCK_APB1: APB1 prescaler in register value and APB1 frequecny in Hz
+ *  - CLOCK_APB2_DIV, CLOCK_APB2: APB2 prescaler in register value and APB2 frequecny in Hz
+ *  - CLOCK_PLL_M, CLOCK_PLL_N, CLOCK_PLL_P, CLOCK_PLL_Q: Main PLL factors
+ *
+ * The following macro are optional and can be defined depending on board config
+ * and application needs:
+ *  - CLOCK_ENABLE_PLL_I2S: if a second PLL (PLL I2S) is available on the cpu, it
+ * can be activated with this macro, then CLOCK_PLL_I2S_M, CLOCK_PLL_I2S_N,
+ * CLOCK_PLL_I2S_P and CLOCK_PLL_I2S_Q need to be defined
+ *  - CLOCK_ENABLE_PLL_SAI: if a second PLL (PLL SAI) is available on the cpu, it
+ * can be activated with this macro, then CLOCK_PLL_SAI_M, CLOCK_PLL_SAI_N,
+ * CLOCK_PLL_SAI_P and CLOCK_PLL_SAI_Q need to be defined
+ *  - CLOCK_USE_ALT_48MHZ: if the 48MHz clock should be generated by the alternate
+ * source (PLL I2S or PLL SAI, depending on cpu)
+ *
+ * All the previous constants can be generated using the tool in
+ * `cpu/stm32_common/dist/clk_conf`.
+ *
+ * Clock outputs can also be setup with macro:
+ *  - CLOCK_MCOx_SRC, CLOCK_MCOx_PRE, with x=1,2: MCO1 and MCO2 output configuration
+ * macros. CLOCK_MCOx_SRC defines the MCOx source, as a register value (see vendor header),
+ * CLOCK_MCOx_PRE defines the MCOx prescaler, as a register value.
+ */
diff --git a/cpu/stm32_common/stmclk.c b/cpu/stm32_common/stmclk.c
new file mode 100644
index 0000000000000000000000000000000000000000..96f7e75a18d7b3b4b729cd24823cc61427b42003
--- /dev/null
+++ b/cpu/stm32_common/stmclk.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2017 Freie Universität Berlin
+ *               2017 OTA keys S.A.
+ *
+ * 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     cpu_stm32_common
+ * @{
+ *
+ * @file
+ * @brief       Implementation of STM32 clock configuration
+ *
+ * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
+ * @author      Vincent Dupont <vincent@otakeys.com>
+ * @}
+ */
+
+#if defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) || defined(CPU_FAM_STM32F7)
+
+#include "cpu.h"
+#include "stmclk.h"
+#include "periph_conf.h"
+
+/* make sure we have all needed information about the clock configuration */
+#ifndef CLOCK_HSE
+#error "Please provide CLOCK_HSE in your board's perhip_conf.h"
+#endif
+#ifndef CLOCK_LSE
+#error "Please provide CLOCK_LSE in your board's periph_conf.h"
+#endif
+#ifndef CLOCK_CORECLOCK
+#error "Please provide CLOCK_CORECLOCK in your board's periph_conf.h"
+#endif
+
+/**
+ * @name    PLL configuration
+ * @{
+ */
+/* figure out which input to use */
+#if (CLOCK_HSE)
+#define PLL_SRC                  RCC_PLLCFGR_PLLSRC_HSE
+#else
+#define PLL_SRC                  RCC_PLLCFGR_PLLSRC_HSI
+#endif
+
+#if (CLOCK_ENABLE_PLL_I2S)
+#ifdef RCC_PLLI2SCFGR_PLLI2SM_Pos
+#define PLLI2S_M                 (CLOCK_PLL_I2S_M << RCC_PLLI2SCFGR_PLLI2SM_Pos)
+#else
+#define PLLI2S_M                 (0)
+#endif
+#define PLLI2S_N                 (CLOCK_PLL_I2S_N << RCC_PLLI2SCFGR_PLLI2SN_Pos)
+#ifdef RCC_PLLI2SCFGR_PLLI2SP_Pos
+#define PLLI2S_P                 (((CLOCK_PLL_I2S_P / 2) - 1) << RCC_PLLI2SCFGR_PLLI2SP_Pos)
+#else
+#define PLLI2S_P                 (0)
+#endif
+#define PLLI2S_Q                 (CLOCK_PLL_I2S_Q << RCC_PLLI2SCFGR_PLLI2SQ_Pos)
+#endif /* CLOCK_ENABLE_PLLI_2S */
+
+#if (CLOCK_ENABLE_PLL_SAI)
+#ifdef RCC_PLLSAICFGR_PLLSAIN_Pos
+#define PLLSAI_M                 (CLOCK_PLL_SAI_M << RCC_PLLSAICFGR_PLLSAIN_Pos)
+#else
+#define PLLSAI_M                 (0)
+#endif
+#define PLLSAI_N                 (CLOCK_PLL_SAI_N << RCC_PLLSAICFGR_PLLSAIN_Pos)
+#ifdef RCC_PLLSAICFGR_PLLSAIP_Pos
+#define PLLSAI_P                 (((CLOCK_PLL_SAI_P / 2) - 1) << RCC_PLLSAICFGR_PLLSAIP_Pos)
+#else
+#define PLLSAI_P                 (0)
+#endif
+#define PLLSAI_Q                 (CLOCK_PLL_SAI_Q << RCC_PLLSAICFGR_PLLSAIQ_Pos)
+#endif /* CLOCK_ENABLE_PLL_SAI */
+
+#if defined(CPU_FAM_STM32F2)
+#define RCC_PLLCFGR_PLLP_Pos    (16U)
+#define RCC_PLLCFGR_PLLM_Pos    (0U)
+#define RCC_PLLCFGR_PLLN_Pos    (6U)
+#define RCC_PLLCFGR_PLLQ_Pos    (24U)
+#endif
+
+/* now we get the actual bitfields */
+#define PLL_P                   (((CLOCK_PLL_P / 2) - 1) << RCC_PLLCFGR_PLLP_Pos)
+#define PLL_M                   (CLOCK_PLL_M << RCC_PLLCFGR_PLLM_Pos)
+#define PLL_N                   (CLOCK_PLL_N << RCC_PLLCFGR_PLLN_Pos)
+#define PLL_Q                   (CLOCK_PLL_Q << RCC_PLLCFGR_PLLQ_Pos)
+/** @} */
+
+/**
+ * @name    Deduct the needed flash wait states from the core clock frequency
+ * @{
+ */
+#define FLASH_WAITSTATES        (CLOCK_CORECLOCK / 30000000U)
+/* we enable I+D cashes, pre-fetch, and we set the actual number of
+ * needed flash wait states */
+#if defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4)
+#define FLASH_ACR_CONFIG        (FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN | FLASH_WAITSTATES)
+#elif defined(CPU_FAM_STM32F7)
+#define FLASH_ACR_CONFIG        (FLASH_ACR_ARTEN | FLASH_ACR_PRFTEN | FLASH_WAITSTATES)
+#endif
+/** @} */
+
+void stmclk_init_sysclk(void)
+{
+    /* disable any interrupts. Global interrupts could be enabled if this is
+     * called from some kind of bootloader...  */
+    unsigned is = irq_disable();
+    RCC->CIR = 0;
+
+    /* enable HSI clock for the duration of initialization */
+    stmclk_enable_hsi();
+
+    /* use HSI as system clock while we do any further configuration and
+     * configure the AHB and APB clock dividers as configure by the board */
+    RCC->CFGR = (RCC_CFGR_SW_HSI | CLOCK_AHB_DIV |
+                 CLOCK_APB1_DIV | CLOCK_APB2_DIV);
+    while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) {}
+
+    /* Flash config */
+    FLASH->ACR = FLASH_ACR_CONFIG;
+
+    /* disable all active clocks except HSI -> resets the clk configuration */
+    RCC->CR = (RCC_CR_HSION | RCC_CR_HSITRIM_4);
+
+#if (CLOCK_MCO1_SRC)
+#ifndef RCC_CFGR_MCO1
+#error "stmclk: no MCO1 on this device"
+#endif
+    RCC->CFGR |= CLOCK_MCO1_SRC | CLOCK_MCO1_PRE;
+#endif
+#if (CLOCK_MCO2_SRC)
+#ifndef RCC_CFGR_MCO2
+#error "stmclk: no MCO2 on this device"
+#endif
+    RCC->CFGR |= CLOCK_MCO2_SRC | CLOCK_MCO2_PRE;
+#endif
+
+    /* if configured, we need to enable the HSE clock now */
+#if (CLOCK_HSE)
+    RCC->CR |= (RCC_CR_HSEON);
+    while (!(RCC->CR & RCC_CR_HSERDY)) {}
+#endif
+
+#if CLOCK_USE_ALT_48MHZ
+    RCC->DCKCFGR2 |= RCC_DCKCFGR2_CK48MSEL;
+#endif
+    /* now we can safely configure and start the PLL */
+    RCC->PLLCFGR = (PLL_SRC | PLL_M | PLL_N | PLL_P | PLL_Q);
+    RCC->CR |= (RCC_CR_PLLON);
+    while (!(RCC->CR & RCC_CR_PLLRDY)) {}
+
+    /* now that the PLL is running, we use it as system clock */
+    RCC->CFGR |= (RCC_CFGR_SW_PLL);
+    while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) {}
+
+    stmclk_disable_hsi();
+
+#if (CLOCK_ENABLE_PLLI2S)
+    RCC->PLLI2SCFGR = (PLLI2S_SRC | PLLI2S_M | PLLI2S_N | PLLI2s_P | PLLI2S_Q);
+    RCC->CR |= (RCC_CR_PLLI2SON);
+    while (!(RCC->CR & RCC_CR_PLLI2SRDY)) {}
+#endif /* CLOCK_ENABLE_PLLI2S */
+
+#if (CLOCK_ENABLE_PLLSAI)
+    RCC->PLLSAICFGR = (PLLSAI_M | PLLSAI_N | PLLSAI_P | PLLSAI_Q);
+    RCC->CR |= (RCC_CR_PLLSAION);
+    while (!(RCC->CR & RCC_CR_PLLSAIRDY)) {}
+#endif
+
+    irq_restore(is);
+}
+#else
+typedef int dont_be_pedantic;
+#endif /* defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) || defined(CPU_FAM_STM32F7) */
diff --git a/cpu/stm32f2/stmclk.c b/cpu/stm32f2/stmclk.c
deleted file mode 100644
index a32ca10e143b38f113b96c522d34249126bd5f12..0000000000000000000000000000000000000000
--- a/cpu/stm32f2/stmclk.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2017 Freie Universität Berlin
- *               2017 OTA keys S.A.
- *
- * 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     cpu_stm32f2
- * @{
- *
- * @file
- * @brief       Implementation of STM32 clock configuration
- *
- * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
- * @author      Vincent Dupont <vincent@otakeys.com>
- * @}
- */
-
-#include "cpu.h"
-#include "stmclk.h"
-#include "periph_conf.h"
-
-/* make sure we have all needed information about the clock configuration */
-#ifndef CLOCK_HSE
-#error "Please provide CLOCK_HSE in your board's perhip_conf.h"
-#endif
-#ifndef CLOCK_LSE
-#error "Please provide CLOCK_LSE in your board's periph_conf.h"
-#endif
-
-/**
- * @name    PLL configuration
- * @{
- */
-/* figure out which input to use */
-#if (CLOCK_HSE)
-#define PLL_IN                      CLOCK_HSE
-#define PLL_SRC                     RCC_PLLCFGR_PLLSRC_HSE
-#else
-#define PLL_IN                      (16000000U)         /* HSI fixed @ 16MHz */
-#define PLL_SRC                     RCC_PLLCFGR_PLLSRC_HSI
-#endif
-
-#ifndef P
-/* we fix P to 2 (so the PLL output equals 2 * CLOCK_CORECLOCK) */
-#define P                       (2U)
-#if ((P != 2) && (P != 4) && (P != 6) && (P != 8))
-#error "PLL configuration: PLL P value is invalid"
-#endif
-#endif /* P */
-/* the recommended input clock for the PLL should be 2MHz */
-#define M                       (PLL_IN / 2000000U)
-#if ((M < 2) || (M > 63))
-#error "PLL configuration: PLL M value is out of range"
-#endif
-/* next we multiply the input freq to 2 * CORECLOCK */
-#define N                       (P * CLOCK_CORECLOCK / 2000000U)
-#if ((N < 50) || (N > 432))
-#error "PLL configuration: PLL N value is out of range"
-#endif
-/* finally we need to set Q, so that the USB clock is 48MHz */
-#define Q                       ((P * CLOCK_CORECLOCK) / 48000000U)
-#if ((Q * 48000000U) != (P * CLOCK_CORECLOCK))
-#error "PLL configuration: USB frequency is not 48MHz"
-#endif
-
-#define RCC_PLLCFGR_PLLP_Pos    (16U)
-#define RCC_PLLCFGR_PLLM_Pos    (0U)
-#define RCC_PLLCFGR_PLLN_Pos    (6U)
-#define RCC_PLLCFGR_PLLQ_Pos    (24U)
-/* now we get the actual bitfields */
-#define PLL_P                   (((P / 2) - 1) << RCC_PLLCFGR_PLLP_Pos)
-#define PLL_M                   (M << RCC_PLLCFGR_PLLM_Pos)
-#define PLL_N                   (N << RCC_PLLCFGR_PLLN_Pos)
-#define PLL_Q                   (Q << RCC_PLLCFGR_PLLQ_Pos)
-/** @} */
-
-/**
- * @name    Deduct the needed flash wait states from the core clock frequency
- * @{
- */
-#define FLASH_WAITSTATES        (CLOCK_CORECLOCK / 30000000U)
-/** @} */
-
-void stmclk_init_sysclk(void)
-{
-    /* disable any interrupts. Global interrupts could be enabled if this is
-     * called from some kind of bootloader...  */
-    unsigned is = irq_disable();
-    RCC->CIR = 0;
-
-    /* enable HSI clock for the duration of initialization */
-    stmclk_enable_hsi();
-
-    /* use HSI as system clock while we do any further configuration and
-     * configure the AHB and APB clock dividers as configure by the board */
-    RCC->CFGR = (RCC_CFGR_SW_HSI | CLOCK_AHB_DIV |
-                 CLOCK_APB1_DIV | CLOCK_APB2_DIV);
-    while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) {}
-
-    /* we enable I+D cashes, pre-fetch, and we set the actual number of
-     * needed flash wait states */
-    FLASH->ACR = (FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN | FLASH_WAITSTATES);
-
-    /* disable all active clocks except HSI -> resets the clk configuration */
-    RCC->CR = (RCC_CR_HSION | RCC_CR_HSITRIM_4);
-
-    /* if configured, we need to enable the HSE clock now */
-#if (CLOCK_HSE)
-    RCC->CR |= (RCC_CR_HSEON);
-    while (!(RCC->CR & RCC_CR_HSERDY)) {}
-#endif
-
-#ifdef ENABLE_PLLI2S_MCO2
-    /* reset PLL I2S config register */
-    RCC->PLLI2SCFGR = 0x00000000U;
-    /* set PLL I2S division factor */
-    RCC->PLLI2SCFGR |= (CLOCK_PLL_I2S_R & 0x07) << 28;
-    /* set PLL I2S multiplication factor */
-    RCC->PLLI2SCFGR |= (CLOCK_PLL_I2S_N & 0x1FF) << 6;
-
-    /* MCO2 output is PLLI2S */
-    RCC->CFGR |= (uint32_t) RCC_CFGR_MCO2_0;
-    RCC->CFGR &= ~(uint32_t) RCC_CFGR_MCO2_1;
-    /* MCO2 prescaler div by 5 */
-    RCC->CFGR |= (uint32_t) ((CLOCK_MC02_PRE + 4 - 2) & 0x7) << 27;
-    /* enable PLL I2S clock */
-    RCC->CR |= RCC_CR_PLLI2SON;
-    /* wait till PLL I2S clock is ready */
-    while ((RCC->CR & RCC_CR_PLLI2SRDY) == 0) {}
-#endif
-
-    /* now we can safely configure and start the PLL */
-    RCC->PLLCFGR = (PLL_SRC | PLL_M | PLL_N | PLL_P | PLL_Q);
-    RCC->CR |= (RCC_CR_PLLON);
-    while (!(RCC->CR & RCC_CR_PLLRDY)) {}
-
-    /* now that the PLL is running, we use it as system clock */
-    RCC->CFGR |= (RCC_CFGR_SW_PLL);
-    while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) {}
-
-    stmclk_disable_hsi();
-    irq_restore(is);
-}
diff --git a/cpu/stm32f4/stmclk.c b/cpu/stm32f4/stmclk.c
deleted file mode 100644
index ea2281f445b3c5c53455b09d5538b1782453b5fd..0000000000000000000000000000000000000000
--- a/cpu/stm32f4/stmclk.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2017 Freie Universität Berlin
- *               2017 OTA keys S.A.
- *
- * 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     cpu_stm32f4
- * @{
- *
- * @file
- * @brief       Implementation of STM32 clock configuration
- *
- * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
- * @author      Vincent Dupont <vincent@otakeys.com>
- * @}
- */
-
-#include "cpu.h"
-#include "stmclk.h"
-#include "periph_conf.h"
-
-/* make sure we have all needed information about the clock configuration */
-#ifndef CLOCK_HSE
-#error "Please provide CLOCK_HSE in your board's perhip_conf.h"
-#endif
-#ifndef CLOCK_LSE
-#error "Please provide CLOCK_LSE in your board's periph_conf.h"
-#endif
-
-/**
- * @name    PLL configuration
- * @{
- */
-/* figure out which input to use */
-#if (CLOCK_HSE)
-#define PLL_IN                      CLOCK_HSE
-#define PLL_SRC                     RCC_PLLCFGR_PLLSRC_HSE
-#else
-#define PLL_IN                      (16000000U)         /* HSI fixed @ 16MHz */
-#define PLL_SRC                     RCC_PLLCFGR_PLLSRC_HSI
-#endif
-
-#ifndef P
-/* we fix P to 2 (so the PLL output equals 2 * CLOCK_CORECLOCK) */
-#define P                       (2U)
-#if ((P != 2) && (P != 4) && (P != 6) && (P != 8))
-#error "PLL configuration: PLL P value is invalid"
-#endif
-#endif /* P */
-/* the recommended input clock for the PLL should be 2MHz */
-#define M                       (PLL_IN / 2000000U)
-#if ((M < 2) || (M > 63))
-#error "PLL configuration: PLL M value is out of range"
-#endif
-/* next we multiply the input freq to 2 * CORECLOCK */
-#define N                       (P * CLOCK_CORECLOCK / 2000000U)
-#if ((N < 50) || (N > 432))
-#error "PLL configuration: PLL N value is out of range"
-#endif
-/* finally we need to set Q, so that the USB clock is 48MHz */
-#define Q                       ((P * CLOCK_CORECLOCK) / 48000000U)
-#if ((Q * 48000000U) != (P * CLOCK_CORECLOCK))
-#error "PLL configuration: USB frequency is not 48MHz"
-#endif
-
-/* now we get the actual bitfields */
-#define PLL_P                   (((P / 2) - 1) << RCC_PLLCFGR_PLLP_Pos)
-#define PLL_M                   (M << RCC_PLLCFGR_PLLM_Pos)
-#define PLL_N                   (N << RCC_PLLCFGR_PLLN_Pos)
-#define PLL_Q                   (Q << RCC_PLLCFGR_PLLQ_Pos)
-/** @} */
-
-/**
- * @name    Deduct the needed flash wait states from the core clock frequency
- * @{
- */
-#define FLASH_WAITSTATES        (CLOCK_CORECLOCK / 30000000U)
-/** @} */
-
-void stmclk_init_sysclk(void)
-{
-    /* disable any interrupts. Global interrupts could be enabled if this is
-     * called from some kind of bootloader...  */
-    unsigned is = irq_disable();
-    RCC->CIR = 0;
-
-    /* enable HSI clock for the duration of initialization */
-    stmclk_enable_hsi();
-
-    /* use HSI as system clock while we do any further configuration and
-     * configure the AHB and APB clock dividers as configure by the board */
-    RCC->CFGR = (RCC_CFGR_SW_HSI | CLOCK_AHB_DIV |
-                 CLOCK_APB1_DIV | CLOCK_APB2_DIV);
-    while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_HSI) {}
-
-    /* we enable I+D cashes, pre-fetch, and we set the actual number of
-     * needed flash wait states */
-    FLASH->ACR = (FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN | FLASH_WAITSTATES);
-
-    /* disable all active clocks except HSI -> resets the clk configuration */
-    RCC->CR = (RCC_CR_HSION | RCC_CR_HSITRIM_4);
-
-    /* if configured, we need to enable the HSE clock now */
-#if (CLOCK_HSE)
-    RCC->CR |= (RCC_CR_HSEON);
-    while (!(RCC->CR & RCC_CR_HSERDY)) {}
-#endif
-
-    /* now we can safely configure and start the PLL */
-    RCC->PLLCFGR = (PLL_SRC | PLL_M | PLL_N | PLL_P | PLL_Q);
-    RCC->CR |= (RCC_CR_PLLON);
-    while (!(RCC->CR & RCC_CR_PLLRDY)) {}
-
-    /* now that the PLL is running, we use it as system clock */
-    RCC->CFGR |= (RCC_CFGR_SW_PLL);
-    while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL) {}
-
-    stmclk_disable_hsi();
-    irq_restore(is);
-}
diff --git a/cpu/stm32f7/stmclk.c b/cpu/stm32f7/stmclk.c
deleted file mode 100644
index 4d00169390f80d264e2bcde1bb200e1ae16a37ef..0000000000000000000000000000000000000000
--- a/cpu/stm32f7/stmclk.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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     cpu_stm32f7
- * @{
- *
- * @file
- * @brief       Implementation of STM32 clock configuration
- *
- * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
- * @}
- */
-
-#include "cpu.h"
-#include "stmclk.h"
-#include "periph_conf.h"
-
-/* make sure we have all needed information about the clock configuration */
-#ifndef CLOCK_HSE
-#error "Please provide CLOCK_HSE in your board's perhip_conf.h"
-#endif
-#ifndef CLOCK_LSE
-#error "Please provide CLOCK_LSE in your board's periph_conf.h"
-#endif
-
-/**
- * @name    PLL configuration
- * @{
- */
-/* figure out which input to use */
-#if (CLOCK_HSE)
-#define PLL_IN                      CLOCK_HSE
-#define PLL_SRC                     RCC_PLLCFGR_PLLSRC_HSE
-#else
-#define PLL_IN                      (16000000U)         /* HSI fixed @ 16MHz */
-#define PLL_SRC                     RCC_PLLCFGR_PLLSRC_HSI
-#endif
-
-/* we fix P to 2 (so the PLL output equals 2 * CLOCK_CORECLOCK) */
-#define P                       (2U)
-/* the recommended input clock for the PLL should be 2MHz > ref. man. p. 143 */
-#define M                       (PLL_IN / 2000000U)
-#if ((M < 2) || (M > 63))
-#error "PLL configuration: PLL M value is out of range"
-#endif
-/* next we multiply the input freq to 2 * CORECLOCK */
-#define N                       (P * CLOCK_CORECLOCK / 2000000U)
-#if ((N < 50) || (N > 432))
-#error "PLL configuration: PLL N value is out of range"
-#endif
-/* finally we need to set Q, so that the USB clock is 48MHz */
-#define Q                       ((P * CLOCK_CORECLOCK) / 48000000U)
-#if ((Q * 48000000U) != (P * CLOCK_CORECLOCK))
-#error "PLL configuration: USB frequency is not 48MHz"
-#endif
-
-/* now we get the actual bitfields */
-#define PLL_P                   (0)
-#define PLL_M                   (M << RCC_PLLCFGR_PLLM_Pos)
-#define PLL_N                   (N << RCC_PLLCFGR_PLLN_Pos)
-#define PLL_Q                   (Q << RCC_PLLCFGR_PLLQ_Pos)
-/** @} */
-
-/**
- * @name    Deduct the needed flash wait states from the core clock frequency
- * @{
- */
-#define FLASH_WAITSTATES        (CLOCK_CORECLOCK / 30000000U)
-/** @} */
-
-void stmclk_init_sysclk(void)
-{
-    /* disable any interrupts. Global interrupts could be enabled if this is
-     * called from some kind of bootloader...  */
-    unsigned is = irq_disable();
-    RCC->CIR = 0;
-
-    /* enable HSI clock for the duration of initialization */
-    stmclk_enable_hsi();
-
-    /* use HSI as system clock while we do any further configuration and
-     * configure the AHB and APB clock dividers as configure by the board */
-    RCC->CFGR = (RCC_CFGR_SW_HSI | CLOCK_AHB_DIV |
-                 CLOCK_APB1_DIV | CLOCK_APB2_DIV);
-    while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_HSI) {}
-
-    /* we enable I+D cashes, pre-fetch, and we set the actual number of
-     * needed flash wait states */
-    FLASH->ACR = (FLASH_ACR_ARTEN | FLASH_ACR_PRFTEN | FLASH_WAITSTATES);
-
-    /* disable all active clocks except HSI -> resets the clk configuration */
-    RCC->CR = (RCC_CR_HSION | RCC_CR_HSITRIM_4);
-
-    /* if configured, we need to enable the HSE clock now */
-#if (CLOCK_HSE)
-    RCC->CR |= (RCC_CR_HSEON);
-    while (!(RCC->CR & RCC_CR_HSERDY)) {}
-#endif
-
-    /* now we can safely configure and start the PLL */
-    RCC->PLLCFGR = (PLL_SRC | PLL_M | PLL_N | PLL_P | PLL_Q);
-    RCC->CR |= (RCC_CR_PLLON);
-    while (!(RCC->CR & RCC_CR_PLLRDY)) {}
-
-    /* now that the PLL is running, we use it as system clock */
-    RCC->CFGR |= (RCC_CFGR_SW_PLL);
-    while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL) {}
-
-    stmclk_disable_hsi();
-    irq_restore(is);
-}