You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ut...@apache.org on 2020/02/19 15:00:23 UTC

[mynewt-core] branch master updated (c6e8680 -> a965755)

This is an automated email from the ASF dual-hosted git repository.

utzig pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git.


    from c6e8680  hw/bsp/da1469x: Fix help text in serial load script
     new 5dc1e8d  stm32: unify peripheral initialization
     new a965755  stm32: unify ADC initialization

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 hw/bsp/b-l072z-lrwan1/include/bsp/bsp.h            |   3 -
 hw/bsp/b-l072z-lrwan1/pkg.yml                      |   5 -
 hw/bsp/b-l072z-lrwan1/src/hal_bsp.c                | 124 ++---
 hw/bsp/b-l072z-lrwan1/syscfg.yml                   |  28 +-
 hw/bsp/b-l475e-iot01a/include/bsp/bsp.h            |   3 -
 hw/bsp/b-l475e-iot01a/pkg.yml                      |   5 -
 hw/bsp/b-l475e-iot01a/src/hal_bsp.c                | 112 +----
 hw/bsp/b-l475e-iot01a/syscfg.yml                   |  29 +-
 hw/bsp/black_vet6/include/bsp/bsp.h                |   4 -
 hw/bsp/black_vet6/pkg.yml                          |  13 -
 hw/bsp/black_vet6/src/hal_bsp.c                    | 511 ++++++---------------
 hw/bsp/black_vet6/syscfg.yml                       | 113 +----
 hw/bsp/bluepill/include/bsp/bsp.h                  |   3 -
 hw/bsp/bluepill/pkg.yml                            |   3 -
 hw/bsp/bluepill/src/hal_bsp.c                      | 134 +-----
 hw/bsp/bluepill/syscfg.yml                         |  31 +-
 hw/bsp/nucleo-f030r8/include/bsp/bsp.h             |   5 -
 hw/bsp/nucleo-f030r8/pkg.yml                       |   6 -
 hw/bsp/nucleo-f030r8/src/hal_bsp.c                 | 127 ++---
 hw/bsp/nucleo-f030r8/syscfg.yml                    |  17 +-
 hw/bsp/nucleo-f072rb/include/bsp/bsp.h             |   5 -
 hw/bsp/nucleo-f072rb/pkg.yml                       |   6 -
 hw/bsp/nucleo-f072rb/src/hal_bsp.c                 | 147 ++----
 hw/bsp/nucleo-f072rb/syscfg.yml                    |  31 +-
 hw/bsp/nucleo-f103rb/include/bsp/bsp.h             |  15 -
 hw/bsp/nucleo-f103rb/pkg.yml                       |   3 -
 hw/bsp/nucleo-f103rb/src/hal_bsp.c                 | 210 ++-------
 hw/bsp/nucleo-f103rb/syscfg.yml                    |  43 +-
 hw/bsp/nucleo-f303k8/include/bsp/bsp.h             |  13 +-
 hw/bsp/nucleo-f303k8/pkg.yml                       |  16 -
 hw/bsp/nucleo-f303k8/src/hal_bsp.c                 | 192 ++------
 hw/bsp/nucleo-f303k8/syscfg.yml                    |  30 +-
 hw/bsp/nucleo-f303re/include/bsp/bsp.h             |  15 +-
 hw/bsp/nucleo-f303re/pkg.yml                       |  15 -
 hw/bsp/nucleo-f303re/src/hal_bsp.c                 | 191 ++------
 hw/bsp/nucleo-f303re/syscfg.yml                    |  30 +-
 hw/bsp/nucleo-f401re/include/bsp/bsp.h             |   3 -
 hw/bsp/nucleo-f401re/pkg.yml                       |   5 -
 hw/bsp/nucleo-f401re/src/hal_bsp.c                 | 100 +---
 hw/bsp/nucleo-f401re/syscfg.yml                    |  19 +-
 hw/bsp/nucleo-f411re/include/bsp/bsp.h             |   3 -
 hw/bsp/nucleo-f411re/pkg.yml                       |   3 -
 hw/bsp/nucleo-f411re/src/hal_bsp.c                 | 187 +++-----
 hw/bsp/nucleo-f411re/syscfg.yml                    |  73 +--
 hw/bsp/nucleo-f413zh/include/bsp/bsp.h             |   3 -
 hw/bsp/nucleo-f413zh/pkg.yml                       |   3 -
 hw/bsp/nucleo-f413zh/src/hal_bsp.c                 | 106 +----
 hw/bsp/nucleo-f413zh/syscfg.yml                    |  18 +-
 hw/bsp/nucleo-f439zi/include/bsp/bsp.h             |   3 -
 hw/bsp/nucleo-f439zi/pkg.yml                       |  15 -
 hw/bsp/nucleo-f439zi/src/hal_bsp.c                 | 166 +------
 hw/bsp/nucleo-f439zi/syscfg.yml                    |  20 +-
 hw/bsp/nucleo-f746zg/include/bsp/bsp.h             |   8 -
 hw/bsp/nucleo-f746zg/pkg.yml                       |  15 -
 hw/bsp/nucleo-f746zg/src/hal_bsp.c                 | 181 ++------
 hw/bsp/nucleo-f746zg/syscfg.yml                    |  39 +-
 hw/bsp/nucleo-f767zi/include/bsp/bsp.h             |   8 -
 hw/bsp/nucleo-f767zi/pkg.yml                       |  15 -
 hw/bsp/nucleo-f767zi/src/hal_bsp.c                 | 181 ++------
 hw/bsp/nucleo-f767zi/syscfg.yml                    |  39 +-
 hw/bsp/nucleo-l476rg/include/bsp/bsp.h             |   3 -
 hw/bsp/nucleo-l476rg/pkg.yml                       |   5 -
 hw/bsp/nucleo-l476rg/src/hal_bsp.c                 | 108 +----
 hw/bsp/nucleo-l476rg/syscfg.yml                    |  61 +--
 hw/bsp/olimex-p103/include/bsp/bsp.h               |   3 -
 hw/bsp/olimex-p103/pkg.yml                         |   3 -
 hw/bsp/olimex-p103/src/hal_bsp.c                   | 134 +-----
 hw/bsp/olimex-p103/syscfg.yml                      |  31 +-
 .../olimex_stm32-e407_devboard/include/bsp/bsp.h   |   4 -
 hw/bsp/olimex_stm32-e407_devboard/pkg.yml          |  13 -
 hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c    | 460 ++++++-------------
 hw/bsp/olimex_stm32-e407_devboard/syscfg.yml       |  31 +-
 hw/bsp/p-nucleo-wb55/include/bsp/bsp.h             |   3 -
 hw/bsp/p-nucleo-wb55/pkg.yml                       |  11 -
 hw/bsp/p-nucleo-wb55/src/hal_bsp.c                 | 125 +----
 hw/bsp/p-nucleo-wb55/syscfg.yml                    |  27 +-
 hw/bsp/stm32f3discovery/include/bsp/bsp.h          |   7 +-
 hw/bsp/stm32f3discovery/pkg.yml                    |   6 -
 hw/bsp/stm32f3discovery/src/hal_bsp.c              | 140 +-----
 hw/bsp/stm32f3discovery/syscfg.yml                 |  33 +-
 hw/bsp/stm32f429discovery/include/bsp/bsp.h        |   3 -
 hw/bsp/stm32f429discovery/pkg.yml                  |   3 -
 hw/bsp/stm32f429discovery/src/hal_bsp.c            |  72 +--
 hw/bsp/stm32f429discovery/syscfg.yml               |  19 +-
 hw/bsp/stm32f4discovery/include/bsp/bsp.h          |   3 -
 hw/bsp/stm32f4discovery/pkg.yml                    |   3 -
 hw/bsp/stm32f4discovery/src/hal_bsp.c              | 113 ++---
 hw/bsp/stm32f4discovery/syscfg.yml                 |  25 +-
 hw/bsp/stm32f7discovery/include/bsp/bsp.h          |   8 -
 hw/bsp/stm32f7discovery/pkg.yml                    |  15 -
 hw/bsp/stm32f7discovery/src/hal_bsp.c              | 135 ++----
 hw/bsp/stm32f7discovery/syscfg.yml                 |  33 +-
 hw/bsp/stm32l152discovery/include/bsp/bsp.h        |   3 -
 hw/bsp/stm32l152discovery/pkg.yml                  |   3 -
 hw/bsp/stm32l152discovery/src/hal_bsp.c            | 114 +----
 hw/bsp/stm32l152discovery/syscfg.yml               |  27 +-
 .../stm32_common/include/stm32_common/stm32_hal.h  |  12 +-
 hw/mcu/stm/stm32_common/pkg.yml                    |  33 ++
 hw/mcu/stm/stm32_common/src/hal_uart.c             |  19 +-
 hw/mcu/stm/stm32_common/src/stm32_periph.c         | 412 +++++++++++++++++
 hw/mcu/stm/stm32_common/syscfg.yml                 | 206 +++++++++
 hw/mcu/stm/stm32f0xx/syscfg.yml                    |  15 -
 hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h       |   1 +
 hw/mcu/stm/stm32f1xx/syscfg.yml                    |  32 --
 hw/mcu/stm/stm32f3xx/syscfg.yml                    |  32 --
 hw/mcu/stm/stm32f4xx/syscfg.yml                    |  58 ---
 hw/mcu/stm/stm32f7xx/syscfg.yml                    |  22 -
 hw/mcu/stm/stm32l0xx/syscfg.yml                    |  26 --
 hw/mcu/stm/stm32l1xx/syscfg.yml                    |  26 --
 hw/mcu/stm/stm32l4xx/syscfg.yml                    |  58 ---
 hw/mcu/stm/stm32wbxx/syscfg.yml                    |  31 --
 111 files changed, 1903 insertions(+), 4318 deletions(-)
 create mode 100644 hw/mcu/stm/stm32_common/src/stm32_periph.c
 create mode 100644 hw/mcu/stm/stm32_common/syscfg.yml


[mynewt-core] 01/02: stm32: unify peripheral initialization

Posted by ut...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

utzig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 5dc1e8dacb375ef37ef241ea94f54ec11da6b47a
Author: Fabio Utzig <ut...@apache.org>
AuthorDate: Fri Feb 7 09:52:39 2020 -0300

    stm32: unify peripheral initialization
---
 hw/bsp/b-l072z-lrwan1/include/bsp/bsp.h            |   3 -
 hw/bsp/b-l072z-lrwan1/pkg.yml                      |   5 -
 hw/bsp/b-l072z-lrwan1/src/hal_bsp.c                | 124 ++-----
 hw/bsp/b-l072z-lrwan1/syscfg.yml                   |  28 +-
 hw/bsp/b-l475e-iot01a/include/bsp/bsp.h            |   3 -
 hw/bsp/b-l475e-iot01a/pkg.yml                      |   5 -
 hw/bsp/b-l475e-iot01a/src/hal_bsp.c                | 112 ++-----
 hw/bsp/b-l475e-iot01a/syscfg.yml                   |  29 +-
 hw/bsp/black_vet6/include/bsp/bsp.h                |   4 -
 hw/bsp/black_vet6/pkg.yml                          |   6 -
 hw/bsp/black_vet6/src/hal_bsp.c                    | 186 +++--------
 hw/bsp/black_vet6/syscfg.yml                       | 103 ++----
 hw/bsp/bluepill/include/bsp/bsp.h                  |   3 -
 hw/bsp/bluepill/pkg.yml                            |   3 -
 hw/bsp/bluepill/src/hal_bsp.c                      | 134 ++------
 hw/bsp/bluepill/syscfg.yml                         |  31 +-
 hw/bsp/nucleo-f030r8/include/bsp/bsp.h             |   5 -
 hw/bsp/nucleo-f030r8/pkg.yml                       |   6 -
 hw/bsp/nucleo-f030r8/src/hal_bsp.c                 | 127 +++----
 hw/bsp/nucleo-f030r8/syscfg.yml                    |  17 +-
 hw/bsp/nucleo-f072rb/include/bsp/bsp.h             |   5 -
 hw/bsp/nucleo-f072rb/pkg.yml                       |   6 -
 hw/bsp/nucleo-f072rb/src/hal_bsp.c                 | 147 +++------
 hw/bsp/nucleo-f072rb/syscfg.yml                    |  31 +-
 hw/bsp/nucleo-f103rb/include/bsp/bsp.h             |  15 -
 hw/bsp/nucleo-f103rb/pkg.yml                       |   3 -
 hw/bsp/nucleo-f103rb/src/hal_bsp.c                 | 210 +++---------
 hw/bsp/nucleo-f103rb/syscfg.yml                    |  43 ++-
 hw/bsp/nucleo-f303k8/include/bsp/bsp.h             |  13 +-
 hw/bsp/nucleo-f303k8/pkg.yml                       |  16 -
 hw/bsp/nucleo-f303k8/src/hal_bsp.c                 | 192 +++--------
 hw/bsp/nucleo-f303k8/syscfg.yml                    |  30 +-
 hw/bsp/nucleo-f303re/include/bsp/bsp.h             |  15 +-
 hw/bsp/nucleo-f303re/pkg.yml                       |  15 -
 hw/bsp/nucleo-f303re/src/hal_bsp.c                 | 191 +++--------
 hw/bsp/nucleo-f303re/syscfg.yml                    |  30 +-
 hw/bsp/nucleo-f401re/include/bsp/bsp.h             |   3 -
 hw/bsp/nucleo-f401re/pkg.yml                       |   5 -
 hw/bsp/nucleo-f401re/src/hal_bsp.c                 | 100 ++----
 hw/bsp/nucleo-f401re/syscfg.yml                    |  19 +-
 hw/bsp/nucleo-f411re/include/bsp/bsp.h             |   3 -
 hw/bsp/nucleo-f411re/pkg.yml                       |   3 -
 hw/bsp/nucleo-f411re/src/hal_bsp.c                 | 187 ++++-------
 hw/bsp/nucleo-f411re/syscfg.yml                    |  73 +----
 hw/bsp/nucleo-f413zh/include/bsp/bsp.h             |   3 -
 hw/bsp/nucleo-f413zh/pkg.yml                       |   3 -
 hw/bsp/nucleo-f413zh/src/hal_bsp.c                 | 106 ++----
 hw/bsp/nucleo-f413zh/syscfg.yml                    |  18 +-
 hw/bsp/nucleo-f439zi/include/bsp/bsp.h             |   3 -
 hw/bsp/nucleo-f439zi/pkg.yml                       |  15 -
 hw/bsp/nucleo-f439zi/src/hal_bsp.c                 | 166 ++--------
 hw/bsp/nucleo-f439zi/syscfg.yml                    |  20 +-
 hw/bsp/nucleo-f746zg/include/bsp/bsp.h             |   8 -
 hw/bsp/nucleo-f746zg/pkg.yml                       |  15 -
 hw/bsp/nucleo-f746zg/src/hal_bsp.c                 | 181 ++--------
 hw/bsp/nucleo-f746zg/syscfg.yml                    |  39 +--
 hw/bsp/nucleo-f767zi/include/bsp/bsp.h             |   8 -
 hw/bsp/nucleo-f767zi/pkg.yml                       |  15 -
 hw/bsp/nucleo-f767zi/src/hal_bsp.c                 | 181 ++--------
 hw/bsp/nucleo-f767zi/syscfg.yml                    |  39 +--
 hw/bsp/nucleo-l476rg/include/bsp/bsp.h             |   3 -
 hw/bsp/nucleo-l476rg/pkg.yml                       |   5 -
 hw/bsp/nucleo-l476rg/src/hal_bsp.c                 | 108 +-----
 hw/bsp/nucleo-l476rg/syscfg.yml                    |  61 +---
 hw/bsp/olimex-p103/include/bsp/bsp.h               |   3 -
 hw/bsp/olimex-p103/pkg.yml                         |   3 -
 hw/bsp/olimex-p103/src/hal_bsp.c                   | 134 ++------
 hw/bsp/olimex-p103/syscfg.yml                      |  31 +-
 .../olimex_stm32-e407_devboard/include/bsp/bsp.h   |   4 -
 hw/bsp/olimex_stm32-e407_devboard/pkg.yml          |   6 -
 hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c    | 139 +++-----
 hw/bsp/olimex_stm32-e407_devboard/syscfg.yml       |  21 +-
 hw/bsp/p-nucleo-wb55/include/bsp/bsp.h             |   3 -
 hw/bsp/p-nucleo-wb55/pkg.yml                       |  11 -
 hw/bsp/p-nucleo-wb55/src/hal_bsp.c                 | 125 +------
 hw/bsp/p-nucleo-wb55/syscfg.yml                    |  27 +-
 hw/bsp/stm32f3discovery/include/bsp/bsp.h          |   7 +-
 hw/bsp/stm32f3discovery/pkg.yml                    |   6 -
 hw/bsp/stm32f3discovery/src/hal_bsp.c              | 140 +-------
 hw/bsp/stm32f3discovery/syscfg.yml                 |  33 +-
 hw/bsp/stm32f429discovery/include/bsp/bsp.h        |   3 -
 hw/bsp/stm32f429discovery/pkg.yml                  |   3 -
 hw/bsp/stm32f429discovery/src/hal_bsp.c            |  72 ++--
 hw/bsp/stm32f429discovery/syscfg.yml               |  19 +-
 hw/bsp/stm32f4discovery/include/bsp/bsp.h          |   3 -
 hw/bsp/stm32f4discovery/pkg.yml                    |   3 -
 hw/bsp/stm32f4discovery/src/hal_bsp.c              | 113 ++-----
 hw/bsp/stm32f4discovery/syscfg.yml                 |  25 +-
 hw/bsp/stm32f7discovery/include/bsp/bsp.h          |   8 -
 hw/bsp/stm32f7discovery/pkg.yml                    |  15 -
 hw/bsp/stm32f7discovery/src/hal_bsp.c              | 135 ++------
 hw/bsp/stm32f7discovery/syscfg.yml                 |  33 +-
 hw/bsp/stm32l152discovery/include/bsp/bsp.h        |   3 -
 hw/bsp/stm32l152discovery/pkg.yml                  |   3 -
 hw/bsp/stm32l152discovery/src/hal_bsp.c            | 114 ++-----
 hw/bsp/stm32l152discovery/syscfg.yml               |  27 +-
 .../stm32_common/include/stm32_common/stm32_hal.h  |  12 +-
 hw/mcu/stm/stm32_common/pkg.yml                    |  26 ++
 hw/mcu/stm/stm32_common/src/hal_uart.c             |  19 +-
 hw/mcu/stm/stm32_common/src/stm32_periph.c         | 365 +++++++++++++++++++++
 hw/mcu/stm/stm32_common/syscfg.yml                 | 196 +++++++++++
 hw/mcu/stm/stm32f0xx/syscfg.yml                    |  15 -
 hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h       |   1 +
 hw/mcu/stm/stm32f1xx/syscfg.yml                    |  32 --
 hw/mcu/stm/stm32f3xx/syscfg.yml                    |  32 --
 hw/mcu/stm/stm32f4xx/syscfg.yml                    |  58 ----
 hw/mcu/stm/stm32f7xx/syscfg.yml                    |  22 --
 hw/mcu/stm/stm32l0xx/syscfg.yml                    |  26 --
 hw/mcu/stm/stm32l1xx/syscfg.yml                    |  26 --
 hw/mcu/stm/stm32l4xx/syscfg.yml                    |  58 ----
 hw/mcu/stm/stm32wbxx/syscfg.yml                    |  31 --
 111 files changed, 1613 insertions(+), 3864 deletions(-)

diff --git a/hw/bsp/b-l072z-lrwan1/include/bsp/bsp.h b/hw/bsp/b-l072z-lrwan1/include/bsp/bsp.h
index 6a93b93..55c6ce1 100644
--- a/hw/bsp/b-l072z-lrwan1/include/bsp/bsp.h
+++ b/hw/bsp/b-l072z-lrwan1/include/bsp/bsp.h
@@ -53,9 +53,6 @@ extern uint8_t _ram_start;
 #define SX1276_DIO5         (-1)
 #define SX1276_NRESET       MCU_GPIO_PORTC(0)
 
-/* UART */
-#define UART_CNT 1
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/bsp/b-l072z-lrwan1/pkg.yml b/hw/bsp/b-l072z-lrwan1/pkg.yml
index 3ef5e86..5c6cd9d 100644
--- a/hw/bsp/b-l072z-lrwan1/pkg.yml
+++ b/hw/bsp/b-l072z-lrwan1/pkg.yml
@@ -34,10 +34,5 @@ pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32l0xx"
     - "@apache-mynewt-core/libc/baselibc"
 
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-pkg.deps.UART_1:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
 pkg.deps.LORA_NODE:
     - "@apache-mynewt-core/hw/drivers/lora/sx1276"
diff --git a/hw/bsp/b-l072z-lrwan1/src/hal_bsp.c b/hw/bsp/b-l072z-lrwan1/src/hal_bsp.c
index 3295800..fd915e0 100644
--- a/hw/bsp/b-l072z-lrwan1/src/hal_bsp.c
+++ b/hw/bsp/b-l072z-lrwan1/src/hal_bsp.c
@@ -18,37 +18,19 @@
  */
 #include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
 #include <hal/hal_flash_int.h>
-#include <hal/hal_timer.h>
-
-#if MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_1_SLAVE)
-#include <hal/hal_spi.h>
-#endif
+#include <hal/hal_system.h>
 
 #include <stm32l072xx.h>
-#include <stm32l0xx_hal_rcc.h>
-#include <stm32l0xx_hal_pwr.h>
-#include <stm32l0xx_hal_flash.h>
-#include <stm32l0xx_hal_gpio_ex.h>
-#include <mcu/stm32l0_bsp.h>
-#include "mcu/stm32l0xx_mynewt_hal.h"
-#include "mcu/stm32_hal.h"
-#include "hal/hal_i2c.h"
-
-#include "bsp/bsp.h"
+#include <stm32_common/stm32_hal.h>
 
-#define TIMER_0_TIM TIM2
-#define TIMER_1_TIM TIM3
-#define TIMER_2_TIM TIM21
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
+#endif
 
 #if MYNEWT_VAL(LORA_NODE)
 
@@ -76,48 +58,44 @@
 
 #endif /* MYNEWT_VAL(LORA_NODE) */
 
-
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
-
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
-    [0] = {
-        .suc_uart = USART2,
-        .suc_rcc_reg = &RCC->APB1ENR,
-        .suc_rcc_dev = RCC_APB1ENR_USART2EN,
-        .suc_pin_tx = MCU_GPIO_PORTA(2),
-        .suc_pin_rx = MCU_GPIO_PORTA(3),
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af = GPIO_AF4_USART2,
-        .suc_irqn = USART2_IRQn
-    }
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART2,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART2EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF4_USART2,
+    .suc_irqn = USART2_IRQn,
 };
 #endif
 
 #if MYNEWT_VAL(I2C_0)
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(9),     /* PB9 on CN3 */
-    .hic_pin_scl = MCU_GPIO_PORTB(8),     /* PB8 on CN3 */
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
     .hic_timingr = 0x10420F13,      /* FIXME: 100KHz at 8MHz of SysCoreClock */
 };
 #endif
 
-#if MYNEWT_VAL(SPI_1_SLAVE) || MYNEWT_VAL(SPI_1_MASTER)
-struct stm32_hal_spi_cfg spi1_cfg = {
+#if ((MYNEWT_VAL(SPI_1_SLAVE) || MYNEWT_VAL(SPI_1_MASTER)) && \
+    MYNEWT_VAL(SPI_1_CUSTOM_CFG))
+const struct stm32_hal_spi_cfg os_bsp_spi1_cfg = {
 #if (MYNEWT_VAL(LORA_NODE) && (MYNEWT_VAL(SX1276_SPI_IDX) == 1))
-    .ss_pin   = MYNEWT_VAL(SX1276_SPI_CS_PIN),
+    .ss_pin = MYNEWT_VAL(SX1276_SPI_CS_PIN),
 #else
-    .ss_pin   = MCU_GPIO_PORTB(12),
+    .ss_pin = MYNEWT_VAL(SPI_1_PIN_SS),
 #endif
-    .sck_pin  = MCU_GPIO_PORTB(13),
-    .miso_pin = MCU_GPIO_PORTB(14),
-    .mosi_pin = MCU_GPIO_PORTB(15),
+    .sck_pin = MYNEWT_VAL(SPI_1_PIN_SCK),
+    .miso_pin = MYNEWT_VAL(SPI_1_PIN_MISO),
+    .mosi_pin = MYNEWT_VAL(SPI_1_PIN_MOSI),
     .irq_prio = 2,
 };
 #endif
@@ -152,47 +130,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[0]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIMER_0_TIM);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    hal_timer_init(1, TIMER_1_TIM);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    hal_timer_init(2, TIMER_2_TIM);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_1_MASTER)
-    rc = hal_spi_init(1, &spi1_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_1_SLAVE)
-    rc = hal_spi_init(1, &spi1_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
+    stm32_periph_create();
 }
 
 /**
@@ -217,11 +155,11 @@ void lora_bsp_enable_mac_timer(void)
     /* Turn on the LoRa MAC timer. This function is automatically
      * called by the LoRa stack when exiting low power mode.*/
     #if MYNEWT_VAL(LORA_MAC_TIMER_NUM) == 0
-        #define LORA_TIM  TIMER_0_TIM
+        #define LORA_TIM  MYNEWT_VAL(TIMER_0_TIM)
     #elif MYNEWT_VAL(LORA_MAC_TIMER_NUM) == 1
-        #define LORA_TIM  TIMER_1_TIM
+        #define LORA_TIM  MYNEWT_VAL(TIMER_1_TIM)
     #elif MYNEWT_VAL(LORA_MAC_TIMER_NUM) == 2
-        #define LORA_TIM  TIMER_2_TIM
+        #define LORA_TIM  MYNEWT_VAL(TIMER_2_TIM)
     #else
         #error "Invalid LORA_MAC_TIMER_NUM"
     #endif
diff --git a/hw/bsp/b-l072z-lrwan1/syscfg.yml b/hw/bsp/b-l072z-lrwan1/syscfg.yml
index 6d15159..6e5f7f2 100644
--- a/hw/bsp/b-l072z-lrwan1/syscfg.yml
+++ b/hw/bsp/b-l072z-lrwan1/syscfg.yml
@@ -22,22 +22,6 @@ syscfg.defs:
         description: 'Total flash size in KB.'
         value: 192
 
-    UART_0:
-        description: 'Whether to enable UART0'
-        value:  1
-
-    TIMER_0:
-        description: 'Whether to enable TIMER_0'
-        value: 1
-
-    TIMER_1:
-        description: 'Whether to enable TIMER_1'
-        value: 0
-
-    TIMER_2:
-        description: 'Whether to enable TIMER_2'
-        value: 0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -65,3 +49,15 @@ syscfg.vals:
     STM32_CLOCK_APB2_DIVIDER: 'RCC_HCLK_DIV1'
     STM32_FLASH_LATENCY: 1  # max 32MHz
     STM32_FLASH_PREFETCH_ENABLE: 0
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(2)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTA(3)'
+    SPI_1_CUSTOM_CFG: 1
+    SPI_1_PIN_SCK: 'MCU_GPIO_PORTB(13)'
+    SPI_1_PIN_MOSI: 'MCU_GPIO_PORTB(15)'
+    SPI_1_PIN_MISO: 'MCU_GPIO_PORTB(14)'
+    SPI_1_PIN_SS: 'MCU_GPIO_PORTB(12)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    TIMER_0_TIM: 'TIM2'
+    TIMER_1_TIM: 'TIM3'
+    TIMER_2_TIM: 'TIM21'
diff --git a/hw/bsp/b-l475e-iot01a/include/bsp/bsp.h b/hw/bsp/b-l475e-iot01a/include/bsp/bsp.h
index 2270653..e68beed 100644
--- a/hw/bsp/b-l475e-iot01a/include/bsp/bsp.h
+++ b/hw/bsp/b-l475e-iot01a/include/bsp/bsp.h
@@ -41,9 +41,6 @@ extern uint8_t _ram_start;
 /* LED pins */
 #define LED_BLINK_PIN       MCU_GPIO_PORTA(5)
 
-/* UART */
-#define UART_CNT 1
-
 /* Arduino pins */
 #define ARDUINO_PIN_D0      MCU_GPIO_PORTA(1)
 #define ARDUINO_PIN_D1      MCU_GPIO_PORTA(0)
diff --git a/hw/bsp/b-l475e-iot01a/pkg.yml b/hw/bsp/b-l475e-iot01a/pkg.yml
index 0e914f7..c555e20 100644
--- a/hw/bsp/b-l475e-iot01a/pkg.yml
+++ b/hw/bsp/b-l475e-iot01a/pkg.yml
@@ -37,11 +37,6 @@ pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32l4xx"
     - "@apache-mynewt-core/libc/baselibc"
 
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-pkg.deps.UART_1:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
 pkg.deps.LPS22HB_ONB:
     - "@apache-mynewt-core/hw/drivers/sensors/lps33hw"
 
diff --git a/hw/bsp/b-l475e-iot01a/src/hal_bsp.c b/hw/bsp/b-l475e-iot01a/src/hal_bsp.c
index a542eca..cf54745 100644
--- a/hw/bsp/b-l475e-iot01a/src/hal_bsp.c
+++ b/hw/bsp/b-l475e-iot01a/src/hal_bsp.c
@@ -18,20 +18,18 @@
  */
 #include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
 #include <hal/hal_flash_int.h>
-#include <hal/hal_timer.h>
+#include <hal/hal_system.h>
+
+#include <stm32l475xx.h>
+#include <stm32_common/stm32_hal.h>
 
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-#include <hal/hal_spi.h>
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
 #endif
 
 #if MYNEWT_VAL(LPS22HB_ONB)
@@ -39,29 +37,15 @@
 static struct lps33hw lps22hb;
 #endif
 
-#include <stm32l475xx.h>
-#include <stm32l4xx_hal_rcc.h>
-#include <stm32l4xx_hal_pwr.h>
-#include <stm32l4xx_hal_flash.h>
-#include <stm32l4xx_hal_gpio_ex.h>
-#include <mcu/stm32l4_bsp.h>
-#include "mcu/stm32l4xx_mynewt_hal.h"
-#include "mcu/stm32_hal.h"
-#include "hal/hal_i2c.h"
-
-#include "bsp/bsp.h"
-
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
-
-static const struct stm32_uart_cfg uart0_cfg = {
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
     .suc_uart = USART1,
     .suc_rcc_reg = &RCC->APB2ENR,
     .suc_rcc_dev = RCC_APB2ENR_USART1EN,
-    .suc_pin_tx = MCU_GPIO_PORTB(6),
-    .suc_pin_rx = MCU_GPIO_PORTB(7),
-    .suc_pin_rts = -1,
-    .suc_pin_cts = -1,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
     .suc_pin_af = GPIO_AF7_USART1,
     .suc_irqn = USART1_IRQn
 };
@@ -74,12 +58,12 @@ static const struct stm32_uart_cfg uart0_cfg = {
  * be removed (they are the default connections) and SB46/SB52 need to
  * be added.
  */
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR1,
     .hic_rcc_dev = RCC_APB1ENR1_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(9),     /* PB9 - D14 on CN1 */
-    .hic_pin_scl = MCU_GPIO_PORTB(8),     /* PB8 - D15 on CN1 */
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
     .hic_timingr = 0x10420F13,            /* 100KHz at 8MHz of SysCoreClock */
@@ -87,25 +71,15 @@ static struct stm32_hal_i2c_cfg i2c_cfg0 = {
 #endif
 
 #if MYNEWT_VAL(I2C_1)
-static struct stm32_hal_i2c_cfg i2c_cfg1 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c1_cfg = {
     .hic_i2c = I2C2,
     .hic_rcc_reg = &RCC->APB1ENR1,
     .hic_rcc_dev = RCC_APB1ENR1_I2C2EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(10),
-    .hic_pin_scl = MCU_GPIO_PORTB(11),
+    .hic_pin_sda = MYNEWT_VAL(I2C_1_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_1_PIN_SCL),
     .hic_pin_af = GPIO_AF4_I2C2,
     .hic_10bit = 0,
-    .hic_timingr = 0x10420F13,            /* 100KHz at 8MHz of SysCoreClock */
-};
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .ss_pin   = MCU_GPIO_PORTA(2),        /* D10 on CN1 */
-    .sck_pin  = MCU_GPIO_PORTA(5),        /* D13 on CN1 */
-    .miso_pin = MCU_GPIO_PORTA(6),        /* D12 on CN1 */
-    .mosi_pin = MCU_GPIO_PORTA(7),        /* D11 on CN1 */
-    .irq_prio = 2,
+    .hic_timingr = 0x10420F13,         /* 100KHz at 8MHz of SysCoreClock */
 };
 #endif
 
@@ -192,53 +166,7 @@ sensor_dev_create(void)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart0_cfg);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM2);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    hal_timer_init(1, TIM3);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    hal_timer_init(2, TIM4);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_1)
-    rc = hal_i2c_init(1, &i2c_cfg1);
-    assert(rc == 0);
-#endif
-
+    stm32_periph_create();
     sensor_dev_create();
 }
 
diff --git a/hw/bsp/b-l475e-iot01a/syscfg.yml b/hw/bsp/b-l475e-iot01a/syscfg.yml
index 6cd42ef..f63eb7e 100644
--- a/hw/bsp/b-l475e-iot01a/syscfg.yml
+++ b/hw/bsp/b-l475e-iot01a/syscfg.yml
@@ -22,22 +22,6 @@ syscfg.defs:
         description: 'Total flash size in KB.'
         value: 1024
 
-    UART_0:
-        description: 'Whether to enable UART0'
-        value:  1
-
-    TIMER_0:
-        description: 'Whether to enable TIMER_0'
-        value: 1
-
-    TIMER_1:
-        description: 'Whether to enable TIMER_1'
-        value: 0
-
-    TIMER_2:
-        description: 'Whether to enable TIMER_2'
-        value: 0
-
     LPS22HB_ONB:
         description: 'Enable onboard LPS22HB pressure sensor'
         value:  0
@@ -71,3 +55,16 @@ syscfg.vals:
     STM32_FLASH_PREFETCH_ENABLE: 0
     STM32_INSTRUCTION_CACHE_ENABLE: 1
     STM32_DATA_CACHE_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTB(6)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTB(7)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    I2C_1_PIN_SCL: 'MCU_GPIO_PORTB(11)'
+    I2C_1_PIN_SDA: 'MCU_GPIO_PORTB(10)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTA(5)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTA(7)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTA(6)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTA(2)'
+    TIMER_0_TIM: 'TIM2'
+    TIMER_1_TIM: 'TIM3'
+    TIMER_2_TIM: 'TIM4'
diff --git a/hw/bsp/black_vet6/include/bsp/bsp.h b/hw/bsp/black_vet6/include/bsp/bsp.h
index 84ec2e9..5bed3ec 100644
--- a/hw/bsp/black_vet6/include/bsp/bsp.h
+++ b/hw/bsp/black_vet6/include/bsp/bsp.h
@@ -43,10 +43,6 @@ extern uint8_t _ccram_start;
 /* LED pins */
 #define LED_BLINK_PIN   MCU_GPIO_PORTA(6)
 
-/* UART */
-#define UART_CNT 3
-#define SPI_SS_PIN       (4)
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/bsp/black_vet6/pkg.yml b/hw/bsp/black_vet6/pkg.yml
index 47e16b5..27b61b7 100644
--- a/hw/bsp/black_vet6/pkg.yml
+++ b/hw/bsp/black_vet6/pkg.yml
@@ -44,9 +44,3 @@ pkg.deps.ADC_2:
     - "@apache-mynewt-core/hw/drivers/adc/adc_stm32f4"
 pkg.deps.ADC_3:
     - "@apache-mynewt-core/hw/drivers/adc/adc_stm32f4"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
-pkg.deps.ETH_0:
-    - "@apache-mynewt-core/hw/drivers/lwip/stm32_eth"
diff --git a/hw/bsp/black_vet6/src/hal_bsp.c b/hw/bsp/black_vet6/src/hal_bsp.c
index 3967f6e..a36acfb 100644
--- a/hw/bsp/black_vet6/src/hal_bsp.c
+++ b/hw/bsp/black_vet6/src/hal_bsp.c
@@ -16,46 +16,36 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 #include <assert.h>
-#include "os/mynewt.h"
+
 #include "bsp/bsp.h"
