You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/11/21 11:32:03 UTC

[GitHub] utzig closed pull request #1522: [STM32] Unify flash drivers

utzig closed pull request #1522: [STM32] Unify flash drivers
URL: https://github.com/apache/mynewt-core/pull/1522
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/hw/bsp/b-l072z-lrwan1/src/hal_bsp.c b/hw/bsp/b-l072z-lrwan1/src/hal_bsp.c
index 16d6aabe8f..d700a07230 100644
--- a/hw/bsp/b-l072z-lrwan1/src/hal_bsp.c
+++ b/hw/bsp/b-l072z-lrwan1/src/hal_bsp.c
@@ -94,6 +94,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     },
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -103,7 +104,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return &stm32l0_flash_dev;
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/b-l072z-lrwan1/syscfg.yml b/hw/bsp/b-l072z-lrwan1/syscfg.yml
index e69c957cdd..ada6a40d6d 100644
--- a/hw/bsp/b-l072z-lrwan1/syscfg.yml
+++ b/hw/bsp/b-l072z-lrwan1/syscfg.yml
@@ -18,6 +18,10 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 192
+
     UART_0:
         description: 'Whether to enable UART0'
         value:  1
diff --git a/hw/bsp/bluepill/src/hal_bsp.c b/hw/bsp/bluepill/src/hal_bsp.c
index e25affefda..1a0912feaa 100644
--- a/hw/bsp/bluepill/src/hal_bsp.c
+++ b/hw/bsp/bluepill/src/hal_bsp.c
@@ -109,6 +109,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     },
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -118,7 +119,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return &stm32f1_flash_dev;
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/bluepill/syscfg.yml b/hw/bsp/bluepill/syscfg.yml
index d58f466911..ee2a793f38 100644
--- a/hw/bsp/bluepill/syscfg.yml
+++ b/hw/bsp/bluepill/syscfg.yml
@@ -18,6 +18,10 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 128
+
     UART_0:
         description: 'UART 0'
         value:  1
diff --git a/hw/bsp/nucleo-f030r8/src/hal_bsp.c b/hw/bsp/nucleo-f030r8/src/hal_bsp.c
index a90ea52d63..30a7e04ce6 100644
--- a/hw/bsp/nucleo-f030r8/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f030r8/src/hal_bsp.c
@@ -101,6 +101,7 @@ hal_bsp_mem_dump dump_cfg[] = {
     },
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -110,7 +111,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return &stm32f0_flash_dev;
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/nucleo-f030r8/syscfg.yml b/hw/bsp/nucleo-f030r8/syscfg.yml
index 2ca209ed87..7d55e21bba 100644
--- a/hw/bsp/nucleo-f030r8/syscfg.yml
+++ b/hw/bsp/nucleo-f030r8/syscfg.yml
@@ -18,6 +18,10 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 64
+
     UART_0:
         description: 'Whether to enable UART2'
         value:  0
diff --git a/hw/bsp/nucleo-f303k8/src/hal_bsp.c b/hw/bsp/nucleo-f303k8/src/hal_bsp.c
index 28e6cf61b9..472400ab11 100644
--- a/hw/bsp/nucleo-f303k8/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f303k8/src/hal_bsp.c
@@ -136,6 +136,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     }
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -145,7 +146,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return stm32f3_flash_dev();
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/nucleo-f303k8/syscfg.yml b/hw/bsp/nucleo-f303k8/syscfg.yml
index 427947867c..dd0b72c3d3 100644
--- a/hw/bsp/nucleo-f303k8/syscfg.yml
+++ b/hw/bsp/nucleo-f303k8/syscfg.yml
@@ -18,6 +18,10 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 64
+
     UART_0:
         description: 'Whether to enable UART0'
         value:  1
diff --git a/hw/bsp/nucleo-f303re/src/hal_bsp.c b/hw/bsp/nucleo-f303re/src/hal_bsp.c
index f667c57f3c..5ee9626c36 100644
--- a/hw/bsp/nucleo-f303re/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f303re/src/hal_bsp.c
@@ -136,6 +136,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     }
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -145,7 +146,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return stm32f3_flash_dev();
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/nucleo-f303re/syscfg.yml b/hw/bsp/nucleo-f303re/syscfg.yml
index 427947867c..96a0bd4399 100644
--- a/hw/bsp/nucleo-f303re/syscfg.yml
+++ b/hw/bsp/nucleo-f303re/syscfg.yml
@@ -18,6 +18,10 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 512
+
     UART_0:
         description: 'Whether to enable UART0'
         value:  1
diff --git a/hw/bsp/nucleo-f401re/src/hal_bsp.c b/hw/bsp/nucleo-f401re/src/hal_bsp.c
index fbc6ef2108..e8aba90f64 100644
--- a/hw/bsp/nucleo-f401re/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f401re/src/hal_bsp.c
@@ -26,7 +26,6 @@
 
 #include <hal/hal_bsp.h>
 #include <hal/hal_gpio.h>
-#include <hal/hal_flash_int.h>
 #include <hal/hal_i2c.h>
 #include <hal/hal_timer.h>
 #if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
@@ -39,7 +38,7 @@
 #include "bsp/bsp.h"
 #include <assert.h>
 
-const uint32_t stm32f4_flash_sectors[] = {
+const uint32_t stm32_flash_sectors[] = {
     0x08000000,     /* 16kB */
     0x08004000,     /* 16kB */
     0x08008000,     /* 16kB */
@@ -51,18 +50,9 @@ const uint32_t stm32f4_flash_sectors[] = {
     0x08080000,     /* End of flash */
 };
 
-#define NAREAS (sizeof(stm32f4_flash_sectors) / sizeof(stm32f4_flash_sectors[0]))
-
-extern const struct hal_flash_funcs stm32f4_flash_funcs;
-
-const struct hal_flash stm32f4_flash_dev = {
-    .hf_itf = &stm32f4_flash_funcs,
-    .hf_base_addr = 0x08000000,
-    .hf_size = 512 * 1024,
-    .hf_sector_cnt = NAREAS - 1,
-    .hf_align = 1,
-    .hf_erased_val = 0xff,
-};
+#define SZ (sizeof(stm32_flash_sectors) / sizeof(stm32_flash_sectors[0]))
+_Static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) == SZ,
+        "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
 #if MYNEWT_VAL(UART_0)
 static struct uart_dev hal_uart0;
@@ -118,6 +108,7 @@ struct stm32_hal_spi_cfg spi0_cfg = {
 };
 #endif
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -127,7 +118,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return &stm32f4_flash_dev;
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/nucleo-f401re/syscfg.yml b/hw/bsp/nucleo-f401re/syscfg.yml
index 72bf3b2bcc..073ed2d926 100644
--- a/hw/bsp/nucleo-f401re/syscfg.yml
+++ b/hw/bsp/nucleo-f401re/syscfg.yml
@@ -18,6 +18,14 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 512
+
+    STM32_FLASH_NUM_AREAS:
+        description: 'Amount of flash sectors for a non-linear STM32 MCU.'
+        value: 9
+
     UART_0:
         description: 'Whether to enable UART0'
         value:  1
diff --git a/hw/bsp/nucleo-f413zh/src/hal_bsp.c b/hw/bsp/nucleo-f413zh/src/hal_bsp.c
index eb2e56ed97..583fec56a9 100644
--- a/hw/bsp/nucleo-f413zh/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f413zh/src/hal_bsp.c
@@ -28,7 +28,6 @@
 
 #include <hal/hal_bsp.h>
 #include <hal/hal_gpio.h>
-#include <hal/hal_flash_int.h>
 #include <hal/hal_timer.h>
 
 #include <stm32f4xx_hal_gpio_ex.h>
@@ -40,7 +39,7 @@
 
 #include "bsp/bsp.h"
 
-const uint32_t stm32f4_flash_sectors[] = {
+const uint32_t stm32_flash_sectors[] = {
     0x08000000,     /* 16kB */
     0x08004000,     /* 16kB */
     0x08008000,     /* 16kB */
@@ -60,18 +59,9 @@ const uint32_t stm32f4_flash_sectors[] = {
     0x08180000,     /* End of flash */
 };
 
-#define NAREAS (sizeof(stm32f4_flash_sectors) / sizeof(stm32f4_flash_sectors[0]))
-
-extern const struct hal_flash_funcs stm32f4_flash_funcs;
-
-const struct hal_flash stm32f4_flash_dev = {
-    .hf_itf = &stm32f4_flash_funcs,
-    .hf_base_addr = 0x08000000,
-    .hf_size = 1536 * 1024,
-    .hf_sector_cnt = NAREAS - 1,
-    .hf_align = 1,
-    .hf_erased_val = 0xff,
-};
+#define SZ (sizeof(stm32_flash_sectors) / sizeof(stm32_flash_sectors[0]))
+_Static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) == SZ,
+        "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
 #if MYNEWT_VAL(UART_0)
 static struct uart_dev hal_uart0;
@@ -96,11 +86,11 @@ static struct stm32_hal_i2c_cfg i2c_cfg0 = {
     .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 = MCU_GPIO_PORTB(9),       /* PB9 */
+    .hic_pin_scl = MCU_GPIO_PORTB(8),       /* PB8 */
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
-    .hic_speed = 100000				/* 100kHz */
+    .hic_speed = 100000,                    /* 100kHz */
 };
 #endif
 
@@ -138,6 +128,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     }
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -147,7 +138,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return &stm32f4_flash_dev;
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/nucleo-f413zh/syscfg.yml b/hw/bsp/nucleo-f413zh/syscfg.yml
index 7d9521f7ae..33d0d0c57c 100644
--- a/hw/bsp/nucleo-f413zh/syscfg.yml
+++ b/hw/bsp/nucleo-f413zh/syscfg.yml
@@ -18,6 +18,14 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 1536
+
+    STM32_FLASH_NUM_AREAS:
+        description: 'Amount of flash sectors for a non-linear STM32 MCU.'
+        value: 17
+
     UART_0:
         description: 'UART 0'
         value:  1
diff --git a/hw/bsp/nucleo-f746zg/src/hal_bsp.c b/hw/bsp/nucleo-f746zg/src/hal_bsp.c
index 5225006e23..5ec5c87e54 100644
--- a/hw/bsp/nucleo-f746zg/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f746zg/src/hal_bsp.c
@@ -80,8 +80,23 @@ static struct stm32_pwm_conf  stm32_pwm_config[PWM_CNT] = {
 #endif
 };
 
+#endif /* PWM_CNT */
+
+const uint32_t stm32_flash_sectors[] = {
+    0x08000000,     /* 32kB  */
+    0x08008000,     /* 32kB  */
+    0x08010000,     /* 32kB  */
+    0x08018000,     /* 32kB  */
+    0x08020000,     /* 128kB */
+    0x08040000,     /* 256kB */
+    0x08080000,     /* 256kB */
+    0x080c0000,     /* 256kB */
+    0x08100000,     /* End of flash */
+};
 
-#endif
+#define SZ (sizeof(stm32_flash_sectors) / sizeof(stm32_flash_sectors[0]))
+_Static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) == SZ,
+        "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
 #if MYNEWT_VAL(TRNG)
 static struct trng_dev os_bsp_trng;
@@ -185,6 +200,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     },
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -194,7 +210,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return &stm32f7_flash_dev;
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/nucleo-f746zg/syscfg.yml b/hw/bsp/nucleo-f746zg/syscfg.yml
index 5fe108d830..292bdb9a19 100644
--- a/hw/bsp/nucleo-f746zg/syscfg.yml
+++ b/hw/bsp/nucleo-f746zg/syscfg.yml
@@ -18,6 +18,14 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 1024
+
+    STM32_FLASH_NUM_AREAS:
+        description: 'Amount of flash sectors for a non-linear STM32 MCU.'
+        value: 9
+
     UART_0:
         description: 'Uart 0'
         value:  1
