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:25 UTC

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

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