+#include "os/mynewt.h"
+
+#include <hal/hal_bsp.h>
+#include <hal/hal_flash_int.h>
+#include <hal/hal_system.h>
+
 #include "stm32f407xx.h"
-#include "stm32f4xx_hal_gpio_ex.h"
-#include "stm32f4xx_hal_dma.h"
-#include "stm32f4xx_hal_adc.h"
-#include "flash_map/flash_map.h"
-#if MYNEWT_VAL(TRNG)
-#include "trng/trng.h"
-#include "trng_stm32/trng_stm32.h"
+#include <stm32_common/stm32_hal.h>
+
+#if MYNEWT_VAL(ETH_0)
+#include <stm32_eth/stm32_eth.h>
+#include <stm32_eth/stm32_eth_cfg.h>
 #endif
-#if MYNEWT_VAL(UART_0) || MYNEWT_VAL(UART_1) || MYNEWT_VAL(UART_2)
-#include "uart/uart.h"
-#include "uart_hal/uart_hal.h"
+
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
 #endif
+
 #if MYNEWT_VAL(ADC_1) || MYNEWT_VAL(ADC_2) || MYNEWT_VAL(ADC_3)
+#include "stm32f4xx_hal_adc.h"
 #include "adc_stm32f4/adc_stm32f4.h"
 #endif
-#include "hal/hal_i2c.h"
-#include "hal/hal_timer.h"
-#include "hal/hal_bsp.h"
-#include "hal/hal_gpio.h"
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-#include "hal/hal_spi.h"
-#endif
-#if MYNEWT_VAL(ETH_0)
-#include "stm32_eth/stm32_eth.h"
-#include "stm32_eth/stm32_eth_cfg.h"
-#endif
-#include "mcu/stm32_hal.h"
-#include "mcu/stm32f4_bsp.h"
-#include "mcu/stm32f4xx_mynewt_hal.h"
 
 #if MYNEWT_VAL(SPIFLASH)
 #include <spiflash/spiflash.h>
 #endif
 
-
 const uint32_t stm32_flash_sectors[] = {
     0x08000000,     /* 16kB */
     0x08004000,     /* 16kB */
@@ -72,27 +62,6 @@ const uint32_t stm32_flash_sectors[] = {
 static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) + 1 == SZ,
         "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
-#if MYNEWT_VAL(TRNG)
-static struct trng_dev os_bsp_trng;
-#endif
-
-#if MYNEWT_VAL(UART_0)
-struct uart_dev hal_uart0;
-#endif
-
-#if MYNEWT_VAL(UART_1)
-struct uart_dev hal_uart1;
-#endif
-
-#if MYNEWT_VAL(UART_2)
-struct uart_dev hal_uart2;
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE) || \
-    MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_1_SLAVE)
-#include <hal/hal_spi.h>
-#endif
-
 #if MYNEWT_VAL(ADC_1)
 struct adc_dev my_dev_adc1;
 #endif
@@ -295,79 +264,59 @@ struct stm32f4_adc_dev_cfg adc3_config = STM32F4_ADC3_DEFAULT_CONFIG;
 #endif
 
 #if MYNEWT_VAL(I2C_0)
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(9),
-    .hic_pin_scl = MCU_GPIO_PORTB(8),
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
-    .hic_speed = 100000				/* 100kHz */
-};
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .ss_pin = -1,
-    .sck_pin  = MYNEWT_VAL(SPI_0_SCK),
-    .miso_pin = MYNEWT_VAL(SPI_0_MISO),
-    .mosi_pin = MYNEWT_VAL(SPI_0_MOSI),
-    .irq_prio = 2
-};
-#endif
-
-#if MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_1_SLAVE)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .ss_pin = -1,
-    .sck_pin  = MYNEWT_VAL(SPI_1_SCK),
-    .miso_pin = MYNEWT_VAL(SPI_1_MISO),
-    .mosi_pin = MYNEWT_VAL(SPI_1_MOSI),
-    .irq_prio = 2
+    .hic_speed = 100000,
 };
 #endif
 
 #if MYNEWT_VAL(UART_0)
-static const struct stm32_uart_cfg uart_cfg0 = {
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
     .suc_uart = USART1,
     .suc_rcc_reg = &RCC->APB2ENR,
     .suc_rcc_dev = RCC_APB2ENR_USART1EN,
-    .suc_pin_tx = MYNEWT_VAL(UART_0_TX),
-    .suc_pin_rx = MYNEWT_VAL(UART_0_RX),
-    .suc_pin_rts = MYNEWT_VAL(UART_0_RTS),
-    .suc_pin_cts = MYNEWT_VAL(UART_0_CTS),
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
     .suc_pin_af = GPIO_AF7_USART1,
     .suc_irqn = USART1_IRQn
 };
 #endif
 #if MYNEWT_VAL(UART_1)
-static const struct stm32_uart_cfg uart_cfg1 = {
+const struct stm32_uart_cfg os_bsp_uart1_cfg = {
     .suc_uart = USART2,
     .suc_rcc_reg = &RCC->APB1ENR,
     .suc_rcc_dev = RCC_APB1ENR_USART2EN,
-    .suc_pin_tx = MYNEWT_VAL(UART_1_TX),
-    .suc_pin_rx = MYNEWT_VAL(UART_1_RX),
-    .suc_pin_rts = MYNEWT_VAL(UART_1_RTS),
-    .suc_pin_cts = MYNEWT_VAL(UART_1_CTS),
+    .suc_pin_tx = MYNEWT_VAL(UART_1_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_1_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_1_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_1_PIN_CTS),
     .suc_pin_af = GPIO_AF7_USART2,
     .suc_irqn = USART2_IRQn
 };
 #endif
 #if MYNEWT_VAL(UART_2)
-static const struct stm32_uart_cfg uart_cfg2 = {
+const struct stm32_uart_cfg os_bsp_uart2_cfg = {
     .suc_uart = USART3,
     .suc_rcc_reg = &RCC->APB1ENR,
     .suc_rcc_dev = RCC_APB1ENR_USART3EN,
-    .suc_pin_tx = MYNEWT_VAL(UART_2_TX),
-    .suc_pin_rx = MYNEWT_VAL(UART_2_RX),
-    .suc_pin_rts = MYNEWT_VAL(UART_2_RTS),
-    .suc_pin_cts = MYNEWT_VAL(UART_2_CTS),
+    .suc_pin_tx = MYNEWT_VAL(UART_2_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_2_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_2_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_2_PIN_CTS),
     .suc_pin_af = GPIO_AF7_USART3,
     .suc_irqn = USART3_IRQn
 };
 #endif
 #if MYNEWT_VAL(ETH_0)
-static const struct stm32_eth_cfg eth_cfg = {
+const struct stm32_eth_cfg os_bsp_eth0_cfg = {
     /*
      * PORTA
      *   PA1 - ETH_RMII_REF_CLK
@@ -474,39 +423,7 @@ hal_bsp_init(void)
 
     (void)rc;
 
-#if MYNEWT_VAL(TRNG)
-    rc = os_dev_create(&os_bsp_trng.dev, "trng", OS_DEV_INIT_KERNEL,
-                       OS_DEV_INIT_PRIO_DEFAULT, stm32_trng_dev_init, NULL);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg0);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_1)
-    rc = os_dev_create((struct os_dev *) &hal_uart1, "uart1",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg1);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_2)
-    rc = os_dev_create((struct os_dev *) &hal_uart2, "uart2",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg2);
-    assert(rc == 0);
-#endif
+    stm32_periph_create();
 
 #if MYNEWT_VAL(ADC_1)
     rc = os_dev_create((struct os_dev *) &my_dev_adc1, "adc1",
@@ -526,31 +443,4 @@ hal_bsp_init(void)
             stm32f4_adc_dev_init, &adc3_config);
     assert(rc == 0);
 #endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM2);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    hal_timer_init(1, TIM3);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    hal_timer_init(2, TIM4);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(ETH_0)
-    rc = stm32_eth_init(&eth_cfg);
-    assert(rc == 0);
-#endif
 }
diff --git a/hw/bsp/black_vet6/syscfg.yml b/hw/bsp/black_vet6/syscfg.yml
index d1c2d3d..83384ce 100644
--- a/hw/bsp/black_vet6/syscfg.yml
+++ b/hw/bsp/black_vet6/syscfg.yml
@@ -35,88 +35,6 @@ syscfg.defs:
         description: "ADC_3"
         value:  0
 
-    UART_0:
-        description: 'Whether to enable UART0'
-        value:  1
-    UART_0_TX:
-        description: 'USART1 TX pin. TX from J6 connector'
-        value:  'MCU_GPIO_PORTA(9)'
-    UART_0_RX:
-        description: 'USART1 RX pin. RX from J6 connector'
-        value:  'MCU_GPIO_PORTA(10)'
-    UART_0_RTS:
-        description: 'USART1 RTS pin.'
-        value:  -1
-    UART_0_CTS:
-        description: 'USART1 CTS pin.'
-        value:  -1
-
-    UART_1:
-        description: 'Whether to enable UART0'
-        value:  1
-    UART_1_TX:
-        description: 'USART2 TX pin. PA2, PD5'
-        value:  'MCU_GPIO_PORTD(5)'
-    UART_1_RX:
-        description: 'USART2 RX pin. PA3, PD6'
-        value:  'MCU_GPIO_PORTD(6)'
-    UART_1_RTS:
-        description: 'USART2 RTS pin.'
-        value:  -1
-    UART_1_CTS:
-        description: 'USART2 CTS pin.'
-        value:  -1
-
-    UART_2:
-        description: 'Whether to enable UART0'
-        value:  1
-    UART_2_TX:
-        description: 'USART3 TX pin. PB10, PC10, PD8'
-        value:  'MCU_GPIO_PORTD(8)'
-    UART_2_RX:
-        description: 'USART3 RX pin. PB11, PC11, PD9'
-        value:  'MCU_GPIO_PORTD(9)'
-    UART_2_RTS:
-        description: 'USART3 RTS pin.'
-        value:  -1
-    UART_2_CTS:
-        description: 'USART3 CTS pin.'
-        value:  -1
-
-    SPI_0_SCK:
-        description: 'SPI_0 clock pin'
-        value: 'MCU_GPIO_PORTB(3)'
-    SPI_0_MISO:
-        description: 'SPI_0 MISO pin'
-        value: 'MCU_GPIO_PORTB(4)'
-    SPI_0_MOSI:
-        description: 'SPI_0 MOSI pin'
-        value: 'MCU_GPIO_PORTB(5)'
-
-    SPI_1_SCK:
-        description: 'SPI_1 clock pin'
-        value: 'MCU_GPIO_PORTB(13)'
-    SPI_1_MISO:
-        description: 'SPI_1 MISO pin'
-        value: 'MCU_GPIO_PORTB(14)'
-    SPI_1_MOSI:
-        description: 'SPI_1 MOSI pin'
-        value: 'MCU_GPIO_PORTB(15)'
-
-    TIMER_0:
-        description: 'Enable TIMER_0, (TIM2 up to 84MHz, 32 bits)'
-        value: 1
-    TIMER_1:
-        description: 'Enable TIMER_1, (TIM3 up to 84MHz, 16 bits)'
-        value: 0
-    TIMER_2:
-        description: 'Enable TIMER_2, (TIM4 up to 84MHz, 16 bits)'
-        value: 0
-
-    ETH_0:
-        description: 'Ethernet driver for LwIP'
-        value: 0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -166,3 +84,24 @@ syscfg.vals:
     SPIFLASH_TCE_MAXIMUM: 10000000
 
     BSP_FLASH_SPI_BUS: '"spi0"'
+
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(9)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTA(10)'
+    UART_1: 1
+    UART_1_PIN_TX: 'MCU_GPIO_PORTD(5)'
+    UART_1_PIN_RX: 'MCU_GPIO_PORTD(6)'
+    UART_2: 1
+    UART_2_PIN_TX: 'MCU_GPIO_PORTD(8)'
+    UART_2_PIN_RX: 'MCU_GPIO_PORTD(9)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTA(4)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTB(3)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTB(4)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTB(5)'
+    SPI_1_PIN_SCK: 'MCU_GPIO_PORTB(13)'
+    SPI_1_PIN_MISO: 'MCU_GPIO_PORTB(14)'
+    SPI_1_PIN_MOSI: 'MCU_GPIO_PORTB(15)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    TIMER_0_TIM: 'TIM2'
+    TIMER_1_TIM: 'TIM3'
+    TIMER_2_TIM: 'TIM4'
diff --git a/hw/bsp/bluepill/include/bsp/bsp.h b/hw/bsp/bluepill/include/bsp/bsp.h
index a273763..34d3f99 100644
--- a/hw/bsp/bluepill/include/bsp/bsp.h
+++ b/hw/bsp/bluepill/include/bsp/bsp.h
@@ -43,9 +43,6 @@ extern uint8_t _ram_start;
 /* NOTE: no LED is installed here */
 #define LED_2           MCU_GPIO_PORTC(0)
 
-/* UART */
-#define UART_CNT 1
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/bsp/bluepill/pkg.yml b/hw/bsp/bluepill/pkg.yml
index 3b776d0..81cd190 100644
--- a/hw/bsp/bluepill/pkg.yml
+++ b/hw/bsp/bluepill/pkg.yml
@@ -33,6 +33,3 @@ pkg.deps:
     - '@apache-mynewt-core/hw/mcu/stm/stm32f1xx'
     - '@apache-mynewt-core/kernel/os'
     - '@apache-mynewt-core/libc/baselibc'
-
-pkg.deps.UART_0:
-    - '@apache-mynewt-core/hw/drivers/uart/uart_hal'
diff --git a/hw/bsp/bluepill/src/hal_bsp.c b/hw/bsp/bluepill/src/hal_bsp.c
index 21044f8..4895035 100644
--- a/hw/bsp/bluepill/src/hal_bsp.c
+++ b/hw/bsp/bluepill/src/hal_bsp.c
@@ -16,86 +16,43 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 #include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
 #include <hal/hal_flash_int.h>
-#include <hal/hal_timer.h>
-
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE) || \
-    MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_1_SLAVE)
-#include <hal/hal_spi.h>
-#endif
+#include <hal/hal_system.h>
 
 #include <stm32f103xb.h>
-#include <stm32f1xx_hal_rcc.h>
-#include <stm32f1xx_hal_pwr.h>
-#include <stm32f1xx_hal_flash.h>
-#include <stm32f1xx_hal_gpio_ex.h>
-#include <stm32f1xx_ll_gpio.h>       /* AF remapping */
-#include <mcu/stm32f1_bsp.h>
-#include "mcu/stm32f1xx_mynewt_hal.h"
-#include "mcu/stm32_hal.h"
-#include "hal/hal_i2c.h"
-
-#include "bsp/bsp.h"
-
-#if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
+#include <stm32_common/stm32_hal.h>
 
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
-    [0] = {
-        .suc_uart = USART2,
-        .suc_rcc_reg = &RCC->APB1ENR,
-        .suc_rcc_dev = RCC_APB1ENR_USART2EN,
-        .suc_pin_tx = MCU_GPIO_PORTA(2),
-        .suc_pin_rx = MCU_GPIO_PORTA(3),
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_remap_fn = LL_GPIO_AF_DisableRemap_USART2,
-        .suc_irqn = USART2_IRQn,
-    }
-};
-#endif
-
-/* NOTE: UEXT connector */
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .ss_pin   = MCU_GPIO_PORTA(4),
-    .sck_pin  = MCU_GPIO_PORTA(5),
-    .miso_pin = MCU_GPIO_PORTA(6),
-    .mosi_pin = MCU_GPIO_PORTA(7),
-    .irq_prio = 2,
-};
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
 #endif
 
-/* NOTE: SD-MMC */
-#if MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_1_SLAVE)
-struct stm32_hal_spi_cfg spi1_cfg = {
-    .ss_pin   = MCU_GPIO_PORTB(12),
-    .sck_pin  = MCU_GPIO_PORTB(13),
-    .miso_pin = MCU_GPIO_PORTB(14),
-    .mosi_pin = MCU_GPIO_PORTB(15),
-    .irq_prio = 2,
+#if MYNEWT_VAL(UART_0)
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART2,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART2EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_remap_fn = LL_GPIO_AF_DisableRemap_USART2,
+    .suc_irqn = USART2_IRQn,
 };
 #endif
 
 #if MYNEWT_VAL(I2C_0)
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(7),
-    .hic_pin_scl = MCU_GPIO_PORTB(6),
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_remap_fn = LL_GPIO_AF_DisableRemap_I2C1,
     .hic_10bit = 0,
     .hic_speed = 100000,
@@ -132,58 +89,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[0]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM2);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    hal_timer_init(1, TIM3);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    hal_timer_init(2, TIM4);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_1_MASTER)
-    rc = hal_spi_init(1, &spi1_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_1_SLAVE)
-    rc = hal_spi_init(1, &spi1_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/bluepill/syscfg.yml b/hw/bsp/bluepill/syscfg.yml
index 4f33ade..0b83d06 100644
--- a/hw/bsp/bluepill/syscfg.yml
+++ b/hw/bsp/bluepill/syscfg.yml
@@ -22,22 +22,6 @@ syscfg.defs:
         description: 'Total flash size in KB.'
         value: 128
 
-    UART_0:
-        description: 'UART 0'
-        value:  1
-
-    TIMER_0:
-        description: 'Timer 0'
-        value:  1
-
-    TIMER_1:
-        description: 'Timer 1'
-        value:  0
-
-    TIMER_2:
-        description: 'Timer 2'
-        value:  0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -53,3 +37,18 @@ syscfg.vals:
     STM32_CLOCK_APB2_DIVIDER: 'RCC_HCLK_DIV1'
     STM32_FLASH_LATENCY: 'FLASH_LATENCY_2'
     STM32_FLASH_PREFETCH_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(2)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTA(3)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTA(4)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTA(5)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTA(6)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTA(7)'
+    SPI_1_PIN_SS: 'MCU_GPIO_PORTB(12)'
+    SPI_1_PIN_SCK: 'MCU_GPIO_PORTB(13)'
+    SPI_1_PIN_MISO: 'MCU_GPIO_PORTB(14)'
+    SPI_1_PIN_MOSI: 'MCU_GPIO_PORTB(15)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(6)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(7)'
+    TIMER_0_TIM: 'TIM2'
+    TIMER_1_TIM: 'TIM3'
+    TIMER_2_TIM: 'TIM4'
diff --git a/hw/bsp/nucleo-f030r8/include/bsp/bsp.h b/hw/bsp/nucleo-f030r8/include/bsp/bsp.h
index 6debfed..b99e75a 100644
--- a/hw/bsp/nucleo-f030r8/include/bsp/bsp.h
+++ b/hw/bsp/nucleo-f030r8/include/bsp/bsp.h
@@ -43,11 +43,6 @@ extern uint8_t _ram_start;
 
 /* LED pins */
 #define LED_BLINK_PIN MCU_GPIO_PORTA(5)
-   
-/* UART ports */
-#define UART_CNT 2
-#define UART_0_DEV_ID   0
-#define UART_1_DEV_ID   1
 
 /* Arduino pins */
 #define ARDUINO_PIN_D0      MCU_GPIO_PORTA(3)
diff --git a/hw/bsp/nucleo-f030r8/pkg.yml b/hw/bsp/nucleo-f030r8/pkg.yml
index dd42775..748fc93 100644
--- a/hw/bsp/nucleo-f030r8/pkg.yml
+++ b/hw/bsp/nucleo-f030r8/pkg.yml
@@ -36,9 +36,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f0xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
-pkg.deps.UART_1:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
diff --git a/hw/bsp/nucleo-f030r8/src/hal_bsp.c b/hw/bsp/nucleo-f030r8/src/hal_bsp.c
index 9b3eafa..84ad267 100644
--- a/hw/bsp/nucleo-f030r8/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f030r8/src/hal_bsp.c
@@ -16,84 +16,64 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-#include <stddef.h>
+#include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#include "assert.h"
-#include "bsp/bsp.h"
-#include "hal/hal_bsp.h"
-#include "hal/hal_flash_int.h"
-#include "hal/hal_gpio.h"
-#include "hal/hal_system.h"
-#include "mcu/mcu.h"
-#include "mcu/stm32f0_bsp.h"
-#include "stm32f0xx.h"
-#include "stm32f0xx_hal.h"
-#include "stm32f0xx_hal_gpio.h"
-#include "stm32f0xx_hal_rcc.h"
-#include "mcu/stm32f0xx_mynewt_hal.h"
+#include <hal/hal_bsp.h>
+#include <hal/hal_flash_int.h>
+#include <hal/hal_system.h>
 
-#if MYNEWT_VAL(I2C_0)
-#include "stm32f0xx_hal_i2c.h"
-#include "hal/hal_i2c.h"
-#endif
+#include <stm32f030x8.h>
+#include <stm32_common/stm32_hal.h>
 
-#if MYNEWT_VAL(UART_0) || MYNEWT_VAL(UART_1)
-
-/*
- * It is necessary to include uart/uart.h before stm32fxx_hal_uart.h gets included
- * due to a name conflict for UART_PARITY_NONE.
- */
-#include "stm32f0xx_hal_usart.h"
-#include "stm32f0xx_hal_usart_ex.h"
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-static struct uart_dev hal_uart[UART_CNT];
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
+#endif
 
-static const struct 
-stm32_uart_cfg uart_cfg[UART_CNT] = {
-    [0] = {
-        .suc_uart    = USART2,
-        .suc_rcc_reg = &RCC->APB1ENR,
-        .suc_rcc_dev = RCC_APB1ENR_USART2EN,
-        .suc_pin_tx  = MCU_GPIO_PORTA(2),
-        .suc_pin_rx  = MCU_GPIO_PORTA(3),
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af  = GPIO_AF1_USART2,
-        .suc_irqn    = USART2_IRQn
-    },
-    [1] = {
-        .suc_uart    = USART1,
-        .suc_rcc_reg = &RCC->APB2ENR,
-        .suc_rcc_dev = RCC_APB2ENR_USART1EN,
-        .suc_pin_tx  = MCU_GPIO_PORTA(9),
-        .suc_pin_rx  = MCU_GPIO_PORTA(10),
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af  = GPIO_AF1_USART1,
-        .suc_irqn    = USART1_IRQn
-    }
+#if MYNEWT_VAL(UART_0)
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART2,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART2EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF1_USART2,
+    .suc_irqn = USART2_IRQn,
 };
 #endif
 
+#if MYNEWT_VAL(UART_1)
+const struct stm32_uart_cfg os_bsp_uart1_cfg = {
+    .suc_uart = USART1,
+    .suc_rcc_reg = &RCC->APB2ENR,
+    .suc_rcc_dev = RCC_APB2ENR_USART1EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_1_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_1_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_1_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_1_PIN_CTS),
+    .suc_pin_af = GPIO_AF1_USART1,
+    .suc_irqn = USART1_IRQn,
+};
+#endif
 
 #if MYNEWT_VAL(I2C_0)
-static struct 
-stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(9),     /* PB9 on CN3 */
-    .hic_pin_scl = MCU_GPIO_PORTB(8),     /* PB8 on CN3 */
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF3_I2C1,
     .hic_10bit = 0,
     .hic_timingr = 0x10420F13,      /* FIXME: 100KHz at 8MHz of SysCoreClock */
 };
 #endif
 