diff --git a/hw/bsp/nucleo-f767zi/src/hal_bsp.c b/hw/bsp/nucleo-f767zi/src/hal_bsp.c
index d202630dd4..56fbf0a33e 100644
--- a/hw/bsp/nucleo-f767zi/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f767zi/src/hal_bsp.c
@@ -80,8 +80,28 @@ static struct stm32_pwm_conf  stm32_pwm_config[PWM_CNT] = {
 #endif
 };
 
+#endif /* PWM_CNT */
+
+/* FIXME: this works but shouldn't it be dual bank? */
+const uint32_t stm32_flash_sectors[] = {
+    0x08000000,     /* 32kB  */
+    0x08008000,     /* 32kB  */
+    0x08010000,     /* 32kB  */
+    0x08018000,     /* 32kB  */
+    0x08020000,     /* 128kB */
+    0x08040000,     /* 256kB */
+    0x08080000,     /* 256kB */
+    0x080c0000,     /* 256kB */
+    0x08100000,     /* 256kB */
+    0x08140000,     /* 256kB */
+    0x08180000,     /* 256kB */
+    0x081c0000,     /* 256kB */
+    0x08200000,     /* End of flash */
+};
 
-#endif
+#define SZ (sizeof(stm32_flash_sectors) / sizeof(stm32_flash_sectors[0]))
+_Static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) == SZ,
+        "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
 #if MYNEWT_VAL(TRNG)
 static struct trng_dev os_bsp_trng;
@@ -185,6 +205,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     },
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -194,7 +215,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return &stm32f7_flash_dev;
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/nucleo-f767zi/syscfg.yml b/hw/bsp/nucleo-f767zi/syscfg.yml
index 5fe108d830..f57ceb2436 100644
--- a/hw/bsp/nucleo-f767zi/syscfg.yml
+++ b/hw/bsp/nucleo-f767zi/syscfg.yml
@@ -18,6 +18,14 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 2048
+
+    STM32_FLASH_NUM_AREAS:
+        description: 'Amount of flash sectors for a non-linear STM32 MCU.'
+        value: 13
+
     UART_0:
         description: 'Uart 0'
         value:  1
diff --git a/hw/bsp/nucleo-l476rg/src/hal_bsp.c b/hw/bsp/nucleo-l476rg/src/hal_bsp.c
index c90aed1481..dcb45b0b97 100644
--- a/hw/bsp/nucleo-l476rg/src/hal_bsp.c
+++ b/hw/bsp/nucleo-l476rg/src/hal_bsp.c
@@ -100,6 +100,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     },
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -109,7 +110,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return &stm32l4_flash_dev;
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/nucleo-l476rg/syscfg.yml b/hw/bsp/nucleo-l476rg/syscfg.yml
index 5fe0adedc1..747555786c 100644
--- a/hw/bsp/nucleo-l476rg/syscfg.yml
+++ b/hw/bsp/nucleo-l476rg/syscfg.yml
@@ -18,6 +18,10 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 1024
+
     UART_0:
         description: 'Whether to enable UART0'
         value:  1
diff --git a/hw/bsp/olimex-p103/src/hal_bsp.c b/hw/bsp/olimex-p103/src/hal_bsp.c
index e25affefda..1a0912feaa 100644
--- a/hw/bsp/olimex-p103/src/hal_bsp.c
+++ b/hw/bsp/olimex-p103/src/hal_bsp.c
@@ -109,6 +109,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     },
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -118,7 +119,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return &stm32f1_flash_dev;
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/olimex-p103/syscfg.yml b/hw/bsp/olimex-p103/syscfg.yml
index 153623531e..15c4ba298c 100644
--- a/hw/bsp/olimex-p103/syscfg.yml
+++ b/hw/bsp/olimex-p103/syscfg.yml
@@ -18,6 +18,10 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 128
+
     UART_0:
         description: 'UART 0'
         value:  1
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 818e5c4619..a05b1699cf 100644
--- a/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c
+++ b/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c
@@ -40,7 +40,6 @@
 #include "hal/hal_timer.h"
 #include "hal/hal_bsp.h"
 #include "hal/hal_gpio.h"
-#include "hal/hal_flash_int.h"
 #if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE)
 #include "hal/hal_spi.h"
 #endif
@@ -52,7 +51,7 @@
 #include "mcu/stm32f4_bsp.h"
 #include "mcu/stm32f4xx_mynewt_hal.h"
 
-const uint32_t stm32f4_flash_sectors[] = {
+const uint32_t stm32_flash_sectors[] = {
     0x08000000,     /* 16kB */
     0x08004000,     /* 16kB */
     0x08008000,     /* 16kB */
@@ -68,18 +67,9 @@ const uint32_t stm32f4_flash_sectors[] = {
     0x08100000,     /* End of flash */
 };
 
-#define NAREAS (sizeof(stm32f4_flash_sectors) / sizeof(stm32f4_flash_sectors[0]))
-
-extern const struct hal_flash_funcs stm32f4_flash_funcs;
-
-const struct hal_flash stm32f4_flash_dev = {
-    .hf_itf = &stm32f4_flash_funcs,
-    .hf_base_addr = 0x08000000,
-    .hf_size = 1024 * 1024,
-    .hf_sector_cnt = NAREAS - 1,
-    .hf_align = 1,
-    .hf_erased_val = 0xff,
-};
+#define SZ (sizeof(stm32_flash_sectors) / sizeof(stm32_flash_sectors[0]))
+_Static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) == SZ,
+        "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
 #if MYNEWT_VAL(TRNG)
 static struct trng_dev os_bsp_trng;
@@ -366,6 +356,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     }
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -375,7 +366,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return &stm32f4_flash_dev;
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml b/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml
index d9adcd7272..0bb96c9031 100644
--- a/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml
+++ b/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml
@@ -17,6 +17,14 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 1024
+
+    STM32_FLASH_NUM_AREAS:
+        description: 'Amount of flash sectors for a non-linear STM32 MCU.'
+        value: 13
+
     ADC_1:
         description: "ADC_1"
         value:  0
@@ -26,6 +34,7 @@ syscfg.defs:
     ADC_3:
         description: "ADC_3"
         value:  0
+
     UART_0:
         description: 'Whether to enable UART0'
         value:  1
diff --git a/hw/bsp/stm32f3discovery/src/hal_bsp.c b/hw/bsp/stm32f3discovery/src/hal_bsp.c
index 21815be2d9..c1a935b78c 100644
--- a/hw/bsp/stm32f3discovery/src/hal_bsp.c
+++ b/hw/bsp/stm32f3discovery/src/hal_bsp.c
@@ -119,6 +119,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     }
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -128,7 +129,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return stm32f3_flash_dev();
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/stm32f3discovery/syscfg.yml b/hw/bsp/stm32f3discovery/syscfg.yml
index dc199f8d3e..7d2bfca2b5 100644
--- a/hw/bsp/stm32f3discovery/syscfg.yml
+++ b/hw/bsp/stm32f3discovery/syscfg.yml
@@ -18,6 +18,10 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 1024
+
     UART_0:
         description: 'Whether to enable UART0'
         value:  1
@@ -29,11 +33,9 @@ syscfg.defs:
     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
diff --git a/hw/bsp/stm32f429discovery/src/hal_bsp.c b/hw/bsp/stm32f429discovery/src/hal_bsp.c
index c5a4a3c25d..f210f3fb5c 100644
--- a/hw/bsp/stm32f429discovery/src/hal_bsp.c
+++ b/hw/bsp/stm32f429discovery/src/hal_bsp.c
@@ -32,14 +32,12 @@
 
 #include <hal/hal_bsp.h>
 #include <hal/hal_gpio.h>
-#include <hal/hal_flash.h>
-#include <hal/hal_flash_int.h>
 #include <hal/hal_timer.h>
 #include <hal/hal_system.h>
 
 #include <mcu/stm32f4_bsp.h>
 
-const uint32_t stm32f4_flash_sectors[] = {
+const uint32_t stm32_flash_sectors[] = {
     /* Bank 1 */
     0x08000000,     /* 16kB */
     0x08004000,     /* 16kB */
@@ -69,18 +67,9 @@ const uint32_t stm32f4_flash_sectors[] = {
     0x08200000,     /* End of flash */
 };
 
-#define NAREAS (sizeof(stm32f4_flash_sectors) / sizeof(stm32f4_flash_sectors[0]))
-
-extern const struct hal_flash_funcs stm32f4_flash_funcs;
-
-const struct hal_flash stm32f4_flash_dev = {
-    .hf_itf = &stm32f4_flash_funcs,
-    .hf_base_addr = 0x08000000,
-    .hf_size = 2048 * 1024,
-    .hf_sector_cnt = NAREAS - 1,
-    .hf_align = 1,
-    .hf_erased_val = 0xff,
-};
+#define SZ (sizeof(stm32_flash_sectors) / sizeof(stm32_flash_sectors[0]))
+_Static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) == SZ,
+        "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
 #if MYNEWT_VAL(UART_0)
 static struct uart_dev hal_uart0;
@@ -112,6 +101,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     }
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -121,7 +111,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return &stm32f4_flash_dev;
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/stm32f429discovery/syscfg.yml b/hw/bsp/stm32f429discovery/syscfg.yml
index d2eecb330f..3d9f14144d 100644
--- a/hw/bsp/stm32f429discovery/syscfg.yml
+++ b/hw/bsp/stm32f429discovery/syscfg.yml
@@ -18,9 +18,18 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 2048
+
+    STM32_FLASH_NUM_AREAS:
+        description: 'Amount of flash sectors for a non-linear STM32 MCU.'
+        value: 25
+
     UART_0:
         description: 'UART 0'
         value: 1
+
     TIMER_0:
         description: 'Timer 0'
         value: 1
diff --git a/hw/bsp/stm32f4discovery/src/hal_bsp.c b/hw/bsp/stm32f4discovery/src/hal_bsp.c
index 4f9d35da23..62a4f88e7f 100644
--- a/hw/bsp/stm32f4discovery/src/hal_bsp.c
+++ b/hw/bsp/stm32f4discovery/src/hal_bsp.c
@@ -27,7 +27,6 @@
 
 #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)
@@ -41,7 +40,7 @@
 
 #include "bsp/bsp.h"
 
-const uint32_t stm32f4_flash_sectors[] = {
+const uint32_t stm32_flash_sectors[] = {
     0x08000000,     /* 16kB */
     0x08004000,     /* 16kB */
     0x08008000,     /* 16kB */
@@ -57,18 +56,9 @@ const uint32_t stm32f4_flash_sectors[] = {
     0x08100000,     /* End of flash */
 };
 
-#define NAREAS (sizeof(stm32f4_flash_sectors) / sizeof(stm32f4_flash_sectors[0]))
-
-extern const struct hal_flash_funcs stm32f4_flash_funcs;
-
-const struct hal_flash stm32f4_flash_dev = {
-    .hf_itf = &stm32f4_flash_funcs,
-    .hf_base_addr = 0x08000000,
-    .hf_size = 1024 * 1024,
-    .hf_sector_cnt = NAREAS - 1,
-    .hf_align = 1,
-    .hf_erased_val = 0xff,
-};
+#define SZ (sizeof(stm32_flash_sectors) / sizeof(stm32_flash_sectors[0]))
+_Static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) == SZ,
+        "STM32_FLASH_NUM_AREAS does not match flash sectors");
 
 #if MYNEWT_VAL(UART_0)
 static struct uart_dev hal_uart0;
@@ -93,11 +83,11 @@ static struct stm32_hal_i2c_cfg i2c_cfg0 = {
     .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 = MCU_GPIO_PORTB(9),       /* PB9 */
+    .hic_pin_scl = MCU_GPIO_PORTB(8),       /* PB8 */
     .hic_pin_af = GPIO_AF4_I2C1,
     .hic_10bit = 0,
-    .hic_speed = 100000				/* 100kHz */
+    .hic_speed = 100000,                    /* 100kHz */
 };
 #endif
 