-static const struct 
+static const struct
 hal_bsp_mem_dump dump_cfg[] = {
     [0] = {
         .hbmd_start = &_ram_start,
@@ -140,34 +120,5 @@ hal_bsp_get_nvic_priority(int irq_num, uint32_t pri)
 void
 hal_bsp_init(void)
 {
-    int rc;
-    (void)rc;  /* in case there are no devices declared */
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart[UART_0_DEV_ID], "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[UART_0_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_1)
-    rc = os_dev_create((struct os_dev *) &hal_uart[UART_1_DEV_ID], "uart1",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[UART_1_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    rc = hal_timer_init(0, TIM15);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
+    stm32_periph_create();
 }
diff --git a/hw/bsp/nucleo-f030r8/syscfg.yml b/hw/bsp/nucleo-f030r8/syscfg.yml
index 1db4f92..e398046 100644
--- a/hw/bsp/nucleo-f030r8/syscfg.yml
+++ b/hw/bsp/nucleo-f030r8/syscfg.yml
@@ -22,16 +22,6 @@ syscfg.defs:
         description: 'Total flash size in KB.'
         value: 64
 
-    UART_0:
-        description: 'Whether to enable UART0'
-        value:  1
-    UART_1:
-        description: 'Whether to enable UART1'
-        value:  0
-    TIMER_0:
-        description: 'Support for timer 0'
-        value: 1
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -48,3 +38,10 @@ syscfg.vals:
     STM32_CLOCK_APB1_DIVIDER: 'RCC_HCLK_DIV1'
     STM32_FLASH_LATENCY: 'FLASH_LATENCY_1'
     STM32_FLASH_PREFETCH_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(2)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTA(3)'
+    UART_1_PIN_TX: 'MCU_GPIO_PORTA(9)'
+    UART_1_PIN_RX: 'MCU_GPIO_PORTA(10)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    TIMER_0_TIM: 'TIM15'
diff --git a/hw/bsp/nucleo-f072rb/include/bsp/bsp.h b/hw/bsp/nucleo-f072rb/include/bsp/bsp.h
index 54b68fe..e93ca23 100644
--- a/hw/bsp/nucleo-f072rb/include/bsp/bsp.h
+++ b/hw/bsp/nucleo-f072rb/include/bsp/bsp.h
@@ -44,11 +44,6 @@ extern uint8_t _ram_start;
 /* LED pins */
 #define LED_BLINK_PIN MCU_GPIO_PORTA(5)
 
-/* UART ports */
-#define UART_CNT 2
-#define UART_0_DEV_ID   0
-#define UART_1_DEV_ID   1
-
 /* Arduino pins */
 #define ARDUINO_PIN_D0      MCU_GPIO_PORTA(3)
 #define ARDUINO_PIN_D1      MCU_GPIO_PORTA(2)
diff --git a/hw/bsp/nucleo-f072rb/pkg.yml b/hw/bsp/nucleo-f072rb/pkg.yml
index 3ed423d..b904c49 100644
--- a/hw/bsp/nucleo-f072rb/pkg.yml
+++ b/hw/bsp/nucleo-f072rb/pkg.yml
@@ -36,9 +36,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f0xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
-pkg.deps.UART_1:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
diff --git a/hw/bsp/nucleo-f072rb/src/hal_bsp.c b/hw/bsp/nucleo-f072rb/src/hal_bsp.c
index ec7f076..752bde4 100644
--- a/hw/bsp/nucleo-f072rb/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f072rb/src/hal_bsp.c
@@ -16,61 +16,51 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-#include <stddef.h>
+#include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0) || MYNEWT_VAL(UART_1)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
+#include <hal/hal_bsp.h>
+#include <hal/hal_flash_int.h>
+#include <hal/hal_system.h>
 
-#include "hal/hal_bsp.h"
-#include "hal/hal_gpio.h"
-#include <hal/hal_timer.h>
-#if MYNEWT_VAL(I2C_0)
-#include "hal/hal_i2c.h"
-#endif
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-#include <hal/hal_spi.h>
-#endif
 #include <stm32f072xb.h>
-#include "hal/hal_system.h"
-#include <mcu/mcu.h>
-#include "bsp/bsp.h"
-#include "mcu/stm32_hal.h"
-#include <assert.h>
+#include <stm32_common/stm32_hal.h>
 
-#if MYNEWT_VAL(UART_0) || MYNEWT_VAL(UART_1)
-static struct uart_dev hal_uart[UART_CNT];
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
+#endif
 
-static const struct
-stm32_uart_cfg uart_cfg[UART_CNT] = {
-    [0] = {
-        .suc_uart    = USART2,
-        .suc_rcc_reg = &RCC->APB1ENR,
-        .suc_rcc_dev = RCC_APB1ENR_USART2EN,
-        .suc_pin_tx  = MCU_GPIO_PORTA(2),
-        .suc_pin_rx  = MCU_GPIO_PORTA(3),
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af  = GPIO_AF1_USART2,
-        .suc_irqn    = USART2_IRQn
-    },
-    [1] = {
-        .suc_uart    = USART1,
-        .suc_rcc_reg = &RCC->APB2ENR,
-        .suc_rcc_dev = RCC_APB2ENR_USART1EN,
-        .suc_pin_tx  = MCU_GPIO_PORTA(9),
-        .suc_pin_rx  = MCU_GPIO_PORTA(10),
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af  = GPIO_AF1_USART1,
-        .suc_irqn    = USART1_IRQn
-    }
+#if MYNEWT_VAL(UART_0)
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART2,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART2EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF1_USART2,
+    .suc_irqn = USART2_IRQn,
 };
 #endif
 
+#if MYNEWT_VAL(UART_1)
+const struct stm32_uart_cfg os_bsp_uart1_cfg = {
+    .suc_uart = USART1,
+    .suc_rcc_reg = &RCC->APB2ENR,
+    .suc_rcc_dev = RCC_APB2ENR_USART1EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_1_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_1_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_1_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_1_PIN_CTS),
+    .suc_pin_af = GPIO_AF1_USART1,
+    .suc_irqn = USART1_IRQn,
+};
+#endif
+
+
 #if MYNEWT_VAL(I2C_0)
 /*
  * NOTE: The PB8 and PB9 pins are connected through jumpers in the board to
@@ -78,29 +68,18 @@ stm32_uart_cfg uart_cfg[UART_CNT] = {
  * be removed (they are the default connections) and SB46/SB52 need to
  * be added.
  */
-static struct
-stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(9),     /* CN5 - D14 */
-    .hic_pin_scl = MCU_GPIO_PORTB(8),     /* CN5 - D15 */
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF1_I2C1,
     .hic_10bit = 0,
     .hic_timingr = 0x10420F13,      /* FIXME: 100KHz at 8MHz of SysCoreClock */
 };
 #endif
 
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .ss_pin   = MCU_GPIO_PORTB(6),        /* CN5 - D10 */
-    .sck_pin  = MCU_GPIO_PORTA(5),        /* CN5 - D13 */
-    .miso_pin = MCU_GPIO_PORTA(6),        /* CN5 - D12 */
-    .mosi_pin = MCU_GPIO_PORTA(7),        /* CN5 - D11 */
-    .irq_prio = 2
-};
-#endif
-
 static const struct
 hal_bsp_mem_dump dump_cfg[] = {
     [0] = {
@@ -148,53 +127,5 @@ hal_bsp_get_nvic_priority(int irq_num, uint32_t pri)
 void
 hal_bsp_init(void)
 {
-    int rc;
-    (void)rc;  /* in case there are no devices declared */
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart[UART_0_DEV_ID], "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[UART_0_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_1)
-    rc = os_dev_create((struct os_dev *) &hal_uart[UART_1_DEV_ID], "uart1",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[UART_1_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    rc = hal_timer_init(0, TIM15);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    rc = hal_timer_init(1, TIM16);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    rc = hal_timer_init(2, TIM17);
-    assert(rc == 0);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
+    stm32_periph_create();
 }
diff --git a/hw/bsp/nucleo-f072rb/syscfg.yml b/hw/bsp/nucleo-f072rb/syscfg.yml
index 1d430bf..dbe0c8d 100644
--- a/hw/bsp/nucleo-f072rb/syscfg.yml
+++ b/hw/bsp/nucleo-f072rb/syscfg.yml
@@ -22,23 +22,6 @@ syscfg.defs:
         description: 'Total flash size in KB.'
         value: 128
 
-    UART_0:
-        description: 'Whether to enable UART0'
-        value:  1
-    UART_1:
-        description: 'Whether to enable UART1'
-        value:  0
-
-    TIMER_0:
-        description: 'Support for TIMER_0'
-        value: 1
-    TIMER_1:
-        description: 'Support for TIMER_1'
-        value: 0
-    TIMER_2:
-        description: 'Support for TIMER_2'
-        value: 0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -55,3 +38,17 @@ syscfg.vals:
     STM32_CLOCK_APB1_DIVIDER: 'RCC_HCLK_DIV1'
     STM32_FLASH_LATENCY: 'FLASH_LATENCY_1'
     STM32_FLASH_PREFETCH_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(2)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTA(3)'
+    UART_1_PIN_TX: 'MCU_GPIO_PORTA(9)'
+    UART_1_PIN_RX: 'MCU_GPIO_PORTA(10)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTB(6)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTA(5)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTA(6)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTA(7)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    TIMER_0: 1
+    TIMER_0_TIM: 'TIM15'
+    TIMER_1_TIM: 'TIM16'
+    TIMER_2_TIM: 'TIM17'
diff --git a/hw/bsp/nucleo-f103rb/include/bsp/bsp.h b/hw/bsp/nucleo-f103rb/include/bsp/bsp.h
index c1d6d52..ebe72ea 100644
--- a/hw/bsp/nucleo-f103rb/include/bsp/bsp.h
+++ b/hw/bsp/nucleo-f103rb/include/bsp/bsp.h
@@ -42,21 +42,6 @@ extern uint8_t _ram_start;
 /* One led LED pin, two names */
 #define LED_BLINK_PIN   ARDUINO_PIN_D13
 
-/* UART ports */
-enum {
-#if MYNEWT_VAL(UART_0)
-    UART_0_DEV_ID,
-#endif
-#if MYNEWT_VAL(UART_1)
-    UART_1_DEV_ID,
-#endif
-#if MYNEWT_VAL(UART_2)
-    UART_2_DEV_ID,
-#endif
-};
-
-#define UART_CNT (MYNEWT_VAL(UART_0) + MYNEWT_VAL(UART_1) + MYNEWT_VAL(UART_2))
-
 /* Arduino pins */
 #define ARDUINO_PIN_D0      MCU_GPIO_PORTA(3)
 #define ARDUINO_PIN_D1      MCU_GPIO_PORTA(2)
diff --git a/hw/bsp/nucleo-f103rb/pkg.yml b/hw/bsp/nucleo-f103rb/pkg.yml
index fa3a706..fce363c 100644
--- a/hw/bsp/nucleo-f103rb/pkg.yml
+++ b/hw/bsp/nucleo-f103rb/pkg.yml
@@ -31,6 +31,3 @@ pkg.cflags: -DSTM32F103xB
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f1xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
diff --git a/hw/bsp/nucleo-f103rb/src/hal_bsp.c b/hw/bsp/nucleo-f103rb/src/hal_bsp.c
index a4f534c..41173e7 100644
--- a/hw/bsp/nucleo-f103rb/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f103rb/src/hal_bsp.c
@@ -16,138 +16,75 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 #include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
 #include <hal/hal_flash_int.h>
-#include <hal/hal_timer.h>
-
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE) || \
-    MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_1_SLAVE)
-#include <hal/hal_spi.h>
-#endif
+#include <hal/hal_system.h>
 
 #include <stm32f103xb.h>
-#include <stm32f1xx_hal_rcc.h>
-#include <stm32f1xx_hal_pwr.h>
-#include <stm32f1xx_hal_flash.h>
-#include <stm32f1xx_hal_gpio_ex.h>
-#include <stm32f1xx_ll_gpio.h>       /* AF remapping */
-#include <mcu/stm32f1_bsp.h>
-#include "mcu/stm32f1xx_mynewt_hal.h"
-#include "mcu/stm32_hal.h"
-#include "hal/hal_i2c.h"
+#include <stm32_common/stm32_hal.h>
+
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
+#endif
 
 #if MYNEWT_VAL(SPIFLASH)
 #include <spiflash/spiflash.h>
 #endif
 
-#include "bsp/bsp.h"
-
-#if UART_CNT > 0
-static struct uart_dev hal_uart[UART_CNT];
-
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
 #if MYNEWT_VAL(UART_0)
-    {
-        .suc_uart         = USART2,
-        .suc_rcc_reg      = &RCC->APB1ENR,
-        .suc_rcc_dev      = RCC_APB1ENR_USART2EN,
-        .suc_pin_tx       = MCU_GPIO_PORTA(2),
-        .suc_pin_rx       = MCU_GPIO_PORTA(3),
-        .suc_pin_rts      = -1,
-        .suc_pin_cts      = -1,
-        .suc_pin_remap_fn = LL_GPIO_AF_DisableRemap_USART2,
-        .suc_irqn         = USART2_IRQn
-    },
-#endif
-#if MYNEWT_VAL(UART_1)
-{
-        .suc_uart         = USART1,
-        .suc_rcc_reg      = &RCC->APB2ENR,
-        .suc_rcc_dev      = RCC_APB2ENR_USART1EN,
-        .suc_pin_tx       = MCU_GPIO_PORTA(9),
-        .suc_pin_rx       = MCU_GPIO_PORTA(10),
-        .suc_pin_rts      = -1,
-        .suc_pin_cts      = -1,
-        .suc_pin_remap_fn = LL_GPIO_AF_DisableRemap_USART1,
-        .suc_irqn         = USART1_IRQn
-    },
-#endif
-#if MYNEWT_VAL(UART_2)
-{
-        .suc_uart         = USART3,
-        .suc_rcc_reg      = &RCC->APB1ENR,
-        .suc_rcc_dev      = RCC_APB1ENR_USART3EN,
-        .suc_pin_tx       = MCU_GPIO_PORTB(10),
-        .suc_pin_rx       = MCU_GPIO_PORTB(11),
-        .suc_pin_rts      = -1,
-        .suc_pin_cts      = -1,
-        .suc_pin_remap_fn = LL_GPIO_AF_DisableRemap_USART3,
-        .suc_irqn         = USART3_IRQn
-    },
-#endif
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART2,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART2EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_remap_fn = LL_GPIO_AF_DisableRemap_USART2,
+    .suc_irqn = USART2_IRQn,
 };
-
-const struct stm32_uart_cfg *
-bsp_uart_config(int port)
-{
-    assert(port < UART_CNT);
-    return &uart_cfg[port];
-}
-
-static const char *uart_dev_name[UART_CNT] = {
-#if UART_CNT > 0
-    "uart0",
-#endif
-#if UART_CNT > 1
-    "uart1",
-#endif
-#if UART_CNT > 2
-    "uart2",
-#endif
-};
-
 #endif
 
-/* NOTE: UEXT connector */
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .ss_pin   = MCU_GPIO_PORTA(4),
-    .sck_pin  = MCU_GPIO_PORTA(5),
-    .miso_pin = MCU_GPIO_PORTA(6),
-    .mosi_pin = MCU_GPIO_PORTA(7),
-    .irq_prio = 2,
+#if MYNEWT_VAL(UART_1)
+const struct stm32_uart_cfg os_bsp_uart1_cfg = {
+    .suc_uart = USART1,
+    .suc_rcc_reg = &RCC->APB2ENR,
+    .suc_rcc_dev = RCC_APB2ENR_USART1EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_1_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_1_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_1_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_1_PIN_CTS),
+    .suc_pin_remap_fn = LL_GPIO_AF_DisableRemap_USART1,
+    .suc_irqn = USART1_IRQn,
 };
 #endif
 
-/* NOTE: SD-MMC */
-#if MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_1_SLAVE)
-struct stm32_hal_spi_cfg spi1_cfg = {
-    .ss_pin   = MCU_GPIO_PORTB(12),
-    .sck_pin  = MCU_GPIO_PORTB(13),
-    .miso_pin = MCU_GPIO_PORTB(14),
-    .mosi_pin = MCU_GPIO_PORTB(15),
-    .irq_prio = 2,
+#if MYNEWT_VAL(UART_2)
+const struct stm32_uart_cfg os_bsp_uart1_cfg = {
+    .suc_uart = USART3,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART3EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_2_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_2_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_2_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_2_PIN_CTS),
+    .suc_pin_remap_fn = LL_GPIO_AF_DisableRemap_USART3,
+    .suc_irqn = USART3_IRQn,
 };
 #endif
 
 #if MYNEWT_VAL(I2C_0)
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(7),
-    .hic_pin_scl = MCU_GPIO_PORTB(6),
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_remap_fn = LL_GPIO_AF_DisableRemap_I2C1,
     .hic_10bit = 0,
     .hic_speed = 100000,
@@ -200,68 +137,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *)&hal_uart[UART_0_DEV_ID],
-                       uart_dev_name[UART_0_DEV_ID], OS_DEV_INIT_PRIMARY, 0,
-                       uart_hal_init, (void *)&uart_cfg[UART_0_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_1)
-    rc = os_dev_create((struct os_dev *)&hal_uart[UART_1_DEV_ID],
-                       uart_dev_name[UART_1_DEV_ID], OS_DEV_INIT_PRIMARY, 0,
-                       uart_hal_init, (void *)&uart_cfg[UART_1_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_2)
-    rc = os_dev_create((struct os_dev *)&hal_uart[UART_2_DEV_ID],
-                       uart_dev_name[UART_2_DEV_ID], OS_DEV_INIT_PRIMARY, 0,
-                       uart_hal_init, (void *)&uart_cfg[UART_2_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM2);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    hal_timer_init(1, TIM3);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    hal_timer_init(2, TIM4);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_1_MASTER)
-    rc = hal_spi_init(1, &spi1_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_1_SLAVE)
-    rc = hal_spi_init(1, &spi1_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/nucleo-f103rb/syscfg.yml b/hw/bsp/nucleo-f103rb/syscfg.yml
index 501a6c2..742ec83 100644
--- a/hw/bsp/nucleo-f103rb/syscfg.yml
+++ b/hw/bsp/nucleo-f103rb/syscfg.yml
@@ -22,30 +22,6 @@ syscfg.defs:
         description: 'Total flash size in KB.'
         value: 128
 
-    UART_0:
-        description: 'USART 2, mapped to PA2/D1 for TX and PA3/D0 for RX, routed to USB by default'
-        value:  1
-
-    UART_1:
-        description: 'USART 1, mapped to PA9/D8 for TX, and PA10/D2 for RX'
-        value:  0
-
-    UART_2:
-        description: 'USART 3, mapped to PB10 for TX and PB11 for RX'
-        value:  0
-
-    TIMER_0:
-        description: 'TIM2'
-        value:  1
-
-    TIMER_1:
-        description: 'TIM3'
-        value:  0
-
-    TIMER_2:
-        description: 'TIM4'
-        value:  0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -61,3 +37,22 @@ syscfg.vals:
     STM32_CLOCK_APB2_DIVIDER: 'RCC_HCLK_DIV1'
     STM32_FLASH_LATENCY: 'FLASH_LATENCY_2'
     STM32_FLASH_PREFETCH_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(2)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTA(3)'
+    UART_1_PIN_TX: 'MCU_GPIO_PORTA(9)'
+    UART_1_PIN_RX: 'MCU_GPIO_PORTA(10)'
+    UART_2_PIN_TX: 'MCU_GPIO_PORTB(10)'
+    UART_2_PIN_RX: 'MCU_GPIO_PORTB(11)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTA(4)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTA(5)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTA(6)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTA(7)'
+    SPI_1_PIN_SS: 'MCU_GPIO_PORTB(12)'
+    SPI_1_PIN_SCK: 'MCU_GPIO_PORTB(13)'
+    SPI_1_PIN_MISO: 'MCU_GPIO_PORTB(14)'
+    SPI_1_PIN_MOSI: 'MCU_GPIO_PORTB(15)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(6)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(7)'
+    TIMER_0_TIM: 'TIM2'
+    TIMER_1_TIM: 'TIM3'
+    TIMER_2_TIM: 'TIM4'
diff --git a/hw/bsp/nucleo-f303k8/include/bsp/bsp.h b/hw/bsp/nucleo-f303k8/include/bsp/bsp.h
index 1d39976..9230af1 100644
--- a/hw/bsp/nucleo-f303k8/include/bsp/bsp.h
+++ b/hw/bsp/nucleo-f303k8/include/bsp/bsp.h
@@ -46,19 +46,8 @@ extern uint8_t _ccram_start;
 
 /* LED pins */
 #define LED_BLINK_PIN_1   MCU_GPIO_PORTB(3)
-    
-#define LED_BLINK_PIN LED_BLINK_PIN_1
-   
-/* UART ports */
-#define UART_CNT (MYNEWT_VAL(UART_0) + MYNEWT_VAL(UART_1))
-#define UART_0_DEV_ID   0
-#define UART_1_DEV_ID   (UART_0_DEV_ID + MYNEWT_VAL(UART_0))
 
-/* PWM */
-#define PWM_CNT (MYNEWT_VAL(PWM_0) + MYNEWT_VAL(PWM_1) + MYNEWT_VAL(PWM_2))
-#define PWM_0_DEV_ID    0
-#define PWM_1_DEV_ID    (PWM_0_DEV_ID + MYNEWT_VAL(PWM_0))
-#define PWM_2_DEV_ID    (PWM_1_DEV_ID + MYNEWT_VAL(PWM_1))
+#define LED_BLINK_PIN LED_BLINK_PIN_1
 
 /* Arduino nano pins */
 #define ARDUINO_PIN_D0      MCU_GPIO_PORTA(10)
diff --git a/hw/bsp/nucleo-f303k8/pkg.yml b/hw/bsp/nucleo-f303k8/pkg.yml
index f4f2669..961d3b1 100644
--- a/hw/bsp/nucleo-f303k8/pkg.yml
+++ b/hw/bsp/nucleo-f303k8/pkg.yml
@@ -35,19 +35,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f3xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
-pkg.deps.UART_1:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
-pkg.deps.PWM_0:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
-
-pkg.deps.PWM_1:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
-
-pkg.deps.PWM_2:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
-
diff --git a/hw/bsp/nucleo-f303k8/src/hal_bsp.c b/hw/bsp/nucleo-f303k8/src/hal_bsp.c
index c2b6c6e..c6ddfa7 100644
--- a/hw/bsp/nucleo-f303k8/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f303k8/src/hal_bsp.c
@@ -16,115 +16,69 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-#include <stddef.h>
+#include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0) || MYNEWT_VAL(UART_1)
-/*
- * It is necessary to include uart/uart.h before stm32fxx_hal_uart.h gets included
- * due to a name conflict for UART_PARITY_NONE.
- */
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
+#include <hal/hal_bsp.h>
+#include <hal/hal_flash_int.h>
+#include <hal/hal_system.h>
 
-#include "assert.h"
-#include "bsp/bsp.h"
-#include "hal/hal_bsp.h"
-#include "hal/hal_flash_int.h"
-#include "hal/hal_gpio.h"
-#include "hal/hal_system.h"
-#include "mcu/mcu.h"
-#include "mcu/stm32f3_bsp.h"
-#include "stm32f3xx.h"
-#include "stm32f3xx_hal.h"
-#include "stm32f3xx_hal_gpio.h"
-#include "stm32f3xx_hal_rcc.h"
+#include <stm32f3xx.h>
+#include <stm32_common/stm32_hal.h>
 
-#if MYNEWT_VAL(UART_0) || MYNEWT_VAL(UART_1)
-static struct uart_dev hal_uart[UART_CNT];
-
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
-#if MYNEWT_VAL(UART_0)
-    {
-        .suc_uart    = USART2,
-        .suc_rcc_reg = &RCC->APB1ENR,
-        .suc_rcc_dev = RCC_APB1ENR_USART2EN,
-        .suc_pin_tx  = MCU_GPIO_PORTA(2),
-        .suc_pin_rx  = MCU_GPIO_PORTA(15),
-        .suc_pin_rts = MCU_GPIO_PORTA(1),
-        .suc_pin_cts = MCU_GPIO_PORTA(0),
-        .suc_pin_af  = GPIO_AF7_USART2,
-        .suc_irqn    = USART2_IRQn
-    },
-#endif
-#if MYNEWT_VAL(UART_1)
-    {
-        .suc_uart    = USART1,
-        .suc_rcc_reg = &RCC->APB2ENR,
-        .suc_rcc_dev = RCC_APB2ENR_USART1EN,
-        .suc_pin_tx  = MCU_GPIO_PORTA(9),
-        .suc_pin_rx  = MCU_GPIO_PORTA(10),
-        .suc_pin_rts = MCU_GPIO_PORTA(12),
-        .suc_pin_cts = MCU_GPIO_PORTA(11),
-        .suc_pin_af  = GPIO_AF7_USART1,
-        .suc_irqn    = USART1_IRQn
-    },
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
 #endif
-};
 
-const struct stm32_uart_cfg *
-bsp_uart_config(int port)
-{
-    assert(port < UART_CNT);
-    return &uart_cfg[port];
-}
-
-static char *stm32_uart_dev_name[UART_CNT] = {
-#if UART_CNT > 0
-    "uart0",
-#endif
-#if UART_CNT > 1
-    "uart1",
-#endif
+#if MYNEWT_VAL(UART_0)
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART2,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART2EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF7_USART2,
+    .suc_irqn = USART2_IRQn,
 };
-
 #endif
 
-
-#if PWM_CNT
-#include <pwm_stm32/pwm_stm32.h>
-static struct pwm_dev stm32_pwm_dev_driver[PWM_CNT];
-static const char *stm32_pwm_dev_name[PWM_CNT] = {
-#if PWM_CNT > 0
-    "pwm0",
-#endif
-#if PWM_CNT > 1
-    "pwm1",
-#endif
-#if PWM_CNT > 2
-    "pwm2",
-#endif
+#if MYNEWT_VAL(UART_1)
+const struct stm32_uart_cfg os_bsp_uart1_cfg = {
+    .suc_uart = USART1,
+    .suc_rcc_reg = &RCC->APB2ENR,
+    .suc_rcc_dev = RCC_APB2ENR_USART1EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_1_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_1_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_1_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_1_PIN_CTS),
+    .suc_pin_af = GPIO_AF7_USART1,
+    .suc_irqn = USART1_IRQn,
 };
+#endif
 
-static struct stm32_pwm_conf  stm32_pwm_config[PWM_CNT] = {
 #if MYNEWT_VAL(PWM_0)
-    { TIM2, TIM2_IRQn },
+struct stm32_pwm_conf os_bsp_pwm0_cfg = {
+    .tim = TIM2,
+    .irq = TIM2_IRQn,
+};
 #endif
 #if MYNEWT_VAL(PWM_1)
-    { TIM15, TIM1_BRK_TIM15_IRQn },
+struct stm32_pwm_conf os_bsp_pwm1_cfg = {
+    .tim = TIM15,
+    .irq = TIM1_BRK_TIM15_IRQn,
+};
 #endif
 #if MYNEWT_VAL(PWM_2)
-    { TIM3, TIM3_IRQn },
-#endif
+struct stm32_pwm_conf os_bsp_pwm2_cfg = {
+    .tim = TIM3,
+    .irq = TIM3_IRQn,
 };
-
-
 #endif
 
-
-
 static const struct hal_bsp_mem_dump dump_cfg[] = {
     [0] = {
         .hbmd_start = &_sram_start,
@@ -176,63 +130,5 @@ hal_bsp_get_nvic_priority(int irq_num, uint32_t pri)
 void
 hal_bsp_init(void)
 {
-    int rc;
-    (void)rc;  /* in case there are no devices declared */
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *)&hal_uart[UART_0_DEV_ID],
-        stm32_uart_dev_name[UART_0_DEV_ID],
-        OS_DEV_INIT_PRIMARY, 0, uart_hal_init,
-        (void *)&uart_cfg[UART_0_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_1)
-    rc = os_dev_create((struct os_dev *)&hal_uart[UART_1_DEV_ID],
-        stm32_uart_dev_name[UART_1_DEV_ID],
-        OS_DEV_INIT_PRIMARY, 0, uart_hal_init,
-        (void *)&uart_cfg[UART_1_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    rc = hal_timer_init(0, TIM15);
-    assert(rc == 0);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(PWM_0)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_0_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_0_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_0_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(PWM_1)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_1_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_1_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_1_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(PWM_2)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_2_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_2_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_2_DEV_ID]);
-    assert(rc == 0);
-#endif
-
+    stm32_periph_create();
 }
diff --git a/hw/bsp/nucleo-f303k8/syscfg.yml b/hw/bsp/nucleo-f303k8/syscfg.yml
index 6e20700..ff2c4a1 100644
--- a/hw/bsp/nucleo-f303k8/syscfg.yml
+++ b/hw/bsp/nucleo-f303k8/syscfg.yml
@@ -22,27 +22,6 @@ syscfg.defs:
         description: 'Total flash size in KB.'
         value: 64
 
-    UART_0:
-        description: 'Whether to enable UART0'
-        value:  1
-    UART_1:
-        description: 'Whether to enable UART1'
-        value:  0
-
-    TIMER_0:
-        description: 'Support for timer 0'
-        value: 1
-
-    PWM_0:
-        description: 'Support for PWM 0'
-        value: 0
-    PWM_1:
-        description: 'Support for PWM 1'
-        value: 0
-    PWM_2:
-        description: 'Support for PWM 2'
-        value: 0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -58,3 +37,12 @@ syscfg.vals:
     STM32_CLOCK_APB2_DIVIDER: 'RCC_HCLK_DIV1'
     STM32_FLASH_LATENCY: 'FLASH_LATENCY_2'
     STM32_FLASH_PREFETCH_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(2)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTA(15)'
+    UART_0_PIN_RTS: 'MCU_GPIO_PORTA(1)'
+    UART_0_PIN_CTS: 'MCU_GPIO_PORTA(0)'
+    UART_1_PIN_TX: 'MCU_GPIO_PORTA(9)'
+    UART_1_PIN_RX: 'MCU_GPIO_PORTA(10)'
+    UART_1_PIN_RTS: 'MCU_GPIO_PORTA(12)'
+    UART_1_PIN_CTS: 'MCU_GPIO_PORTA(11)'
+    TIMER_0_TIM: 'TIM15'
diff --git a/hw/bsp/nucleo-f303re/include/bsp/bsp.h b/hw/bsp/nucleo-f303re/include/bsp/bsp.h
index 649620b..a53e4c3 100644
--- a/hw/bsp/nucleo-f303re/include/bsp/bsp.h
+++ b/hw/bsp/nucleo-f303re/include/bsp/bsp.h
@@ -46,23 +46,12 @@ extern uint8_t _ccram_start;
 
 /* LED pins */
 #define LED_BLINK_PIN_1   MCU_GPIO_PORTA(5)
-    
+
 #define LED_BLINK_PIN LED_BLINK_PIN_1
-    
+
 /* Buttons */
 #define BTN_USER_1        MCU_GPIO_PORTC(13)
 
-/* UART ports */
-#define UART_CNT (MYNEWT_VAL(UART_0) + MYNEWT_VAL(UART_1))
-#define UART_0_DEV_ID   0
-#define UART_1_DEV_ID   (UART_0_DEV_ID + MYNEWT_VAL(UART_0))
-
-/* PWM */
-#define PWM_CNT (MYNEWT_VAL(PWM_0) + MYNEWT_VAL(PWM_1) + MYNEWT_VAL(PWM_2))
-#define PWM_0_DEV_ID    0
-#define PWM_1_DEV_ID    (PWM_0_DEV_ID + MYNEWT_VAL(PWM_0))
-#define PWM_2_DEV_ID    (PWM_1_DEV_ID + MYNEWT_VAL(PWM_1))
-
 /* This defines the maximum NFFS areas (block) are in the BSPs NFS file 
  * system space.  This in conjunction with flash map determines how 
  * many NFS blocks there will be.  A minimum is the number of individually
diff --git a/hw/bsp/nucleo-f303re/pkg.yml b/hw/bsp/nucleo-f303re/pkg.yml
index 9d7aa5f..45f16ad 100644
--- a/hw/bsp/nucleo-f303re/pkg.yml
+++ b/hw/bsp/nucleo-f303re/pkg.yml
@@ -35,18 +35,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f3xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
-pkg.deps.UART_1:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
-pkg.deps.PWM_0:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
-
-pkg.deps.PWM_1:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
-
-pkg.deps.PWM_2:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
diff --git a/hw/bsp/nucleo-f303re/src/hal_bsp.c b/hw/bsp/nucleo-f303re/src/hal_bsp.c
index 61e42e2..eadff88 100644
--- a/hw/bsp/nucleo-f303re/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f303re/src/hal_bsp.c
@@ -16,115 +16,68 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-#include <stddef.h>
+#include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0) || MYNEWT_VAL(UART_1)
-/*
- * It is necessary to include uart/uart.h before stm32fxx_hal_uart.h gets included
- * due to a name conflict for UART_PARITY_NONE.
- */
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
+#include <hal/hal_bsp.h>
+#include <hal/hal_flash_int.h>
+#include <hal/hal_system.h>
 
-#include "assert.h"
-#include "bsp/bsp.h"
-#include "hal/hal_bsp.h"
-#include "hal/hal_flash_int.h"
-#include "hal/hal_gpio.h"
-#include "hal/hal_system.h"
-#include "mcu/mcu.h"
-#include "mcu/stm32f3_bsp.h"
-#include "stm32f3xx.h"
-#include "stm32f3xx_hal.h"
-#include "stm32f3xx_hal_gpio.h"
-#include "stm32f3xx_hal_rcc.h"
+#include <stm32f3xx.h>
+#include <stm32_common/stm32_hal.h>
 
-#if MYNEWT_VAL(UART_0) || MYNEWT_VAL(UART_1)
-static struct uart_dev hal_uart[UART_CNT];
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
+#endif
 
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
 #if MYNEWT_VAL(UART_0)
-    {
-        .suc_uart    = USART2,
-        .suc_rcc_reg = &RCC->APB1ENR,
-        .suc_rcc_dev = RCC_APB1ENR_USART2EN,
-        .suc_pin_tx  = MCU_GPIO_PORTA(2),
-        .suc_pin_rx  = MCU_GPIO_PORTA(3),
-        .suc_pin_rts = MCU_GPIO_PORTA(1),
-        .suc_pin_cts = MCU_GPIO_PORTA(0),
-        .suc_pin_af  = GPIO_AF7_USART2,
-        .suc_irqn    = USART2_IRQn
-    },
-#endif
-#if MYNEWT_VAL(UART_1)
-    {
-        .suc_uart    = USART1,
-        .suc_rcc_reg = &RCC->APB2ENR,
-        .suc_rcc_dev = RCC_APB2ENR_USART1EN,
-        .suc_pin_tx  = MCU_GPIO_PORTA(9),
-        .suc_pin_rx  = MCU_GPIO_PORTA(10),
-        .suc_pin_rts = MCU_GPIO_PORTA(12),
-        .suc_pin_cts = MCU_GPIO_PORTA(11),
-        .suc_pin_af  = GPIO_AF7_USART1,
-        .suc_irqn    = USART1_IRQn
-    },
-#endif
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART2,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART2EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF7_USART2,
+    .suc_irqn = USART2_IRQn,
 };
-
-const struct stm32_uart_cfg *
-bsp_uart_config(int port)
-{
-    assert(port < UART_CNT);
-    return &uart_cfg[port];
-}
-
-static char *stm32_uart_dev_name[UART_CNT] = {
-#if UART_CNT > 0
-    "uart0",
-#endif
-#if UART_CNT > 1
-    "uart1",
 #endif
+#if MYNEWT_VAL(UART_1)
+const struct stm32_uart_cfg os_bsp_uart1_cfg = {
+    .suc_uart = USART1,
+    .suc_rcc_reg = &RCC->APB2ENR,
+    .suc_rcc_dev = RCC_APB2ENR_USART1EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_1_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_1_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_1_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_1_PIN_CTS),
+    .suc_pin_af = GPIO_AF7_USART1,
+    .suc_irqn = USART1_IRQn,
 };
-
 #endif
 
-
-#if PWM_CNT
-#include <pwm_stm32/pwm_stm32.h>
-static struct pwm_dev stm32_pwm_dev_driver[PWM_CNT];
-static const char *stm32_pwm_dev_name[PWM_CNT] = {
-#if PWM_CNT > 0
-    "pwm0",
-#endif
-#if PWM_CNT > 1
-    "pwm1",
-#endif
-#if PWM_CNT > 2
-    "pwm2",
-#endif
-};
-
-static struct stm32_pwm_conf  stm32_pwm_config[PWM_CNT] = {
 #if MYNEWT_VAL(PWM_0)
-    { TIM2, TIM2_IRQn },
+struct stm32_pwm_conf os_bsp_pwm0_cfg = {
+    .tim = TIM2,
+    .irq = TIM2_IRQn,
+};
 #endif
 #if MYNEWT_VAL(PWM_1)
-    { TIM4, TIM4_IRQn },
+struct stm32_pwm_conf os_bsp_pwm1_cfg = {
+    .tim = TIM4,
+    .irq = TIM4_IRQn,
+};
 #endif
 #if MYNEWT_VAL(PWM_2)
-    { TIM3, TIM3_IRQn },
-#endif
+struct stm32_pwm_conf os_bsp_pwm2_cfg = {
+    .tim = TIM3,
+    .irq = TIM3_IRQn,
 };
-
-
 #endif
 
-
-
 static const struct hal_bsp_mem_dump dump_cfg[] = {
     [0] = {
         .hbmd_start = &_sram_start,
@@ -176,63 +129,5 @@ hal_bsp_get_nvic_priority(int irq_num, uint32_t pri)
 void
 hal_bsp_init(void)
 {
-    int rc;
-    (void)rc;  /* in case there are no devices declared */
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *)&hal_uart[UART_0_DEV_ID],
-        stm32_uart_dev_name[UART_0_DEV_ID],
-        OS_DEV_INIT_PRIMARY, 0, uart_hal_init,
-        (void *)&uart_cfg[UART_0_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_1)
-    rc = os_dev_create((struct os_dev *)&hal_uart[UART_1_DEV_ID],
-        stm32_uart_dev_name[UART_1_DEV_ID],
-        OS_DEV_INIT_PRIMARY, 0, uart_hal_init,
-        (void *)&uart_cfg[UART_1_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    rc = hal_timer_init(0, TIM15);
-    assert(rc == 0);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(PWM_0)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_0_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_0_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_0_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(PWM_1)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_1_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_1_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_1_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(PWM_2)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_2_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_2_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_2_DEV_ID]);
-    assert(rc == 0);
-#endif
-
+    stm32_periph_create();
 }
diff --git a/hw/bsp/nucleo-f303re/syscfg.yml b/hw/bsp/nucleo-f303re/syscfg.yml
index 5546139..662cec0 100644
--- a/hw/bsp/nucleo-f303re/syscfg.yml
+++ b/hw/bsp/nucleo-f303re/syscfg.yml
@@ -22,27 +22,6 @@ syscfg.defs:
         description: 'Total flash size in KB.'
         value: 512
 
-    UART_0:
-        description: 'Whether to enable UART0'
-        value:  1
-    UART_1:
-        description: 'Whether to enable UART1'
-        value:  0
-
-    TIMER_0:
-        description: 'Support for timer 0'
-        value: 1
-
-    PWM_0:
-        description: 'Support for PWM 0'
-        value: 0
-    PWM_1:
-        description: 'Support for PWM 1'
-        value: 0
-    PWM_2:
-        description: 'Support for PWM 2'
-        value: 0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -58,3 +37,12 @@ syscfg.vals:
     STM32_CLOCK_APB2_DIVIDER: 'RCC_HCLK_DIV1'
     STM32_FLASH_LATENCY: 'FLASH_LATENCY_2'
     STM32_FLASH_PREFETCH_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(2)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTA(3)'
+    UART_0_PIN_RTS: 'MCU_GPIO_PORTA(1)'
+    UART_0_PIN_CTS: 'MCU_GPIO_PORTA(0)'
+    UART_1_PIN_TX: 'MCU_GPIO_PORTA(9)'
+    UART_1_PIN_RX: 'MCU_GPIO_PORTA(10)'
+    UART_1_PIN_RTS: 'MCU_GPIO_PORTA(12)'
+    UART_1_PIN_CTS: 'MCU_GPIO_PORTA(11)'
+    TIMER_0_TIM: 'TIM15'
diff --git a/hw/bsp/nucleo-f401re/include/bsp/bsp.h b/hw/bsp/nucleo-f401re/include/bsp/bsp.h
index e409951..7500cbf 100644
--- a/hw/bsp/nucleo-f401re/include/bsp/bsp.h
+++ b/hw/bsp/nucleo-f401re/include/bsp/bsp.h
@@ -41,9 +41,6 @@ extern uint8_t _ram_start;
 /* LED pins */
 #define LED_BLINK_PIN   MCU_GPIO_PORTA(5)
 
-/* UART */
-#define UART_CNT 1
-
 /* Arduino pins */
 #define ARDUINO_PIN_D0      MCU_GPIO_PORTA(3)
 #define ARDUINO_PIN_D1      MCU_GPIO_PORTA(2)
diff --git a/hw/bsp/nucleo-f401re/pkg.yml b/hw/bsp/nucleo-f401re/pkg.yml
index 11a3f21..575bcd0 100644
--- a/hw/bsp/nucleo-f401re/pkg.yml
+++ b/hw/bsp/nucleo-f401re/pkg.yml
@@ -36,8 +36,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f4xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-pkg.deps.UART_1:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
diff --git a/hw/bsp/nucleo-f401re/src/hal_bsp.c b/hw/bsp/nucleo-f401re/src/hal_bsp.c
index f11b008..3b65748 100644
--- a/hw/bsp/nucleo-f401re/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f401re/src/hal_bsp.c
@@ -16,27 +16,21 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+#include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
-#include <hal/hal_i2c.h>
-#include <hal/hal_timer.h>
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-#include <hal/hal_spi.h>
-#endif
+#include <hal/hal_flash_int.h>
+#include <hal/hal_system.h>
+
 #include <stm32f401xe.h>
-#include <stm32f4xx_hal_gpio_ex.h>
-#include <mcu/mcu.h>
-#include "mcu/stm32_hal.h"
-#include "bsp/bsp.h"
-#include <assert.h>
+#include <stm32_common/stm32_hal.h>
+
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
+#endif
 
 const uint32_t stm32_flash_sectors[] = {
     0x08000000,     /* 16kB */
@@ -55,20 +49,16 @@ static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) + 1 == SZ,
         "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
-
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
-    [0] = {
-        .suc_uart    = USART2,
-        .suc_rcc_reg = &RCC->APB1ENR,
-        .suc_rcc_dev = RCC_APB1ENR_USART2EN,
-        .suc_pin_tx  = MCU_GPIO_PORTA(2),
-        .suc_pin_rx  = MCU_GPIO_PORTA(3),
-        .suc_pin_rts = MCU_GPIO_PORTA(1),
-        .suc_pin_cts = MCU_GPIO_PORTA(0),
-        .suc_pin_af  = GPIO_AF7_USART2,
-        .suc_irqn    = USART2_IRQn
-    }
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART2,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART2EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF7_USART2,
+    .suc_irqn = USART2_IRQn,
 };
 #endif
 
@@ -86,28 +76,18 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
  * be removed (they are the default connections) and SB46/SB52 need to
  * be added.
  */
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(9),       /* PB9 - D14 on CN5 */
-    .hic_pin_scl = MCU_GPIO_PORTB(8),       /* PB8 - D15 on CN5 */
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
     .hic_speed = 100000,                    /* 100kHz */
 };
 #endif
 
-#if MYNEWT_VAL(SPI_0_SLAVE) || MYNEWT_VAL(SPI_0_MASTER)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .ss_pin   = MCU_GPIO_PORTA(4),          /* CN8 - A2 */
-    .sck_pin  = MCU_GPIO_PORTA(5),          /* CN5 - D13 */
-    .miso_pin = MCU_GPIO_PORTA(6),          /* CN5 - D12 */
-    .mosi_pin = MCU_GPIO_PORTA(7),          /* CN5 - D11 */
-    .irq_prio = 2
-};
-#endif
-
 extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
@@ -131,39 +111,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[0]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM9);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/nucleo-f401re/syscfg.yml b/hw/bsp/nucleo-f401re/syscfg.yml
index 503ba8f..0788b39 100644
--- a/hw/bsp/nucleo-f401re/syscfg.yml
+++ b/hw/bsp/nucleo-f401re/syscfg.yml
@@ -26,14 +26,6 @@ syscfg.defs:
         description: 'Number of flash sectors for a non-linear STM32 MCU.'
         value: 8
 
-    UART_0:
-        description: 'Whether to enable UART0'
-        value:  1
-
-    TIMER_0:
-        description: 'TIMER_0'
-        value: 1
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -54,3 +46,14 @@ syscfg.vals:
     STM32_FLASH_PREFETCH_ENABLE: 1
     STM32_INSTRUCTION_CACHE_ENABLE: 1
     STM32_DATA_CACHE_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(2)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTA(3)'
+    UART_0_PIN_RTS: 'MCU_GPIO_PORTA(1)'
+    UART_0_PIN_CTS: 'MCU_GPIO_PORTA(0)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTA(4)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTA(5)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTA(6)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTA(7)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    TIMER_0_TIM: 'TIM9'
diff --git a/hw/bsp/nucleo-f411re/include/bsp/bsp.h b/hw/bsp/nucleo-f411re/include/bsp/bsp.h
index 4d3ac18..037aab0 100644
--- a/hw/bsp/nucleo-f411re/include/bsp/bsp.h
+++ b/hw/bsp/nucleo-f411re/include/bsp/bsp.h
@@ -44,9 +44,6 @@ extern uint8_t _ram_start;
 /* Button pin */
 #define BUTTON_1        MCU_GPIO_PORTC(13)
 
-/* UART */
-#define UART_CNT 3
-
 /* Arduino pins */
 #define ARDUINO_PIN_D0      MCU_GPIO_PORTA(3)
 #define ARDUINO_PIN_D1      MCU_GPIO_PORTA(2)
diff --git a/hw/bsp/nucleo-f411re/pkg.yml b/hw/bsp/nucleo-f411re/pkg.yml
index 692cac0..5a85446 100644
--- a/hw/bsp/nucleo-f411re/pkg.yml
+++ b/hw/bsp/nucleo-f411re/pkg.yml
@@ -37,6 +37,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f4xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.'(UART_0 || UART_1 || UART_2)':
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
diff --git a/hw/bsp/nucleo-f411re/src/hal_bsp.c b/hw/bsp/nucleo-f411re/src/hal_bsp.c
index e17f49e..8b57767 100644
--- a/hw/bsp/nucleo-f411re/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f411re/src/hal_bsp.c
@@ -16,40 +16,32 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+#include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0) || MYNEWT_VAL(UART_1) || MYNEWT_VAL(UART_2)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
-#if MYNEWT_VAL(I2C_0) || MYNEWT_VAL(I2C_1) || MYNEWT_VAL(I2C_2)
-#include <hal/hal_i2c.h>
-#endif
+#include <hal/hal_flash_int.h>
+#include <hal/hal_system.h>
 
-#include <hal/hal_timer.h>
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-#include <hal/hal_spi.h>
-#endif
 #include <stm32f411xe.h>
-#include <stm32f4xx_hal_gpio_ex.h>
-#include <mcu/mcu.h>
-#include "mcu/stm32_hal.h"
-#include "bsp/bsp.h"
-#include <assert.h>
+#include <stm32_common/stm32_hal.h>
+
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
+#endif
 
 const uint32_t stm32_flash_sectors[] = {
-        0x08000000,     /* 16kB */
-        0x08004000,     /* 16kB */
-        0x08008000,     /* 16kB */
-        0x0800c000,     /* 16kB */
-        0x08010000,     /* 64kB */
-        0x08020000,     /* 128kB */
-        0x08040000,     /* 128kB */
-        0x08060000,     /* 128kB */
-        0x08080000,     /* End of flash */
+    0x08000000,     /* 16kB */
+    0x08004000,     /* 16kB */
+    0x08008000,     /* 16kB */
+    0x0800c000,     /* 16kB */
+    0x08010000,     /* 64kB */
+    0x08020000,     /* 128kB */
+    0x08040000,     /* 128kB */
+    0x08060000,     /* 128kB */
+    0x08080000,     /* End of flash */
 };
 
 #define SZ (sizeof(stm32_flash_sectors) / sizeof(stm32_flash_sectors[0]))
@@ -57,55 +49,52 @@ static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) + 1 == SZ,
               "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