@@ -122,6 +112,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     }
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -131,7 +122,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return &stm32f4_flash_dev;
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/stm32f4discovery/syscfg.yml b/hw/bsp/stm32f4discovery/syscfg.yml
index e6e6299fa0..b92ec7a7a0 100644
--- a/hw/bsp/stm32f4discovery/syscfg.yml
+++ b/hw/bsp/stm32f4discovery/syscfg.yml
@@ -18,9 +18,18 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 1024
+
+    STM32_FLASH_NUM_AREAS:
+        description: 'Amount of flash sectors for a non-linear STM32 MCU.'
+        value: 13
+
     UART_0:
         description: 'UART 0'
         value:  1
+
     TIMER_0:
         description: 'Timer 0'
         value:  0
diff --git a/hw/bsp/stm32f7discovery/include/bsp/stm32f7xx_hal_conf.h b/hw/bsp/stm32f7discovery/include/bsp/stm32f7xx_hal_conf.h
index 425b819e30..38099fa687 100644
--- a/hw/bsp/stm32f7discovery/include/bsp/stm32f7xx_hal_conf.h
+++ b/hw/bsp/stm32f7discovery/include/bsp/stm32f7xx_hal_conf.h
@@ -54,8 +54,8 @@
 #define HAL_ADC_MODULE_ENABLED
 #define HAL_CAN_MODULE_ENABLED
 #define HAL_CEC_MODULE_ENABLED
-#define HAL_CRC_MODULE_ENABLED
-/*#define HAL_CRYP_MODULE_ENABLED*/
+/* #define HAL_CRC_MODULE_ENABLED */
+/* #define HAL_CRYP_MODULE_ENABLED */
 #define HAL_DAC_MODULE_ENABLED
 #define HAL_DCMI_MODULE_ENABLED
 #define HAL_DMA_MODULE_ENABLED
@@ -66,7 +66,7 @@
 #define HAL_NOR_MODULE_ENABLED
 #define HAL_SRAM_MODULE_ENABLED
 #define HAL_SDRAM_MODULE_ENABLED
-/*#define HAL_HASH_MODULE_ENABLED*/
+/* #define HAL_HASH_MODULE_ENABLED */
 #define HAL_GPIO_MODULE_ENABLED
 #define HAL_I2C_MODULE_ENABLED
 #define HAL_I2S_MODULE_ENABLED
@@ -89,8 +89,8 @@
 #define HAL_SMARTCARD_MODULE_ENABLED
 #define HAL_WWDG_MODULE_ENABLED
 #define HAL_CORTEX_MODULE_ENABLED
-#define HAL_PCD_MODULE_ENABLED
-#define HAL_HCD_MODULE_ENABLED
+/* #define HAL_PCD_MODULE_ENABLED */
+/* #define HAL_HCD_MODULE_ENABLED */
 /* #define HAL_DFSDM_MODULE_ENABLED */
 /* #define HAL_DSI_MODULE_ENABLED */
 /* #define HAL_JPEG_MODULE_ENABLED */
diff --git a/hw/bsp/stm32f7discovery/src/hal_bsp.c b/hw/bsp/stm32f7discovery/src/hal_bsp.c
index d521574532..f5e75646e4 100644
--- a/hw/bsp/stm32f7discovery/src/hal_bsp.c
+++ b/hw/bsp/stm32f7discovery/src/hal_bsp.c
@@ -69,8 +69,23 @@ static struct stm32_pwm_conf  stm32_pwm_config[PWM_CNT] = {
 #endif
 };
 
+#endif /* PWM_CNT */
+
+const uint32_t stm32_flash_sectors[] = {
+    0x08000000,     /* 32kB  */
+    0x08008000,     /* 32kB  */
+    0x08010000,     /* 32kB  */
+    0x08018000,     /* 32kB  */
+    0x08020000,     /* 128kB */
+    0x08040000,     /* 256kB */
+    0x08080000,     /* 256kB */
+    0x080c0000,     /* 256kB */
+    0x08100000,     /* End of flash */
+};
+
+const uint32_t STM32_FLASH_NUM_AREAS = (sizeof(stm32_flash_sectors) /
+                                        sizeof(stm32_flash_sectors[0]) - 1);
 
-#endif
 
 #if MYNEWT_VAL(UART_0)
 static struct uart_dev hal_uart0;
@@ -136,6 +151,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     },
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -145,7 +161,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return &stm32f7_flash_dev;
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/stm32f7discovery/syscfg.yml b/hw/bsp/stm32f7discovery/syscfg.yml
index 5fe108d830..2a757ee14e 100644
--- a/hw/bsp/stm32f7discovery/syscfg.yml
+++ b/hw/bsp/stm32f7discovery/syscfg.yml
@@ -18,6 +18,14 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 1024
+
+    STM32_FLASH_NUM_AREAS:
+        description: 'Amount of flash sectors for a non-linear STM32 MCU.'
+        value: 13
+
     UART_0:
         description: 'Uart 0'
         value:  1
diff --git a/hw/bsp/stm32l152discovery/src/hal_bsp.c b/hw/bsp/stm32l152discovery/src/hal_bsp.c
index c5521b8888..78f832f8a4 100644
--- a/hw/bsp/stm32l152discovery/src/hal_bsp.c
+++ b/hw/bsp/stm32l152discovery/src/hal_bsp.c
@@ -98,6 +98,7 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     },
 };
 
+extern const struct hal_flash stm32_flash_dev;
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
@@ -107,7 +108,7 @@ hal_bsp_flash_dev(uint8_t id)
     if (id != 0) {
         return NULL;
     }
-    return &stm32l1_flash_dev;
+    return &stm32_flash_dev;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/stm32l152discovery/syscfg.yml b/hw/bsp/stm32l152discovery/syscfg.yml
index 153623531e..7e8fdb3e26 100644
--- a/hw/bsp/stm32l152discovery/syscfg.yml
+++ b/hw/bsp/stm32l152discovery/syscfg.yml
@@ -18,6 +18,10 @@
 #
 
 syscfg.defs:
+    STM32_FLASH_SIZE_KB:
+        description: 'Total flash size in KB.'
+        value: 256
+
     UART_0:
         description: 'UART 0'
         value:  1
diff --git a/hw/mcu/stm/stm32_common/src/hal_flash.c b/hw/mcu/stm/stm32_common/src/hal_flash.c
new file mode 100644
index 0000000000..f2948b44d1
--- /dev/null
+++ b/hw/mcu/stm/stm32_common/src/hal_flash.c
@@ -0,0 +1,249 @@
+/*
+ * 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 <string.h>
+#include <os/mynewt.h>
+#include <mcu/stm32_hal.h>
+#include "hal/hal_flash_int.h"
+#include "hal/hal_watchdog.h"
+
+#define FLASH_IS_LINEAR    MYNEWT_VAL(STM32_FLASH_IS_LINEAR)
+#define FLASH_WRITE_SIZE   MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE)
+#define FLASH_ERASED_VAL   MYNEWT_VAL(MCU_FLASH_ERASED_VAL)
+
+#define _FLASH_SIZE         (MYNEWT_VAL(STM32_FLASH_SIZE_KB) * 1024)
+
+#if FLASH_IS_LINEAR
+#define _FLASH_SECTOR_SIZE  MYNEWT_VAL(STM32_FLASH_SECTOR_SIZE)
+#endif
+
+static int stm32_flash_read(const struct hal_flash *dev, uint32_t address,
+        void *dst, uint32_t num_bytes);
+static int stm32_flash_write(const struct hal_flash *dev, uint32_t address,
+        const void *src, uint32_t num_bytes);
+static int stm32_flash_erase_sector(const struct hal_flash *dev,
+        uint32_t sector_address);
+static int stm32_flash_sector_info(const struct hal_flash *dev, int idx,
+        uint32_t *address, uint32_t *sz);
+static int stm32_flash_init(const struct hal_flash *dev);
+
+const struct hal_flash_funcs stm32_flash_funcs = {
+    .hff_read = stm32_flash_read,
+    .hff_write = stm32_flash_write,
+    .hff_erase_sector = stm32_flash_erase_sector,
+    .hff_sector_info = stm32_flash_sector_info,
+    .hff_init = stm32_flash_init
+};
+
+#if !FLASH_IS_LINEAR
+extern const uint32_t stm32_flash_sectors[];
+#define FLASH_NUM_AREAS (MYNEWT_VAL(STM32_FLASH_NUM_AREAS) - 1)
+#else
+#define FLASH_NUM_AREAS (_FLASH_SIZE / _FLASH_SECTOR_SIZE)
+#endif
+
+const struct hal_flash stm32_flash_dev = {
+    .hf_itf = &stm32_flash_funcs,
+    .hf_base_addr = FLASH_BASE,
+    .hf_size = _FLASH_SIZE,
+    .hf_sector_cnt = FLASH_NUM_AREAS,
+    .hf_align = FLASH_WRITE_SIZE,
+    .hf_erased_val = FLASH_ERASED_VAL,
+};
+
+static int
+stm32_flash_read(const struct hal_flash *dev, uint32_t address, void *dst,
+        uint32_t num_bytes)
+{
+    memcpy(dst, (void *)address, num_bytes);
+    return 0;
+}
+
+#if FLASH_IS_LINEAR
+static int
+stm32_flash_write_linear(const struct hal_flash *dev, uint32_t address,
+        const void *src, uint32_t num_bytes)
+{
+    uint64_t val;
+    uint32_t i;
+    int rc;
+    uint8_t align;
+    uint32_t num_words;
+
+    align = dev->hf_align;
+
+#if MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) == 1
+    num_words = num_bytes;
+#elif MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) == 2
+    num_words = ((num_bytes - 1) >> 1) + 1;
+#elif MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) == 4
+    num_words = ((num_bytes - 1) >> 2) + 1;
+#elif MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) == 8
+    num_words = ((num_bytes - 1) >> 3) + 1;
+#else
+    #error "Unsupported MCU_FLASH_MIN_WRITE_SIZE"
+#endif
+
+    /* FIXME: L4 didn't have error clearing here, should check if other families
+     *        need this (or can be removed)! */
+    STM32_HAL_FLASH_CLEAR_ERRORS();
+
+    for (i = 0; i < num_words; i++) {
+        if (num_bytes < align) {
+            memcpy(&val, &((uint8_t *)src)[i * align], num_bytes);
+            memset((uint32_t *)&val + num_bytes, dev->hf_erased_val, align - num_bytes);
+        } else {
+            memcpy(&val, &((uint8_t *)src)[i * align], align);
+        }
+
+        /* FIXME: L1 was previously unlocking flash before erasing/programming,
+         * and locking again afterwards. Maybe all MCUs should do the same?
+         */
+        rc = HAL_FLASH_Program(FLASH_PROGRAM_TYPE, address, val);
+        if (rc != HAL_OK) {
+            return rc;
+        }
+
+        address += align;
+
+        /* underflowing is ok here... */
+        num_bytes -= align;
+
+        /*
+         * Long writes take excessive time, and stall the idle thread,
+         * so tickling the watchdog here to avoid reset...
+         */
+        if (!(i % 32)) {
+            hal_watchdog_tickle();
+        }
+    }
+
+    return 0;
+}
+#endif
+
+#if !FLASH_IS_LINEAR
+static int
+stm32_flash_write_non_linear(const struct hal_flash *dev, uint32_t address,
+        const void *src, uint32_t num_bytes)
+{
+    const uint8_t *sptr;
+    uint32_t i;
+    int rc;
+
+    sptr = src;
+    /*
+     * Clear status of previous operation.
+     */
+    STM32_HAL_FLASH_CLEAR_ERRORS();
+
+    for (i = 0; i < num_bytes; i++) {
+        rc = HAL_FLASH_Program(FLASH_PROGRAM_TYPE, address, sptr[i]);
+        if (rc != 0) {
+            return rc;
+        }
+
+        address++;
+    }
+
+    return 0;
+}
+#endif
+
+static int
+stm32_flash_write(const struct hal_flash *dev, uint32_t address,
+        const void *src, uint32_t num_bytes)
+{
+    if (!num_bytes) {
+        return -1;
+    }
+
+#if FLASH_IS_LINEAR
+    return stm32_flash_write_linear(dev, address, src, num_bytes);
+#else
+    return stm32_flash_write_non_linear(dev, address, src, num_bytes);
+#endif
+}
+
+#if !FLASH_IS_LINEAR
+static int
+stm32_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
+{
+    FLASH_EraseInitTypeDef eraseinit;
+    HAL_StatusTypeDef err;
+    uint32_t SectorError;
+    int i;
+
+    for (i = 0; i < dev->hf_sector_cnt; i++) {
+        if (stm32_flash_sectors[i] == sector_address) {
+            eraseinit.TypeErase = FLASH_TYPEERASE_SECTORS;
+#ifdef FLASH_OPTCR_nDBANK
+            eraseinit.Banks = FLASH_BANK_1; /* Only used for mass erase */
+#endif
+            eraseinit.Sector = i;
+            eraseinit.NbSectors = 1;
+            eraseinit.VoltageRange = FLASH_VOLTAGE_RANGE_1;
+
+            err = HAL_FLASHEx_Erase(&eraseinit, &SectorError);
+            if (err) {
+                return -1;
+            }
+            return 0;
+        }
+    }
+
+    return -1;
+}
+
+#else /* FLASH_IS_LINEAR */
+
+int stm32_mcu_flash_erase_sector(const struct hal_flash *, uint32_t);
+
+static int
+stm32_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
+{
+    return stm32_mcu_flash_erase_sector(dev, sector_address);
+}
+
+#endif
+
+static int
+stm32_flash_sector_info(const struct hal_flash *dev, int idx,
+        uint32_t *address, uint32_t *sz)
+{
+    (void)dev;
+
+#if FLASH_IS_LINEAR
+    *address = dev->hf_base_addr + _FLASH_SECTOR_SIZE * idx;
+    *sz = _FLASH_SECTOR_SIZE;
+#else
+    *address = stm32_flash_sectors[idx];
+    *sz = stm32_flash_sectors[idx + 1] - stm32_flash_sectors[idx];
+#endif
+
+    return 0;
+}
+
+static int
+stm32_flash_init(const struct hal_flash *dev)
+{
+    (void)dev;
+    STM32_HAL_FLASH_INIT();
+    return 0;
+}
diff --git a/hw/mcu/stm/stm32f0xx/include/mcu/stm32_hal.h b/hw/mcu/stm/stm32f0xx/include/mcu/stm32_hal.h
index a639869675..fe81c701c1 100644
--- a/hw/mcu/stm/stm32f0xx/include/mcu/stm32_hal.h
+++ b/hw/mcu/stm/stm32f0xx/include/mcu/stm32_hal.h
@@ -74,6 +74,22 @@ struct stm32_hal_spi_cfg {
 
 #define STM32_HAL_TIMER_MAX     (3)
 
+/* hal_flash */
+#include "stm32f0xx_hal_def.h"
+#include "stm32f0xx_hal_flash.h"
+#include "stm32f0xx_hal_flash_ex.h"
+#define STM32_HAL_FLASH_INIT()        \
+    do {                              \
+        HAL_FLASH_Unlock();           \
+    } while (0)
+#define FLASH_PROGRAM_TYPE FLASH_TYPEPROGRAM_HALFWORD
+#define STM32_HAL_FLASH_CLEAR_ERRORS()            \
+    do {                                          \
+        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP |   \
+                FLASH_FLAG_WRPERR |               \
+                FLASH_FLAG_PGERR);                \
+    } while (0)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/mcu/stm/stm32f0xx/src/hal_flash.c b/hw/mcu/stm/stm32f0xx/src/hal_flash.c
index 8d4b6c42cf..e8c9e82894 100644
--- a/hw/mcu/stm/stm32f0xx/src/hal_flash.c
+++ b/hw/mcu/stm/stm32f0xx/src/hal_flash.c
@@ -18,80 +18,12 @@
  */
 
 #include <string.h>
-#include "stm32f0xx_hal_def.h"
-#include "stm32f0xx_hal_flash.h"
-#include "stm32f0xx_hal_flash_ex.h"
+#include <syscfg/syscfg.h>
+#include <mcu/stm32_hal.h>
 #include "hal/hal_flash_int.h"
 
-/*
- * Flash is organized in FLASH_PAGE_SIZE blocks, which for the
- * STM32F0 family is 2KB.
- * */
-#define HAL_FLASH_SECTOR_SIZE   FLASH_PAGE_SIZE
-#define HAL_FLASH_SIZE          (64 * 1024)
-
-
-static int stm32f0_flash_read(const struct hal_flash *dev, uint32_t address, 
-                              void *dst, uint32_t num_bytes);
-static int stm32f0_flash_write(const struct hal_flash *dev, uint32_t address,
-                               const void *src, uint32_t num_bytes);
-static int stm32f0_flash_erase_sector(const struct hal_flash *dev,
-                                      uint32_t sector_address);
-static int stm32f0_flash_sector_info(const struct hal_flash *dev, int idx,
-                                     uint32_t *address, uint32_t *sz);
-static int stm32f0_flash_init(const struct hal_flash *dev);
-
-static const struct hal_flash_funcs stm32f0_flash_funcs = {
-    .hff_read = stm32f0_flash_read,
-    .hff_write = stm32f0_flash_write,
-    .hff_erase_sector = stm32f0_flash_erase_sector,
-    .hff_sector_info = stm32f0_flash_sector_info,
-    .hff_init = stm32f0_flash_init
-};
-
-const struct hal_flash stm32f0_flash_dev = {
-    .hf_itf = &stm32f0_flash_funcs,
-    .hf_base_addr = FLASH_BASE,
-    .hf_size = HAL_FLASH_SIZE,
-    .hf_sector_cnt = HAL_FLASH_SIZE / HAL_FLASH_SECTOR_SIZE,
-    .hf_align = 2,
-    .hf_erased_val = 0xff,
-};
-
-
-static int
-stm32f0_flash_read(const struct hal_flash *dev, uint32_t address, void *dst,
-                   uint32_t num_bytes)
-{
-    memcpy(dst, (void *)address, num_bytes);
-    return 0;
-}
-
-static int
-stm32f0_flash_write(const struct hal_flash *dev, uint32_t address,
-                    const void *src, uint32_t num_bytes)
-{
-    const uint16_t *sptr;
-    uint32_t i, half_words;
-    int rc;
-
-    sptr = src;
-    half_words = (num_bytes + 1) / 2;
-
-    HAL_FLASH_Unlock();
-    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
-
-    for (i = 0, rc = HAL_OK; i < half_words && rc == HAL_OK; ++i) {
-        rc = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address, sptr[i]);
-        address += 2;
-    }
-    HAL_FLASH_Lock();
-
-    return rc == HAL_OK ? 0 : rc;
-}
-
-static int
-stm32f0_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
+int
+stm32_mcu_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
 {
     FLASH_EraseInitTypeDef erase;
     int rc = -1;
@@ -101,27 +33,9 @@ stm32f0_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
     erase.PageAddress = sector_address;
     erase.NbPages = 1;
 
-    HAL_FLASH_Unlock();
     if (HAL_OK == HAL_FLASHEx_Erase(&erase, &errorPage)) {
       rc = 0;
     }
-    HAL_FLASH_Lock();
 
     return rc;
 }
-
-static int
-stm32f0_flash_sector_info(const struct hal_flash *dev, int idx,
-                          uint32_t *address, uint32_t *sz)
-{
-    *address = FLASH_BASE + HAL_FLASH_SECTOR_SIZE * idx;
-    *sz = HAL_FLASH_SECTOR_SIZE;
-    return 0;
-}
-
-static int
-stm32f0_flash_init(const struct hal_flash *dev)
-{
-    HAL_FLASH_Lock();
-    return 0;
-}
\ No newline at end of file
diff --git a/hw/mcu/stm/stm32f0xx/syscfg.yml b/hw/mcu/stm/stm32f0xx/syscfg.yml
index ae580499c2..1e0f87e9fc 100644
--- a/hw/mcu/stm/stm32f0xx/syscfg.yml
+++ b/hw/mcu/stm/stm32f0xx/syscfg.yml
@@ -37,6 +37,18 @@ syscfg.defs:
         description: This MCU's UART uses ISR register (not SR) for status.
         value: 0
 
+    MCU_FLASH_ERASED_VAL:
+        description: Value read from erased flash.
+        value: 0xff
+
+    STM32_FLASH_IS_LINEAR:
+        description: This MCU's Flash has one single sector size.
+        value: 1
+
+    STM32_FLASH_SECTOR_SIZE:
+        description: This MCU's Flash sector size in bytes.
+        value: 2048
+
     MCU_SYSCLK_PLL_HSI:
         description: Configure PLL as sysclock driven by HSI.
         value: 0
diff --git a/hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h b/hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h
index dc99bb97fe..3af1e23957 100644
--- a/hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h
+++ b/hw/mcu/stm/stm32f1xx/include/mcu/stm32_hal.h
@@ -69,6 +69,23 @@ struct stm32_hal_spi_cfg {
 
 #define STM32_HAL_TIMER_MAX     (3)
 
+/* hal_flash */
+#include "stm32f1xx_hal_def.h"
+#include "stm32f1xx_hal_flash.h"
+#include "stm32f1xx_hal_flash_ex.h"
+#define STM32_HAL_FLASH_INIT()        \
+    do {                              \
+        HAL_FLASH_Unlock();           \
+    } while (0)
+#define FLASH_PROGRAM_TYPE FLASH_TYPEPROGRAM_HALFWORD
+#define STM32_HAL_FLASH_CLEAR_ERRORS()           \
+    do {                                         \
+        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP |  \
+                FLASH_FLAG_WRPERR |              \
+                FLASH_FLAG_PGERR |               \
+                FLASH_FLAG_BSY);                 \
+    } while (0)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/mcu/stm/stm32f1xx/src/hal_flash.c b/hw/mcu/stm/stm32f1xx/src/hal_flash.c
index 78a29ba652..64d607d9b5 100644
--- a/hw/mcu/stm/stm32f1xx/src/hal_flash.c
+++ b/hw/mcu/stm/stm32f1xx/src/hal_flash.c
@@ -18,79 +18,14 @@
  */
 
 #include <string.h>
-#include "stm32f1xx_hal_def.h"
-#include "stm32f1xx_hal_flash.h"
-#include "stm32f1xx_hal_flash_ex.h"
+#include <syscfg/syscfg.h>
+#include <mcu/stm32_hal.h>
 #include "hal/hal_flash_int.h"
 
-static int stm32f1_flash_read(const struct hal_flash *dev, uint32_t address,
-        void *dst, uint32_t num_bytes);
-static int stm32f1_flash_write(const struct hal_flash *dev, uint32_t address,
-        const void *src, uint32_t num_bytes);
-static int stm32f1_flash_erase_sector(const struct hal_flash *dev,
-        uint32_t sector_address);
-static int stm32f1_flash_sector_info(const struct hal_flash *dev, int idx,
-        uint32_t *address, uint32_t *sz);
-static int stm32f1_flash_init(const struct hal_flash *dev);
+#define _FLASH_SECTOR_SIZE MYNEWT_VAL(STM32_FLASH_SECTOR_SIZE)
 