-static const struct stm32_uart_cfg uart0_cfg = {
-        .suc_uart    = USART2,
-        .suc_rcc_reg = &RCC->APB1ENR,
-        .suc_rcc_dev = RCC_APB1ENR_USART2EN,
-        .suc_pin_tx  = MYNEWT_VAL(UART_0_TX),
-        .suc_pin_rx  = MYNEWT_VAL(UART_0_RX),
-        .suc_pin_rts = MYNEWT_VAL(UART_0_RTS),
-        .suc_pin_cts = MYNEWT_VAL(UART_0_CTS),
-        .suc_pin_af  = GPIO_AF7_USART2,
-        .suc_irqn    = USART2_IRQn
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART2,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART2EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF7_USART2,
+    .suc_irqn = USART2_IRQn,
 };
 #endif
 
 #if MYNEWT_VAL(UART_1)
-static struct uart_dev hal_uart1;
-static const struct stm32_uart_cfg uart1_cfg = {
-        .suc_uart    = USART1,
-        .suc_rcc_reg = &RCC->APB2ENR,
-        .suc_rcc_dev = RCC_APB2ENR_USART1EN,
-        .suc_pin_tx  = MYNEWT_VAL(UART_1_TX),
-        .suc_pin_rx  = MYNEWT_VAL(UART_1_RX),
-        .suc_pin_rts = MYNEWT_VAL(UART_1_RTS),
-        .suc_pin_cts = MYNEWT_VAL(UART_1_CTS),
-        .suc_pin_af  = GPIO_AF7_USART1,
-        .suc_irqn    = USART1_IRQn
+const struct stm32_uart_cfg os_bsp_uart1_cfg = {
+    .suc_uart = USART1,
+    .suc_rcc_reg = &RCC->APB2ENR,
+    .suc_rcc_dev = RCC_APB2ENR_USART1EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_1_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_1_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_1_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_1_PIN_CTS),
+    .suc_pin_af = GPIO_AF7_USART1,
+    .suc_irqn = USART1_IRQn,
 };
 #endif
 
 #if MYNEWT_VAL(UART_2)
-static struct uart_dev hal_uart2;
-static const struct stm32_uart_cfg uart2_cfg = {
-        .suc_uart    = USART6,
-        .suc_rcc_reg = &RCC->APB2ENR,
-        .suc_rcc_dev = RCC_APB2ENR_USART6EN,
-        .suc_pin_tx  = MYNEWT_VAL(UART_2_TX),
-        .suc_pin_rx  = MYNEWT_VAL(UART_2_RX),
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af  = GPIO_AF8_USART6,
-        .suc_irqn    = USART6_IRQn
+const struct stm32_uart_cfg os_bsp_uart2_cfg = {
+    .suc_uart = USART6,
+    .suc_rcc_reg = &RCC->APB2ENR,
+    .suc_rcc_dev = RCC_APB2ENR_USART6EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_2_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_2_PIN_RX),
+    .suc_pin_rts = -1,
+    .suc_pin_cts = -1,
+    .suc_pin_af = GPIO_AF8_USART6,
+    .suc_irqn = USART6_IRQn,
 };
 #endif
 
 static const struct hal_bsp_mem_dump dump_cfg[] = {
-        [0] = {
-                .hbmd_start = &_ram_start,
-                .hbmd_size = RAM_SIZE
-        }
+    [0] = {
+        .hbmd_start = &_ram_start,
+        .hbmd_size = RAM_SIZE
+    }
 };
 
 #if MYNEWT_VAL(I2C_0)
@@ -115,7 +104,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
  * be removed (they are the default connections) and SB46/SB52 need to
  * be added.
  */
-static struct stm32_hal_i2c_cfg i2c0_cfg = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
@@ -128,7 +117,7 @@ static struct stm32_hal_i2c_cfg i2c0_cfg = {
 #endif
 
 #if MYNEWT_VAL(I2C_1)
-static struct stm32_hal_i2c_cfg i2c1_cfg = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c1_cfg = {
     .hic_i2c = I2C2,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C2EN,
@@ -141,7 +130,7 @@ static struct stm32_hal_i2c_cfg i2c1_cfg = {
 #endif
 
 #if MYNEWT_VAL(I2C_2)
-static struct stm32_hal_i2c_cfg i2c2_cfg = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c2_cfg = {
     .hic_i2c = I2C3,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C3EN,
@@ -153,16 +142,6 @@ static struct stm32_hal_i2c_cfg i2c2_cfg = {
 };
 #endif
 
-#if MYNEWT_VAL(SPI_0_SLAVE) || MYNEWT_VAL(SPI_0_MASTER)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .ss_pin   = MCU_GPIO_PORTA(4),          /* CN8 - A2 */
-    .sck_pin  = MCU_GPIO_PORTA(5),          /* CN5 - D13 */
-    .miso_pin = MCU_GPIO_PORTA(6),          /* CN5 - D12 */
-    .mosi_pin = MCU_GPIO_PORTA(7),          /* CN5 - D11 */
-    .irq_prio = 2
-};
-#endif
-
 extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
@@ -186,61 +165,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-  int rc;
-
-  (void)rc;
-
-#if MYNEWT_VAL(UART_0)
-  rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-                     OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart0_cfg);
-  assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_1)
-  rc = os_dev_create((struct os_dev *) &hal_uart1, "uart1",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart1_cfg);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_2)
-  rc = os_dev_create((struct os_dev *) &hal_uart2, "uart2",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart2_cfg);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-  rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-  rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-  rc = hal_i2c_init(0, &i2c0_cfg);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_1)
-  rc = hal_i2c_init(0, &i2c1_cfg);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_2)
-  rc = hal_i2c_init(0, &i2c2_cfg);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-  hal_timer_init(0, TIM9);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-  rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-  assert(rc == 0);
-#endif
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/nucleo-f411re/syscfg.yml b/hw/bsp/nucleo-f411re/syscfg.yml
index 5b7679e..037fcfe 100644
--- a/hw/bsp/nucleo-f411re/syscfg.yml
+++ b/hw/bsp/nucleo-f411re/syscfg.yml
@@ -26,63 +26,7 @@ syscfg.defs:
         description: 'Number of flash sectors for a non-linear STM32 MCU.'
         value: 8
 
-    UART_0:
-        description:
-            Enables UART_0 mapped to USART 2, PA2 and PA3 routed to USB by default.
-            Solder bridges needed for Arduino/Morpho header visibility
-        value:  1
-    UART_1:
-        description: 'Enables UART_1 mapped to USART 1'
-        value:  0
-    UART_2:
-        description: 'Enables UART_2 mapped to USART 6'
-        value:  0
-
-    UART_0_TX:
-        description: 'UART_0 TX pin. PA2(Arduino TX/D0) or PD5'
-        value:  'MCU_GPIO_PORTA(2)'
-    UART_0_RX:
-        description: 'UART_0 RX pin. PA3(Arduino RX/D1) or PD6'
-        value:  'MCU_GPIO_PORTA(3)'
-    UART_0_RTS:
-        description: 'UART_0 RTS pin. PA1 or PD4'
-        value:  -1
-    UART_0_CTS:
-        description: 'UART_0 CTS pin. PA0 or PD3'
-        value:  -1
-
-    UART_1_TX:
-        description: 'UART_0 TX pin. PA9(Arduino D8) or PB6(Arduino D10) or PA15'
-        value:  'MCU_GPIO_PORTA(9)'
-    UART_1_RX:
-        description: 'UART_1 RX pin. PA10(Arduino D2) or PB7 or PB3(Arduino D3)'
-        value:  'MCU_GPIO_PORTA(10)'
-    UART_1_RTS:
-        description: 'UART_1 RTS pin. PA12'
-        value:  -1
-    UART_1_CTS:
-        description: 'UART_1 CTS pin. PA11'
-        value:  -1
-
-    UART_2_TX:
-        description: 'UART_2 TX pin. PA11 or PC6'
-        value:  'MCU_GPIO_PORTA(11)'
-    UART_2_RX:
-        description: 'UART_2 RX pin. PA12 or PC7(Arduino D9)'
-        value:  'MCU_GPIO_PORTA(12)'
-
-    TIMER_0:
-        description: 'TIMER_0'
-        value: 1
-
 syscfg.vals:
-    I2C_0_PIN_SCL: MCU_GPIO_PORTB(8)
-    I2C_0_PIN_SDA: MCU_GPIO_PORTB(9)
-    I2C_1_PIN_SCL: MCU_GPIO_PORTB(10)
-    I2C_1_PIN_SDA: MCU_GPIO_PORTB(11)
-    I2C_2_PIN_SCL: MCU_GPIO_PORTA(8)
-    I2C_2_PIN_SDA: MCU_GPIO_PORTC(9)
-
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
     NFFS_FLASH_AREA: FLASH_AREA_NFFS
@@ -103,3 +47,20 @@ syscfg.vals:
     STM32_FLASH_PREFETCH_ENABLE: 1
     STM32_INSTRUCTION_CACHE_ENABLE: 1
     STM32_DATA_CACHE_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(2)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTA(3)'
+    UART_1_PIN_TX: 'MCU_GPIO_PORTA(9)'
+    UART_1_PIN_RX: 'MCU_GPIO_PORTA(10)'
+    UART_2_PIN_TX: 'MCU_GPIO_PORTA(11)'
+    UART_2_PIN_RX: 'MCU_GPIO_PORTA(12)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTA(4)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTA(5)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTA(6)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTA(7)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    I2C_1_PIN_SCL: 'MCU_GPIO_PORTB(10)'
+    I2C_1_PIN_SDA: 'MCU_GPIO_PORTB(11)'
+    I2C_2_PIN_SCL: 'MCU_GPIO_PORTA(8)'
+    I2C_2_PIN_SDA: 'MCU_GPIO_PORTC(9)'
+    TIMER_0_TIM: 'TIM9'
diff --git a/hw/bsp/nucleo-f413zh/include/bsp/bsp.h b/hw/bsp/nucleo-f413zh/include/bsp/bsp.h
index c5b5c3e..af39f0a 100644
--- a/hw/bsp/nucleo-f413zh/include/bsp/bsp.h
+++ b/hw/bsp/nucleo-f413zh/include/bsp/bsp.h
@@ -43,9 +43,6 @@ extern uint8_t _ccram_start;
 /* LED pins */
 #define LED_BLINK_PIN   MCU_GPIO_PORTB(7)
 
-/* UART */
-#define UART_CNT 1
-
 /* Arduino pins */
 #define ARDUINO_PIN_D0      MCU_GPIO_PORTG(9)
 #define ARDUINO_PIN_D1      MCU_GPIO_PORTG(14)
diff --git a/hw/bsp/nucleo-f413zh/pkg.yml b/hw/bsp/nucleo-f413zh/pkg.yml
index 5a5b871..79f82eb 100644
--- a/hw/bsp/nucleo-f413zh/pkg.yml
+++ b/hw/bsp/nucleo-f413zh/pkg.yml
@@ -37,6 +37,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f4xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
diff --git a/hw/bsp/nucleo-f413zh/src/hal_bsp.c b/hw/bsp/nucleo-f413zh/src/hal_bsp.c
index f1d65e9..9c4d15c 100644
--- a/hw/bsp/nucleo-f413zh/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f413zh/src/hal_bsp.c
@@ -16,28 +16,21 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 #include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
-#include <hal/hal_timer.h>
+#include <hal/hal_flash_int.h>
+#include <hal/hal_system.h>
 
-#include <stm32f4xx_hal_gpio_ex.h>
-#include "mcu/stm32_hal.h"
-#include <mcu/stm32f4_bsp.h>
-#include "mcu/stm32f4xx_mynewt_hal.h"
-#include "hal/hal_i2c.h"
-#include "hal/hal_spi.h"
+#include <stm32f413xx.h>
+#include <stm32_common/stm32_hal.h>
 
-#include "bsp/bsp.h"
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
+#endif
 
 const uint32_t stm32_flash_sectors[] = {
     0x08000000,     /* 16kB */
@@ -64,56 +57,29 @@ static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) + 1 == SZ,
         "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
-
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
-    [0] = {
-        .suc_uart = USART3,
-        .suc_rcc_reg = &RCC->APB1ENR,
-        .suc_rcc_dev = RCC_APB1ENR_USART3EN,
-        .suc_pin_tx = MCU_GPIO_PORTD(8),	/* PD8 */
-        .suc_pin_rx = MCU_GPIO_PORTD(9),	/* PD9 */
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af = GPIO_AF7_USART3,
-        .suc_irqn = USART3_IRQn
-    }
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART3,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART3EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF7_USART3,
+    .suc_irqn = USART3_IRQn
 };
 #endif
 
 #if MYNEWT_VAL(I2C_0)
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(9),       /* PB9 */
-    .hic_pin_scl = MCU_GPIO_PORTB(8),       /* PB8 */
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
-    .hic_speed = 100000,                    /* 100kHz */
-};
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-/*
- * NOTE: Our HAL expects that the SS pin, if used, is treated as a gpio line
- * and is handled outside the SPI routines.
- */
-static const struct stm32_hal_spi_cfg os_bsp_spi0m_cfg = {
-    .sck_pin      = MCU_GPIO_PORTB(3),
-    .mosi_pin     = MCU_GPIO_PORTB(5),
-    .miso_pin     = MCU_GPIO_PORTB(4),
-    .irq_prio     = 2,
-};
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-static const struct stm32_hal_spi_cfg os_bsp_spi0s_cfg = {
-    .sck_pin      = MCU_GPIO_PORTB(3),
-    .mosi_pin     = MCU_GPIO_PORTB(5),
-    .miso_pin     = MCU_GPIO_PORTB(4),
-    .ss_pin       = MCU_GPIO_PORTA(4),
-    .irq_prio     = 2,
+    .hic_speed = 100000,
 };
 #endif
 
@@ -151,33 +117,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[0]);
-    assert(rc == 0);
-#endif
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM9);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, (void *)&os_bsp_spi0m_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, (void *)&os_bsp_spi0s_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/nucleo-f413zh/syscfg.yml b/hw/bsp/nucleo-f413zh/syscfg.yml
index be59dd3..ed09ad7 100644
--- a/hw/bsp/nucleo-f413zh/syscfg.yml
+++ b/hw/bsp/nucleo-f413zh/syscfg.yml
@@ -26,13 +26,6 @@ syscfg.defs:
         description: 'Number of flash sectors for a non-linear STM32 MCU.'
         value: 16
 
-    UART_0:
-        description: 'UART 0'
-        value:  1
-    TIMER_0:
-        description: 'Timer 0'
-        value:  1
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -55,3 +48,14 @@ syscfg.vals:
     STM32_FLASH_PREFETCH_ENABLE: 1
     STM32_INSTRUCTION_CACHE_ENABLE: 1
     STM32_DATA_CACHE_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTD(8)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTD(9)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTA(4)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTB(3)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTB(4)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTB(5)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    TIMER_0_TIM: 'TIM9'
+    TIMER_1_TIM: 'TIM10'
+    TIMER_2_TIM: 'TIM11'
diff --git a/hw/bsp/nucleo-f439zi/include/bsp/bsp.h b/hw/bsp/nucleo-f439zi/include/bsp/bsp.h
index 5e326f1..ecb8860 100644
--- a/hw/bsp/nucleo-f439zi/include/bsp/bsp.h
+++ b/hw/bsp/nucleo-f439zi/include/bsp/bsp.h
@@ -43,9 +43,6 @@ extern uint8_t _ccram_start;
 /* LED pins */
 #define LED_BLINK_PIN   MCU_GPIO_PORTB(7)
 
-/* UART */
-#define UART_CNT 1
-
 /* Arduino pins */
 #define ARDUINO_PIN_D0      MCU_GPIO_PORTG(9)
 #define ARDUINO_PIN_D1      MCU_GPIO_PORTG(14)
diff --git a/hw/bsp/nucleo-f439zi/pkg.yml b/hw/bsp/nucleo-f439zi/pkg.yml
index c0e665e..176fcdb 100644
--- a/hw/bsp/nucleo-f439zi/pkg.yml
+++ b/hw/bsp/nucleo-f439zi/pkg.yml
@@ -37,18 +37,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f4xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
-pkg.deps.ETH_0:
-    - "@apache-mynewt-core/hw/drivers/lwip/stm32_eth"
-
-pkg.deps.TRNG:
-    - "@apache-mynewt-core/hw/drivers/trng/trng_stm32"
-
-pkg.deps.CRYPTO:
-    - "@apache-mynewt-core/hw/drivers/crypto/crypto_stm32"
-
-pkg.deps.HASH:
-    - "@apache-mynewt-core/hw/drivers/hash/hash_stm32"
diff --git a/hw/bsp/nucleo-f439zi/src/hal_bsp.c b/hw/bsp/nucleo-f439zi/src/hal_bsp.c
index 896151d..7ccce33 100644
--- a/hw/bsp/nucleo-f439zi/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f439zi/src/hal_bsp.c
@@ -16,49 +16,27 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 #include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
+#include <hal/hal_bsp.h>
+#include <hal/hal_flash_int.h>
+#include <hal/hal_system.h>
+
+#include <stm32f439xx.h>
+#include <stm32_common/stm32_hal.h>
 
 #if MYNEWT_VAL(ETH_0)
 #include <stm32_eth/stm32_eth.h>
 #include <stm32_eth/stm32_eth_cfg.h>
 #endif
 
-#if MYNEWT_VAL(TRNG)
-#include "trng/trng.h"
-#include "trng_stm32/trng_stm32.h"
-#endif
-
-#if MYNEWT_VAL(CRYPTO)
-#include "crypto/crypto.h"
-#include "crypto_stm32/crypto_stm32.h"
-#endif
-
-#if MYNEWT_VAL(HASH)
-#include "hash/hash.h"
-#include "hash_stm32/hash_stm32.h"
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
 #endif
 
-#include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
-#include <hal/hal_timer.h>
-
-#include <stm32f4xx_hal_gpio_ex.h>
-#include <mcu/stm32_hal.h>
-#include <mcu/stm32f4_bsp.h>
-#include <mcu/stm32f4xx_mynewt_hal.h>
-#include <hal/hal_i2c.h>
-#include <hal/hal_spi.h>
-
-#include "bsp/bsp.h"
-
 const uint32_t stm32_flash_sectors[] = {
     /* Bank 1 */
     0x08000000,     /* 16kB */
@@ -94,38 +72,22 @@ const uint32_t stm32_flash_sectors[] = {
 static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) + 1 == SZ,
         "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
-#if MYNEWT_VAL(TRNG)
-static struct trng_dev os_bsp_trng;
-#endif
-
-#if MYNEWT_VAL(CRYPTO)
-static struct crypto_dev os_bsp_crypto;
-#endif
-
-#if MYNEWT_VAL(HASH)
-static struct hash_dev os_bsp_hash;
-#endif
-
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
-
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
-    [0] = {
-        .suc_uart = USART3,
-        .suc_rcc_reg = &RCC->APB1ENR,
-        .suc_rcc_dev = RCC_APB1ENR_USART3EN,
-        .suc_pin_tx = MCU_GPIO_PORTD(8),	/* PD8 */
-        .suc_pin_rx = MCU_GPIO_PORTD(9),	/* PD9 */
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af = GPIO_AF7_USART3,
-        .suc_irqn = USART3_IRQn
-    }
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART3,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART3EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF7_USART3,
+    .suc_irqn = USART3_IRQn
 };
 #endif
 
 #if MYNEWT_VAL(ETH_0)
-static const struct stm32_eth_cfg eth_cfg = {
+const struct stm32_eth_cfg os_bsp_eth0_cfg = {
     /*
      * PORTA
      *   PA1 - ETH_RMII_REF_CLK
@@ -160,38 +122,15 @@ static const struct stm32_eth_cfg eth_cfg = {
 #endif
 
 #if MYNEWT_VAL(I2C_0)
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(9),       /* PB9 */
-    .hic_pin_scl = MCU_GPIO_PORTB(8),       /* PB8 */
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
-    .hic_speed = 100000,                    /* 100kHz */
-};
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-/*
- * NOTE: Our HAL expects that the SS pin, if used, is treated as a gpio line
- * and is handled outside the SPI routines.
- */
-static const struct stm32_hal_spi_cfg os_bsp_spi0m_cfg = {
-    .sck_pin      = MCU_GPIO_PORTB(3),
-    .mosi_pin     = MCU_GPIO_PORTB(5),
-    .miso_pin     = MCU_GPIO_PORTB(4),
-    .irq_prio     = 2,
-};
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-static const struct stm32_hal_spi_cfg os_bsp_spi0s_cfg = {
-    .sck_pin      = MCU_GPIO_PORTB(3),
-    .mosi_pin     = MCU_GPIO_PORTB(5),
-    .miso_pin     = MCU_GPIO_PORTB(4),
-    .ss_pin       = MCU_GPIO_PORTA(4),
-    .irq_prio     = 2,
+    .hic_speed = 100000,
 };
 #endif
 
@@ -229,62 +168,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
-#if MYNEWT_VAL(TRNG)
-    rc = os_dev_create(&os_bsp_trng.dev, "trng",
-                       OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
-                       stm32_trng_dev_init, NULL);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(CRYPTO)
-    rc = os_dev_create(&os_bsp_crypto.dev, "crypto",
-                       OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
-                       stm32_crypto_dev_init, NULL);
-#endif
-
-#if MYNEWT_VAL(HASH)
-    rc = os_dev_create(&os_bsp_hash.dev, "hash", OS_DEV_INIT_KERNEL,
-                       OS_DEV_INIT_PRIO_DEFAULT, stm32_hash_dev_init, NULL);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[0]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM9);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, (void *)&os_bsp_spi0m_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, (void *)&os_bsp_spi0s_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(ETH_0)
-    stm32_eth_init(&eth_cfg);
-#endif
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/nucleo-f439zi/syscfg.yml b/hw/bsp/nucleo-f439zi/syscfg.yml
index ef3378b..af88585 100644
--- a/hw/bsp/nucleo-f439zi/syscfg.yml
+++ b/hw/bsp/nucleo-f439zi/syscfg.yml
@@ -26,17 +26,6 @@ syscfg.defs:
         description: 'Number of flash sectors for a non-linear STM32 MCU.'
         value: 24
 
-    UART_0:
-        description: 'UART 0'
-        value:  1
-    TIMER_0:
-        description: 'Timer 0'
-        value:  1
-
-    ETH_0:
-        description: 'Ethernet driver for LwIP'
-        value: 0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -58,3 +47,12 @@ syscfg.vals:
     STM32_FLASH_PREFETCH_ENABLE: 1
     STM32_INSTRUCTION_CACHE_ENABLE: 1
     STM32_DATA_CACHE_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTD(8)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTD(9)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTA(4)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTB(3)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTB(4)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTB(5)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    TIMER_0_TIM: 'TIM9'
diff --git a/hw/bsp/nucleo-f746zg/include/bsp/bsp.h b/hw/bsp/nucleo-f746zg/include/bsp/bsp.h
index 34a2829..ac29ae7 100644
--- a/hw/bsp/nucleo-f746zg/include/bsp/bsp.h
+++ b/hw/bsp/nucleo-f746zg/include/bsp/bsp.h
@@ -58,14 +58,6 @@ extern uint8_t _ram2_start;
 /* BUTTON pins */
 #define BTN_USER_1      MCU_GPIO_PORTC(13)
 
-/* UART */
-#define UART_CNT        1
-
-#define PWM_CNT (MYNEWT_VAL(PWM_0) + MYNEWT_VAL(PWM_1) + MYNEWT_VAL(PWM_2))
-#define PWM_0_DEV_ID    0
-#define PWM_1_DEV_ID    (PWM_0_DEV_ID + MYNEWT_VAL(PWM_0))
-#define PWM_2_DEV_ID    (PWM_1_DEV_ID + MYNEWT_VAL(PWM_1))
-
 /* Arduino pins */
 #define ARDUINO_PIN_D0      MCU_GPIO_PORTG(9)
 #define ARDUINO_PIN_D1      MCU_GPIO_PORTG(14)
diff --git a/hw/bsp/nucleo-f746zg/pkg.yml b/hw/bsp/nucleo-f746zg/pkg.yml
index 627c765..7593700 100644
--- a/hw/bsp/nucleo-f746zg/pkg.yml
+++ b/hw/bsp/nucleo-f746zg/pkg.yml
@@ -35,18 +35,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f7xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
-pkg.deps.ETH_0:
-    - "@apache-mynewt-core/hw/drivers/lwip/stm32_eth"
-
-pkg.deps.PWM_0:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
-
-pkg.deps.PWM_1:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
-
-pkg.deps.PWM_2:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
diff --git a/hw/bsp/nucleo-f746zg/src/hal_bsp.c b/hw/bsp/nucleo-f746zg/src/hal_bsp.c
index 0ec79ef..5f7bc45 100644
--- a/hw/bsp/nucleo-f746zg/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f746zg/src/hal_bsp.c
@@ -21,66 +21,40 @@
 #include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(TRNG)
-#include "trng/trng.h"
-#include "trng_stm32/trng_stm32.h"
-#endif
-
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
-#include "hal/hal_i2c.h"
 #include <hal/hal_flash_int.h>
 #include <hal/hal_system.h>
-#include <hal/hal_timer.h>
-
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-#include <hal/hal_spi.h>
-#endif
 
 #include <stm32f746xx.h>
-#include <stm32f7xx_hal_gpio_ex.h>
-#include "mcu/stm32_hal.h"
-#include <mcu/stm32f7_bsp.h>
-#include <mcu/stm32f7xx_mynewt_hal.h>
+#include <stm32_common/stm32_hal.h>
 
 #if MYNEWT_VAL(ETH_0)
 #include <stm32_eth/stm32_eth.h>
 #include <stm32_eth/stm32_eth_cfg.h>
 #endif
 
-#if PWM_CNT
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
 #include <pwm_stm32/pwm_stm32.h>
-static struct pwm_dev stm32_pwm_dev_driver[PWM_CNT];
-static const char *stm32_pwm_dev_name[PWM_CNT] = {
-#if PWM_CNT > 0
-    "pwm0",
 #endif
-#if PWM_CNT > 1
-    "pwm1",
-#endif
-#if PWM_CNT > 2
-    "pwm2",
-#endif
-};
 
-static struct stm32_pwm_conf  stm32_pwm_config[PWM_CNT] = {
 #if MYNEWT_VAL(PWM_0)
-    { TIM3, TIM3_IRQn },
+struct stm32_pwm_conf os_bsp_pwm0_cfg = {
+    .tim = TIM3,
+    .irq = TIM3_IRQn,
+};
 #endif
 #if MYNEWT_VAL(PWM_1)
-    { TIM4, TIM4_IRQn },
+struct stm32_pwm_conf os_bsp_pwm1_cfg = {
+    .tim = TIM4,
+    .irq = TIM4_IRQn,
+};
 #endif
 #if MYNEWT_VAL(PWM_2)
-    { TIM11, TIM1_TRG_COM_TIM11_IRQn },
-#endif
+struct stm32_pwm_conf os_bsp_pwm2_cfg = {
+    .tim = TIM11,
+    .irq = TIM1_TRG_COM_TIM11_IRQn,
 };
-
-#endif /* PWM_CNT */
+#endif
 
 const uint32_t stm32_flash_sectors[] = {
     0x08000000,     /* 32kB  */
@@ -98,35 +72,17 @@ const uint32_t stm32_flash_sectors[] = {
 static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) + 1 == SZ,
         "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
-#if MYNEWT_VAL(TRNG)
-static struct trng_dev os_bsp_trng;
-#endif
-
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
-
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
-    [0] = {
-        .suc_uart = USART3,
-        .suc_rcc_reg = &RCC->APB1ENR,
-        .suc_rcc_dev = RCC_APB1ENR_USART3EN,
-        .suc_pin_tx = MCU_GPIO_PORTD(8),     /* PD8 */
-        .suc_pin_rx = MCU_GPIO_PORTD(9),     /* PD9 */
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af = GPIO_AF7_USART3,
-        .suc_irqn = USART3_IRQn,
-    }
-};
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE) || MYNEWT_VAL(SPI_0_MASTER)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .sck_pin  = MCU_GPIO_PORTA(5),           /* D13 on CN7 */
-    .miso_pin = MCU_GPIO_PORTA(6),           /* D12 on CN7 */
-    .mosi_pin = MCU_GPIO_PORTA(7),           /* D11 on CN7 */
-    .ss_pin   = MCU_GPIO_PORTD(14),          /* D10 on CN7 */
-    .irq_prio = 2,
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART3,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART3EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF7_USART3,
+    .suc_irqn = USART3_IRQn,
 };
 #endif
 
@@ -137,12 +93,12 @@ struct stm32_hal_spi_cfg spi0_cfg = {
  * to be removed (they are the default connections) and SB138/SB143 need
  * to be shorted.
  */
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(9),    /* D14 on CN7 */
-    .hic_pin_scl = MCU_GPIO_PORTB(8),    /* D15 on CN7 */
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
     .hic_timingr = 0x30420F13,    /* 100KHz at 16MHz of SysCoreClock */
@@ -150,7 +106,7 @@ static struct stm32_hal_i2c_cfg i2c_cfg0 = {
 #endif
 
 #if MYNEWT_VAL(ETH_0)
-static const struct stm32_eth_cfg eth_cfg = {
+const struct stm32_eth_cfg os_bsp_eth0_cfg = {
     /*
      * PORTA
      *   PA1 - ETH_RMII_REF_CLK
@@ -223,86 +179,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-    (void)rc;
-
-#if MYNEWT_VAL(TRNG)
-    rc = os_dev_create(&os_bsp_trng.dev, "trng", OS_DEV_INIT_KERNEL,
-                       OS_DEV_INIT_PRIO_DEFAULT, stm32_trng_dev_init, NULL);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[0]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM9);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    hal_timer_init(1, TIM10);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    hal_timer_init(2, TIM11);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(ETH_0)
-    stm32_eth_init(&eth_cfg);
-#endif
-
-#if MYNEWT_VAL(PWM_0)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_0_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_0_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_0_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(PWM_1)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_1_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_1_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_1_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(PWM_2)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_2_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_2_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_2_DEV_ID]);
-    assert(rc == 0);
-#endif
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/nucleo-f746zg/syscfg.yml b/hw/bsp/nucleo-f746zg/syscfg.yml
index 5eeafe7..ab47dbe 100644
--- a/hw/bsp/nucleo-f746zg/syscfg.yml
+++ b/hw/bsp/nucleo-f746zg/syscfg.yml
@@ -26,34 +26,6 @@ syscfg.defs:
         description: 'Number of flash sectors for a non-linear STM32 MCU.'
         value: 8
 
-    UART_0:
-        description: 'Uart 0'
-        value:  1
-
-    TIMER_0:
-        description: 'Timer 0'
-        value:  1
-    TIMER_1:
-        description: 'Timer 1'
-        value: 1
-    TIMER_2:
-        description: 'Timer 2'
-        value: 1
-
-    ETH_0:
-        description: 'Ethernet driver for LwIP'
-        value: 0
-
-    PWM_0:
-        description: 'Support for PWM 0'
-        value: 0
-    PWM_1:
-        description: 'Support for PWM 1'
-        value: 0
-    PWM_2:
-        description: 'Support for PWM 2'
-        value: 0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -74,3 +46,14 @@ syscfg.vals:
     STM32_FLASH_LATENCY: 'FLASH_LATENCY_7'
     STM32_FLASH_PREFETCH_ENABLE: 1
     STM32_ART_ACCLERATOR_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTD(8)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTD(9)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTD(14)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTA(5)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTA(6)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTA(7)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    TIMER_0_TIM: 'TIM9'
+    TIMER_1_TIM: 'TIM10'
+    TIMER_2_TIM: 'TIM11'
diff --git a/hw/bsp/nucleo-f767zi/include/bsp/bsp.h b/hw/bsp/nucleo-f767zi/include/bsp/bsp.h
index f8e916c..907bfc6 100644
--- a/hw/bsp/nucleo-f767zi/include/bsp/bsp.h
+++ b/hw/bsp/nucleo-f767zi/include/bsp/bsp.h
@@ -58,14 +58,6 @@ extern uint8_t _ram2_start;
 /* BUTTON pins */
 #define BTN_USER_1      MCU_GPIO_PORTC(13)
 
-/* UART */
-#define UART_CNT        1
-
-#define PWM_CNT (MYNEWT_VAL(PWM_0) + MYNEWT_VAL(PWM_1) + MYNEWT_VAL(PWM_2))
-#define PWM_0_DEV_ID    0
-#define PWM_1_DEV_ID    (PWM_0_DEV_ID + MYNEWT_VAL(PWM_0))
-#define PWM_2_DEV_ID    (PWM_1_DEV_ID + MYNEWT_VAL(PWM_1))
-
 /* Arduino pins */
 #define ARDUINO_PIN_D0      MCU_GPIO_PORTG(9)
 #define ARDUINO_PIN_D1      MCU_GPIO_PORTG(14)
diff --git a/hw/bsp/nucleo-f767zi/pkg.yml b/hw/bsp/nucleo-f767zi/pkg.yml
index 339f40b..e177c03 100644
--- a/hw/bsp/nucleo-f767zi/pkg.yml
+++ b/hw/bsp/nucleo-f767zi/pkg.yml
@@ -35,18 +35,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f7xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
-pkg.deps.ETH_0:
-    - "@apache-mynewt-core/hw/drivers/lwip/stm32_eth"
-
-pkg.deps.PWM_0:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
-
-pkg.deps.PWM_1:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
-
-pkg.deps.PWM_2:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
diff --git a/hw/bsp/nucleo-f767zi/src/hal_bsp.c b/hw/bsp/nucleo-f767zi/src/hal_bsp.c
index acc6ca8..c748f69 100644
--- a/hw/bsp/nucleo-f767zi/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f767zi/src/hal_bsp.c
@@ -21,66 +21,40 @@
 #include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(TRNG)
-#include "trng/trng.h"
-#include "trng_stm32/trng_stm32.h"
-#endif
-
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
-#include "hal/hal_i2c.h"
 #include <hal/hal_flash_int.h>
 #include <hal/hal_system.h>
-#include <hal/hal_timer.h>
-
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-#include <hal/hal_spi.h>
-#endif
 
 #include <stm32f767xx.h>
-#include <stm32f7xx_hal_gpio_ex.h>
-#include "mcu/stm32_hal.h"
-#include <mcu/stm32f7_bsp.h>
-#include <mcu/stm32f7xx_mynewt_hal.h>
+#include <stm32_common/stm32_hal.h>
 
 #if MYNEWT_VAL(ETH_0)
 #include <stm32_eth/stm32_eth.h>
 #include <stm32_eth/stm32_eth_cfg.h>
 #endif
 
-#if PWM_CNT
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
 #include <pwm_stm32/pwm_stm32.h>
-static struct pwm_dev stm32_pwm_dev_driver[PWM_CNT];
-static const char *stm32_pwm_dev_name[PWM_CNT] = {
-#if PWM_CNT > 0
-    "pwm0",
 #endif
-#if PWM_CNT > 1
-    "pwm1",
-#endif
-#if PWM_CNT > 2
-    "pwm2",
-#endif
-};
 
-static struct stm32_pwm_conf  stm32_pwm_config[PWM_CNT] = {
 #if MYNEWT_VAL(PWM_0)
-    { TIM3, TIM3_IRQn },
+struct stm32_pwm_conf os_bsp_pwm0_cfg = {
+    .tim = TIM3,
+    .irq = TIM3_IRQn,
+};
 #endif
 #if MYNEWT_VAL(PWM_1)
-    { TIM4, TIM4_IRQn },
+struct stm32_pwm_conf os_bsp_pwm1_cfg = {
+    .tim = TIM4,
+    .irq = TIM4_IRQn,
+};
 #endif
 #if MYNEWT_VAL(PWM_2)
-    { TIM11, TIM1_TRG_COM_TIM11_IRQn },
-#endif
+struct stm32_pwm_conf os_bsp_pwm2_cfg = {
+    .tim = TIM11,
+    .irq = TIM1_TRG_COM_TIM11_IRQn,
 };
-
-#endif /* PWM_CNT */
+#endif
 
 /* FIXME: this works but shouldn't it be dual bank? */
 const uint32_t stm32_flash_sectors[] = {
@@ -103,35 +77,17 @@ const uint32_t stm32_flash_sectors[] = {
 static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) + 1 == SZ,
         "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
-#if MYNEWT_VAL(TRNG)
-static struct trng_dev os_bsp_trng;
-#endif
-
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
-
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
-    [0] = {
-        .suc_uart = USART3,
-        .suc_rcc_reg = &RCC->APB1ENR,
-        .suc_rcc_dev = RCC_APB1ENR_USART3EN,
-        .suc_pin_tx = MCU_GPIO_PORTD(8),     /* PD8 */
-        .suc_pin_rx = MCU_GPIO_PORTD(9),     /* PD9 */
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af = GPIO_AF7_USART3,
-        .suc_irqn = USART3_IRQn,
-    }
-};
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE) || MYNEWT_VAL(SPI_0_MASTER)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .sck_pin  = MCU_GPIO_PORTA(5),           /* D13 on CN7 */
-    .miso_pin = MCU_GPIO_PORTA(6),           /* D12 on CN7 */
-    .mosi_pin = MCU_GPIO_PORTA(7),           /* D11 on CN7 */
-    .ss_pin   = MCU_GPIO_PORTD(14),          /* D10 on CN7 */
-    .irq_prio = 2,
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART3,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART3EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF7_USART3,
+    .suc_irqn = USART3_IRQn,
 };
 #endif
 
@@ -142,12 +98,12 @@ struct stm32_hal_spi_cfg spi0_cfg = {
  * to be removed (they are the default connections) and SB138/SB143 need
  * to be shorted.
  */
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(9),    /* D14 on CN7 */
-    .hic_pin_scl = MCU_GPIO_PORTB(8),    /* D15 on CN7 */
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
     .hic_timingr = 0x30420F13,    /* 100KHz at 16MHz of SysCoreClock */
@@ -155,7 +111,7 @@ static struct stm32_hal_i2c_cfg i2c_cfg0 = {
 #endif
 
 #if MYNEWT_VAL(ETH_0)
-static const struct stm32_eth_cfg eth_cfg = {
+const struct stm32_eth_cfg os_bsp_eth0_cfg = {
     /*
      * PORTA
      *   PA1 - ETH_RMII_REF_CLK
@@ -228,86 +184,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-    (void)rc;
-
-#if MYNEWT_VAL(TRNG)
-    rc = os_dev_create(&os_bsp_trng.dev, "trng", OS_DEV_INIT_KERNEL,
-                       OS_DEV_INIT_PRIO_DEFAULT, stm32_trng_dev_init, NULL);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[0]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM9);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    hal_timer_init(1, TIM10);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    hal_timer_init(2, TIM11);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(ETH_0)
-    stm32_eth_init(&eth_cfg);
-#endif
-
-#if MYNEWT_VAL(PWM_0)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_0_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_0_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_0_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(PWM_1)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_1_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_1_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_1_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(PWM_2)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_2_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_2_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_2_DEV_ID]);
-    assert(rc == 0);
-#endif
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/nucleo-f767zi/syscfg.yml b/hw/bsp/nucleo-f767zi/syscfg.yml
index 718b79a..b4ffd38 100644
--- a/hw/bsp/nucleo-f767zi/syscfg.yml
+++ b/hw/bsp/nucleo-f767zi/syscfg.yml
@@ -26,34 +26,6 @@ syscfg.defs:
         description: 'Number of flash sectors for a non-linear STM32 MCU.'
         value: 12
 
-    UART_0:
-        description: 'Uart 0'
-        value:  1
-
-    TIMER_0:
-        description: 'Timer 0'
-        value:  1
-    TIMER_1:
-        description: 'Timer 1'
-        value: 1
-    TIMER_2:
-        description: 'Timer 2'
-        value: 1
-
-    ETH_0:
-        description: 'Ethernet driver for LwIP'
-        value: 0
-
-    PWM_0:
-        description: 'Support for PWM 0'
-        value: 0
-    PWM_1:
-        description: 'Support for PWM 1'
-        value: 0
-    PWM_2:
-        description: 'Support for PWM 2'
-        value: 0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -75,3 +47,14 @@ syscfg.vals:
     STM32_FLASH_LATENCY: 'FLASH_LATENCY_7'
     STM32_FLASH_PREFETCH_ENABLE: 1
     STM32_ART_ACCLERATOR_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTD(8)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTD(9)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTD(14)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTA(5)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTA(6)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTA(7)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    TIMER_0_TIM: 'TIM9'
+    TIMER_1_TIM: 'TIM10'
+    TIMER_2_TIM: 'TIM11'
diff --git a/hw/bsp/nucleo-l476rg/include/bsp/bsp.h b/hw/bsp/nucleo-l476rg/include/bsp/bsp.h
index 5084118..779cf55 100644
--- a/hw/bsp/nucleo-l476rg/include/bsp/bsp.h
+++ b/hw/bsp/nucleo-l476rg/include/bsp/bsp.h
@@ -41,9 +41,6 @@ extern uint8_t _ram_start;
 /* LED pins */
 #define LED_BLINK_PIN   MCU_GPIO_PORTA(5)
 
-/* UART */
-#define UART_CNT 2
-
 /* Arduino pins */
 #define ARDUINO_PIN_D0      MCU_GPIO_PORTA(3)
 #define ARDUINO_PIN_D1      MCU_GPIO_PORTA(2)
diff --git a/hw/bsp/nucleo-l476rg/pkg.yml b/hw/bsp/nucleo-l476rg/pkg.yml
index 42e6795..b5cce66 100644
--- a/hw/bsp/nucleo-l476rg/pkg.yml
+++ b/hw/bsp/nucleo-l476rg/pkg.yml
@@ -36,8 +36,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32l4xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-pkg.deps.UART_1:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
diff --git a/hw/bsp/nucleo-l476rg/src/hal_bsp.c b/hw/bsp/nucleo-l476rg/src/hal_bsp.c
index e25224d..31020b8 100644
--- a/hw/bsp/nucleo-l476rg/src/hal_bsp.c
+++ b/hw/bsp/nucleo-l476rg/src/hal_bsp.c
@@ -18,38 +18,22 @@
  */
 #include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
 #include <hal/hal_flash_int.h>
-#include <hal/hal_timer.h>
-
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-#include <hal/hal_spi.h>
-#endif
+#include <hal/hal_system.h>
 
 #include <stm32l476xx.h>
-#include <stm32l4xx_hal_rcc.h>
-#include <stm32l4xx_hal_pwr.h>
-#include <stm32l4xx_hal_flash.h>
-#include <stm32l4xx_hal_gpio_ex.h>
-#include <mcu/stm32l4_bsp.h>
-#include "mcu/stm32l4xx_mynewt_hal.h"
-#include "mcu/stm32_hal.h"
-#include "hal/hal_i2c.h"
+#include <stm32_common/stm32_hal.h>
 
-#include "bsp/bsp.h"
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
+#endif
 
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
-
-static const struct stm32_uart_cfg uart0_cfg = {
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
     .suc_uart = USART2,
     .suc_rcc_reg = &RCC->APB1ENR1,
     .suc_rcc_dev = RCC_APB1ENR1_USART2EN,
@@ -63,9 +47,7 @@ static const struct stm32_uart_cfg uart0_cfg = {
 #endif
 
 #if MYNEWT_VAL(UART_1)
-static struct uart_dev hal_uart1;
-
-static const struct stm32_uart_cfg uart1_cfg = {
+const struct stm32_uart_cfg os_bsp_uart1_cfg = {
     .suc_uart = USART1,
     .suc_rcc_reg = &RCC->APB2ENR,
     .suc_rcc_dev = RCC_APB2ENR_USART1EN,
@@ -85,7 +67,7 @@ static const struct stm32_uart_cfg uart1_cfg = {
  * be removed (they are the default connections) and SB46/SB52 need to
  * be added.
  */
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR1,
     .hic_rcc_dev = RCC_APB1ENR1_I2C1EN,
@@ -98,7 +80,7 @@ static struct stm32_hal_i2c_cfg i2c_cfg0 = {
 #endif
 
 #if MYNEWT_VAL(I2C_1)
-static struct stm32_hal_i2c_cfg i2c_cfg1 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c1_cfg = {
     .hic_i2c = I2C2,
     .hic_rcc_reg = &RCC->APB1ENR1,
     .hic_rcc_dev = RCC_APB1ENR1_I2C2EN,
@@ -117,7 +99,7 @@ static struct stm32_hal_i2c_cfg i2c_cfg1 = {
  * If solder brides are removed I2C_2 can't be accessed since only PC0, PC1
  * are present on Nucleo-64 board for I2C3 to use.
  */
-static struct stm32_hal_i2c_cfg i2c_cfg2 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c2_cfg = {
     .hic_i2c = I2C3,
     .hic_rcc_reg = &RCC->APB1ENR1,
     .hic_rcc_dev = RCC_APB1ENR1_I2C3EN,
@@ -129,16 +111,6 @@ static struct stm32_hal_i2c_cfg i2c_cfg2 = {
 };
 #endif
 
-#if MYNEWT_VAL(SPI_0_SLAVE) || MYNEWT_VAL(SPI_0_MASTER)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .ss_pin   = MCU_GPIO_PORTA(4),
-    .sck_pin  = MCU_GPIO_PORTA(5),
-    .miso_pin = MCU_GPIO_PORTA(6),
-    .mosi_pin = MCU_GPIO_PORTA(7),
-    .irq_prio = 2,
-};
-#endif
-
 static const struct hal_bsp_mem_dump dump_cfg[] = {
     [0] = {
         .hbmd_start = &_ram_start,
@@ -169,63 +141,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart0_cfg);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_1)
-    rc = os_dev_create((struct os_dev *) &hal_uart1, "uart1",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart1_cfg);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM2);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    hal_timer_init(1, TIM3);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    hal_timer_init(2, TIM4);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_1)
-    rc = hal_i2c_init(1, &i2c_cfg1);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_2)
-    rc = hal_i2c_init(2, &i2c_cfg2);
-    assert(rc == 0);
-#endif
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/nucleo-l476rg/syscfg.yml b/hw/bsp/nucleo-l476rg/syscfg.yml
index 69e781a..de38f02 100644
--- a/hw/bsp/nucleo-l476rg/syscfg.yml
+++ b/hw/bsp/nucleo-l476rg/syscfg.yml
@@ -22,50 +22,6 @@ syscfg.defs:
         description: 'Total flash size in KB.'
         value: 1024
 
-    UART_0:
-        description: 'Whether to enable USART2'
-        value:  1
-    UART_0_PIN_TX:
-        description: 'TX pin for USART2, PA2, PD5'
-        value: MCU_GPIO_PORTA(2)
-    UART_0_PIN_RX:
-        description: 'RX pin for USART2, PA3, PD6'
-        value: MCU_GPIO_PORTA(3)
-    UART_0_PIN_CTS:
-        description: 'CTS pin for USART2, PA0, PD3'
-        value: -1
-    UART_0_PIN_RTS:
-        description: 'RTS pin for USART2, PA1, PD4'
-        value: -1
-
-    UART_1:
-        description: 'Whether to enable USART1'
-        value:  0
-    UART_1_PIN_TX:
-        description: 'TX pin for USART1, PA9, PB6'
-        value: MCU_GPIO_PORTA(9)
-    UART_1_PIN_RX:
-        description: 'RX pin for USART1, PA10, PB7'
-        value: MCU_GPIO_PORTA(10)
-    UART_1_PIN_CTS:
-        description: 'CTS pin for USART1, PA11, PB4'
-        value: -1
-    UART_1_PIN_RTS:
-        description: 'RTS pin for USART1, PA12, PB3'
-        value: -1
-
-    TIMER_0:
-        description: 'Whether to enable TIMER_0'
-        value: 1
-
-    TIMER_1:
-        description: 'Whether to enable TIMER_1'
-        value: 0
-
-    TIMER_2:
-        description: 'Whether to enable TIMER_2'
-        value: 0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -95,3 +51,20 @@ syscfg.vals:
     STM32_FLASH_PREFETCH_ENABLE: 0
     STM32_INSTRUCTION_CACHE_ENABLE: 1
     STM32_DATA_CACHE_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(2)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTA(3)'
+    UART_1_PIN_TX: 'MCU_GPIO_PORTA(9)'
+    UART_1_PIN_RX: 'MCU_GPIO_PORTA(10)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    I2C_1_PIN_SCL: 'MCU_GPIO_PORTB(10)'
+    I2C_1_PIN_SDA: 'MCU_GPIO_PORTB(11)'
+    I2C_2_PIN_SCL: 'MCU_GPIO_PORTC(0)'
+    I2C_2_PIN_SDA: 'MCU_GPIO_PORTC(1)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTA(4)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTA(5)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTA(6)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTA(7)'
+    TIMER_0_TIM: 'TIM2'
+    TIMER_1_TIM: 'TIM3'
+    TIMER_2_TIM: 'TIM4'
diff --git a/hw/bsp/olimex-p103/include/bsp/bsp.h b/hw/bsp/olimex-p103/include/bsp/bsp.h
index ba3b128..501ecbb 100644
--- a/hw/bsp/olimex-p103/include/bsp/bsp.h
+++ b/hw/bsp/olimex-p103/include/bsp/bsp.h
@@ -43,9 +43,6 @@ extern uint8_t _ram_start;
 /* NOTE: no LED is installed here */
 #define LED_2           MCU_GPIO_PORTC(0)
 
-/* UART */
-#define UART_CNT 1
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/bsp/olimex-p103/pkg.yml b/hw/bsp/olimex-p103/pkg.yml
index bbfe4d8..795a1e0 100644
--- a/hw/bsp/olimex-p103/pkg.yml
+++ b/hw/bsp/olimex-p103/pkg.yml
@@ -31,6 +31,3 @@ pkg.cflags: -DSTM32F103xB
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f1xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
diff --git a/hw/bsp/olimex-p103/src/hal_bsp.c b/hw/bsp/olimex-p103/src/hal_bsp.c
index 21044f8..4895035 100644
--- a/hw/bsp/olimex-p103/src/hal_bsp.c
+++ b/hw/bsp/olimex-p103/src/hal_bsp.c
@@ -16,86 +16,43 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 #include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
 #include <hal/hal_flash_int.h>
-#include <hal/hal_timer.h>
-
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE) || \
-    MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_1_SLAVE)
-#include <hal/hal_spi.h>
-#endif
+#include <hal/hal_system.h>
 
 #include <stm32f103xb.h>
-#include <stm32f1xx_hal_rcc.h>
-#include <stm32f1xx_hal_pwr.h>
-#include <stm32f1xx_hal_flash.h>
-#include <stm32f1xx_hal_gpio_ex.h>
-#include <stm32f1xx_ll_gpio.h>       /* AF remapping */
-#include <mcu/stm32f1_bsp.h>
-#include "mcu/stm32f1xx_mynewt_hal.h"
-#include "mcu/stm32_hal.h"
-#include "hal/hal_i2c.h"
-
-#include "bsp/bsp.h"
-
-#if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
+#include <stm32_common/stm32_hal.h>
 
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
-    [0] = {
-        .suc_uart = USART2,
-        .suc_rcc_reg = &RCC->APB1ENR,
-        .suc_rcc_dev = RCC_APB1ENR_USART2EN,
-        .suc_pin_tx = MCU_GPIO_PORTA(2),
-        .suc_pin_rx = MCU_GPIO_PORTA(3),
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_remap_fn = LL_GPIO_AF_DisableRemap_USART2,
-        .suc_irqn = USART2_IRQn,
-    }
-};
-#endif
-
-/* NOTE: UEXT connector */
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .ss_pin   = MCU_GPIO_PORTA(4),
-    .sck_pin  = MCU_GPIO_PORTA(5),
-    .miso_pin = MCU_GPIO_PORTA(6),
-    .mosi_pin = MCU_GPIO_PORTA(7),
-    .irq_prio = 2,
-};
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
 #endif
 
-/* NOTE: SD-MMC */
-#if MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_1_SLAVE)
-struct stm32_hal_spi_cfg spi1_cfg = {
-    .ss_pin   = MCU_GPIO_PORTB(12),
-    .sck_pin  = MCU_GPIO_PORTB(13),
-    .miso_pin = MCU_GPIO_PORTB(14),
-    .mosi_pin = MCU_GPIO_PORTB(15),
-    .irq_prio = 2,
+#if MYNEWT_VAL(UART_0)
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART2,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART2EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_remap_fn = LL_GPIO_AF_DisableRemap_USART2,
+    .suc_irqn = USART2_IRQn,
 };
 #endif
 
 #if MYNEWT_VAL(I2C_0)
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(7),
-    .hic_pin_scl = MCU_GPIO_PORTB(6),
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_remap_fn = LL_GPIO_AF_DisableRemap_I2C1,
     .hic_10bit = 0,
     .hic_speed = 100000,
@@ -132,58 +89,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[0]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM2);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    hal_timer_init(1, TIM3);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    hal_timer_init(2, TIM4);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_1_MASTER)
-    rc = hal_spi_init(1, &spi1_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_1_SLAVE)
-    rc = hal_spi_init(1, &spi1_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/olimex-p103/syscfg.yml b/hw/bsp/olimex-p103/syscfg.yml
index 36877c1..58ad0eb 100644
--- a/hw/bsp/olimex-p103/syscfg.yml
+++ b/hw/bsp/olimex-p103/syscfg.yml
@@ -22,22 +22,6 @@ syscfg.defs:
         description: 'Total flash size in KB.'
         value: 128
 
-    UART_0:
-        description: 'UART 0'
-        value:  1
-
-    TIMER_0:
-        description: 'Timer 0'
-        value:  1
-
-    TIMER_1:
-        description: 'Timer 1'
-        value:  0
-
-    TIMER_2:
-        description: 'Timer 2'
-        value:  0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -53,3 +37,18 @@ syscfg.vals:
     STM32_CLOCK_APB2_DIVIDER: 'RCC_HCLK_DIV1'
     STM32_FLASH_LATENCY: 'FLASH_LATENCY_2'
     STM32_FLASH_PREFETCH_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(2)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTA(3)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTA(4)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTA(5)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTA(6)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTA(7)'
+    SPI_1_PIN_SS: 'MCU_GPIO_PORTB(12)'
+    SPI_1_PIN_SCK: 'MCU_GPIO_PORTB(13)'
+    SPI_1_PIN_MOSI: 'MCU_GPIO_PORTB(15)'
+    SPI_1_PIN_MISO: 'MCU_GPIO_PORTB(14)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(6)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(7)'
+    TIMER_0_TIM: 'TIM2'
+    TIMER_1_TIM: 'TIM3'
+    TIMER_2_TIM: 'TIM4'
diff --git a/hw/bsp/olimex_stm32-e407_devboard/include/bsp/bsp.h b/hw/bsp/olimex_stm32-e407_devboard/include/bsp/bsp.h
index 21d3f95..effa894 100644
--- a/hw/bsp/olimex_stm32-e407_devboard/include/bsp/bsp.h
+++ b/hw/bsp/olimex_stm32-e407_devboard/include/bsp/bsp.h
@@ -43,10 +43,6 @@ extern uint8_t _ccram_start;
 /* LED pins */
 #define LED_BLINK_PIN   MCU_GPIO_PORTC(13)
 
-/* UART */
-#define UART_CNT 1
-#define SPI_SS_PIN       (4)
-
 /* Arduino pins */
 #define ARDUINO_PIN_D0      MCU_GPIO_PORTB(7)
 #define ARDUINO_PIN_D1      MCU_GPIO_PORTB(6)
diff --git a/hw/bsp/olimex_stm32-e407_devboard/pkg.yml b/hw/bsp/olimex_stm32-e407_devboard/pkg.yml
index 37a2c75..12a0d81 100644
--- a/hw/bsp/olimex_stm32-e407_devboard/pkg.yml
+++ b/hw/bsp/olimex_stm32-e407_devboard/pkg.yml
@@ -44,9 +44,3 @@ pkg.deps.ADC_2:
     - "@apache-mynewt-core/hw/drivers/adc/adc_stm32f4"
 pkg.deps.ADC_3:
     - "@apache-mynewt-core/hw/drivers/adc/adc_stm32f4"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
-pkg.deps.ETH_0:
-    - "@apache-mynewt-core/hw/drivers/lwip/stm32_eth"
diff --git a/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c b/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c
index 01aaaaf..e5d8ab6 100644
--- a/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c
+++ b/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c
@@ -16,40 +16,31 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 #include <assert.h>
-#include "os/mynewt.h"
+
 #include "bsp/bsp.h"
+#include "os/mynewt.h"
+
+#include <hal/hal_bsp.h>
+#include <hal/hal_flash_int.h>
+#include <hal/hal_system.h>
+
 #include "stm32f407xx.h"
-#include "stm32f4xx_hal_gpio_ex.h"
-#include "stm32f4xx_hal_dma.h"
-#include "stm32f4xx_hal_adc.h"
-#include "flash_map/flash_map.h"
-#if MYNEWT_VAL(TRNG)
-#include "trng/trng.h"
-#include "trng_stm32/trng_stm32.h"
+#include <stm32_common/stm32_hal.h>
+
+#if MYNEWT_VAL(ETH_0)
+#include <stm32_eth/stm32_eth.h>
+#include <stm32_eth/stm32_eth_cfg.h>
 #endif
-#if MYNEWT_VAL(UART_0)
-#include "uart/uart.h"
-#include "uart_hal/uart_hal.h"
+
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
 #endif
+
 #if MYNEWT_VAL(ADC_1) || MYNEWT_VAL(ADC_2) || MYNEWT_VAL(ADC_3)
+#include "stm32f4xx_hal_adc.h"
 #include "adc_stm32f4/adc_stm32f4.h"
 #endif
-#include "hal/hal_i2c.h"
-#include "hal/hal_timer.h"
-#include "hal/hal_bsp.h"
-#include "hal/hal_gpio.h"
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-#include "hal/hal_spi.h"
-#endif
-#if MYNEWT_VAL(ETH_0)
-#include "stm32_eth/stm32_eth.h"
-#include "stm32_eth/stm32_eth_cfg.h"
-#endif
-#include "mcu/stm32_hal.h"
-#include "mcu/stm32f4_bsp.h"
-#include "mcu/stm32f4xx_mynewt_hal.h"
 
 const uint32_t stm32_flash_sectors[] = {
     0x08000000,     /* 16kB */
@@ -71,14 +62,6 @@ const uint32_t stm32_flash_sectors[] = {
 static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) + 1 == SZ,
         "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
-#if MYNEWT_VAL(TRNG)
-static struct trng_dev os_bsp_trng;
-#endif
-
-#if MYNEWT_VAL(UART_0)
-struct uart_dev hal_uart0;
-#endif
-
 #if MYNEWT_VAL(ADC_1)
 struct adc_dev my_dev_adc1;
 #endif
@@ -280,43 +263,35 @@ struct adc_chan_config adc3_chan4_config = STM32F4_ADC3_DEFAULT_SAC;
 struct stm32f4_adc_dev_cfg adc3_config = STM32F4_ADC3_DEFAULT_CONFIG;
 #endif
 
+#if MYNEWT_VAL(UART_0)
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART6,
+    .suc_rcc_reg = &RCC->APB2ENR,
+    .suc_rcc_dev = RCC_APB2ENR_USART6EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF8_USART6,
+    .suc_irqn = USART6_IRQn
+};
+#endif
+
 #if MYNEWT_VAL(I2C_0)
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(9),		/* PB9 */
-    .hic_pin_scl = MCU_GPIO_PORTB(8),		/* PB8 */
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
-    .hic_speed = 100000				/* 100kHz */
+    .hic_speed = 100000,
 };
 #endif
 
-#if MYNEWT_VAL(SPI_0_SLAVE) || MYNEWT_VAL(SPI_0_MASTER)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .ss_pin = MCU_GPIO_PORTA(4),		/* PA4 */
-    .sck_pin  = MCU_GPIO_PORTA(5),		/* PA5 */
-    .miso_pin = MCU_GPIO_PORTA(6),		/* PA6 */
-    .mosi_pin = MCU_GPIO_PORTB(5),		/* PB5 */
-    .irq_prio = 2
-};
-#endif
-#if MYNEWT_VAL(UART_0)
-static const struct stm32_uart_cfg uart_cfg0 = {
-    .suc_uart = USART6,
-    .suc_rcc_reg = &RCC->APB2ENR,
-    .suc_rcc_dev = RCC_APB2ENR_USART6EN,
-    .suc_pin_tx = MCU_GPIO_PORTC(6),	/* PC6 */
-    .suc_pin_rx = MCU_GPIO_PORTC(7),	/* PC7 */
-    .suc_pin_rts = -1,
-    .suc_pin_cts = -1,
-    .suc_pin_af = GPIO_AF8_USART6,
-    .suc_irqn = USART6_IRQn
-};
-#endif
 #if MYNEWT_VAL(ETH_0)
-static const struct stm32_eth_cfg eth_cfg = {
+const struct stm32_eth_cfg os_bsp_eth0_cfg = {
     /*
      * PORTA
      *   PA1 - ETH_RMII_REF_CLK
@@ -345,6 +320,7 @@ static const struct stm32_eth_cfg eth_cfg = {
     .sec_phy_irq = MCU_GPIO_PORTA(3)
 };
 #endif
+
 static const struct hal_bsp_mem_dump dump_cfg[] = {
     [0] = {
         .hbmd_start = &_ram_start,
@@ -405,27 +381,7 @@ hal_bsp_init(void)
 
     (void)rc;
 
-#if MYNEWT_VAL(TRNG)
-    rc = os_dev_create(&os_bsp_trng.dev, "trng", OS_DEV_INIT_KERNEL,
-                       OS_DEV_INIT_PRIO_DEFAULT, stm32_trng_dev_init, NULL);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg0);
-    assert(rc == 0);
-#endif
+    stm32_periph_create();
 
 #if MYNEWT_VAL(ADC_1)
     rc = os_dev_create((struct os_dev *) &my_dev_adc1, "adc1",
@@ -445,23 +401,4 @@ hal_bsp_init(void)
             stm32f4_adc_dev_init, &adc3_config);
     assert(rc == 0);
 #endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM9);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(ETH_0)
-    rc = stm32_eth_init(&eth_cfg);
-    assert(rc == 0);
-#endif
 }
diff --git a/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml b/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml
index e762aba..f1194f0 100644
--- a/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml
+++ b/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml
@@ -35,18 +35,6 @@ syscfg.defs:
         description: "ADC_3"
         value:  0
 
-    UART_0:
-        description: 'Whether to enable UART0'
-        value:  1
-
-    TIMER_0:
-        description: 'TIMER_0'
-        value: 1
-
-    ETH_0:
-        description: 'Ethernet driver for LwIP'
-        value: 0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -68,3 +56,12 @@ syscfg.vals:
     STM32_FLASH_PREFETCH_ENABLE: 1
     STM32_INSTRUCTION_CACHE_ENABLE: 1
     STM32_DATA_CACHE_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTC(6)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTC(7)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTA(4)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTA(5)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTA(6)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTA(7)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    TIMER_0_TIM: 'TIM9'
diff --git a/hw/bsp/p-nucleo-wb55/include/bsp/bsp.h b/hw/bsp/p-nucleo-wb55/include/bsp/bsp.h
index 28f9708..023fea6 100644
--- a/hw/bsp/p-nucleo-wb55/include/bsp/bsp.h
+++ b/hw/bsp/p-nucleo-wb55/include/bsp/bsp.h
@@ -42,9 +42,6 @@ extern uint8_t _ram_start;
 #define LED_BLINK_PIN       MCU_GPIO_PORTB(5)
 #define LED_2               MCU_GPIO_PORTB(0)
 
-/* UART */
-#define UART_CNT 1
-
 /* Arduino pins */
 #define ARDUINO_PIN_D0      MCU_GPIO_PORTA(3)
 #define ARDUINO_PIN_D1      MCU_GPIO_PORTA(2)
diff --git a/hw/bsp/p-nucleo-wb55/pkg.yml b/hw/bsp/p-nucleo-wb55/pkg.yml
index aa8129e..7bcb928 100644
--- a/hw/bsp/p-nucleo-wb55/pkg.yml
+++ b/hw/bsp/p-nucleo-wb55/pkg.yml
@@ -36,14 +36,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32wbxx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-pkg.deps.UART_1:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
-pkg.deps.TRNG:
-    - "@apache-mynewt-core/hw/drivers/trng/trng_stm32"
-
-pkg.deps.CRYPTO:
-    - "@apache-mynewt-core/hw/drivers/crypto/crypto_stm32"
diff --git a/hw/bsp/p-nucleo-wb55/src/hal_bsp.c b/hw/bsp/p-nucleo-wb55/src/hal_bsp.c
index 4d418d6..f810f71 100644
--- a/hw/bsp/p-nucleo-wb55/src/hal_bsp.c
+++ b/hw/bsp/p-nucleo-wb55/src/hal_bsp.c
@@ -18,91 +18,52 @@
  */
 #include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(TRNG)
-#include "trng/trng.h"
-#include "trng_stm32/trng_stm32.h"
-#endif
-
-#if MYNEWT_VAL(CRYPTO)
-#include "crypto/crypto.h"
-#include "crypto_stm32/crypto_stm32.h"
-#endif
-
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
 #include <hal/hal_flash_int.h>
-#include <hal/hal_timer.h>
-
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-#include <hal/hal_spi.h>
-#endif
+#include <hal/hal_system.h>
 
 #include <stm32wb55xx.h>
-#include <stm32wbxx_hal_rcc.h>
-#include <stm32wbxx_hal_pwr.h>
-#include <stm32wbxx_hal_flash.h>
-#include <stm32wbxx_hal_gpio_ex.h>
-#include <mcu/stm32wb_bsp.h>
-#include "mcu/stm32wbxx_mynewt_hal.h"
-#include "mcu/stm32_hal.h"
-#include "hal/hal_i2c.h"
+#include <stm32_common/stm32_hal.h>
 
-#include "bsp/bsp.h"
-
-#if MYNEWT_VAL(TRNG)
-static struct trng_dev os_bsp_trng;
+#if MYNEWT_VAL(ETH_0)
+#include <stm32_eth/stm32_eth.h>
+#include <stm32_eth/stm32_eth_cfg.h>
 #endif
 
-#if MYNEWT_VAL(CRYPTO)
-static struct crypto_dev os_bsp_crypto;
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
 #endif
 
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
-
-static const struct stm32_uart_cfg uart0_cfg = {
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
     .suc_uart = USART1,
     .suc_rcc_reg = &RCC->APB2ENR,
     .suc_rcc_dev = RCC_APB2ENR_USART1EN,
-    .suc_pin_tx = MCU_GPIO_PORTB(6),
-    .suc_pin_rx = MCU_GPIO_PORTB(7),
-    .suc_pin_rts = -1,
-    .suc_pin_cts = -1,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
     .suc_pin_af = GPIO_AF7_USART1,
     .suc_irqn = USART1_IRQn,
 };
 #endif
 
 #if MYNEWT_VAL(I2C_0)
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR1,
     .hic_rcc_dev = RCC_APB1ENR1_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(9),     /* PB9 - D14 on CN10 */
-    .hic_pin_scl = MCU_GPIO_PORTB(8),     /* PB8 - D15 on CN10 */
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
     .hic_timingr = 0x00C0216C,            /* 400KHz at 64MHz */
 };
 #endif
 
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .ss_pin   = MCU_GPIO_PORTA(4),        /* D10 on CN5 */
-    .sck_pin  = MCU_GPIO_PORTA(5),        /* D13 on CN5 */
-    .miso_pin = MCU_GPIO_PORTA(6),        /* D12 on CN5 */
-    .mosi_pin = MCU_GPIO_PORTA(7),        /* D11 on CN5 */
-    .irq_prio = 2,
-};
-#endif
-
 static const struct hal_bsp_mem_dump dump_cfg[] = {
     [0] = {
         .hbmd_start = &_ram_start,
@@ -133,59 +94,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
-#if MYNEWT_VAL(TRNG)
-    rc = os_dev_create(&os_bsp_trng.dev, "trng", OS_DEV_INIT_KERNEL,
-                       OS_DEV_INIT_PRIO_DEFAULT, stm32_trng_dev_init, NULL);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(CRYPTO)
-    rc = os_dev_create(&os_bsp_crypto.dev, "crypto",
-                       OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
-                       stm32_crypto_dev_init, NULL);
-#endif
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-            OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart0_cfg);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM2);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    hal_timer_init(1, TIM16);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    hal_timer_init(2, TIM17);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/p-nucleo-wb55/syscfg.yml b/hw/bsp/p-nucleo-wb55/syscfg.yml
index ea4b23e..aae359d 100644
--- a/hw/bsp/p-nucleo-wb55/syscfg.yml
+++ b/hw/bsp/p-nucleo-wb55/syscfg.yml
@@ -22,22 +22,6 @@ syscfg.defs:
         description: 'Total flash size in KB.'
         value: 1024
 
-    UART_0:
-        description: 'Whether to enable UART0'
-        value:  1
-
-    TIMER_0:
-        description: 'Whether to enable TIMER_0'
-        value: 1
-
-    TIMER_1:
-        description: 'Whether to enable TIMER_1'
-        value: 0
-
-    TIMER_2:
-        description: 'Whether to enable TIMER_2'
-        value: 0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -72,3 +56,14 @@ syscfg.vals:
     STM32_FLASH_PREFETCH_ENABLE: 1
     STM32_INSTRUCTION_CACHE_ENABLE: 1
     STM32_DATA_CACHE_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTB(6)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTB(7)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTA(4)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTA(5)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTA(6)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTA(7)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    TIMER_0_TIM: 'TIM2'
+    TIMER_1_TIM: 'TIM16'
+    TIMER_2_TIM: 'TIM17'
diff --git a/hw/bsp/stm32f3discovery/include/bsp/bsp.h b/hw/bsp/stm32f3discovery/include/bsp/bsp.h
index c791f6b..35099ff 100644
--- a/hw/bsp/stm32f3discovery/include/bsp/bsp.h
+++ b/hw/bsp/stm32f3discovery/include/bsp/bsp.h
@@ -49,11 +49,8 @@ extern uint8_t _ccram_start;
 
 #define BTN_USER_1         MCU_GPIO_PORTA(0)
 
-#define UART_CNT           1
-#define UART_DEV_NAME      "uart0"
-
-/* This defines the maximum NFFS areas (block) are in the BSPs NFS file 
- * system space.  This in conjunction with flash map determines how 
+/* This defines the maximum NFFS areas (block) are in the BSPs NFS file
+ * system space.  This in conjunction with flash map determines how
  * many NFS blocks there will be.  A minimum is the number of individually
  * erasable sectors in the flash area and the maximum is this number. If
  * your max is less than the number of sectors then the NFFS will combine
diff --git a/hw/bsp/stm32f3discovery/pkg.yml b/hw/bsp/stm32f3discovery/pkg.yml
index ed0f9f9..df705c8 100644
--- a/hw/bsp/stm32f3discovery/pkg.yml
+++ b/hw/bsp/stm32f3discovery/pkg.yml
@@ -36,12 +36,6 @@ pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f3xx"
     - "@apache-mynewt-core/libc/baselibc"
 
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
-pkg.deps.UART_1:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
 pkg.deps.LSM303DLHC_ONB:
     - "@apache-mynewt-core/hw/drivers/sensors/lsm303dlhc"
 
diff --git a/hw/bsp/stm32f3discovery/src/hal_bsp.c b/hw/bsp/stm32f3discovery/src/hal_bsp.c
index f63bab2..beee7ce 100644
--- a/hw/bsp/stm32f3discovery/src/hal_bsp.c
+++ b/hw/bsp/stm32f3discovery/src/hal_bsp.c
@@ -16,39 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-#include <stddef.h>
 #include <assert.h>
-#include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0)
-/*
- * It is necessary to include uart/uart.h before stm32fxx_hal_uart.h gets included
- * due to a name conflict for UART_PARITY_NONE.
- */
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
+#include "bsp/bsp.h"
+#include "os/mynewt.h"
 
 #include <hal/hal_bsp.h>
 #include <hal/hal_flash_int.h>
-#include <hal/hal_gpio.h>
-#include <hal/hal_i2c.h>
 #include <hal/hal_system.h>
 
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE) || \
-    MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_1_SLAVE)
-#include <hal/hal_spi.h>
-#endif
-
 #include <stm32f3xx.h>
-#include <stm32f3xx_hal.h>
-#include "mcu/stm32f3_bsp.h"
-#include "mcu/stm32f3xx_mynewt_hal.h"
-#include "mcu/stm32_hal.h"
-
-#include "bsp/bsp.h"
-#include "mcu/mcu.h"
-#include "os/os_cputime.h"
+#include <stm32_common/stm32_hal.h>
 
 #if MYNEWT_VAL(LSM303DLHC_ONB)
 #include "lsm303dlhc/lsm303dlhc.h"
@@ -64,57 +42,26 @@ static struct sensor_itf i2c_0_itf = {
 #endif
 
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart[1];
-
-static const struct stm32_uart_cfg uart_cfg[1] = {
-    {
-        .suc_uart    = USART1,
-        .suc_rcc_reg = &RCC->APB2ENR,
-        .suc_rcc_dev = RCC_APB2ENR_USART1EN,
-        .suc_pin_tx  = MCU_GPIO_PORTA(9),
-        .suc_pin_rx  = MCU_GPIO_PORTA(10),
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af  = GPIO_AF7_USART1,
-        .suc_irqn    = USART1_IRQn,
-    },
-};
-
-const struct stm32_uart_cfg *
-bsp_uart_config(int port)
-{
-    assert(port == 0);
-    return &uart_cfg[port];
-}
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .ss_pin   = MCU_GPIO_PORTA(4),
-    .sck_pin  = MCU_GPIO_PORTA(5),
-    .miso_pin = MCU_GPIO_PORTA(6),
-    .mosi_pin = MCU_GPIO_PORTA(7),
-    .irq_prio = 2,
-};
-#endif
-
-#if MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_1_SLAVE)
-struct stm32_hal_spi_cfg spi1_cfg = {
-    .ss_pin   = MCU_GPIO_PORTB(12),
-    .sck_pin  = MCU_GPIO_PORTB(13),
-    .miso_pin = MCU_GPIO_PORTB(14),
-    .mosi_pin = MCU_GPIO_PORTB(15),
-    .irq_prio = 2,
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART1,
+    .suc_rcc_reg = &RCC->APB2ENR,
+    .suc_rcc_dev = RCC_APB2ENR_USART1EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF7_USART1,
+    .suc_irqn = USART1_IRQn,
 };
 #endif
 
 #if MYNEWT_VAL(I2C_0)
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(7),
-    .hic_pin_scl = MCU_GPIO_PORTB(6),
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
     .hic_timingr = 0x10420F13,    /* 100KHz at 8MHz of SysCoreClock */
@@ -223,59 +170,6 @@ sensor_dev_create(void)
 void
 hal_bsp_init(void)
 {
-    int rc;
-    (void)rc;  /* in case there are no devices declared */
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *)&hal_uart[0], UART_DEV_NAME,
-            OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[0]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    rc = hal_timer_init(0, TIM15);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    rc = hal_timer_init(1, TIM16);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    rc = hal_timer_init(2, TIM17);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_1_MASTER)
-    rc = hal_spi_init(1, &spi1_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_1_SLAVE)
-    rc = hal_spi_init(1, &spi1_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
+    stm32_periph_create();
     sensor_dev_create();
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
 }
diff --git a/hw/bsp/stm32f3discovery/syscfg.yml b/hw/bsp/stm32f3discovery/syscfg.yml
index fb7f62f..a2a4531 100644
--- a/hw/bsp/stm32f3discovery/syscfg.yml
+++ b/hw/bsp/stm32f3discovery/syscfg.yml
@@ -22,24 +22,6 @@ syscfg.defs:
         description: 'Total flash size in KB'
         value: 256
 
-    UART_0:
-        description: 'Whether to enable UART0'
-        value:  1
-
-    UART_1:
-        description: 'Whether to enable UART1'
-        value:  0
-
-    TIMER_0:
-        description: 'Support for timer 0'
-        value: 1
-    TIMER_1:
-        description: 'Support for timer 1'
-        value: 0
-    TIMER_2:
-        description: 'Support for timer 2'
-        value: 0
-
     LSM303DLHC_ONB:
         description: 'Onboard lsm303dlhc sensor'
         value:  0
@@ -68,6 +50,21 @@ syscfg.vals:
     STM32_CLOCK_APB2_DIVIDER: 'RCC_HCLK_DIV1'
     STM32_FLASH_LATENCY: 'FLASH_LATENCY_2'
     STM32_FLASH_PREFETCH_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(9)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTA(10)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTA(4)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTA(5)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTA(6)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTA(7)'
+    SPI_1_PIN_SS: 'MCU_GPIO_PORTB(12)'
+    SPI_1_PIN_SCK: 'MCU_GPIO_PORTB(13)'
+    SPI_1_PIN_MISO: 'MCU_GPIO_PORTB(14)'
+    SPI_1_PIN_MOSI: 'MCU_GPIO_PORTB(15)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(6)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(7)'
+    TIMER_0_TIM: 'TIM15'
+    TIMER_1_TIM: 'TIM16'
+    TIMER_2_TIM: 'TIM17'
 
 syscfg.restrictions:
     - "!LSM303DLHC_ONB || I2C_0"
diff --git a/hw/bsp/stm32f429discovery/include/bsp/bsp.h b/hw/bsp/stm32f429discovery/include/bsp/bsp.h
index 15a4f8b..71dd9c6 100644
--- a/hw/bsp/stm32f429discovery/include/bsp/bsp.h
+++ b/hw/bsp/stm32f429discovery/include/bsp/bsp.h
@@ -44,9 +44,6 @@ extern uint8_t _ccram_start;
 #define LED_BLINK_PIN   MCU_GPIO_PORTG(14)
 #define LED_2           MCU_GPIO_PORTG(13)
 
-/* UART */
-#define UART_CNT 1
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/bsp/stm32f429discovery/pkg.yml b/hw/bsp/stm32f429discovery/pkg.yml
index 9fd73f5..67ec82d 100644
--- a/hw/bsp/stm32f429discovery/pkg.yml
+++ b/hw/bsp/stm32f429discovery/pkg.yml
@@ -35,6 +35,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f4xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
diff --git a/hw/bsp/stm32f429discovery/src/hal_bsp.c b/hw/bsp/stm32f429discovery/src/hal_bsp.c
index 85866a7..9866537 100644
--- a/hw/bsp/stm32f429discovery/src/hal_bsp.c
+++ b/hw/bsp/stm32f429discovery/src/hal_bsp.c
@@ -18,24 +18,24 @@
  */
 #include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
-#include <bsp/bsp.h>
-#include <mcu/cmsis_nvic.h>
-#include <flash_map/flash_map.h>
-#include <stm32f429xx.h>
-#include <stm32f4xx_hal_gpio_ex.h>
-
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
 
 #include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
-#include <hal/hal_timer.h>
+#include <hal/hal_flash_int.h>
 #include <hal/hal_system.h>
 
-#include <mcu/stm32f4_bsp.h>
+#include <stm32f429xx.h>
+#include <stm32_common/stm32_hal.h>
+
+#if MYNEWT_VAL(ETH_0)
+#include <stm32_eth/stm32_eth.h>
+#include <stm32_eth/stm32_eth_cfg.h>
+#endif
+
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
+#endif
 
 const uint32_t stm32_flash_sectors[] = {
     /* Bank 1 */
@@ -72,21 +72,17 @@ static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) + 1 == SZ,
         "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
-
 /* UART connected to st-link */
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
-    [0] = {
-        .suc_uart = USART1,
-        .suc_rcc_reg = &RCC->APB2ENR,
-        .suc_rcc_dev = RCC_APB2ENR_USART1EN,
-        .suc_pin_tx = MCU_GPIO_PORTA(9),
-        .suc_pin_rx = MCU_GPIO_PORTA(10),
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af = GPIO_AF7_USART1,
-        .suc_irqn = USART1_IRQn
-    }
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART1,
+    .suc_rcc_reg = &RCC->APB2ENR,
+    .suc_rcc_dev = RCC_APB2ENR_USART1EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF7_USART1,
+    .suc_irqn = USART1_IRQn,
 };
 #endif
 
@@ -124,27 +120,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[0]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM9);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    hal_timer_init(1, TIM10);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    hal_timer_init(2, TIM11);
-#endif
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/stm32f429discovery/syscfg.yml b/hw/bsp/stm32f429discovery/syscfg.yml
index 6fb516b..d1e3ec7 100644
--- a/hw/bsp/stm32f429discovery/syscfg.yml
+++ b/hw/bsp/stm32f429discovery/syscfg.yml
@@ -26,20 +26,6 @@ syscfg.defs:
         description: 'Number of flash sectors for a non-linear STM32 MCU.'
         value: 24
 