-static const struct hal_flash_funcs stm32f1_flash_funcs = {
-    .hff_read = stm32f1_flash_read,
-    .hff_write = stm32f1_flash_write,
-    .hff_erase_sector = stm32f1_flash_erase_sector,
-    .hff_sector_info = stm32f1_flash_sector_info,
-    .hff_init = stm32f1_flash_init,
-};
-
-#define _FLASH_SIZE            (128 * 1024)
-#define _FLASH_SECTOR_SIZE     1024
-
-const struct hal_flash stm32f1_flash_dev = {
-    .hf_itf = &stm32f1_flash_funcs,
-    .hf_base_addr = 0x08000000,
-    .hf_size = _FLASH_SIZE,
-    .hf_sector_cnt = _FLASH_SIZE / _FLASH_SECTOR_SIZE,
-    .hf_align = 2,
-    .hf_erased_val = 0xff,
-};
-
-static int
-stm32f1_flash_read(const struct hal_flash *dev, uint32_t address, void *dst,
-        uint32_t num_bytes)
-{
-    memcpy(dst, (void *)address, num_bytes);
-    return 0;
-}
-
-static int
-stm32f1_flash_write(const struct hal_flash *dev, uint32_t address,
-        const void *src, uint32_t num_bytes)
-{
-    const uint16_t *sptr;
-    uint32_t i;
-    int rc;
-
-    /*
-     * Clear status of previous operation.
-     */
-    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP |
-                           FLASH_FLAG_WRPERR |
-                           FLASH_FLAG_PGERR |
-                           FLASH_FLAG_BSY);
-
-    num_bytes /= 2;
-    for (i = 0, sptr = src; i < num_bytes; i++) {
-        rc = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address, sptr[i]);
-        if (rc != 0) {
-            return rc;
-        }
-        address += 2;
-    }
-
-    return 0;
-}
-
-static int
-stm32f1_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
+int
+stm32_mcu_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
 {
     FLASH_EraseInitTypeDef eraseinit;
     uint32_t PageError;
@@ -109,19 +44,3 @@ stm32f1_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
 
     return -1;
 }
-
-static int
-stm32f1_flash_sector_info(const struct hal_flash *dev, int idx,
-        uint32_t *address, uint32_t *sz)
-{
-    *address = dev->hf_base_addr + _FLASH_SECTOR_SIZE * idx;
-    *sz = _FLASH_SECTOR_SIZE;
-    return 0;
-}
-
-static int
-stm32f1_flash_init(const struct hal_flash *dev)
-{
-    HAL_FLASH_Unlock();
-    return 0;
-}
diff --git a/hw/mcu/stm/stm32f1xx/syscfg.yml b/hw/mcu/stm/stm32f1xx/syscfg.yml
index a6becf1c34..cf211e04fc 100644
--- a/hw/mcu/stm/stm32f1xx/syscfg.yml
+++ b/hw/mcu/stm/stm32f1xx/syscfg.yml
@@ -21,7 +21,7 @@ syscfg.defs:
         description: >
             Specifies the required alignment for internal flash writes.
             Used internally by the newt tool.
-        value: 1
+        value: 2  # STM32F1 HW allows 1 but the HAL API only allows 2/4/8.
 
     MCU_STM32F1:
         description: MCUs are of STM32F1xx family
@@ -39,6 +39,18 @@ syscfg.defs:
         description: This MCU's UART uses SR register for status.
         value: 1
 
+    MCU_FLASH_ERASED_VAL:
+        description: Value read from erased flash.
+        value: 0xff
+
+    STM32_FLASH_IS_LINEAR:
+        description: This MCU's Flash has one single sector size.
+        value: 1
+
+    STM32_FLASH_SECTOR_SIZE:
+        description: This MCU's Flash sector size in bytes.
+        value: 1024
+
     I2C_0:
         description: 'I2C (TWI) interface 0'
         value:  0
diff --git a/hw/mcu/stm/stm32f3xx/include/mcu/stm32_hal.h b/hw/mcu/stm/stm32f3xx/include/mcu/stm32_hal.h
index 1eddd45ade..530e40d7bd 100644
--- a/hw/mcu/stm/stm32f3xx/include/mcu/stm32_hal.h
+++ b/hw/mcu/stm/stm32f3xx/include/mcu/stm32_hal.h
@@ -75,6 +75,23 @@ struct stm32_hal_spi_cfg {
 
 #define STM32_HAL_TIMER_MAX     (3)
 
+/* hal_flash */
+#include "stm32f3xx_hal_def.h"
+#include "stm32f3xx_hal_flash.h"
+#include "stm32f3xx_hal_flash_ex.h"
+#define STM32_HAL_FLASH_INIT()
+#define FLASH_PROGRAM_TYPE FLASH_TYPEPROGRAM_HALFWORD
+#define STM32_HAL_FLASH_CLEAR_ERRORS()            \
+    do {                                          \
+        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP |   \
+                FLASH_FLAG_WRPERR |               \
+                FLASH_FLAG_PGERR);                \
+    } while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/mcu/stm/stm32f3xx/src/hal_flash.c b/hw/mcu/stm/stm32f3xx/src/hal_flash.c
index 98d8fe8cec..9cb1813d77 100644
--- a/hw/mcu/stm/stm32f3xx/src/hal_flash.c
+++ b/hw/mcu/stm/stm32f3xx/src/hal_flash.c
@@ -18,72 +18,11 @@
  */
 
 #include <string.h>
-#include "stm32f3xx_hal_def.h"
-#include "stm32f3xx_hal_flash.h"
-#include "stm32f3xx_hal_flash_ex.h"
+#include <mcu/stm32_hal.h>
 #include "hal/hal_flash_int.h"
 
-/*
- * Flash is organized in FLASH_PAGE_SIZE blocks, which for the
- * STM32F3 family is 2KB.
- * */
-#define HAL_FLASH_SECTOR_SIZE   FLASH_PAGE_SIZE
-#define HAL_FLASH_SIZE          ((*((uint16_t*)FLASH_SIZE_DATA_REGISTER)) * 1024U)
-
-
-static int stm32f3_flash_read(const struct hal_flash *dev, uint32_t address,
-        void *dst, uint32_t num_bytes);
-static int stm32f3_flash_write(const struct hal_flash *dev, uint32_t address,
-        const void *src, uint32_t num_bytes);
-static int stm32f3_flash_erase_sector(const struct hal_flash *dev,
-        uint32_t sector_address);
-static int stm32f3_flash_sector_info(const struct hal_flash *dev, int idx,
-        uint32_t *address, uint32_t *sz);
-static int stm32f3_flash_init(const struct hal_flash *dev);
-
-static const struct hal_flash_funcs stm32f3_flash_funcs = {
-    .hff_read = stm32f3_flash_read,
-    .hff_write = stm32f3_flash_write,
-    .hff_erase_sector = stm32f3_flash_erase_sector,
-    .hff_sector_info = stm32f3_flash_sector_info,
-    .hff_init = stm32f3_flash_init
-};
-
-struct hal_flash stm32f3_flash_dev_;
-
-static int
-stm32f3_flash_read(const struct hal_flash *dev, uint32_t address, void *dst,
-        uint32_t num_bytes)
-{
-    memcpy(dst, (void *)address, num_bytes);
-    return 0;
-}
-
-static int
-stm32f3_flash_write(const struct hal_flash *dev, uint32_t address,
-        const void *src, uint32_t num_bytes)
-{
-    const uint16_t *sptr;
-    uint32_t i, half_words;
-    int rc;
-
-    sptr = src;
-    half_words = (num_bytes + 1) / 2;
-
-    HAL_FLASH_Unlock();
-    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
-
-    for (i = 0, rc = HAL_OK; i < half_words && rc == HAL_OK; ++i) {
-        rc = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address, sptr[i]);
-        address += 2;
-    }
-    HAL_FLASH_Lock();
-
-    return rc == HAL_OK ? 0 : rc;
-}
-
-static int
-stm32f3_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
+int
+stm32_mcu_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
 {
     FLASH_EraseInitTypeDef erase;
     int rc = -1;
@@ -101,33 +40,3 @@ stm32f3_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
 
     return rc;
 }
-
-static int
-stm32f3_flash_sector_info(const struct hal_flash *dev, int idx,
-        uint32_t *address, uint32_t *sz)
-{
-    *address = FLASH_BASE + HAL_FLASH_SECTOR_SIZE * idx;
-    *sz = HAL_FLASH_SECTOR_SIZE;
-    return 0;
-}
-
-static int
-stm32f3_flash_init(const struct hal_flash *dev)
-{
-    HAL_FLASH_Lock();
-    return 0;
-}
-
-struct hal_flash*
-stm32f3_flash_dev()
-{
-    if (0 == stm32f3_flash_dev_.hf_itf) {
-        stm32f3_flash_dev_.hf_itf = &stm32f3_flash_funcs;
-        stm32f3_flash_dev_.hf_base_addr = FLASH_BASE;
-        stm32f3_flash_dev_.hf_size = HAL_FLASH_SIZE;
-        stm32f3_flash_dev_.hf_sector_cnt = HAL_FLASH_SIZE / HAL_FLASH_SECTOR_SIZE;
-        stm32f3_flash_dev_.hf_align = 2;
-        stm32f3_flash_dev_.hf_erased_val = 0xff;
-    }
-    return &stm32f3_flash_dev_;
-}
diff --git a/hw/mcu/stm/stm32f3xx/syscfg.yml b/hw/mcu/stm/stm32f3xx/syscfg.yml
index 4c78f61dab..38a90debf4 100644
--- a/hw/mcu/stm/stm32f3xx/syscfg.yml
+++ b/hw/mcu/stm/stm32f3xx/syscfg.yml
@@ -39,6 +39,18 @@ syscfg.defs:
         description: This MCU's UART uses ISR register (not SR) for status.
         value: 0
 
+    MCU_FLASH_ERASED_VAL:
+        description: Value read from erased flash.
+        value: 0xff
+
+    STM32_FLASH_IS_LINEAR:
+        description: This MCU's Flash has one single sector size.
+        value: 1
+
+    STM32_FLASH_SECTOR_SIZE:
+        description: This MCU's Flash sector size in bytes.
+        value: 2048
+
     MCU_SYSCLK_PLL_HSI:
         description: Configure PLL as sysclock driven by HSI.
         value: 0