-    UART_0:
-        description: 'UART 0'
-        value: 1
-
-    TIMER_0:
-        description: 'Timer 0'
-        value: 1
-    TIMER_1:
-        description: 'Timer 1'
-        value: 0
-    TIMER_2:
-        description: 'Timer 2'
-        value: 0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -61,3 +47,8 @@ syscfg.vals:
     STM32_FLASH_PREFETCH_ENABLE: 1
     STM32_INSTRUCTION_CACHE_ENABLE: 1
     STM32_DATA_CACHE_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(9)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTA(10)'
+    TIMER_0_TIM: 'TIM9'
+    TIMER_1_TIM: 'TIM10'
+    TIMER_2_TIM: 'TIM11'
diff --git a/hw/bsp/stm32f4discovery/include/bsp/bsp.h b/hw/bsp/stm32f4discovery/include/bsp/bsp.h
index 87b64b4..8d31d19 100644
--- a/hw/bsp/stm32f4discovery/include/bsp/bsp.h
+++ b/hw/bsp/stm32f4discovery/include/bsp/bsp.h
@@ -44,9 +44,6 @@ extern uint8_t _ccram_start;
 #define LED_BLINK_PIN   MCU_GPIO_PORTD(12)
 #define LED_2           MCU_GPIO_PORTD(13)
 
-/* UART */
-#define UART_CNT 1
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/bsp/stm32f4discovery/pkg.yml b/hw/bsp/stm32f4discovery/pkg.yml
index b6840da..3cac031 100644
--- a/hw/bsp/stm32f4discovery/pkg.yml
+++ b/hw/bsp/stm32f4discovery/pkg.yml
@@ -35,6 +35,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f4xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
diff --git a/hw/bsp/stm32f4discovery/src/hal_bsp.c b/hw/bsp/stm32f4discovery/src/hal_bsp.c
index feddd8d..bed3f1f 100644
--- a/hw/bsp/stm32f4discovery/src/hal_bsp.c
+++ b/hw/bsp/stm32f4discovery/src/hal_bsp.c
@@ -16,29 +16,27 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 #include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
-#include <hal/hal_timer.h>
-
-#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
-#include <hal/hal_spi.h>
-#endif
+#include <hal/hal_flash_int.h>
+#include <hal/hal_system.h>
 
 #include <stm32f407xx.h>
-#include <stm32f4xx_hal_gpio_ex.h>
-#include "mcu/stm32_hal.h"
-#include "hal/hal_i2c.h"
+#include <stm32_common/stm32_hal.h>
 
-#include "bsp/bsp.h"
+#if MYNEWT_VAL(ETH_0)
+#include <stm32_eth/stm32_eth.h>
+#include <stm32_eth/stm32_eth_cfg.h>
+#endif
+
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
+#endif
 
 const uint32_t stm32_flash_sectors[] = {
     0x08000000,     /* 16kB */
@@ -61,43 +59,29 @@ static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) + 1 == SZ,
         "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
-
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
-    [0] = {
-        .suc_uart = USART6,
-        .suc_rcc_reg = &RCC->APB2ENR,
-        .suc_rcc_dev = RCC_APB2ENR_USART6EN,
-        .suc_pin_tx = MCU_GPIO_PORTC(6),
-        .suc_pin_rx = MCU_GPIO_PORTC(7),
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af = GPIO_AF8_USART6,
-        .suc_irqn = USART6_IRQn
-    }
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART6,
+    .suc_rcc_reg = &RCC->APB2ENR,
+    .suc_rcc_dev = RCC_APB2ENR_USART6EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF8_USART6,
+    .suc_irqn = USART6_IRQn,
 };
 #endif
 
 #if MYNEWT_VAL(I2C_0)
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(9),       /* PB9 */
-    .hic_pin_scl = MCU_GPIO_PORTB(8),       /* PB8 */
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
-    .hic_speed = 100000,                    /* 100kHz */
-};
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE) || MYNEWT_VAL(SPI_0_MASTER)
-struct stm32_hal_spi_cfg spi0_cfg = {
-    .ss_pin   = MCU_GPIO_PORTA(4),
-    .sck_pin  = MCU_GPIO_PORTA(5),
-    .miso_pin = MCU_GPIO_PORTA(6),
-    .mosi_pin = MCU_GPIO_PORTA(7),
-    .irq_prio = 2,
+    .hic_speed = 100000,
 };
 #endif
 
@@ -135,48 +119,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[0]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM9);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    hal_timer_init(1, TIM10);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    hal_timer_init(2, TIM11);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_MASTER)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_0_SLAVE)
-    rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
-
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/stm32f4discovery/syscfg.yml b/hw/bsp/stm32f4discovery/syscfg.yml
index 464f9b4..2607fff 100644
--- a/hw/bsp/stm32f4discovery/syscfg.yml
+++ b/hw/bsp/stm32f4discovery/syscfg.yml
@@ -26,20 +26,6 @@ syscfg.defs:
         description: 'Number of flash sectors for a non-linear STM32 MCU.'
         value: 12
 
-    UART_0:
-        description: 'UART 0'
-        value:  1
-
-    TIMER_0:
-        description: 'Timer 0'
-        value:  1
-    TIMER_1:
-        description: 'Timer 1'
-        value:  0
-    TIMER_2:
-        description: 'Timer 2'
-        value:  0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -61,3 +47,14 @@ syscfg.vals:
     STM32_FLASH_PREFETCH_ENABLE: 1
     STM32_INSTRUCTION_CACHE_ENABLE: 1
     STM32_DATA_CACHE_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTC(6)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTC(7)'
+    SPI_0_PIN_SS: 'MCU_GPIO_PORTA(4)'
+    SPI_0_PIN_SCK: 'MCU_GPIO_PORTA(5)'
+    SPI_0_PIN_MISO: 'MCU_GPIO_PORTA(6)'
+    SPI_0_PIN_MOSI: 'MCU_GPIO_PORTA(7)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    TIMER_0_TIM: 'TIM9'
+    TIMER_1_TIM: 'TIM10'
+    TIMER_2_TIM: 'TIM11'
diff --git a/hw/bsp/stm32f7discovery/include/bsp/bsp.h b/hw/bsp/stm32f7discovery/include/bsp/bsp.h
index 386be65..72d9a40 100644
--- a/hw/bsp/stm32f7discovery/include/bsp/bsp.h
+++ b/hw/bsp/stm32f7discovery/include/bsp/bsp.h
@@ -45,14 +45,6 @@ extern uint8_t _itcmram_start;
 /* LED pins */
 #define LED_BLINK_PIN   MCU_GPIO_PORTI(1)
 
-/* UART */
-#define UART_CNT        1
-
-#define PWM_CNT (MYNEWT_VAL(PWM_0) + MYNEWT_VAL(PWM_1) + MYNEWT_VAL(PWM_2))
-#define PWM_0_DEV_ID    0
-#define PWM_1_DEV_ID    (PWM_0_DEV_ID + MYNEWT_VAL(PWM_0))
-#define PWM_2_DEV_ID    (PWM_1_DEV_ID + MYNEWT_VAL(PWM_1))
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/bsp/stm32f7discovery/pkg.yml b/hw/bsp/stm32f7discovery/pkg.yml
index 784de0a..c2c0e9d 100644
--- a/hw/bsp/stm32f7discovery/pkg.yml
+++ b/hw/bsp/stm32f7discovery/pkg.yml
@@ -35,18 +35,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f7xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
-
-pkg.deps.ETH_0:
-    - "@apache-mynewt-core/hw/drivers/lwip/stm32_eth"
-
-pkg.deps.PWM_0:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
-
-pkg.deps.PWM_1:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
-
-pkg.deps.PWM_2:
-    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
diff --git a/hw/bsp/stm32f7discovery/src/hal_bsp.c b/hw/bsp/stm32f7discovery/src/hal_bsp.c
index 362af76..7e38678 100644
--- a/hw/bsp/stm32f7discovery/src/hal_bsp.c
+++ b/hw/bsp/stm32f7discovery/src/hal_bsp.c
@@ -18,58 +18,43 @@
  */
 #include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
 #include <hal/hal_flash_int.h>
-#include <hal/hal_gpio.h>
 #include <hal/hal_system.h>
-#include <hal/hal_timer.h>
 
 #include <stm32f746xx.h>
-#include <mcu/stm32f7_bsp.h>
-#include <stm32f7xx_hal_gpio_ex.h>
+#include <stm32_common/stm32_hal.h>
 
 #if MYNEWT_VAL(ETH_0)
 #include <stm32_eth/stm32_eth.h>
 #include <stm32_eth/stm32_eth_cfg.h>
 #endif
 
-#include "bsp/bsp.h"
-
-#if PWM_CNT
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
 #include <pwm_stm32/pwm_stm32.h>
-static struct pwm_dev stm32_pwm_dev_driver[PWM_CNT];
-static const char *stm32_pwm_dev_name[PWM_CNT] = {
-#if PWM_CNT > 0
-    "pwm0",
 #endif
-#if PWM_CNT > 1
-    "pwm1",
-#endif
-#if PWM_CNT > 2
-    "pwm2",
-#endif
-};
 