diff --git a/hw/mcu/stm/stm32f4xx/include/mcu/stm32_hal.h b/hw/mcu/stm/stm32f4xx/include/mcu/stm32_hal.h
index aec79d9d1d..2f93fd7063 100644
--- a/hw/mcu/stm/stm32f4xx/include/mcu/stm32_hal.h
+++ b/hw/mcu/stm/stm32f4xx/include/mcu/stm32_hal.h
@@ -76,6 +76,25 @@ struct stm32_hal_spi_cfg {
 /* hal_trng */
 #include "stm32f4xx_hal_rng.h"
 
+/* hal_flash */
+#include "stm32f4xx_hal_def.h"
+#include "stm32f4xx_hal_flash.h"
+#include "stm32f4xx_hal_flash_ex.h"
+#define STM32_HAL_FLASH_INIT()        \
+    do {                              \
+        HAL_FLASH_Unlock();           \
+    } while (0)
+#define FLASH_PROGRAM_TYPE FLASH_TYPEPROGRAM_BYTE
+#define STM32_HAL_FLASH_CLEAR_ERRORS()            \
+    do {                                          \
+        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP |   \
+                FLASH_FLAG_OPERR |                \
+                FLASH_FLAG_WRPERR |               \
+                FLASH_FLAG_PGAERR |               \
+                FLASH_FLAG_PGPERR |               \
+                FLASH_FLAG_PGSERR);               \
+    } while (0)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/mcu/stm/stm32f4xx/src/hal_flash.c b/hw/mcu/stm/stm32f4xx/src/hal_flash.c
deleted file mode 100644
index 9d944956f0..0000000000
--- a/hw/mcu/stm/stm32f4xx/src/hal_flash.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * 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 <string.h>
-#include "stm32f4xx_hal_def.h"
-#include "stm32f4xx_hal_flash.h"
-#include "stm32f4xx_hal_flash_ex.h"
-#include "hal/hal_flash_int.h"
-
-static int stm32f4_flash_read(const struct hal_flash *dev, uint32_t address,
-        void *dst, uint32_t num_bytes);
-static int stm32f4_flash_write(const struct hal_flash *dev, uint32_t address,
-        const void *src, uint32_t num_bytes);
-static int stm32f4_flash_erase_sector(const struct hal_flash *dev,
-        uint32_t sector_address);
-static int stm32f4_flash_sector_info(const struct hal_flash *dev, int idx,
-        uint32_t *address, uint32_t *sz);
-static int stm32f4_flash_init(const struct hal_flash *dev);
-
-const struct hal_flash_funcs stm32f4_flash_funcs = {
-    .hff_read = stm32f4_flash_read,
-    .hff_write = stm32f4_flash_write,
-    .hff_erase_sector = stm32f4_flash_erase_sector,
-    .hff_sector_info = stm32f4_flash_sector_info,
-    .hff_init = stm32f4_flash_init
-};
-
-extern const uint32_t stm32f4_flash_sectors[];
-extern const uint32_t STM32F4_FLASH_NUM_AREAS;
-
-static int
-stm32f4_flash_read(const struct hal_flash *dev, uint32_t address, void *dst,
-        uint32_t num_bytes)
-{
-    memcpy(dst, (void *)address, num_bytes);
-    return 0;
-}
-
-static int
-stm32f4_flash_write(const struct hal_flash *dev, uint32_t address,
-        const void *src, uint32_t num_bytes)
-{
-    const uint8_t *sptr;
-    uint32_t i;
-    int rc;
-
-    sptr = src;
-    /*
-     * Clear status of previous operation.
-     */
-    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | \
-      FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_PGSERR);
-    for (i = 0; i < num_bytes; i++) {
-        rc = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, address, sptr[i]);
-        if (rc != 0) {
-            return rc;
-        }
-
-        address++;
-    }
-
-    return 0;
-}
-
-static void
-stm32f4_flash_erase_sector_id(int sector_id)
-{
-    FLASH_EraseInitTypeDef eraseinit;
-    uint32_t SectorError;
-
-    eraseinit.TypeErase = FLASH_TYPEERASE_SECTORS;
-    eraseinit.Banks = 0;
-    eraseinit.Sector = sector_id;
-    eraseinit.NbSectors = 1;
-    eraseinit.VoltageRange = FLASH_VOLTAGE_RANGE_1;
-
-    HAL_FLASHEx_Erase(&eraseinit, &SectorError);
-}
-
-static int
-stm32f4_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
-{
-    int i;
-
-    for (i = 0; i < dev->hf_sector_cnt; i++) {
-        if (stm32f4_flash_sectors[i] == sector_address) {
-            stm32f4_flash_erase_sector_id(i);
-            return 0;
-        }
-    }
-
-    return -1;
-}
-
-static int
-stm32f4_flash_sector_info(const struct hal_flash *dev, int idx,
-        uint32_t *address, uint32_t *sz)
-{
-    *address = stm32f4_flash_sectors[idx];
-    *sz = stm32f4_flash_sectors[idx + 1] - stm32f4_flash_sectors[idx];
-    return 0;
-}
-
-static int
-stm32f4_flash_init(const struct hal_flash *dev)
-{
-    HAL_FLASH_Unlock();
-    return 0;
-}
diff --git a/hw/mcu/stm/stm32f4xx/syscfg.yml b/hw/mcu/stm/stm32f4xx/syscfg.yml
index cac584bef1..08ed2ea1c4 100644
--- a/hw/mcu/stm/stm32f4xx/syscfg.yml
+++ b/hw/mcu/stm/stm32f4xx/syscfg.yml
@@ -39,6 +39,14 @@ syscfg.defs:
         description: This MCU's UART uses SR register for status.
         value: 1
 
+    MCU_FLASH_ERASED_VAL:
+        description: Value read from erased flash.
+        value: 0xff
+
+    STM32_FLASH_IS_LINEAR:
+        description: This MCU's Flash has one single sector size.
+        value: 0
+
     I2C_0:
         description: 'I2C (TWI) interface 0'
         value:  0
diff --git a/hw/mcu/stm/stm32f7xx/include/mcu/stm32_hal.h b/hw/mcu/stm/stm32f7xx/include/mcu/stm32_hal.h
index 8cdd6b414e..bdb7d5b09e 100644
--- a/hw/mcu/stm/stm32f7xx/include/mcu/stm32_hal.h
+++ b/hw/mcu/stm/stm32f7xx/include/mcu/stm32_hal.h
@@ -80,6 +80,25 @@ struct stm32_hal_spi_cfg {
 /* hal_trng */
 #include "stm32f7xx_hal_rng.h"
 
+/* hal_flash */
+#include "stm32f7xx_hal_def.h"
+#include "stm32f7xx_hal_flash.h"
+#include "stm32f7xx_hal_flash_ex.h"
+#define STM32_HAL_FLASH_INIT()        \
+    do {                              \
+        HAL_FLASH_Unlock();           \
+    } while (0)
+#define FLASH_PROGRAM_TYPE FLASH_TYPEPROGRAM_BYTE
+#define STM32_HAL_FLASH_CLEAR_ERRORS()            \
+    do {                                          \
+        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP |   \
+                FLASH_FLAG_OPERR |                \
+                FLASH_FLAG_WRPERR |               \
+                FLASH_FLAG_PGAERR |               \
+                FLASH_FLAG_PGPERR |               \
+                FLASH_FLAG_ERSERR);               \
+    } while (0)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/mcu/stm/stm32f7xx/src/hal_flash.c b/hw/mcu/stm/stm32f7xx/src/hal_flash.c
deleted file mode 100644
index 017c7220a2..0000000000
--- a/hw/mcu/stm/stm32f7xx/src/hal_flash.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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 <string.h>
-#include "stm32f7xx_hal_def.h"
-#include "stm32f7xx_hal_flash.h"
-#include "stm32f7xx_hal_flash_ex.h"
-#include "hal/hal_flash_int.h"
-
-static int stm32f7_flash_read(const struct hal_flash *dev, uint32_t address,
-        void *dst, uint32_t num_bytes);
-static int stm32f7_flash_write(const struct hal_flash *dev, uint32_t address,
-        const void *src, uint32_t num_bytes);
-static int stm32f7_flash_erase_sector(const struct hal_flash *dev,
-        uint32_t sector_address);
-static int stm32f7_flash_sector_info(const struct hal_flash *dev, int idx,
-        uint32_t *address, uint32_t *sz);
-static int stm32f7_flash_init(const struct hal_flash *dev);
-
-static const struct hal_flash_funcs stm32f7_flash_funcs = {
-    .hff_read = stm32f7_flash_read,
-    .hff_write = stm32f7_flash_write,
-    .hff_erase_sector = stm32f7_flash_erase_sector,
-    .hff_sector_info = stm32f7_flash_sector_info,
-    .hff_init = stm32f7_flash_init
-};
-
-static const uint32_t stm32f7_flash_sectors[] = {
-    0x08000000,     /* 32kB  */
-    0x08008000,     /* 32kB  */
-    0x08010000,     /* 32kB  */
-    0x08018000,     /* 32kB  */
-    0x08020000,     /* 128kB */
-    0x08040000,     /* 256kB */
-    0x08080000,     /* 256kB */
-    0x080c0000,     /* 256kB */
-    0x08100000,     /* 256kB */
-    0x08140000,     /* 256kB */
-    0x08180000,     /* 256kB */
-    0x081c0000,     /* 256kB */
-    0x08200000,     /* End of flash */
-};
-
-#define STM32F7_FLASH_NUM_AREAS                                         \
-    (int)(sizeof(stm32f7_flash_sectors) /                               \
-      sizeof(stm32f7_flash_sectors[0]))
-
-const struct hal_flash stm32f7_flash_dev = {
-    .hf_itf = &stm32f7_flash_funcs,
-    .hf_base_addr = 0x08000000,
-    .hf_size = 2 * 1024 * 1024,
-    .hf_sector_cnt = STM32F7_FLASH_NUM_AREAS - 1,
-    .hf_align = 1,
-    .hf_erased_val = 0xff,
-};
-
-static int
-stm32f7_flash_read(const struct hal_flash *dev, uint32_t address, void *dst,
-        uint32_t num_bytes)
-{
-    memcpy(dst, (void *)address, num_bytes);
-    return 0;
-}
-
-static int
-stm32f7_flash_write(const struct hal_flash *dev, uint32_t address,
-        const void *src, uint32_t num_bytes)
-{
-    const uint8_t *sptr;
-    uint32_t i;
-    int rc;
-
-    sptr = src;
-    /*
-     * Clear status of previous operation.
-     */
-    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | \
-      FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR);
-    for (i = 0; i < num_bytes; i++) {
-        rc = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, address, sptr[i]);
-        if (rc != 0) {
-            return rc;
-        }
-
-        address++;
-    }
-
-    return 0;
-}
-
-static void
-stm32f7_flash_erase_sector_id(int sector_id)
-{
-    FLASH_Erase_Sector(sector_id, FLASH_VOLTAGE_RANGE_1);
-}
-
-static int
-stm32f7_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
-{
-    int i;
-
-    for (i = 0; i < STM32F7_FLASH_NUM_AREAS - 1; i++) {
-        if (stm32f7_flash_sectors[i] == sector_address) {
-            stm32f7_flash_erase_sector_id(i);
-            return 0;
-        }
-    }
-
-    return -1;
-}
-
-static int
-stm32f7_flash_sector_info(const struct hal_flash *dev, int idx,
-        uint32_t *address, uint32_t *sz)
-{
-    *address = stm32f7_flash_sectors[idx];
-    *sz = stm32f7_flash_sectors[idx + 1] - stm32f7_flash_sectors[idx];
-    return 0;
-}
-
-static int
-stm32f7_flash_init(const struct hal_flash *dev)
-{
-    HAL_FLASH_Unlock();
-    return 0;
-}
diff --git a/hw/mcu/stm/stm32f7xx/syscfg.yml b/hw/mcu/stm/stm32f7xx/syscfg.yml
index 9767dd48b4..4e8c3cdd7f 100644
--- a/hw/mcu/stm/stm32f7xx/syscfg.yml
+++ b/hw/mcu/stm/stm32f7xx/syscfg.yml
@@ -39,6 +39,14 @@ syscfg.defs:
         description: This MCU's UART uses ISR register (not SR) for status.
         value: 0
 
+    MCU_FLASH_ERASED_VAL:
+        description: Value read from erased flash.
+        value: 0xff
+
+    STM32_FLASH_IS_LINEAR:
+        description: This MCU's Flash has one single sector size.
+        value: 0
+
     MCU_SYSCLK_PLL_HSI:
         description: Configure PLL as sysclock driven by HSI.
         value: 0
diff --git a/hw/mcu/stm/stm32l0xx/include/mcu/stm32_hal.h b/hw/mcu/stm/stm32l0xx/include/mcu/stm32_hal.h
index 5e895c3f51..e7f69213cd 100644
--- a/hw/mcu/stm/stm32l0xx/include/mcu/stm32_hal.h
+++ b/hw/mcu/stm/stm32l0xx/include/mcu/stm32_hal.h
@@ -80,6 +80,36 @@ struct stm32_hal_spi_cfg {
 
 #define STM32_HAL_TIMER_MAX     (3)
 
+/* hal_flash */
+#include "stm32l0xx_hal_def.h"
+#include "stm32l0xx_hal_rcc.h"
+#include "stm32l0xx_hal_flash.h"
+#include "stm32l0xx_hal_flash_ex.h"
+/*
+ * FIXME: __HAL_FLASH_BUFFER_CACHE_DISABLE() ?
+ *        __HAL_FLASH_PREREAD_BUFFER_ENABLE() ?
+ *        __HAL_FLASH_PREFETCH_BUFFER_ENABLE() ?
+ */
+#define STM32_HAL_FLASH_INIT()        \
+    do {                              \
+        __HAL_RCC_MIF_CLK_ENABLE();   \
+        HAL_FLASH_Unlock();           \
+    } while (0)
+#define FLASH_PROGRAM_TYPE FLASH_TYPEPROGRAM_WORD
+#define STM32_HAL_FLASH_CLEAR_ERRORS()          \
+    do {                                        \
+        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | \
+                FLASH_FLAG_ENDHV |              \
+                FLASH_FLAG_READY |              \
+                FLASH_FLAG_WRPERR |             \
+                FLASH_FLAG_PGAERR |             \
+                FLASH_FLAG_SIZERR |             \
+                FLASH_FLAG_OPTVERR |            \
+                FLASH_FLAG_RDERR |              \
+                FLASH_FLAG_FWWERR |             \
+                FLASH_FLAG_NOTZEROERR);         \
+    } while (0)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/mcu/stm/stm32l0xx/src/hal_flash.c b/hw/mcu/stm/stm32l0xx/src/hal_flash.c
index 453c25aec0..aa20165b99 100644
--- a/hw/mcu/stm/stm32l0xx/src/hal_flash.c
+++ b/hw/mcu/stm/stm32l0xx/src/hal_flash.c
@@ -18,145 +18,47 @@
  */
 
 #include <string.h>
-#include "stm32l0xx_hal_def.h"
-#include "stm32l0xx_hal_rcc.h"
-#include "stm32l0xx_hal_flash.h"
-#include "stm32l0xx_hal_flash_ex.h"
+#include <syscfg/syscfg.h>
+#include <mcu/stm32_hal.h>
 #include "hal/hal_flash_int.h"
 #include "hal/hal_watchdog.h"
 
-static int stm32l0_flash_read(const struct hal_flash *dev, uint32_t address,
-        void *dst, uint32_t num_bytes);
-static int stm32l0_flash_write(const struct hal_flash *dev, uint32_t address,
-        const void *src, uint32_t num_bytes);
-static int stm32l0_flash_erase_sector(const struct hal_flash *dev,
-        uint32_t sector_address);
-static int stm32l0_flash_sector_info(const struct hal_flash *dev, int idx,
-        uint32_t *address, uint32_t *sz);
-static int stm32l0_flash_init(const struct hal_flash *dev);
-
-static const struct hal_flash_funcs stm32l0_flash_funcs = {
-    .hff_read = stm32l0_flash_read,
-    .hff_write = stm32l0_flash_write,
-    .hff_erase_sector = stm32l0_flash_erase_sector,
-    .hff_sector_info = stm32l0_flash_sector_info,
-    .hff_init = stm32l0_flash_init,
-};
-
-#define _FLASH_SIZE              (192 * 1024)
 /*
  * NOTE: the actual page size if 128 bytes, but that would mean an
  * enormous amount of pages, so here make it look like 1K.
  */
-#define _FLASH_SECTOR_SIZE       1024
-#define _FLASH_PAGES_PER_SECTOR  8
-
-const struct hal_flash stm32l0_flash_dev = {
-    .hf_itf = &stm32l0_flash_funcs,
-    .hf_base_addr = 0x08000000,
-    .hf_size = _FLASH_SIZE,
-    .hf_sector_cnt = _FLASH_SIZE / _FLASH_SECTOR_SIZE,
-    /* FIXME: 2 also ok? */
-    .hf_align = 4,
-    .hf_erased_val = 0,
-};
-
-static int
-stm32l0_flash_read(const struct hal_flash *dev, uint32_t address, void *dst,
-        uint32_t num_bytes)
-{
-    memcpy(dst, (void *)address, num_bytes);
-    return 0;
-}
-
-static int
-stm32l0_flash_write(const struct hal_flash *dev, uint32_t address,
-        const void *src, uint32_t num_bytes)
-{
-    uint64_t val;
-    uint8_t align;
-    uint32_t i;
-    int rc;
-    uint32_t num_words;
-
-    if (!num_bytes) {
-        return -1;
-    }
-
-    align = dev->hf_align;
-    num_words = ((num_bytes - 1) / align) + 1;
-
-    /* clear previous errors */
-    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP |
-                    FLASH_FLAG_ENDHV      |
-                    FLASH_FLAG_READY      |
-                    FLASH_FLAG_WRPERR     |
-                    FLASH_FLAG_PGAERR     |
-                    FLASH_FLAG_SIZERR     |
-                    FLASH_FLAG_OPTVERR    |
-                    FLASH_FLAG_RDERR      |
-                    FLASH_FLAG_FWWERR     |
-                    FLASH_FLAG_NOTZEROERR);
-
-    for (i = 0; i < num_words; i++) {
-        //__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGSERR);
-
-        if (num_bytes < align) {
-            memcpy(&val, &((uint8_t *)src)[i * align], num_bytes);
-            memset((uint32_t *)&val + num_bytes, 0, align - num_bytes);
-        } else {
-            memcpy(&val, &((uint8_t *)src)[i * align], align);
-        }
-
-        rc = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, val);
-        if (rc != HAL_OK) {
-            return rc;
-        }
-
-        address += align;
-
-        /* underflowing is ok here... */
-        num_bytes -= align;
-
-        /*
-         * Long writes take excessive time, and stall the idle thread, so
-         * tickling the watchdog here to avoid resetting during writes...
-         */
-        if (!(i % 32)) {
-            hal_watchdog_tickle();
-        }
-    }
+#define _REAL_SECTOR_SIZE    128
+#define _FLASH_SECTOR_SIZE   MYNEWT_VAL(STM32_FLASH_SECTOR_SIZE)
+#define _PAGES_PER_SECTOR    8
 
-    return 0;
-}
+/* Since the sectors on L0 are too small, avoid having the map each one
+ * of them by aggregating them into _PAGES_PER_SECTOR amount.
+ *
+ * This asserts the MCU constant is not changed, and if it's changed
+ * intentionally alerts the user that this code needs to be updated
+ * as well.
+ */
+_Static_assert(_FLASH_SECTOR_SIZE == (_REAL_SECTOR_SIZE * _PAGES_PER_SECTOR),
+    "STM32_FLASH_SECTOR_SIZE was changed; the erase function needs updating!");
 
-static int
-stm32l0_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
+int
+stm32_mcu_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
 {
     FLASH_EraseInitTypeDef eraseinit;
     uint32_t PageError;
     HAL_StatusTypeDef rc;
 
     (void)PageError;
+    (void)dev;
 
     if (!(sector_address & (_FLASH_SECTOR_SIZE - 1))) {
         /* FIXME: why is an err flag set? */
-
         /* Clear status of previous operation. */
-        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP |
-                        FLASH_FLAG_ENDHV      |
-                        FLASH_FLAG_READY      |
-                        FLASH_FLAG_WRPERR     |
-                        FLASH_FLAG_PGAERR     |
-                        FLASH_FLAG_SIZERR     |
-                        FLASH_FLAG_OPTVERR    |
-                        FLASH_FLAG_RDERR      |
-                        FLASH_FLAG_FWWERR     |
-                        FLASH_FLAG_NOTZEROERR);
+        STM32_HAL_FLASH_CLEAR_ERRORS();
 
         eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
         eraseinit.PageAddress = sector_address;
-        eraseinit.NbPages = _FLASH_PAGES_PER_SECTOR;
+        eraseinit.NbPages = _PAGES_PER_SECTOR;
         rc = HAL_FLASHEx_Erase(&eraseinit, &PageError);
         if (rc == HAL_OK) {
             return 0;
@@ -165,23 +67,3 @@ stm32l0_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
 
     return -1;
 }
-
-static int
-stm32l0_flash_sector_info(const struct hal_flash *dev, int idx,
-        uint32_t *address, uint32_t *sz)
-{
-    *address = dev->hf_base_addr + _FLASH_SECTOR_SIZE * idx;
-    *sz = _FLASH_SECTOR_SIZE;
-    return 0;
-}
-
-static int
-stm32l0_flash_init(const struct hal_flash *dev)
-{
-    //__HAL_FLASH_BUFFER_CACHE_DISABLE();
-    //__HAL_FLASH_PREREAD_BUFFER_ENABLE();
-    //__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
-    __HAL_RCC_MIF_CLK_ENABLE();
-    HAL_FLASH_Unlock();
-    return 0;
-}
diff --git a/hw/mcu/stm/stm32l0xx/syscfg.yml b/hw/mcu/stm/stm32l0xx/syscfg.yml
index 72a9ba139e..ca84f9c25b 100644
--- a/hw/mcu/stm/stm32l0xx/syscfg.yml
+++ b/hw/mcu/stm/stm32l0xx/syscfg.yml
@@ -43,6 +43,18 @@ syscfg.defs:
         description: This MCU's UART uses SR register for status.
         value: 0
 
+    MCU_FLASH_ERASED_VAL:
+        description: Value read from erased flash.
+        value: 0
+
+    STM32_FLASH_IS_LINEAR:
+        description: This MCU's Flash has one single sector size.
+        value: 1
+
+    STM32_FLASH_SECTOR_SIZE:
+        description: This MCU's Flash sector size in bytes.
+        value: 1024 # this is a lie (should be 128)
+
     SPI_0_MASTER:
         description: 'SPI 0 master'
         value:  0
diff --git a/hw/mcu/stm/stm32l1xx/include/mcu/stm32_hal.h b/hw/mcu/stm/stm32l1xx/include/mcu/stm32_hal.h
index 1b95ad9ef6..50416e7c81 100644
--- a/hw/mcu/stm/stm32l1xx/include/mcu/stm32_hal.h
+++ b/hw/mcu/stm/stm32l1xx/include/mcu/stm32_hal.h
@@ -73,6 +73,21 @@ struct stm32_hal_spi_cfg {
 
 #define STM32_HAL_TIMER_MAX     (3)
 
+/* hal_flash */
+#include "stm32l1xx_hal_def.h"
+#include "stm32l1xx_hal_flash.h"
+#include "stm32l1xx_hal_flash_ex.h"
+/* TODO: enable ACC64 + prefetch */
+#define STM32_HAL_FLASH_INIT()        \
+    do {                              \
+        HAL_FLASH_Unlock();           \
+    } while (0)
+#define FLASH_PROGRAM_TYPE FLASH_TYPEPROGRAMDATA_WORD
+#define STM32_HAL_FLASH_CLEAR_ERRORS()            \
+    do {                                          \
+        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_MASK);  \
+    } while (0)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/mcu/stm/stm32l1xx/src/hal_flash.c b/hw/mcu/stm/stm32l1xx/src/hal_flash.c
index d0b6af6f9d..7f56867440 100644
--- a/hw/mcu/stm/stm32l1xx/src/hal_flash.c
+++ b/hw/mcu/stm/stm32l1xx/src/hal_flash.c
@@ -19,114 +19,13 @@
 
 #include <string.h>
 #include <syscfg/syscfg.h>
-#include "stm32l1xx_hal_def.h"
-#include "stm32l1xx_hal_flash.h"
-#include "stm32l1xx_hal_flash_ex.h"
+#include <mcu/stm32_hal.h>
 #include "hal/hal_flash_int.h"
-#include "hal/hal_watchdog.h"
 
-static int stm32l1_flash_read(const struct hal_flash *dev, uint32_t address,
-        void *dst, uint32_t num_bytes);
-static int stm32l1_flash_write(const struct hal_flash *dev, uint32_t address,
-        const void *src, uint32_t num_bytes);
-static int stm32l1_flash_erase_sector(const struct hal_flash *dev,
-        uint32_t sector_address);
-static int stm32l1_flash_sector_info(const struct hal_flash *dev, int idx,
-        uint32_t *address, uint32_t *sz);
-static int stm32l1_flash_init(const struct hal_flash *dev);
+#define _FLASH_SECTOR_SIZE  MYNEWT_VAL(STM32_FLASH_SECTOR_SIZE)
 
-static const struct hal_flash_funcs stm32l1_flash_funcs = {
-    .hff_read = stm32l1_flash_read,
-    .hff_write = stm32l1_flash_write,
-    .hff_erase_sector = stm32l1_flash_erase_sector,
-    .hff_sector_info = stm32l1_flash_sector_info,
-    .hff_init = stm32l1_flash_init,
-};
-
-#define _FLASH_SIZE            (256 * 1024)
-#define _FLASH_SECTOR_SIZE     4096
-
-const struct hal_flash stm32l1_flash_dev = {
-    .hf_itf = &stm32l1_flash_funcs,
-    .hf_base_addr = 0x08000000,
-    .hf_size = _FLASH_SIZE,
-    .hf_sector_cnt = _FLASH_SIZE / _FLASH_SECTOR_SIZE,
-    .hf_align = MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE),
-    .hf_erased_val = 0,
-};
-
-static int
-stm32l1_flash_read(const struct hal_flash *dev, uint32_t address, void *dst,
-        uint32_t num_bytes)
-{
-    memcpy(dst, (void *)address, num_bytes);
-    return 0;
-}
-
-static int
-stm32l1_flash_write(const struct hal_flash *dev, uint32_t address,
-        const void *src, uint32_t num_bytes)
-{
-    uint32_t val;
-    uint32_t i;
-    int rc;
-    uint8_t align;
-    uint32_t num_words;
-
-    if (!num_bytes) {
-        return -1;
-    }
-
-    align = dev->hf_align;
-
-#if MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) == 1
-    num_words = num_bytes;
-#elif MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) == 2
-    num_words = ((num_bytes - 1) >> 1) + 1;
-#elif MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) == 4
-    num_words = ((num_bytes - 1) >> 2) + 1;
-#elif MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) == 8
-    num_words = ((num_bytes - 1) >> 3) + 1;
-#else
-    #error "Unsupported MCU_FLASH_MIN_WRITE_SIZE"
-#endif
-
-    /* Clear status of previous operation. */
-    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_MASK);
-
-    for (i = 0; i < num_words; i++) {
-        if (num_bytes < align) {
-            memcpy(&val, &((uint8_t *)src)[i * align], num_bytes);
-            /* NOTE: 0 is the erased value for L1 */
-            memset((uint32_t *)&val + num_bytes, 0, align - num_bytes);
-        } else {
-            memcpy(&val, &((uint8_t *)src)[i * align], align);
-        }
-
-        HAL_FLASH_Unlock();
-        rc = HAL_FLASH_Program(FLASH_TYPEPROGRAMDATA_WORD, address, val);
-        HAL_FLASH_Lock();
-        if (rc != HAL_OK) {
-            return rc;
-        }
-
-        address += align;
-        num_bytes -= align;
-
-        /*
-         * Long writes take excessive time, and stall the idle thread,
-         * so tickling the watchdog here to avoid reset...
-         */
-        if (!(i % 32)) {
-            hal_watchdog_tickle();
-        }
-    }
-
-    return 0;
-}
-
-static int
-stm32l1_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
+int
+stm32_mcu_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
 {
     FLASH_EraseInitTypeDef eraseinit;
     uint32_t PageError;
@@ -144,9 +43,7 @@ stm32l1_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
         eraseinit.PageAddress = sector_address;
         eraseinit.NbPages = _FLASH_SECTOR_SIZE / FLASH_PAGE_SIZE;
 
-        HAL_FLASH_Unlock();
         rc = HAL_FLASHEx_Erase(&eraseinit, &PageError);
-        HAL_FLASH_Lock();
         if (rc == HAL_OK) {
             return 0;
         }
@@ -154,19 +51,3 @@ stm32l1_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
 
     return -1;
 }