-static struct stm32_pwm_conf  stm32_pwm_config[PWM_CNT] = {
 #if MYNEWT_VAL(PWM_0)
-    { TIM3, TIM3_IRQn },
+struct stm32_pwm_conf os_bsp_pwm0_cfg = {
+    .tim = TIM3,
+    .irq = TIM3_IRQn,
+};
 #endif
 #if MYNEWT_VAL(PWM_1)
-    { TIM4, TIM4_IRQn },
+struct stm32_pwm_conf os_bsp_pwm1_cfg = {
+    .tim = TIM4,
+    .irq = TIM4_IRQn,
+};
 #endif
 #if MYNEWT_VAL(PWM_2)
-    { TIM11, TIM1_TRG_COM_TIM11_IRQn },
-#endif
+struct stm32_pwm_conf os_bsp_pwm2_cfg = {
+    .tim = TIM11,
+    .irq = TIM1_TRG_COM_TIM11_IRQn,
 };
-
-#endif /* PWM_CNT */
+#endif
 
 const uint32_t stm32_flash_sectors[] = {
     0x08000000,     /* 32kB  */
@@ -86,27 +71,24 @@ const uint32_t stm32_flash_sectors[] = {
 const uint32_t STM32_FLASH_NUM_AREAS = (sizeof(stm32_flash_sectors) /
                                         sizeof(stm32_flash_sectors[0]) - 1);
 
-
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
-
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
-    [0] = {
-        .suc_uart = USART1,
-        .suc_rcc_reg = &RCC->APB2ENR,
-        .suc_rcc_dev = RCC_APB2ENR_USART1EN,
-        .suc_pin_tx = MCU_GPIO_PORTA(9),     /* PD8 */
-        .suc_pin_rx = MCU_GPIO_PORTB(7),     /* PB7 */
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af = GPIO_AF7_USART1,
-        .suc_irqn = USART1_IRQn,
-    }
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART1,
+    .suc_rcc_reg = &RCC->APB2ENR,
+    .suc_rcc_dev = RCC_APB2ENR_USART1EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_rts = -1,
+    .suc_pin_cts = -1,
+    .suc_pin_af = GPIO_AF7_USART1,
+    .suc_irqn = USART1_IRQn,
 };
 #endif
 
 #if MYNEWT_VAL(ETH_0)
-static const struct stm32_eth_cfg eth_cfg = {
+const struct stm32_eth_cfg os_bsp_eth0_cfg = {
     /*
      * PORTA
      *   PA1 - ETH_RMII_REF_CLK
@@ -174,66 +156,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[0]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM1);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    hal_timer_init(1, TIM8);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    hal_timer_init(2, TIM9);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(ETH_0)
-    stm32_eth_init(&eth_cfg);
-#endif
-
-#if MYNEWT_VAL(PWM_0)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_0_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_0_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_0_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(PWM_1)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_1_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_1_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_1_DEV_ID]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(PWM_2)
-    rc = os_dev_create((struct os_dev *) &stm32_pwm_dev_driver[PWM_2_DEV_ID],
-        (char*)stm32_pwm_dev_name[PWM_2_DEV_ID],
-        OS_DEV_INIT_KERNEL,
-        OS_DEV_INIT_PRIO_DEFAULT,
-        stm32_pwm_dev_init,
-        &stm32_pwm_config[PWM_2_DEV_ID]);
-    assert(rc == 0);
-#endif
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/stm32f7discovery/syscfg.yml b/hw/bsp/stm32f7discovery/syscfg.yml
index 1c4e1d7..7c25481 100644
--- a/hw/bsp/stm32f7discovery/syscfg.yml
+++ b/hw/bsp/stm32f7discovery/syscfg.yml
@@ -26,34 +26,6 @@ syscfg.defs:
         description: 'Number of flash sectors for a non-linear STM32 MCU.'
         value: 12
 
-    UART_0:
-        description: 'Uart 0'
-        value:  1
-
-    TIMER_0:
-        description: 'Timer 0'
-        value:  1
-    TIMER_1:
-        description: 'Timer 1'
-        value: 1
-    TIMER_2:
-        description: 'Timer 2'
-        value: 1
-
-    ETH_0:
-        description: 'Ethernet driver for LwIP'
-        value: 0
-
-    PWM_0:
-        description: 'Support for PWM 0'
-        value: 0
-    PWM_1:
-        description: 'Support for PWM 1'
-        value: 0
-    PWM_2:
-        description: 'Support for PWM 2'
-        value: 0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -74,3 +46,8 @@ syscfg.vals:
     STM32_FLASH_LATENCY: 'FLASH_LATENCY_7'
     STM32_FLASH_PREFETCH_ENABLE: 1
     STM32_ART_ACCLERATOR_ENABLE: 1
+    UART_0_PIN_TX: 'MCU_GPIO_PORTA(9)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTB(7)'
+    TIMER_0_TIM: 'TIM1'
+    TIMER_1_TIM: 'TIM8'
+    TIMER_2_TIM: 'TIM9'
diff --git a/hw/bsp/stm32l152discovery/include/bsp/bsp.h b/hw/bsp/stm32l152discovery/include/bsp/bsp.h
index 9dad50e..3ff0531 100644
--- a/hw/bsp/stm32l152discovery/include/bsp/bsp.h
+++ b/hw/bsp/stm32l152discovery/include/bsp/bsp.h
@@ -42,9 +42,6 @@ extern uint8_t _ram_start;
 #define LED_BLINK_PIN   MCU_GPIO_PORTB(7)
 #define LED_2           MCU_GPIO_PORTB(6)
 
-/* UART */
-#define UART_CNT 1
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/bsp/stm32l152discovery/pkg.yml b/hw/bsp/stm32l152discovery/pkg.yml
index ca7eff6..d1af895 100644
--- a/hw/bsp/stm32l152discovery/pkg.yml
+++ b/hw/bsp/stm32l152discovery/pkg.yml
@@ -32,6 +32,3 @@ pkg.cflags: -DSTM32L152xC
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32l1xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.UART_0:
-    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
diff --git a/hw/bsp/stm32l152discovery/src/hal_bsp.c b/hw/bsp/stm32l152discovery/src/hal_bsp.c
index dd8bfdc..008dfc1 100644
--- a/hw/bsp/stm32l152discovery/src/hal_bsp.c
+++ b/hw/bsp/stm32l152discovery/src/hal_bsp.c
@@ -18,76 +18,44 @@
  */
 #include <assert.h>
 
+#include "bsp/bsp.h"
 #include "os/mynewt.h"
 
-#if MYNEWT_VAL(UART_0)
-#include <uart/uart.h>
-#include <uart_hal/uart_hal.h>
-#endif
-
 #include <hal/hal_bsp.h>
-#include <hal/hal_gpio.h>
 #include <hal/hal_flash_int.h>
-#include <hal/hal_timer.h>
-
-/*
- * Using SPI2 (spi1 in Mynewt parlance) because some SPI1 (spi0) pins are
- * connected to the onboard LCD.
- */
-#if MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_1_SLAVE)
-#include <hal/hal_spi.h>
-#endif
+#include <hal/hal_system.h>
 
 #include <stm32l152xc.h>
-#include <stm32l1xx_hal_rcc.h>
-#include <stm32l1xx_hal_pwr.h>
-#include <stm32l1xx_hal_flash.h>
-#include <stm32l1xx_hal_gpio_ex.h>
-#include <mcu/stm32l1_bsp.h>
-#include "mcu/stm32l1xx_mynewt_hal.h"
-#include "mcu/stm32_hal.h"
-#include "hal/hal_i2c.h"
+#include <stm32_common/stm32_hal.h>
 
-#include "bsp/bsp.h"
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
+#endif
 
 #if MYNEWT_VAL(UART_0)
-static struct uart_dev hal_uart0;
-
-static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
-    [0] = {
-        .suc_uart = USART3,
-        .suc_rcc_reg = &RCC->APB1ENR,
-        .suc_rcc_dev = RCC_APB1ENR_USART3EN,
-        .suc_pin_tx = MCU_GPIO_PORTB(10),
-        .suc_pin_rx = MCU_GPIO_PORTB(11),
-        .suc_pin_rts = -1,
-        .suc_pin_cts = -1,
-        .suc_pin_af = GPIO_AF7_USART3,
-        .suc_irqn = USART3_IRQn
-    }
+const struct stm32_uart_cfg os_bsp_uart0_cfg = {
+    .suc_uart = USART3,
+    .suc_rcc_reg = &RCC->APB1ENR,
+    .suc_rcc_dev = RCC_APB1ENR_USART3EN,
+    .suc_pin_tx = MYNEWT_VAL(UART_0_PIN_TX),
+    .suc_pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
+    .suc_pin_rts = MYNEWT_VAL(UART_0_PIN_RTS),
+    .suc_pin_cts = MYNEWT_VAL(UART_0_PIN_CTS),
+    .suc_pin_af = GPIO_AF7_USART3,
+    .suc_irqn = USART3_IRQn,
 };
 #endif
 
 #if MYNEWT_VAL(I2C_0)
-static struct stm32_hal_i2c_cfg i2c_cfg0 = {
+const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg = {
     .hic_i2c = I2C1,
     .hic_rcc_reg = &RCC->APB1ENR,
     .hic_rcc_dev = RCC_APB1ENR_I2C1EN,
-    .hic_pin_sda = MCU_GPIO_PORTB(9),
-    .hic_pin_scl = MCU_GPIO_PORTB(8),
+    .hic_pin_sda = MYNEWT_VAL(I2C_0_PIN_SDA),
+    .hic_pin_scl = MYNEWT_VAL(I2C_0_PIN_SCL),
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
-    .hic_speed = 100000                     /* 100kHz */
-};
-#endif
-
-#if MYNEWT_VAL(SPI_1_SLAVE) || MYNEWT_VAL(SPI_1_MASTER)
-struct stm32_hal_spi_cfg spi1_cfg = {
-    .ss_pin   = MCU_GPIO_PORTB(12),
-    .sck_pin  = MCU_GPIO_PORTB(13),
-    .miso_pin = MCU_GPIO_PORTB(14),
-    .mosi_pin = MCU_GPIO_PORTB(15),
-    .irq_prio = 2,
+    .hic_speed = 100000,
 };
 #endif
 
@@ -121,47 +89,7 @@ hal_bsp_core_dump(int *area_cnt)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
-#if MYNEWT_VAL(UART_0)
-    rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
-      OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[0]);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(TIMER_0)
-    hal_timer_init(0, TIM9);
-#endif
-
-#if MYNEWT_VAL(TIMER_1)
-    hal_timer_init(1, TIM10);
-#endif
-
-#if MYNEWT_VAL(TIMER_2)
-    hal_timer_init(2, TIM11);
-#endif
-
-#if (MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0)
-    rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_1_MASTER)
-    rc = hal_spi_init(1, &spi1_cfg, HAL_SPI_TYPE_MASTER);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(SPI_1_SLAVE)
-    rc = hal_spi_init(1, &spi1_cfg, HAL_SPI_TYPE_SLAVE);
-    assert(rc == 0);
-#endif
-
-#if MYNEWT_VAL(I2C_0)
-    rc = hal_i2c_init(0, &i2c_cfg0);
-    assert(rc == 0);
-#endif
+    stm32_periph_create();
 }
 
 /**
diff --git a/hw/bsp/stm32l152discovery/syscfg.yml b/hw/bsp/stm32l152discovery/syscfg.yml
index ee7cbb0..a319abe 100644
--- a/hw/bsp/stm32l152discovery/syscfg.yml
+++ b/hw/bsp/stm32l152discovery/syscfg.yml
@@ -22,22 +22,6 @@ syscfg.defs:
         description: 'Total flash size in KB.'
         value: 256
 
-    UART_0:
-        description: 'UART 0'
-        value:  1
-
-    TIMER_0:
-        description: 'Timer 0'
-        value:  1
-
-    TIMER_1:
-        description: 'Timer 1'
-        value:  0
-
-    TIMER_2:
-        description: 'Timer 2'
-        value:  0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
@@ -61,3 +45,14 @@ syscfg.vals:
     STM32_CLOCK_APB2_DIVIDER: 'RCC_HCLK_DIV1'
     STM32_FLASH_LATENCY: 1  # max 32MHz
     STM32_FLASH_PREFETCH_ENABLE: 0
+    UART_0_PIN_TX: 'MCU_GPIO_PORTB(10)'
+    UART_0_PIN_RX: 'MCU_GPIO_PORTB(11)'
+    SPI_1_PIN_SS: 'MCU_GPIO_PORTB(12)'
+    SPI_1_PIN_SCK: 'MCU_GPIO_PORTB(13)'
+    SPI_1_PIN_MISO: 'MCU_GPIO_PORTB(14)'
+    SPI_1_PIN_MOSI: 'MCU_GPIO_PORTB(15)'
+    I2C_0_PIN_SCL: 'MCU_GPIO_PORTB(8)'
+    I2C_0_PIN_SDA: 'MCU_GPIO_PORTB(9)'
+    TIMER_0_TIM: 'TIM9'
+    TIMER_1_TIM: 'TIM10'
+    TIMER_2_TIM: 'TIM11'
diff --git a/hw/mcu/stm/stm32_common/include/stm32_common/stm32_hal.h b/hw/mcu/stm/stm32_common/include/stm32_common/stm32_hal.h
index 80ef158..aad9e89 100644
--- a/hw/mcu/stm/stm32_common/include/stm32_common/stm32_hal.h
+++ b/hw/mcu/stm/stm32_common/include/stm32_common/stm32_hal.h
@@ -25,8 +25,16 @@ extern "C" {
 
 #include <mcu/stm32_hal.h>
 
-uint32_t
-stm32_hal_timer_get_freq(void *timx);
+#define UART_CNT (((uint8_t)(MYNEWT_VAL(UART_0) != 0)) + \
+                  ((uint8_t)(MYNEWT_VAL(UART_1) != 0)) + \
+                  ((uint8_t)(MYNEWT_VAL(UART_2) != 0)))
+
+#define PWM_CNT (((uint8_t)(MYNEWT_VAL(PWM_0) != 0)) + \
+                 ((uint8_t)(MYNEWT_VAL(PWM_1) != 0)) + \
+                 ((uint8_t)(MYNEWT_VAL(PWM_2) != 0)))
+
+uint32_t stm32_hal_timer_get_freq(void *timx);
+void stm32_periph_create(void);
 
 #ifdef __cplusplus
 }
diff --git a/hw/mcu/stm/stm32_common/pkg.yml b/hw/mcu/stm/stm32_common/pkg.yml
index ba5c173..14e6897 100644
--- a/hw/mcu/stm/stm32_common/pkg.yml
+++ b/hw/mcu/stm/stm32_common/pkg.yml
@@ -27,3 +27,29 @@ pkg.keywords:
 pkg.deps:
     - "@apache-mynewt-core/hw/hal"
     - "@apache-mynewt-core/hw/cmsis-core"
+
+pkg.deps.UART_0:
+    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
+pkg.deps.UART_1:
+    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
+pkg.deps.UART_2:
+    - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
+
+pkg.deps.PWM_0:
+    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
+pkg.deps.PWM_1:
+    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
+pkg.deps.PWM_2:
+    - "@apache-mynewt-core/hw/drivers/pwm/pwm_stm32"
+
+pkg.deps.ETH_0:
+    - "@apache-mynewt-core/hw/drivers/lwip/stm32_eth"
+
+pkg.deps.TRNG:
+    - "@apache-mynewt-core/hw/drivers/trng/trng_stm32"
+
+pkg.deps.CRYPTO:
+    - "@apache-mynewt-core/hw/drivers/crypto/crypto_stm32"
+
+pkg.deps.HASH:
+    - "@apache-mynewt-core/hw/drivers/hash/hash_stm32"
diff --git a/hw/mcu/stm/stm32_common/src/hal_uart.c b/hw/mcu/stm/stm32_common/src/hal_uart.c
index c46f2c7..06dc771 100644
--- a/hw/mcu/stm/stm32_common/src/hal_uart.c
+++ b/hw/mcu/stm/stm32_common/src/hal_uart.c
@@ -20,7 +20,7 @@
 #include "hal/hal_uart.h"
 #include "hal/hal_gpio.h"
 #include "mcu/cmsis_nvic.h"
-#include "mcu/stm32_hal.h"
+#include "stm32_common/stm32_hal.h"
 #include "bsp/bsp.h"
 #include <assert.h>
 #include <stdlib.h>
@@ -86,8 +86,11 @@ hal_uart_init_cbs(int port, hal_uart_tx_char tx_func, hal_uart_tx_done tx_done,
 {
     struct hal_uart *u;
 
+    if (port < 0 || port >= UART_CNT) {
+        return -1;
+    }
     u = &uarts[port];
-    if (port >= UART_CNT || u->u_open) {
+    if (u->u_open) {
         return -1;
     }
     u->u_rx_func = rx_func;
@@ -191,10 +194,14 @@ hal_uart_blocking_tx(int port, uint8_t data)
     struct hal_uart *u;
     USART_TypeDef *regs;
 
+    if (port < 0 || port >= UART_CNT) {
+        return;
+    }
     u = &uarts[port];
-    if (port >= UART_CNT || !u->u_open) {
+    if (!u->u_open) {
         return;
     }
+
     regs = u->u_regs;
 
     while (!(STATUS(regs) & TXE));
@@ -353,7 +360,7 @@ hal_uart_config(int port, int32_t baudrate, uint8_t databits, uint8_t stopbits,
     GPIO_InitTypeDef gpio;
 #endif
 
-    if (port >= UART_CNT) {
+    if (port < 0 || port >= UART_CNT) {
         return -1;
     }
 
@@ -506,7 +513,7 @@ hal_uart_init(int port, void *arg)
 {
     struct hal_uart *u;
 
-    if (port >= UART_CNT) {
+    if (port < 0 || port >= UART_CNT) {
         return -1;
     }
     u = &uarts[port];
@@ -520,7 +527,7 @@ hal_uart_close(int port)
 {
     struct hal_uart *u;
 
-    if (port >= UART_CNT) {
+    if (port < 0 || port >= UART_CNT) {
         return -1;
     }
     u = &uarts[port];
diff --git a/hw/mcu/stm/stm32_common/src/stm32_periph.c b/hw/mcu/stm/stm32_common/src/stm32_periph.c
new file mode 100644
index 0000000..ec2674c
--- /dev/null
+++ b/hw/mcu/stm/stm32_common/src/stm32_periph.c
@@ -0,0 +1,365 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include "syscfg/syscfg.h"
+#include "hal/hal_timer.h"
+#include "hal/hal_i2c.h"
+#include "hal/hal_spi.h"
+#include "bsp/bsp.h"
+#if MYNEWT_VAL(TRNG)
+#include "trng/trng.h"
+#include "trng_stm32/trng_stm32.h"
+#endif
+#if MYNEWT_VAL(CRYPTO)
+#include "crypto/crypto.h"
+#include "crypto_stm32/crypto_stm32.h"
+#endif
+#if MYNEWT_VAL(HASH)
+#include "hash/hash.h"
+#include "hash_stm32/hash_stm32.h"
+#endif
+#if MYNEWT_VAL(UART_0) || MYNEWT_VAL(UART_1) || MYNEWT_VAL(UART_2)
+#include "uart/uart.h"
+#include "uart_hal/uart_hal.h"
+#endif
+#if MYNEWT_VAL(PWM_0) || MYNEWT_VAL(PWM_1) || MYNEWT_VAL(PWM_2)
+#include <pwm_stm32/pwm_stm32.h>
+#endif
+#if MYNEWT_VAL(ETH_0)
+#include <stm32_eth/stm32_eth.h>
+#include <stm32_eth/stm32_eth_cfg.h>
+#endif
+#include "mcu/stm32_hal.h"
+
+#if MYNEWT_VAL(PWM_0)
+static struct pwm_dev os_bsp_pwm0;
+extern struct stm32_pwm_conf os_bsp_pwm0_cfg;
+#endif
+#if MYNEWT_VAL(PWM_1)
+static struct pwm_dev os_bsp_pwm1;
+extern struct stm32_pwm_conf os_bsp_pwm1_cfg;
+#endif
+#if MYNEWT_VAL(PWM_2)
+static struct pwm_dev os_bsp_pwm2;
+extern struct stm32_pwm_conf os_bsp_pwm2_cfg;
+#endif
+
+#if MYNEWT_VAL(TRNG)
+static struct trng_dev os_bsp_trng;
+#endif
+
+#if MYNEWT_VAL(CRYPTO)
+static struct crypto_dev os_bsp_crypto;
+#endif
+
+#if MYNEWT_VAL(HASH)
+static struct hash_dev os_bsp_hash;
+#endif
+
+#if MYNEWT_VAL(UART_0)
+static struct uart_dev os_bsp_uart0;
+extern const struct stm32_uart_cfg os_bsp_uart0_cfg;
+#endif
+#if MYNEWT_VAL(UART_1)
+static struct uart_dev os_bsp_uart1;
+static const struct stm32_uart_cfg os_bsp_uart1_cfg;
+#endif
+
+#if MYNEWT_VAL(I2C_0)
+extern const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg;
+#endif
+#if MYNEWT_VAL(I2C_1)
+extern const struct stm32_hal_i2c_cfg os_bsp_i2c1_cfg;
+#endif
+#if MYNEWT_VAL(I2C_2)
+extern const struct stm32_hal_i2c_cfg os_bsp_i2c2_cfg;
+#endif
+
+#if (MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE))
+#if MYNEWT_VAL(SPI_0_CUSTOM_CFG)
+extern const struct stm32_hal_spi_cfg os_bsp_spi0_cfg;
+#else
+static const struct stm32_hal_spi_cfg os_bsp_spi0_cfg = {
+    .sck_pin = MYNEWT_VAL(SPI_0_PIN_SCK),
+    .mosi_pin = MYNEWT_VAL(SPI_0_PIN_MOSI),
+    .miso_pin = MYNEWT_VAL(SPI_0_PIN_MISO),
+    .ss_pin = MYNEWT_VAL(SPI_0_PIN_SS),
+    .irq_prio = 2,
+};
+#endif
+#endif
+#if (MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_1_SLAVE))
+#if MYNEWT_VAL(SPI_1_CUSTOM_CFG)
+extern const struct stm32_hal_spi_cfg os_bsp_spi1_cfg;
+#else
+static const struct stm32_hal_spi_cfg os_bsp_spi1_cfg = {
+    .sck_pin = MYNEWT_VAL(SPI_1_PIN_SCK),
+    .mosi_pin = MYNEWT_VAL(SPI_1_PIN_MOSI),
+    .miso_pin = MYNEWT_VAL(SPI_1_PIN_MISO),
+    .ss_pin = MYNEWT_VAL(SPI_1_PIN_SS),
+    .irq_prio = 2,
+};
+#endif
+#endif
+#if (MYNEWT_VAL(SPI_2_MASTER) || MYNEWT_VAL(SPI_2_SLAVE))
+#if MYNEWT_VAL(SPI_2_CUSTOM_CFG)
+extern const struct stm32_hal_spi_cfg os_bsp_spi2_cfg;
+#else
+static const struct stm32_hal_spi_cfg os_bsp_spi2_cfg = {
+    .sck_pin = MYNEWT_VAL(SPI_2_PIN_SCK),
+    .mosi_pin = MYNEWT_VAL(SPI_2_PIN_MOSI),
+    .miso_pin = MYNEWT_VAL(SPI_2_PIN_MISO),
+    .ss_pin = MYNEWT_VAL(SPI_2_PIN_SS),
+    .irq_prio = 2,
+};
+#endif
+#endif
+#if (MYNEWT_VAL(SPI_3_MASTER) || MYNEWT_VAL(SPI_3_SLAVE))
+#if MYNEWT_VAL(SPI_3_CUSTOM_CFG)
+extern const struct stm32_hal_spi_cfg os_bsp_spi3_cfg;
+#else
+static const struct stm32_hal_spi_cfg os_bsp_spi3_cfg = {
+    .sck_pin = MYNEWT_VAL(SPI_3_PIN_SCK),
+    .mosi_pin = MYNEWT_VAL(SPI_3_PIN_MOSI),
+    .miso_pin = MYNEWT_VAL(SPI_3_PIN_MISO),
+    .ss_pin = MYNEWT_VAL(SPI_3_PIN_SS),
+    .irq_prio = 2,
+};
+#endif
+#endif
+
+#if MYNEWT_VAL(ETH_0)
+extern const struct stm32_eth_cfg os_bsp_eth0_cfg;
+#endif
+
+static void
+stm32_periph_create_timers(void)
+{
+    int rc;
+
+    (void)rc;
+
+#if MYNEWT_VAL(TIMER_0)
+    rc = hal_timer_init(0, MYNEWT_VAL(TIMER_0_TIM));
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(TIMER_1)
+    rc = hal_timer_init(1, MYNEWT_VAL(TIMER_1_TIM));
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(TIMER_2)
+    rc = hal_timer_init(2, MYNEWT_VAL(TIMER_2_TIM));
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(TIMER_3)
+    rc = hal_timer_init(3, MYNEWT_VAL(TIMER_3_TIM));
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(TIMER_4)
+    rc = hal_timer_init(4, MYNEWT_VAL(TIMER_4_TIM));
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(TIMER_5)
+    rc = hal_timer_init(5, MYNEWT_VAL(TIMER_5_TIM));
+    assert(rc == 0);
+#endif
+}
+
+static void
+stm32_periph_create_pwm(void)
+{
+    int rc;
+
+    (void)rc;
+
+#if MYNEWT_VAL(PWM_0)
+    rc = os_dev_create(&os_bsp_pwm0.pwm_os_dev, "pwm0",
+                       OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
+                       stm32_pwm_dev_init, &os_bsp_pwm0_cfg);
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(PWM_1)
+    rc = os_dev_create(&os_bsp_pwm1.pwm_os_dev, "pwm1",
+                       OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
+                       stm32_pwm_dev_init, &os_bsp_pwm1_cfg);
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(PWM_2)
+    rc = os_dev_create(&os_bsp_pwm2.pwm_os_dev, "pwm2",
+                       OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
+                       stm32_pwm_dev_init, &os_bsp_pwm2_cfg);
+    assert(rc == 0);
+#endif
+}
+
+static void
+stm32_periph_create_trng(void)
+{
+    int rc;
+
+    (void)rc;
+
+#if MYNEWT_VAL(TRNG)
+    rc = os_dev_create(&os_bsp_trng.dev, "trng",
+                       OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
+                       stm32_trng_dev_init, NULL);
+    assert(rc == 0);
+#endif
+}
+
+static void
+stm32_periph_create_crypto(void)
+{
+    int rc;
+
+    (void)rc;
+
+#if MYNEWT_VAL(CRYPTO)
+    rc = os_dev_create(&os_bsp_crypto.dev, "crypto",
+                       OS_DEV_INIT_PRIMARY, OS_DEV_INIT_PRIO_DEFAULT,
+                       stm32_crypto_dev_init, NULL);
+    assert(rc == 0);
+#endif
+}
+
+static void
+stm32_periph_create_hash(void)
+{
+    int rc;
+
+    (void)rc;
+
+#if MYNEWT_VAL(HASH)
+    rc = os_dev_create(&os_bsp_hash.dev, "hash", OS_DEV_INIT_KERNEL,
+                       OS_DEV_INIT_PRIO_DEFAULT, stm32_hash_dev_init, NULL);
+    assert(rc == 0);
+#endif
+}
+
+static void
+stm32_periph_create_uart(void)
+{
+    int rc;
+
+    (void)rc;
+
+#if MYNEWT_VAL(UART_0)
+    rc = os_dev_create(&os_bsp_uart0.ud_dev, "uart0",
+                       OS_DEV_INIT_PRIMARY, 0, uart_hal_init,
+                       (void *)&os_bsp_uart0_cfg);
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(UART_1)
+    rc = os_dev_create(&os_bsp_uart1.ud_dev, "uart1",
+                       OS_DEV_INIT_PRIMARY, 1, uart_hal_init,
+                       (void *)&os_bsp_uart1_cfg);
+    assert(rc == 0);
+#endif
+}
+
+static void
+stm32_periph_create_i2c(void)
+{
+    int rc;
+
+    (void)rc;
+
+#if MYNEWT_VAL(I2C_0)
+    rc = hal_i2c_init(0, (void *)&os_bsp_i2c0_cfg);
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(I2C_1)
+    rc = hal_i2c_init(1, (void *)&os_bsp_i2c1_cfg);
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(I2C_2)
+    rc = hal_i2c_init(2, (void *)&os_bsp_i2c2_cfg);
+    assert(rc == 0);
+#endif
+}
+
+static void
+stm32_periph_create_spi(void)
+{
+    int rc;
+
+    (void)rc;
+
+#if MYNEWT_VAL(SPI_0_MASTER)
+    rc = hal_spi_init(0, (void *)&os_bsp_spi0_cfg, HAL_SPI_TYPE_MASTER);
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(SPI_0_SLAVE)
+    rc = hal_spi_init(0, (void *)&os_bsp_spi0_cfg, HAL_SPI_TYPE_SLAVE);
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(SPI_1_MASTER)
+    rc = hal_spi_init(1, (void *)&os_bsp_spi1_cfg, HAL_SPI_TYPE_MASTER);
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(SPI_1_SLAVE)
+    rc = hal_spi_init(1, (void *)&os_bsp_spi1_cfg, HAL_SPI_TYPE_SLAVE);
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(SPI_2_MASTER)
+    rc = hal_spi_init(2, (void *)&os_bsp_spi2_cfg, HAL_SPI_TYPE_MASTER);
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(SPI_2_SLAVE)
+    rc = hal_spi_init(2, (void *)&os_bsp_spi2_cfg, HAL_SPI_TYPE_SLAVE);
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(SPI_3_MASTER)
+    rc = hal_spi_init(3, (void *)&os_bsp_spi3_cfg, HAL_SPI_TYPE_MASTER);
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(SPI_3_SLAVE)
+    rc = hal_spi_init(3, (void *)&os_bsp_spi3_cfg, HAL_SPI_TYPE_SLAVE);
+    assert(rc == 0);
+#endif
+}
+
+static void
+stm32_periph_create_eth(void)
+{
+    int rc;
+
+    (void)rc;
+
+#if MYNEWT_VAL(ETH_0)
+    rc = stm32_eth_init(&os_bsp_eth0_cfg);
+    assert(rc == 0);
+#endif
+}
+
+void
+stm32_periph_create(void)
+{
+    stm32_periph_create_timers();
+    stm32_periph_create_pwm();
+    stm32_periph_create_trng();
+    stm32_periph_create_crypto();
+    stm32_periph_create_hash();
+    stm32_periph_create_uart();
+    stm32_periph_create_i2c();
+    stm32_periph_create_spi();
+    stm32_periph_create_eth();
+}
diff --git a/hw/mcu/stm/stm32_common/syscfg.yml b/hw/mcu/stm/stm32_common/syscfg.yml
new file mode 100644
index 0000000..da33164
--- /dev/null
+++ b/hw/mcu/stm/stm32_common/syscfg.yml
@@ -0,0 +1,196 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+syscfg.defs:
+    TIMER_0:
+        description: 'Timer 0'
+        value:  1
+    TIMER_0_TIM:
+        description: 'TIMx used by OS TIMER_0'
+        value: ''
+    TIMER_1:
+        description: 'Timer 1'
+        value: 0
+    TIMER_1_TIM:
+        description: 'TIMx used by OS TIMER_1'
+        value: ''
+    TIMER_2:
+        description: 'Timer 2'
+        value: 0
+    TIMER_2_TIM:
+        description: 'TIMx used by OS TIMER_2'
+        value: ''
+
+    UART_0:
+        description: 'UART 0'
+        value:  1
+    UART_0_PIN_TX:
+        description: 'UART_0 TX pin'
+        value: -1
+    UART_0_PIN_RX:
+        description: 'UART_0 RX pin'
+        value: -1
+    UART_0_PIN_RTS:
+        description: 'UART_0 RTS pin'
+        value: -1
+    UART_0_PIN_CTS:
+        description: 'UART_0 CTS pin'
+        value: -1
+
+    UART_1:
+        description: 'UART 1'
+        value:  0
+    UART_1_PIN_TX:
+        description: 'UART_1 TX pin'
+        value: -1
+    UART_1_PIN_RX:
+        description: 'UART_1 RX pin'
+        value: -1
+    UART_1_PIN_RTS:
+        description: 'UART_1 RTS pin'
+        value: -1
+    UART_1_PIN_CTS:
+        description: 'UART_1 CTS pin'
+        value: -1
+
+    UART_2:
+        description: 'UART 2'
+        value:  0
+    UART_2_PIN_TX:
+        description: 'UART_2 TX pin'
+        value: -1
+    UART_2_PIN_RX:
+        description: 'UART_2 RX pin'
+        value: -1
+    UART_2_PIN_RTS:
+        description: 'UART_2 RTS pin'
+        value: -1
+    UART_2_PIN_CTS:
+        description: 'UART_2 CTS pin'
+        value: -1
+
+    SPI_0_MASTER:
+        description: 'SPI 0 master'
+        value:  0
+        restrictions:
+            - "!SPI_0_SLAVE"
+    SPI_0_SLAVE:
+        description: 'SPI 0 slave'
+        value:  0
+        restrictions:
+            - "!SPI_0_MASTER"
+    SPI_0:
+        description: 'SPI 0 enabled'
+        value: 'MYNEWT_VAL_SPI_0_MASTER || MYNEWT_VAL_SPI_0_SLAVE'
+    SPI_0_CUSTOM_CFG:
+        description: 'Allow SPI_0 configuration override'
+        value: 0
+    SPI_0_PIN_SCK:
+        description: 'SCK pin for SPI_0'
+        value: ''
+    SPI_0_PIN_MOSI:
+        description: 'MOSI pin for SPI_0'
+        value: ''
+    SPI_0_PIN_MISO:
+        description: 'MISO pin for SPI_0'
+        value: ''
+    SPI_0_PIN_SS:
+        description: 'SS pin for SPI_0'
+        value: ''
+
+    SPI_1_MASTER:
+        description: 'SPI 1 master'
+        value:  0
+        restrictions:
+            - "!SPI_1_SLAVE"
+    SPI_1_SLAVE:
+        description: 'SPI 1 slave'
+        value:  0
+        restrictions:
+            - "!SPI_1_MASTER"
+    SPI_1:
+        description: 'SPI 1 enabled'
+        value: 'MYNEWT_VAL_SPI_1_MASTER || MYNEWT_VAL_SPI_1_SLAVE'
+    SPI_1_CUSTOM_CFG:
+        description: 'Allow SPI_1 configuration override'
+        value: 0
+    SPI_1_PIN_SCK:
+        description: 'SCK pin for SPI_1'
+        value: ''
+    SPI_1_PIN_MOSI:
+        description: 'MOSI pin for SPI_1'
+        value: ''
+    SPI_1_PIN_MISO:
+        description: 'MISO pin for SPI_1'
+        value: ''
+    SPI_1_PIN_SS:
+        description: 'SS pin for SPI_1'
+        value: ''
+
+    I2C_0:
+        description: 'I2C (TWI) interface 0'
+        value:  0
+    I2C_0_PIN_SCL:
+        description: 'SCL pin for I2C_0'
+        value: -1
+    I2C_0_PIN_SDA:
+        description: 'SDA pin for I2C_0'
+        value: -1
+    I2C_1:
+        description: 'I2C (TWI) interface 1'
+        value:  0
+    I2C_1_PIN_SCL:
+        description: 'SCL pin for I2C_1'
+        value: -1
+    I2C_1_PIN_SDA:
+        description: 'SDA pin for I2C_1'
+        value: -1
+    I2C_2:
+        description: 'I2C (TWI) interface 2'
+        value:  0
+    I2C_2_PIN_SCL:
+        description: 'SCL pin for I2C_2'
+        value: -1
+    I2C_2_PIN_SDA:
+        description: 'SDA pin for I2C_2'
+        value: -1
+
+    TRNG:
+        description: 'True Random Number Generator (RNG)'
+        value: 0
+
+    CRYPTO:
+        description: 'Enable HW Cryptography module (CRYP)'
+        value: 0
+
+    HASH:
+        description: 'Enable HW hash module (HASH)'
+        value: 0
+
+    PWM_0:
+        description: 'Support for PWM 0'
+        value: 0
+    PWM_1:
+        description: 'Support for PWM 1'
+        value: 0
+    PWM_2:
+        description: 'Support for PWM 2'
+        value: 0
+
+    ETH_0:
+        description: 'Ethernet driver for LwIP'
+        value: 0
diff --git a/hw/mcu/stm/stm32f0xx/syscfg.yml b/hw/mcu/stm/stm32f0xx/syscfg.yml
index 7c1810d..4533176 100644
--- a/hw/mcu/stm/stm32f0xx/syscfg.yml
+++ b/hw/mcu/stm/stm32f0xx/syscfg.yml
@@ -100,18 +100,3 @@ syscfg.defs:
     MCU_FLASH_ERASED_VAL:
         description: Value read from erased flash.
         value: 0xff
-
-    I2C_0:
-        description: 'I2C (TWI) interface 0'
-        value:  0
-
-    SPI_0_MASTER:
-        description: 'SPI 0 master'
-        value:  0
-        restrictions:
-            - "!SPI_0_SLAVE"
-    SPI_0_SLAVE:
-        description: 'SPI 0 slave'
-        value:  0
-        restrictions:
-            - "!SPI_0_MASTER"
diff --git a/hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h b/hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h
index 3af1e23..cecc03e 100644
--- a/hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h
+++ b/hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h
@@ -44,6 +44,7 @@ extern "C" {
 #include "stm32f1xx_hal_spi.h"
 #include "stm32f1xx_hal_gpio.h"
 #include "stm32f1xx_hal_gpio_ex.h"
+#include <stm32f1xx_ll_gpio.h>       /* AF remapping */
 #include "stm32f1xx_hal_rcc.h"
 
 struct stm32_hal_spi_cfg {
diff --git a/hw/mcu/stm/stm32f1xx/syscfg.yml b/hw/mcu/stm/stm32f1xx/syscfg.yml
index 9902fca..d264938 100644
--- a/hw/mcu/stm/stm32f1xx/syscfg.yml
+++ b/hw/mcu/stm/stm32f1xx/syscfg.yml
@@ -98,35 +98,3 @@ syscfg.defs:
     MCU_FLASH_ERASED_VAL:
         description: Value read from erased flash.
         value: 0xff
-
-    I2C_0:
-        description: 'I2C (TWI) interface 0'
-        value:  0
-
-    SPI_0_MASTER:
-        description: 'SPI 0 master'
-        value:  0
-        restrictions:
-            - "!SPI_0_SLAVE"
-    SPI_0_SLAVE:
-        description: 'SPI 0 slave'
-        value:  0
-        restrictions:
-            - "!SPI_0_MASTER"
-    SPI_0:
-        description: 'SPI 0 enable'
-        value: 'MYNEWT_VAL_SPI_0_MASTER || MYNEWT_VAL_SPI_0_SLAVE'
-
-    SPI_1_MASTER:
-        description: 'SPI 1 master'
-        value:  0
-        restrictions:
-            - "!SPI_1_SLAVE"
-    SPI_1_SLAVE:
-        description: 'SPI 1 slave'
-        value:  0
-        restrictions:
-            - "!SPI_1_MASTER"
-    SPI_1:
-        description: 'SPI 1 enable'
-        value: 'MYNEWT_VAL_SPI_1_MASTER || MYNEWT_VAL_SPI_1_SLAVE'
diff --git a/hw/mcu/stm/stm32f3xx/syscfg.yml b/hw/mcu/stm/stm32f3xx/syscfg.yml
index 5767330..97d1a81 100644
--- a/hw/mcu/stm/stm32f3xx/syscfg.yml
+++ b/hw/mcu/stm/stm32f3xx/syscfg.yml
@@ -106,35 +106,3 @@ syscfg.defs:
     MCU_FLASH_ERASED_VAL:
         description: Value read from erased flash.
         value: 0xff
-
-    SPI_0_MASTER:
-        description: 'SPI 0 master'
-        value:  0
-        restrictions:
-            - "!SPI_0_SLAVE"
-    SPI_0_SLAVE:
-        description: 'SPI 0 slave'
-        value:  0
-        restrictions:
-            - "!SPI_0_MASTER"
-    SPI_0:
-        description: 'SPI 0 enable'
-        value: 'MYNEWT_VAL_SPI_0_MASTER || MYNEWT_VAL_SPI_0_SLAVE'
-
-    SPI_1_MASTER:
-        description: 'SPI 1 master'
-        value:  0
-        restrictions:
-            - "!SPI_1_SLAVE"
-    SPI_1_SLAVE:
-        description: 'SPI 1 slave'
-        value:  0
-        restrictions:
-            - "!SPI_1_MASTER"
-    SPI_1:
-        description: 'SPI 1 enable'
-        value: 'MYNEWT_VAL_SPI_1_MASTER || MYNEWT_VAL_SPI_1_SLAVE'
-
-    I2C_0:
-        description: 'I2C (TWI) interface 0'
-        value:  0
diff --git a/hw/mcu/stm/stm32f4xx/syscfg.yml b/hw/mcu/stm/stm32f4xx/syscfg.yml
index bdc4f5d..48ab9a3 100644
--- a/hw/mcu/stm/stm32f4xx/syscfg.yml
+++ b/hw/mcu/stm/stm32f4xx/syscfg.yml
@@ -126,61 +126,3 @@ syscfg.defs:
     MCU_FLASH_ERASED_VAL:
         description: Value read from erased flash.
         value: 0xff
-    I2C_0:
-        description: 'I2C (TWI) interface I2C1'
-        value: 0
-
-    I2C_0_PIN_SCL:
-        description: 'SCL pin for I2C1, PB6, PB8'
-        value:
-
-    I2C_0_PIN_SDA:
-        description: 'SDA pin for I2C1, PB7, PB9'
-        value:
-
-    I2C_1:
-        description: 'I2C (TWI) interface I2C2'
-        value: 0
-
-    I2C_1_PIN_SCL:
-        description: 'SCL pin for I2C2, PB10, PF1, PH4'
-        value:
-
-    I2C_1_PIN_SDA:
-        description: 'SDA pin for I2C2, PB11, PF0, PH5'
-        value:
-
-    I2C_2:
-        description: 'I2C (TWI) interface I2C3'
-        value:  0
-
-    I2C_2_PIN_SCL:
-        description: 'SCL pin for I2C3, PA8, PH7'
-        value:
-
-    I2C_2_PIN_SDA:
-        description: 'SDA pin for I2C3, PB4, PB8, PC9'
-        value:
-
-    SPI_0_MASTER:
-        description: 'SPI 0 master'
-        value:  0
-        restrictions:
-            - "!SPI_0_SLAVE"
-    SPI_0_SLAVE:
-        description: 'SPI 0 slave'
-        value:  0
-        restrictions:
-            - "!SPI_0_MASTER"
-
-    TRNG:
-        description: 'True Random Number Generator (RNG)'
-        value: 0
-
-    CRYPTO:
-        description: 'Enable HW Cryptography module (CRYP)'
-        value: 0
-
-    HASH:
-        description: 'Enable HW hash module (HASH)'
-        value: 0
diff --git a/hw/mcu/stm/stm32f7xx/syscfg.yml b/hw/mcu/stm/stm32f7xx/syscfg.yml
index 0af5e42..9e42fb5 100644
--- a/hw/mcu/stm/stm32f7xx/syscfg.yml
+++ b/hw/mcu/stm/stm32f7xx/syscfg.yml
@@ -126,25 +126,3 @@ syscfg.defs:
     MCU_FLASH_ERASED_VAL:
         description: Value read from erased flash.
         value: 0xff
-
-    SPI_0_MASTER:
-        description: 'SPI 0 master'
-        value:  0
-        restrictions:
-            - "!SPI_0_SLAVE"
-    SPI_0_SLAVE:
-        description: 'SPI 0 slave'
-        value:  0
-        restrictions:
-            - "!SPI_0_MASTER"
-    I2C_0:
-        description: 'I2C (TWI) interface 0'
-        value:  0
-
-    TRNG:
-        description: 'True Random Number Generator (RNG)'
-        value: 0
-
-    CRYPTO:
-        description: 'Enable HW Cryptography module (CRYP)'
-        value: 0
diff --git a/hw/mcu/stm/stm32l0xx/syscfg.yml b/hw/mcu/stm/stm32l0xx/syscfg.yml
index 4ad28f1..72005ba 100644
--- a/hw/mcu/stm/stm32l0xx/syscfg.yml
+++ b/hw/mcu/stm/stm32l0xx/syscfg.yml
@@ -17,10 +17,6 @@
 #
 
 syscfg.defs:
-    I2C_0:
-        description: 'I2C (TWI) interface 0'
-        value:  0
-
     MCU_FLASH_MIN_WRITE_SIZE:
         description: >
             Specifies the required alignment for internal flash writes.
@@ -122,25 +118,3 @@ syscfg.defs:
     MCU_FLASH_ERASED_VAL:
         description: Value read from erased flash.
         value: 0
-
-    SPI_0_MASTER:
-        description: 'SPI 0 master'
-        value:  0
-        restrictions:
-            - "!SPI_0_SLAVE"
-    SPI_0_SLAVE:
-        description: 'SPI 0 slave'
-        value:  0
-        restrictions:
-            - "!SPI_0_MASTER"
-
-    SPI_1_MASTER:
-        description: 'SPI 1 master'
-        value:  0
-        restrictions:
-            - "!SPI_1_SLAVE"
-    SPI_1_SLAVE:
-        description: 'SPI 1 slave'
-        value:  0
-        restrictions:
-            - "!SPI_1_MASTER"
diff --git a/hw/mcu/stm/stm32l1xx/syscfg.yml b/hw/mcu/stm/stm32l1xx/syscfg.yml
index 86f7774..3a6bf88 100644
--- a/hw/mcu/stm/stm32l1xx/syscfg.yml
+++ b/hw/mcu/stm/stm32l1xx/syscfg.yml
@@ -17,10 +17,6 @@
 #
 
 syscfg.defs:
-    I2C_0:
-        description: 'I2C (TWI) interface 0'
-        value:  0
-
     MCU_FLASH_MIN_WRITE_SIZE:
         description: >
             Specifies the required alignment for internal flash writes.
@@ -118,25 +114,3 @@ syscfg.defs:
     MCU_FLASH_ERASED_VAL:
         description: Value read from erased flash.
         value: 0
-
-    SPI_0_MASTER:
-        description: 'SPI 0 master'
-        value:  0
-        restrictions:
-            - "!SPI_0_SLAVE"
-    SPI_0_SLAVE:
-        description: 'SPI 0 slave'
-        value:  0
-        restrictions:
-            - "!SPI_0_MASTER"
-
-    SPI_1_MASTER:
-        description: 'SPI 1 master'
-        value:  0
-        restrictions:
-            - "!SPI_1_SLAVE"
-    SPI_1_SLAVE:
-        description: 'SPI 1 slave'
-        value:  0
-        restrictions:
-            - "!SPI_1_MASTER"
diff --git a/hw/mcu/stm/stm32l4xx/syscfg.yml b/hw/mcu/stm/stm32l4xx/syscfg.yml
index 375368b..eb778c6 100644
--- a/hw/mcu/stm/stm32l4xx/syscfg.yml
+++ b/hw/mcu/stm/stm32l4xx/syscfg.yml
@@ -17,42 +17,6 @@
 #
 
 syscfg.defs:
-    I2C_0:
-        description: 'I2C (TWI) interface I2C1'
-        value:  0
-
-    I2C_0_PIN_SCL:
-        description: 'SCL pin for I2C1, PB6, PB8, PG14'
-        value: MCU_GPIO_PORTB(8)
-
-    I2C_0_PIN_SDA:
-        description: 'SDA pin for I2C1, PB7, PB9, PG13'
-        value: MCU_GPIO_PORTB(9)
-
-    I2C_1:
-        description: 'I2C (TWI) interface I2C2'
-        value:  0
-
-    I2C_1_PIN_SCL:
-        description: 'SCL pin for I2C2, PB10, PB13, PF1'
-        value: MCU_GPIO_PORTB(10)
-
-    I2C_1_PIN_SDA:
-        description: 'SDA pin for I2C2, PB11, PB14, PF0'
-        value: MCU_GPIO_PORTB(11)
-
-    I2C_2:
-        description: 'I2C (TWI) interface I2C3'
-        value:  0
-
-    I2C_2_PIN_SCL:
-        description: 'SCL pin for I2C3, PC0, PF1, PG7'
-        value: MCU_GPIO_PORTC(0)
-
-    I2C_2_PIN_SDA:
-        description: 'SDA pin for I2C3, PC1, PF0, PG8'
-        value: MCU_GPIO_PORTC(1)
-
     MCU_FLASH_MIN_WRITE_SIZE:
         description: >
             Specifies the required alignment for internal flash writes.
@@ -174,25 +138,3 @@ syscfg.defs:
     MCU_FLASH_ERASED_VAL:
         description: Value read from erased flash.
         value: 0xff
-
-    SPI_0_MASTER:
-        description: 'SPI 0 master'
-        value:  0
-        restrictions:
-            - "!SPI_0_SLAVE"
-    SPI_0_SLAVE:
-        description: 'SPI 0 slave'
-        value:  0
-        restrictions:
-            - "!SPI_0_MASTER"
-
-    SPI_1_MASTER:
-        description: 'SPI 1 master'
-        value:  0
-        restrictions:
-            - "!SPI_1_SLAVE"
-    SPI_1_SLAVE:
-        description: 'SPI 1 slave'
-        value:  0
-        restrictions:
-            - "!SPI_1_MASTER"
diff --git a/hw/mcu/stm/stm32wbxx/syscfg.yml b/hw/mcu/stm/stm32wbxx/syscfg.yml
index 9c489f3..73b0613 100644
--- a/hw/mcu/stm/stm32wbxx/syscfg.yml
+++ b/hw/mcu/stm/stm32wbxx/syscfg.yml
@@ -158,34 +158,3 @@ syscfg.defs:
     MCU_FLASH_ERASED_VAL:
         description: Value read from erased flash.
         value: 0xff
-
-    I2C_0:
-        description: 'I2C (TWI) interface I2C1'
-        value:  0
-
-    I2C_0_PIN_SCL:
-        description: 'SCL pin for I2C1, PB6, PB8, PG14'
-        value: MCU_GPIO_PORTB(8)
-
-    I2C_0_PIN_SDA:
-        description: 'SDA pin for I2C1, PB7, PB9, PG13'
-        value: MCU_GPIO_PORTB(9)
-
-    SPI_0_MASTER:
-        description: 'SPI 0 master'
-        value:  0
-        restrictions:
-            - "!SPI_0_SLAVE"
-    SPI_0_SLAVE:
-        description: 'SPI 0 slave'
-        value:  0
-        restrictions:
-            - "!SPI_0_MASTER"
-
-    TRNG:
-        description: 'Enable True Random Number Generator (RNG)'
-        value: 0
-
-    CRYPTO:
-        description: 'Enable HW Cryptography module (CRYP)'
-        value: 0


[mynewt-core] 02/02: stm32: unify ADC initialization

Posted by ut...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

utzig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit a965755d4c1f8be3e232ede9a0f3cee98bc0eaa2
Author: Fabio Utzig <ut...@apache.org>
AuthorDate: Tue Feb 11 12:44:46 2020 -0300

    stm32: unify ADC initialization
    
    * Use ADC_0 as starting index as in other drivers
    * Refactor ADC config to be simpler and easier to read
    
    Signed-off-by: Fabio Utzig <ut...@apache.org>
---
 hw/bsp/black_vet6/pkg.yml                       |   7 -
 hw/bsp/black_vet6/src/hal_bsp.c                 | 325 +++++++++---------------
 hw/bsp/black_vet6/syscfg.yml                    |  10 -
 hw/bsp/olimex_stm32-e407_devboard/pkg.yml       |   7 -
 hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c | 325 +++++++++---------------
 hw/bsp/olimex_stm32-e407_devboard/syscfg.yml    |  10 -
 hw/mcu/stm/stm32_common/pkg.yml                 |   7 +
 hw/mcu/stm/stm32_common/src/stm32_periph.c      |  47 ++++
 hw/mcu/stm/stm32_common/syscfg.yml              |  10 +
 9 files changed, 292 insertions(+), 456 deletions(-)

diff --git a/hw/bsp/black_vet6/pkg.yml b/hw/bsp/black_vet6/pkg.yml
index 27b61b7..c1ef16d 100644
--- a/hw/bsp/black_vet6/pkg.yml
+++ b/hw/bsp/black_vet6/pkg.yml
@@ -37,10 +37,3 @@ pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f4xx"
     - "@apache-mynewt-core/libc/baselibc"
     - "@apache-mynewt-core/hw/drivers/flash/spiflash"
-
-pkg.deps.ADC_1:
-    - "@apache-mynewt-core/hw/drivers/adc/adc_stm32f4"
-pkg.deps.ADC_2:
-    - "@apache-mynewt-core/hw/drivers/adc/adc_stm32f4"
-pkg.deps.ADC_3:
-    - "@apache-mynewt-core/hw/drivers/adc/adc_stm32f4"
diff --git a/hw/bsp/black_vet6/src/hal_bsp.c b/hw/bsp/black_vet6/src/hal_bsp.c
index a36acfb..178864f 100644
--- a/hw/bsp/black_vet6/src/hal_bsp.c
+++ b/hw/bsp/black_vet6/src/hal_bsp.c
@@ -37,7 +37,7 @@
 #include <pwm_stm32/pwm_stm32.h>
 #endif
 
-#if MYNEWT_VAL(ADC_1) || MYNEWT_VAL(ADC_2) || MYNEWT_VAL(ADC_3)
+#if MYNEWT_VAL(ADC_0) || MYNEWT_VAL(ADC_1) || MYNEWT_VAL(ADC_2)
 #include "stm32f4xx_hal_adc.h"
 #include "adc_stm32f4/adc_stm32f4.h"
 #endif
@@ -62,205 +62,131 @@ const uint32_t stm32_flash_sectors[] = {
 static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) + 1 == SZ,
         "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
-#if MYNEWT_VAL(ADC_1)
-struct adc_dev my_dev_adc1;
-#endif
-#if MYNEWT_VAL(ADC_2)
-struct adc_dev my_dev_adc2;
-#endif
-#if MYNEWT_VAL(ADC_3)
-struct adc_dev my_dev_adc3;
-#endif
-
-#if MYNEWT_VAL(ADC_1)
+#if MYNEWT_VAL(ADC_0) || MYNEWT_VAL(ADC_1) || MYNEWT_VAL(ADC_2)
 /*
- * adc_handle is defined earlier because the DMA handle's
- * parent needs to be pointing to the adc_handle
+ * Helper macros to build ADC data structures
  */
-extern ADC_HandleTypeDef adc1_handle;
-
-#define STM32F4_DEFAULT_DMA00_HANDLE {\
-    .Instance = DMA2_Stream0,\
-    .Init.Channel = DMA_CHANNEL_0,\
-    .Init.Direction = DMA_PERIPH_TO_MEMORY,\
-    .Init.PeriphInc = DMA_PINC_DISABLE,\
-    .Init.MemInc = DMA_MINC_ENABLE,\
-    .Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD,\
-    .Init.MemDataAlignment = DMA_MDATAALIGN_WORD,\
-    .Init.Mode = DMA_CIRCULAR,\
-    .Init.Priority = DMA_PRIORITY_HIGH,\
-    .Init.FIFOMode = DMA_FIFOMODE_DISABLE,\
-    .Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL,\
-    .Init.MemBurst = DMA_MBURST_SINGLE,\
-    .Init.PeriphBurst = DMA_PBURST_SINGLE,\
-    .Parent = &adc1_handle,\
-}
-
-DMA_HandleTypeDef adc1_dma00_handle = STM32F4_DEFAULT_DMA00_HANDLE;
-#endif
-
-#if MYNEWT_VAL(ADC_2)
-
-extern ADC_HandleTypeDef adc2_handle;
-
-#define STM32F4_DEFAULT_DMA21_HANDLE {\
-    .Instance = DMA2_Stream2,\
-    .Init.Channel = DMA_CHANNEL_1,\
-    .Init.Direction = DMA_PERIPH_TO_MEMORY,\
-    .Init.PeriphInc = DMA_PINC_DISABLE,\
-    .Init.MemInc = DMA_MINC_ENABLE,\
-    .Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD,\
-    .Init.MemDataAlignment = DMA_MDATAALIGN_WORD,\
-    .Init.Mode = DMA_CIRCULAR,\
-    .Init.Priority = DMA_PRIORITY_HIGH,\
-    .Init.FIFOMode = DMA_FIFOMODE_DISABLE,\
-    .Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL,\
-    .Init.MemBurst = DMA_MBURST_SINGLE,\
-    .Init.PeriphBurst = DMA_PBURST_SINGLE,\
-    .Parent = &adc2_handle,\
+#define STM32F4_DEFAULT_DMA_HANDLE(instance, channel, parent) {           \
+        .Instance = (instance),                                           \
+        .Init.Channel = (channel),                                        \
+        .Init.Direction = DMA_PERIPH_TO_MEMORY,                           \
+        .Init.PeriphInc = DMA_PINC_DISABLE,                               \
+        .Init.MemInc = DMA_MINC_ENABLE,                                   \
+        .Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD,                  \
+        .Init.MemDataAlignment = DMA_MDATAALIGN_WORD,                     \
+        .Init.Mode = DMA_CIRCULAR,                                        \
+        .Init.Priority = DMA_PRIORITY_HIGH,                               \
+        .Init.FIFOMode = DMA_FIFOMODE_DISABLE,                            \
+        .Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL,                \
+        .Init.MemBurst = DMA_MBURST_SINGLE,                               \
+        .Init.PeriphBurst = DMA_PBURST_SINGLE,                            \
+        .Parent = (parent),                                               \
 }
 
-DMA_HandleTypeDef adc2_dma21_handle = STM32F4_DEFAULT_DMA21_HANDLE;
+#define ADC_INIT_HANDLE(name, instance, dma_handle)                       \
+    ADC_HandleTypeDef (name) = {                                          \
+        .Init = {                                                         \
+            .ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2,               \
+            .Resolution = ADC_RESOLUTION12b,                              \
+            .DataAlign = ADC_DATAALIGN_RIGHT,                             \
+            .ScanConvMode = DISABLE,                                      \
+            .EOCSelection = DISABLE,                                      \
+            .ContinuousConvMode = ENABLE,                                 \
+            .NbrOfConversion = 1,                                         \
+            .DiscontinuousConvMode = DISABLE,                             \
+            .NbrOfDiscConversion = 0,                                     \
+            .ExternalTrigConv = ADC_SOFTWARE_START,                       \
+            .ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE,        \
+            .DMAContinuousRequests = ENABLE,                              \
+        },                                                                \
+        .Instance = (instance),                                           \
+        .NbrOfCurrentConversionRank = 0,                                  \
+        .DMA_Handle = (dma_handle),                                       \
+        .Lock = HAL_UNLOCKED,                                             \
+        .State = 0,                                                       \
+        .ErrorCode = 0,                                                   \
+    }
 #endif
 
-
-#if MYNEWT_VAL(ADC_3)
-
-extern ADC_HandleTypeDef adc3_handle;
-
-#define STM32F4_DEFAULT_DMA12_HANDLE {\
-    .Instance = DMA2_Stream1,\
-    .Init.Channel = DMA_CHANNEL_2,\
-    .Init.Direction = DMA_PERIPH_TO_MEMORY,\
-    .Init.PeriphInc = DMA_PINC_DISABLE,\
-    .Init.MemInc = DMA_MINC_ENABLE,\
-    .Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD,\
-    .Init.MemDataAlignment = DMA_MDATAALIGN_WORD,\
-    .Init.Mode = DMA_CIRCULAR,\
-    .Init.Priority = DMA_PRIORITY_HIGH,\
-    .Init.FIFOMode = DMA_FIFOMODE_DISABLE,\
-    .Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL,\
-    .Init.MemBurst = DMA_MBURST_SINGLE,\
-    .Init.PeriphBurst = DMA_PBURST_SINGLE,\
-    .Parent = &adc3_handle,\
-}
-
-DMA_HandleTypeDef adc3_dma12_handle = STM32F4_DEFAULT_DMA12_HANDLE;
+#if MYNEWT_VAL(ADC_0)
+ADC_HandleTypeDef adc0_handle;
+
+DMA_HandleTypeDef adc0_dma00_handle = STM32F4_DEFAULT_DMA_HANDLE(
+    DMA2_Stream0, DMA_CHANNEL_0, &adc0_handle);
+
+ADC_INIT_HANDLE(adc0_handle, ADC1, &adc0_dma00_handle);
+
+struct stm32f4_adc_dev_cfg os_bsp_adc0_cfg = {
+    .sac_chan_count = 16,
+    .sac_chans = (struct adc_chan_config [16]) {
+        [0] = { 0 },
+        [1] = { 0 },
+        [2] = { 0 },
+        [3] = { 0 },
+        [4] = { 0 },
+        [5] = { 0 },
+        [6] = { 0 },
+        [7] = { 0 },
+        [8] = { 0 },
+        [9] = { 0 },
+        [10] = {
+            .c_refmv = 3300,
+            .c_res = 12,
+            .c_configured = 1,
+            .c_cnum = ADC_CHANNEL_10,
+        },
+    },
+    .sac_adc_handle = &adc0_handle,
+};
 #endif
 