-
-static int
-stm32l1_flash_sector_info(const struct hal_flash *dev, int idx,
-        uint32_t *address, uint32_t *sz)
-{
-    *address = dev->hf_base_addr + _FLASH_SECTOR_SIZE * idx;
-    *sz = _FLASH_SECTOR_SIZE;
-    return 0;
-}
-
-static int
-stm32l1_flash_init(const struct hal_flash *dev)
-{
-    /* TODO: enable ACC64 + prefetch */
-    return 0;
-}
diff --git a/hw/mcu/stm/stm32l1xx/syscfg.yml b/hw/mcu/stm/stm32l1xx/syscfg.yml
index 0f38087b3a..c83ba8cdbd 100644
--- a/hw/mcu/stm/stm32l1xx/syscfg.yml
+++ b/hw/mcu/stm/stm32l1xx/syscfg.yml
@@ -43,6 +43,18 @@ syscfg.defs:
         description: This MCU's UART uses SR register for status.
         value: 1
 
+    MCU_FLASH_ERASED_VAL:
+        description: Value read from erased flash.
+        value: 0
+
+    STM32_FLASH_IS_LINEAR:
+        description: This MCU's Flash has one single sector size.
+        value: 1
+
+    STM32_FLASH_SECTOR_SIZE:
+        description: This MCU's Flash sector size in bytes.
+        value: 4096
+
     SPI_0_MASTER:
         description: 'SPI 0 master'
         value:  0
diff --git a/hw/mcu/stm/stm32l4xx/include/mcu/stm32_hal.h b/hw/mcu/stm/stm32l4xx/include/mcu/stm32_hal.h
index e3e7fcaef7..75340f91fb 100644
--- a/hw/mcu/stm/stm32l4xx/include/mcu/stm32_hal.h
+++ b/hw/mcu/stm/stm32l4xx/include/mcu/stm32_hal.h
@@ -76,6 +76,17 @@ struct stm32_hal_spi_cfg {
 
 #define STM32_HAL_TIMER_MAX     (3)
 
+/* hal_flash */
+#include "stm32l4xx_hal_def.h"
+#include "stm32l4xx_hal_flash.h"
+#include "stm32l4xx_hal_flash_ex.h"
+#define STM32_HAL_FLASH_INIT()        \
+    do {                              \
+        HAL_FLASH_Unlock();           \
+    } while (0)
+#define FLASH_PROGRAM_TYPE FLASH_TYPEPROGRAM_DOUBLEWORD
+#define STM32_HAL_FLASH_CLEAR_ERRORS()
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/mcu/stm/stm32l4xx/src/hal_flash.c b/hw/mcu/stm/stm32l4xx/src/hal_flash.c
index 07d2745d17..7330d59743 100644
--- a/hw/mcu/stm/stm32l4xx/src/hal_flash.c
+++ b/hw/mcu/stm/stm32l4xx/src/hal_flash.c
@@ -18,99 +18,15 @@
  */
 
 #include <string.h>
-#include "stm32l4xx_hal_def.h"
-#include "stm32l4xx_hal_flash.h"
-#include "stm32l4xx_hal_flash_ex.h"
+#include <syscfg/syscfg.h>
+#include <mcu/stm32_hal.h>
 #include "hal/hal_flash_int.h"
-#include "hal/hal_watchdog.h"
 
-static int stm32l4_flash_read(const struct hal_flash *dev, uint32_t address,
-        void *dst, uint32_t num_bytes);
-static int stm32l4_flash_write(const struct hal_flash *dev, uint32_t address,
-        const void *src, uint32_t num_bytes);
-static int stm32l4_flash_erase_sector(const struct hal_flash *dev,
-        uint32_t sector_address);
-static int stm32l4_flash_sector_info(const struct hal_flash *dev, int idx,
-        uint32_t *address, uint32_t *sz);
-static int stm32l4_flash_init(const struct hal_flash *dev);
+#define _FLASH_SIZE         (MYNEWT_VAL(STM32_FLASH_SIZE_KB) * 1024)
+#define _FLASH_SECTOR_SIZE  MYNEWT_VAL(STM32_FLASH_SECTOR_SIZE)
 
-static const struct hal_flash_funcs stm32l4_flash_funcs = {
-    .hff_read = stm32l4_flash_read,
-    .hff_write = stm32l4_flash_write,
-    .hff_erase_sector = stm32l4_flash_erase_sector,
-    .hff_sector_info = stm32l4_flash_sector_info,
-    .hff_init = stm32l4_flash_init,
-};
-
-#define _FLASH_SIZE            (1024 * 1024)
-#define _FLASH_SECTOR_SIZE     2048
-
-const struct hal_flash stm32l4_flash_dev = {
-    .hf_itf = &stm32l4_flash_funcs,
-    .hf_base_addr = 0x08000000,
-    .hf_size = _FLASH_SIZE,
-    .hf_sector_cnt = _FLASH_SIZE / _FLASH_SECTOR_SIZE,
-    .hf_align = 8,
-    .hf_erased_val = 0xff,
-};
-
-static int
-stm32l4_flash_read(const struct hal_flash *dev, uint32_t address, void *dst,
-        uint32_t num_bytes)
-{
-    memcpy(dst, (void *)address, num_bytes);
-    return 0;
-}
-
-static int
-stm32l4_flash_write(const struct hal_flash *dev, uint32_t address,
-        const void *src, uint32_t num_bytes)
-{
-    uint64_t val;
-    uint8_t align;
-    uint32_t i;
-    int rc;
-    uint32_t num_dwords;
-
-    if (!num_bytes) {
-        return -1;
-    }
-
-    align = dev->hf_align;
-    num_dwords = ((num_bytes - 1) / align) + 1;
-
-    for (i = 0; i < num_dwords; i++) {
-        if (num_bytes < 8) {
-            memcpy(&val, &((uint8_t *)src)[i * align], num_bytes);
-            memset((uint64_t *)&val + num_bytes, 0xff, align - num_bytes);
-        } else {
-            memcpy(&val, &((uint8_t *)src)[i * align], align);
-        }
-
-        rc = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, val);
-        if (rc != HAL_OK) {
-            return rc;
-        }
-
-        address += align;
-
-        /* underflowing is ok here... */
-        num_bytes -= align;
-
-        /*
-         * Long writes take excessive time, and stall the idle thread, so
-         * tickling the watchdog here to avoid resetting during writes...
-         */
-        if (!(i % 32)) {
-            hal_watchdog_tickle();
-        }
-    }
-
-    return 0;
-}
-
-static int
-stm32l4_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
+int
+stm32_mcu_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
 {
     FLASH_EraseInitTypeDef eraseinit;
     uint32_t PageError;
@@ -135,20 +51,3 @@ stm32l4_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
 
     return -1;
 }
-
-static int
-stm32l4_flash_sector_info(const struct hal_flash *dev, int idx,
-        uint32_t *address, uint32_t *sz)
-{
-    *address = dev->hf_base_addr + _FLASH_SECTOR_SIZE * idx;
-    *sz = _FLASH_SECTOR_SIZE;
-    return 0;
-}
-
-static int
-stm32l4_flash_init(const struct hal_flash *dev)
-{
-    HAL_FLASH_Unlock();
-    /* TODO: enable ACC64 + prefetch */
-    return 0;
-}
diff --git a/hw/mcu/stm/stm32l4xx/syscfg.yml b/hw/mcu/stm/stm32l4xx/syscfg.yml
index 3bd9d882d7..0d0ba085cf 100644
--- a/hw/mcu/stm/stm32l4xx/syscfg.yml
+++ b/hw/mcu/stm/stm32l4xx/syscfg.yml
@@ -43,6 +43,18 @@ syscfg.defs:
         description: This MCU's UART uses ISR register (not SR) for status.
         value: 0
 
+    MCU_FLASH_ERASED_VAL:
+        description: Value read from erased flash.
+        value: 0xff
+
+    STM32_FLASH_IS_LINEAR:
+        description: This MCU's Flash has one single sector size.
+        value: 1
+
+    STM32_FLASH_SECTOR_SIZE:
+        description: This MCU's Flash sector size in bytes.
+        value: 2048
+
     SPI_0_MASTER:
         description: 'SPI 0 master'
         value:  0


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services