-#define STM32F4_ADC_DEFAULT_INIT_TD {\
-    .ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2,\
-    .Resolution = ADC_RESOLUTION12b,\
-    .DataAlign = ADC_DATAALIGN_RIGHT,\
-    .ScanConvMode = DISABLE,\
-    .EOCSelection = DISABLE,\
-    .ContinuousConvMode = ENABLE,\
-    .NbrOfConversion = 1,\
-    .DiscontinuousConvMode = DISABLE,\
-    .NbrOfDiscConversion = 0,\
-    .ExternalTrigConv = ADC_SOFTWARE_START,\
-    .ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE,\
-    .DMAContinuousRequests = ENABLE\
-}
-
 #if MYNEWT_VAL(ADC_1)
-
-/*****************ADC1 Config ***************/
-#define STM32F4_DEFAULT_ADC1_HANDLE {\
-    .Init = STM32F4_ADC_DEFAULT_INIT_TD,\
-    .Instance = ADC1,\
-    .NbrOfCurrentConversionRank = 0,\
-    .DMA_Handle = &adc1_dma00_handle,\
-    .Lock = HAL_UNLOCKED,\
-    .State = 0,\
-    .ErrorCode = 0\
-}
-
-ADC_HandleTypeDef adc1_handle = STM32F4_DEFAULT_ADC1_HANDLE;
-
-#define STM32F4_ADC1_DEFAULT_SAC {\
-    .c_refmv = 3300,\
-    .c_res   = 12,\
-    .c_configured = 1,\
-    .c_cnum = ADC_CHANNEL_10\
-}
-
-struct adc_chan_config adc1_chan10_config = STM32F4_ADC1_DEFAULT_SAC;
-
-#define STM32F4_ADC1_DEFAULT_CONFIG {\
-    .sac_chan_count = 16,\
-    .sac_chans = (struct adc_chan_config [16]){{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},STM32F4_ADC1_DEFAULT_SAC},\
-    .sac_adc_handle = &adc1_handle,\
-}
-
-struct stm32f4_adc_dev_cfg adc1_config = STM32F4_ADC1_DEFAULT_CONFIG;
-/*********************************************/
+ADC_HandleTypeDef adc1_handle;
+
+DMA_HandleTypeDef adc1_dma21_handle = STM32F4_DEFAULT_DMA_HANDLE(
+    DMA2_Stream2, DMA_CHANNEL_1, &adc1_handle);
+
+ADC_INIT_HANDLE(adc1_handle, ADC2, &adc1_dma21_handle);
+
+struct stm32f4_adc_dev_cfg os_bsp_adc1_cfg = {
+    .sac_chan_count = 16,
+    .sac_chans = (struct adc_chan_config [16]) {
+        [0] = { 0 },
+        [1] = {
+            .c_refmv = 3300,
+            .c_res = 12,
+            .c_configured = 1,
+            .c_cnum = ADC_CHANNEL_1,
+        },
+    },
+    .sac_adc_handle = &adc1_handle,
+};
 #endif
 
 #if MYNEWT_VAL(ADC_2)
-
-/*****************ADC2 Config ***************/
-#define STM32F4_DEFAULT_ADC2_HANDLE {\
-    .Init = STM32F4_ADC_DEFAULT_INIT_TD,\
-    .Instance = ADC2,\
-    .NbrOfCurrentConversionRank = 0,\
-    .DMA_Handle = &adc2_dma21_handle,\
-    .Lock = HAL_UNLOCKED,\
-    .State = 0,\
-    .ErrorCode = 0\
-}
-
-ADC_HandleTypeDef adc2_handle = STM32F4_DEFAULT_ADC2_HANDLE;
-
-#define STM32F4_ADC2_DEFAULT_SAC {\
-    .c_refmv = 3300,\
-    .c_res   = 12,\
-    .c_configured = 1,\
-    .c_cnum = ADC_CHANNEL_1\
-}
-
-struct adc_chan_config adc2_chan1_config = STM32F4_ADC2_DEFAULT_SAC;
-
-#define STM32F4_ADC2_DEFAULT_CONFIG {\
-    .sac_chan_count = 16,\
-    .sac_chans = (struct adc_chan_config [16]){{0},STM32F4_ADC1_DEFAULT_SAC}\
-    .sac_adc_handle = &adc2_handle,\
-}
-
-struct stm32f4_adc_dev_cfg adc2_config = STM32F4_ADC2_DEFAULT_CONFIG;
-/*********************************************/
-#endif
-
-#if MYNEWT_VAL(ADC_3)
-
-#define STM32F4_DEFAULT_ADC3_HANDLE {\
-    .Init = STM32F4_ADC_DEFAULT_INIT_TD,\
-    .Instance = ADC3,\
-    .NbrOfCurrentConversionRank = 0,\
-    .DMA_Handle = &adc3_dma12_handle,\
-    .Lock = HAL_UNLOCKED,\
-    .State = 0,\
-    .ErrorCode = 0\
-}
-
-ADC_HandleTypeDef adc3_handle = STM32F4_DEFAULT_ADC3_HANDLE;
-
-#define STM32F4_ADC3_DEFAULT_SAC {\
-    .c_refmv = 3300,\
-    .c_res   = 12,\
-    .c_configured = 1,\
-    .c_cnum = ADC_CHANNEL_4\
-}
-
-struct adc_chan_config adc3_chan4_config = STM32F4_ADC3_DEFAULT_SAC;
-
-#define STM32F4_ADC3_DEFAULT_CONFIG {\
-    .sac_chan_count = 16,\
-    .sac_chans = (struct adc_chan_config [16]){{0},{0},{0},{0},STM32F4_ADC3_DEFAULT_SAC},\
-    .sac_adc_handle = &adc3_handle,\
-}
-
-struct stm32f4_adc_dev_cfg adc3_config = STM32F4_ADC3_DEFAULT_CONFIG;
+ADC_HandleTypeDef adc2_handle;
+
+DMA_HandleTypeDef adc2_dma12_handle = STM32F4_DEFAULT_DMA_HANDLE(
+    DMA2_Stream1, DMA_CHANNEL_2, &adc2_handle);
+
+ADC_INIT_HANDLE(adc2_handle, ADC3, &adc2_dma12_handle);
+
+struct stm32f4_adc_dev_cfg os_bsp_adc2_cfg = {
+    .sac_chan_count = 16,
+    .sac_chans = (struct adc_chan_config [16]) {
+        [0] = { 0 },
+        [1] = { 0 },
+        [2] = { 0 },
+        [3] = { 0 },
+        [4] = {
+            .c_refmv = 3300,
+            .c_res = 12,
+            .c_configured = 1,
+            .c_cnum = ADC_CHANNEL_4,
+        },
+    },
+    .sac_adc_handle = &adc2_handle,
+};
 #endif
 
 #if MYNEWT_VAL(I2C_0)
@@ -419,28 +345,5 @@ hal_bsp_get_nvic_priority(int irq_num, uint32_t pri)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
     stm32_periph_create();
-
-#if MYNEWT_VAL(ADC_1)
-    rc = os_dev_create((struct os_dev *) &my_dev_adc1, "adc1",
-            OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
-            stm32f4_adc_dev_init, &adc1_config);
-    assert(rc == 0);
-#endif
-#if MYNEWT_VAL(ADC_2)
-    rc = os_dev_create((struct os_dev *) &my_dev_adc2, "adc2",
-            OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
-            stm32f4_adc_dev_init, &adc2_config);
-    assert(rc == 0);
-#endif
-#if MYNEWT_VAL(ADC_3)
-    rc = os_dev_create((struct os_dev *) &my_dev_adc3, "adc3",
-            OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
-            stm32f4_adc_dev_init, &adc3_config);
-    assert(rc == 0);
-#endif
 }
diff --git a/hw/bsp/black_vet6/syscfg.yml b/hw/bsp/black_vet6/syscfg.yml
index 83384ce..b0cb4f1 100644
--- a/hw/bsp/black_vet6/syscfg.yml
+++ b/hw/bsp/black_vet6/syscfg.yml
@@ -25,16 +25,6 @@ syscfg.defs:
         description: 'Number of flash sectors for a non-linear STM32 MCU.'
         value: 8
 
-    ADC_1:
-        description: "ADC_1"
-        value:  0
-    ADC_2:
-        description: "ADC_2"
-        value:  0
-    ADC_3:
-        description: "ADC_3"
-        value:  0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
diff --git a/hw/bsp/olimex_stm32-e407_devboard/pkg.yml b/hw/bsp/olimex_stm32-e407_devboard/pkg.yml
index 12a0d81..a9c20ba 100644
--- a/hw/bsp/olimex_stm32-e407_devboard/pkg.yml
+++ b/hw/bsp/olimex_stm32-e407_devboard/pkg.yml
@@ -37,10 +37,3 @@ pkg.cflags.HARDFLOAT:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/stm/stm32f4xx"
     - "@apache-mynewt-core/libc/baselibc"
-
-pkg.deps.ADC_1:
-    - "@apache-mynewt-core/hw/drivers/adc/adc_stm32f4"
-pkg.deps.ADC_2:
-    - "@apache-mynewt-core/hw/drivers/adc/adc_stm32f4"
-pkg.deps.ADC_3:
-    - "@apache-mynewt-core/hw/drivers/adc/adc_stm32f4"
diff --git a/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c b/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c
index e5d8ab6..3d2f67d 100644
--- a/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c
+++ b/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c
@@ -37,7 +37,7 @@
 #include <pwm_stm32/pwm_stm32.h>
 #endif
 
-#if MYNEWT_VAL(ADC_1) || MYNEWT_VAL(ADC_2) || MYNEWT_VAL(ADC_3)
+#if MYNEWT_VAL(ADC_0) || MYNEWT_VAL(ADC_1) || MYNEWT_VAL(ADC_2)
 #include "stm32f4xx_hal_adc.h"
 #include "adc_stm32f4/adc_stm32f4.h"
 #endif
@@ -62,205 +62,131 @@ const uint32_t stm32_flash_sectors[] = {
 static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) + 1 == SZ,
         "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
-#if MYNEWT_VAL(ADC_1)
-struct adc_dev my_dev_adc1;
-#endif
-#if MYNEWT_VAL(ADC_2)
-struct adc_dev my_dev_adc2;
-#endif
-#if MYNEWT_VAL(ADC_3)
-struct adc_dev my_dev_adc3;
-#endif
-
-#if MYNEWT_VAL(ADC_1)
+#if MYNEWT_VAL(ADC_0) || MYNEWT_VAL(ADC_1) || MYNEWT_VAL(ADC_2)
 /*
- * adc_handle is defined earlier because the DMA handle's
- * parent needs to be pointing to the adc_handle
+ * Helper macros to build ADC data structures
  */
-extern ADC_HandleTypeDef adc1_handle;
-
-#define STM32F4_DEFAULT_DMA00_HANDLE {\
-    .Instance = DMA2_Stream0,\
-    .Init.Channel = DMA_CHANNEL_0,\
-    .Init.Direction = DMA_PERIPH_TO_MEMORY,\
-    .Init.PeriphInc = DMA_PINC_DISABLE,\
-    .Init.MemInc = DMA_MINC_ENABLE,\
-    .Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD,\
-    .Init.MemDataAlignment = DMA_MDATAALIGN_WORD,\
-    .Init.Mode = DMA_CIRCULAR,\
-    .Init.Priority = DMA_PRIORITY_HIGH,\
-    .Init.FIFOMode = DMA_FIFOMODE_DISABLE,\
-    .Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL,\
-    .Init.MemBurst = DMA_MBURST_SINGLE,\
-    .Init.PeriphBurst = DMA_PBURST_SINGLE,\
-    .Parent = &adc1_handle,\
-}
-
-DMA_HandleTypeDef adc1_dma00_handle = STM32F4_DEFAULT_DMA00_HANDLE;
-#endif
-
-#if MYNEWT_VAL(ADC_2)
-
-extern ADC_HandleTypeDef adc2_handle;
-
-#define STM32F4_DEFAULT_DMA21_HANDLE {\
-    .Instance = DMA2_Stream2,\
-    .Init.Channel = DMA_CHANNEL_1,\
-    .Init.Direction = DMA_PERIPH_TO_MEMORY,\
-    .Init.PeriphInc = DMA_PINC_DISABLE,\
-    .Init.MemInc = DMA_MINC_ENABLE,\
-    .Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD,\
-    .Init.MemDataAlignment = DMA_MDATAALIGN_WORD,\
-    .Init.Mode = DMA_CIRCULAR,\
-    .Init.Priority = DMA_PRIORITY_HIGH,\
-    .Init.FIFOMode = DMA_FIFOMODE_DISABLE,\
-    .Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL,\
-    .Init.MemBurst = DMA_MBURST_SINGLE,\
-    .Init.PeriphBurst = DMA_PBURST_SINGLE,\
-    .Parent = &adc2_handle,\
+#define STM32F4_DEFAULT_DMA_HANDLE(instance, channel, parent) {           \
+        .Instance = (instance),                                           \
+        .Init.Channel = (channel),                                        \
+        .Init.Direction = DMA_PERIPH_TO_MEMORY,                           \
+        .Init.PeriphInc = DMA_PINC_DISABLE,                               \
+        .Init.MemInc = DMA_MINC_ENABLE,                                   \
+        .Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD,                  \
+        .Init.MemDataAlignment = DMA_MDATAALIGN_WORD,                     \
+        .Init.Mode = DMA_CIRCULAR,                                        \
+        .Init.Priority = DMA_PRIORITY_HIGH,                               \
+        .Init.FIFOMode = DMA_FIFOMODE_DISABLE,                            \
+        .Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL,                \
+        .Init.MemBurst = DMA_MBURST_SINGLE,                               \
+        .Init.PeriphBurst = DMA_PBURST_SINGLE,                            \
+        .Parent = (parent),                                               \
 }
 
-DMA_HandleTypeDef adc2_dma21_handle = STM32F4_DEFAULT_DMA21_HANDLE;
+#define ADC_INIT_HANDLE(name, instance, dma_handle)                       \
+    ADC_HandleTypeDef (name) = {                                          \
+        .Init = {                                                         \
+            .ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2,               \
+            .Resolution = ADC_RESOLUTION12b,                              \
+            .DataAlign = ADC_DATAALIGN_RIGHT,                             \
+            .ScanConvMode = DISABLE,                                      \
+            .EOCSelection = DISABLE,                                      \
+            .ContinuousConvMode = ENABLE,                                 \
+            .NbrOfConversion = 1,                                         \
+            .DiscontinuousConvMode = DISABLE,                             \
+            .NbrOfDiscConversion = 0,                                     \
+            .ExternalTrigConv = ADC_SOFTWARE_START,                       \
+            .ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE,        \
+            .DMAContinuousRequests = ENABLE,                              \
+        },                                                                \
+        .Instance = (instance),                                           \
+        .NbrOfCurrentConversionRank = 0,                                  \
+        .DMA_Handle = (dma_handle),                                       \
+        .Lock = HAL_UNLOCKED,                                             \
+        .State = 0,                                                       \
+        .ErrorCode = 0,                                                   \
+    }
 #endif
 
-
-#if MYNEWT_VAL(ADC_3)
-
-extern ADC_HandleTypeDef adc3_handle;
-
-#define STM32F4_DEFAULT_DMA12_HANDLE {\
-    .Instance = DMA2_Stream1,\
-    .Init.Channel = DMA_CHANNEL_2,\
-    .Init.Direction = DMA_PERIPH_TO_MEMORY,\
-    .Init.PeriphInc = DMA_PINC_DISABLE,\
-    .Init.MemInc = DMA_MINC_ENABLE,\
-    .Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD,\
-    .Init.MemDataAlignment = DMA_MDATAALIGN_WORD,\
-    .Init.Mode = DMA_CIRCULAR,\
-    .Init.Priority = DMA_PRIORITY_HIGH,\
-    .Init.FIFOMode = DMA_FIFOMODE_DISABLE,\
-    .Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL,\
-    .Init.MemBurst = DMA_MBURST_SINGLE,\
-    .Init.PeriphBurst = DMA_PBURST_SINGLE,\
-    .Parent = &adc3_handle,\
-}
-
-DMA_HandleTypeDef adc3_dma12_handle = STM32F4_DEFAULT_DMA12_HANDLE;
+#if MYNEWT_VAL(ADC_0)
+ADC_HandleTypeDef adc0_handle;
+
+DMA_HandleTypeDef adc0_dma00_handle = STM32F4_DEFAULT_DMA_HANDLE(
+    DMA2_Stream0, DMA_CHANNEL_0, &adc0_handle);
+
+ADC_INIT_HANDLE(adc0_handle, ADC1, &adc0_dma00_handle);
+
+struct stm32f4_adc_dev_cfg os_bsp_adc0_cfg = {
+    .sac_chan_count = 16,
+    .sac_chans = (struct adc_chan_config [16]) {
+        [0] = { 0 },
+        [1] = { 0 },
+        [2] = { 0 },
+        [3] = { 0 },
+        [4] = { 0 },
+        [5] = { 0 },
+        [6] = { 0 },
+        [7] = { 0 },
+        [8] = { 0 },
+        [9] = { 0 },
+        [10] = {
+            .c_refmv = 3300,
+            .c_res = 12,
+            .c_configured = 1,
+            .c_cnum = ADC_CHANNEL_10,
+        },
+    },
+    .sac_adc_handle = &adc0_handle,
+};
 #endif
 
-#define STM32F4_ADC_DEFAULT_INIT_TD {\
-    .ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2,\
-    .Resolution = ADC_RESOLUTION12b,\
-    .DataAlign = ADC_DATAALIGN_RIGHT,\
-    .ScanConvMode = DISABLE,\
-    .EOCSelection = DISABLE,\
-    .ContinuousConvMode = ENABLE,\
-    .NbrOfConversion = 1,\
-    .DiscontinuousConvMode = DISABLE,\
-    .NbrOfDiscConversion = 0,\
-    .ExternalTrigConv = ADC_SOFTWARE_START,\
-    .ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE,\
-    .DMAContinuousRequests = ENABLE\
-}
-
 #if MYNEWT_VAL(ADC_1)
-
-/*****************ADC1 Config ***************/
-#define STM32F4_DEFAULT_ADC1_HANDLE {\
-    .Init = STM32F4_ADC_DEFAULT_INIT_TD,\
-    .Instance = ADC1,\
-    .NbrOfCurrentConversionRank = 0,\
-    .DMA_Handle = &adc1_dma00_handle,\
-    .Lock = HAL_UNLOCKED,\
-    .State = 0,\
-    .ErrorCode = 0\
-}
-
-ADC_HandleTypeDef adc1_handle = STM32F4_DEFAULT_ADC1_HANDLE;
-
-#define STM32F4_ADC1_DEFAULT_SAC {\
-    .c_refmv = 3300,\
-    .c_res   = 12,\
-    .c_configured = 1,\
-    .c_cnum = ADC_CHANNEL_10\
-}
-
-struct adc_chan_config adc1_chan10_config = STM32F4_ADC1_DEFAULT_SAC;
-
-#define STM32F4_ADC1_DEFAULT_CONFIG {\
-    .sac_chan_count = 16,\
-    .sac_chans = (struct adc_chan_config [16]){{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},STM32F4_ADC1_DEFAULT_SAC},\
-    .sac_adc_handle = &adc1_handle,\
-}
-
-struct stm32f4_adc_dev_cfg adc1_config = STM32F4_ADC1_DEFAULT_CONFIG;
-/*********************************************/
+ADC_HandleTypeDef adc1_handle;
+
+DMA_HandleTypeDef adc1_dma21_handle = STM32F4_DEFAULT_DMA_HANDLE(
+    DMA2_Stream2, DMA_CHANNEL_1, &adc1_handle);
+
+ADC_INIT_HANDLE(adc1_handle, ADC2, &adc1_dma21_handle);
+
+struct stm32f4_adc_dev_cfg os_bsp_adc1_cfg = {
+    .sac_chan_count = 16,
+    .sac_chans = (struct adc_chan_config [16]) {
+        [0] = { 0 },
+        [1] = {
+            .c_refmv = 3300,
+            .c_res = 12,
+            .c_configured = 1,
+            .c_cnum = ADC_CHANNEL_1,
+        },
+    },
+    .sac_adc_handle = &adc1_handle,
+};
 #endif
 
 #if MYNEWT_VAL(ADC_2)
-
-/*****************ADC2 Config ***************/
-#define STM32F4_DEFAULT_ADC2_HANDLE {\
-    .Init = STM32F4_ADC_DEFAULT_INIT_TD,\
-    .Instance = ADC2,\
-    .NbrOfCurrentConversionRank = 0,\
-    .DMA_Handle = &adc2_dma21_handle,\
-    .Lock = HAL_UNLOCKED,\
-    .State = 0,\
-    .ErrorCode = 0\
-}
-
-ADC_HandleTypeDef adc2_handle = STM32F4_DEFAULT_ADC2_HANDLE;
-
-#define STM32F4_ADC2_DEFAULT_SAC {\
-    .c_refmv = 3300,\
-    .c_res   = 12,\
-    .c_configured = 1,\
-    .c_cnum = ADC_CHANNEL_1\
-}
-
-struct adc_chan_config adc2_chan1_config = STM32F4_ADC2_DEFAULT_SAC;
-
-#define STM32F4_ADC2_DEFAULT_CONFIG {\
-    .sac_chan_count = 16,\
-    .sac_chans = (struct adc_chan_config [16]){{0},STM32F4_ADC1_DEFAULT_SAC}\
-    .sac_adc_handle = &adc2_handle,\
-}
-
-struct stm32f4_adc_dev_cfg adc2_config = STM32F4_ADC2_DEFAULT_CONFIG;
-/*********************************************/
-#endif
-
-#if MYNEWT_VAL(ADC_3)
-
-#define STM32F4_DEFAULT_ADC3_HANDLE {\
-    .Init = STM32F4_ADC_DEFAULT_INIT_TD,\
-    .Instance = ADC3,\
-    .NbrOfCurrentConversionRank = 0,\
-    .DMA_Handle = &adc3_dma12_handle,\
-    .Lock = HAL_UNLOCKED,\
-    .State = 0,\
-    .ErrorCode = 0\
-}
-
-ADC_HandleTypeDef adc3_handle = STM32F4_DEFAULT_ADC3_HANDLE;
-
-#define STM32F4_ADC3_DEFAULT_SAC {\
-    .c_refmv = 3300,\
-    .c_res   = 12,\
-    .c_configured = 1,\
-    .c_cnum = ADC_CHANNEL_4\
-}
-
-struct adc_chan_config adc3_chan4_config = STM32F4_ADC3_DEFAULT_SAC;
-
-#define STM32F4_ADC3_DEFAULT_CONFIG {\
-    .sac_chan_count = 16,\
-    .sac_chans = (struct adc_chan_config [16]){{0},{0},{0},{0},STM32F4_ADC3_DEFAULT_SAC},\
-    .sac_adc_handle = &adc3_handle,\
-}
-
-struct stm32f4_adc_dev_cfg adc3_config = STM32F4_ADC3_DEFAULT_CONFIG;
+ADC_HandleTypeDef adc2_handle;
+
+DMA_HandleTypeDef adc2_dma12_handle = STM32F4_DEFAULT_DMA_HANDLE(
+    DMA2_Stream1, DMA_CHANNEL_2, &adc2_handle);
+
+ADC_INIT_HANDLE(adc2_handle, ADC3, &adc2_dma12_handle);
+
+struct stm32f4_adc_dev_cfg os_bsp_adc2_cfg = {
+    .sac_chan_count = 16,
+    .sac_chans = (struct adc_chan_config [16]) {
+        [0] = { 0 },
+        [1] = { 0 },
+        [2] = { 0 },
+        [3] = { 0 },
+        [4] = {
+            .c_refmv = 3300,
+            .c_res = 12,
+            .c_configured = 1,
+            .c_cnum = ADC_CHANNEL_4,
+        },
+    },
+    .sac_adc_handle = &adc2_handle,
+};
 #endif
 
 #if MYNEWT_VAL(UART_0)
@@ -377,28 +303,5 @@ hal_bsp_get_nvic_priority(int irq_num, uint32_t pri)
 void
 hal_bsp_init(void)
 {
-    int rc;
-
-    (void)rc;
-
     stm32_periph_create();
-
-#if MYNEWT_VAL(ADC_1)
-    rc = os_dev_create((struct os_dev *) &my_dev_adc1, "adc1",
-            OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
-            stm32f4_adc_dev_init, &adc1_config);
-    assert(rc == 0);
-#endif
-#if MYNEWT_VAL(ADC_2)
-    rc = os_dev_create((struct os_dev *) &my_dev_adc2, "adc2",
-            OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
-            stm32f4_adc_dev_init, &adc2_config);
-    assert(rc == 0);
-#endif
-#if MYNEWT_VAL(ADC_3)
-    rc = os_dev_create((struct os_dev *) &my_dev_adc3, "adc3",
-            OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
-            stm32f4_adc_dev_init, &adc3_config);
-    assert(rc == 0);
-#endif
 }
diff --git a/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml b/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml
index f1194f0..8cc0ad9 100644
--- a/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml
+++ b/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml
@@ -25,16 +25,6 @@ syscfg.defs:
         description: 'Number of flash sectors for a non-linear STM32 MCU.'
         value: 12
 
-    ADC_1:
-        description: "ADC_1"
-        value:  0
-    ADC_2:
-        description: "ADC_2"
-        value:  0
-    ADC_3:
-        description: "ADC_3"
-        value:  0
-
 syscfg.vals:
     REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
     CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
diff --git a/hw/mcu/stm/stm32_common/pkg.yml b/hw/mcu/stm/stm32_common/pkg.yml
index 14e6897..f8e07d6 100644
--- a/hw/mcu/stm/stm32_common/pkg.yml
+++ b/hw/mcu/stm/stm32_common/pkg.yml
@@ -53,3 +53,10 @@ pkg.deps.CRYPTO:
 
 pkg.deps.HASH:
     - "@apache-mynewt-core/hw/drivers/hash/hash_stm32"
+
+pkg.deps.ADC_0:
+    - "@apache-mynewt-core/hw/drivers/adc/adc_stm32f4"
+pkg.deps.ADC_1:
+    - "@apache-mynewt-core/hw/drivers/adc/adc_stm32f4"
+pkg.deps.ADC_2:
+    - "@apache-mynewt-core/hw/drivers/adc/adc_stm32f4"
diff --git a/hw/mcu/stm/stm32_common/src/stm32_periph.c b/hw/mcu/stm/stm32_common/src/stm32_periph.c
index ec2674c..f8cf7e7 100644
--- a/hw/mcu/stm/stm32_common/src/stm32_periph.c
+++ b/hw/mcu/stm/stm32_common/src/stm32_periph.c
@@ -47,6 +47,12 @@
 #include <stm32_eth/stm32_eth.h>
 #include <stm32_eth/stm32_eth_cfg.h>
 #endif
+#if MYNEWT_VAL(ADC_0) || MYNEWT_VAL(ADC_1) || MYNEWT_VAL(ADC_2)
+#include "stm32f4xx_hal_dma.h"
+#include "stm32f4xx_hal_adc.h"
+#include "adc_stm32f4/adc_stm32f4.h"
+#endif
+
 #include "mcu/stm32_hal.h"
 
 #if MYNEWT_VAL(PWM_0)
@@ -83,6 +89,19 @@ static struct uart_dev os_bsp_uart1;
 static const struct stm32_uart_cfg os_bsp_uart1_cfg;
 #endif
 
+#if MYNEWT_VAL(ADC_0)
+static struct adc_dev os_bsp_adc0;
+extern struct stm32f4_adc_dev_cfg os_bsp_adc0_cfg;
+#endif
+#if MYNEWT_VAL(ADC_1)
+static struct adc_dev os_bsp_adc1;
+extern struct stm32f4_adc_dev_cfg os_bsp_adc1_cfg;
+#endif
+#if MYNEWT_VAL(ADC_2)
+static struct adc_dev os_bsp_adc2;
+extern struct stm32f4_adc_dev_cfg os_bsp_adc2_cfg;
+#endif
+
 #if MYNEWT_VAL(I2C_0)
 extern const struct stm32_hal_i2c_cfg os_bsp_i2c0_cfg;
 #endif
@@ -338,6 +357,33 @@ stm32_periph_create_spi(void)
 }
 
 static void
+stm32_periph_create_adc(void)
+{
+    int rc;
+
+    (void)rc;
+
+#if MYNEWT_VAL(ADC_0)
+    rc = os_dev_create((struct os_dev *) &os_bsp_adc0, "adc0",
+                       OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
+                       stm32f4_adc_dev_init, &os_bsp_adc0_cfg);
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(ADC_1)
+    rc = os_dev_create((struct os_dev *) &os_bsp_adc1, "adc1",
+                       OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
+                       stm32f4_adc_dev_init, &os_bsp_adc1_cfg);
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(ADC_2)
+    rc = os_dev_create((struct os_dev *) &os_bsp_adc2, "adc2",
+                       OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT,
+                       stm32f4_adc_dev_init, &os_bsp_adc2_cfg);
+    assert(rc == 0);
+#endif
+}
+
+static void
 stm32_periph_create_eth(void)
 {
     int rc;
@@ -361,5 +407,6 @@ stm32_periph_create(void)
     stm32_periph_create_uart();
     stm32_periph_create_i2c();
     stm32_periph_create_spi();
+    stm32_periph_create_adc();
     stm32_periph_create_eth();
 }
diff --git a/hw/mcu/stm/stm32_common/syscfg.yml b/hw/mcu/stm/stm32_common/syscfg.yml
index da33164..5da1d28 100644
--- a/hw/mcu/stm/stm32_common/syscfg.yml
+++ b/hw/mcu/stm/stm32_common/syscfg.yml
@@ -194,3 +194,13 @@ syscfg.defs:
     ETH_0:
         description: 'Ethernet driver for LwIP'
         value: 0
+
+    ADC_0:
+        description: "ADC_0"
+        value:  0
+    ADC_1:
+        description: "ADC_1"
+        value:  0
+    ADC_2:
+        description: "ADC_2"
+        value:  0