hw/mcu/stm32h7: Use linear sector flash driver

STM32H7 actually has liner flash with sectors of 128kB.
There is no need for stm32_flash_sectors table in BSP.

Additionally non-linear version that was used so far
would not compile for some H7 chips that have different
FLASH CR register and where FLASH_VOLATEG_RANGE_3 is not defined.

Liner sector variant was chosen when FLASH_PAGE_SIZE was defined.
While H7 and H5 don't have this definition they do have
FLASH_SECTOR_SIZE and when this definition is present
FLASH_IS_LINEAR is also set to 1

For U5 where minimal write size is 16 bytes function
stm32_flash_write_linear() was using to small buffer
possibly clobbering some stack values.
Now val variable is an array to accommodate 16 and 32
accesses needed for U5 and H7

Signed-off-by: Jerzy Kasenberg <jerzy.kasenberg@codecoup.pl>
diff --git a/hw/bsp/nucleo-h723zg/src/hal_bsp.c b/hw/bsp/nucleo-h723zg/src/hal_bsp.c
index d846fd6..6cbf95d 100644
--- a/hw/bsp/nucleo-h723zg/src/hal_bsp.c
+++ b/hw/bsp/nucleo-h723zg/src/hal_bsp.c
@@ -58,22 +58,6 @@
 };
 #endif
 
-const uint32_t stm32_flash_sectors[] = {
-    0x08000000,     /* 128kB */
-    0x08020000,     /* 128kB */
-    0x08040000,     /* 128kB */
-    0x08060000,     /* 128kB */
-    0x08080000,     /* 128kB */
-    0x080a0000,     /* 128kB */
-    0x080c0000,     /* 128kB */
-    0x080e0000,     /* 128kB */
-    0x08100000,     /* End of flash */
-};
-
-#define SZ (sizeof(stm32_flash_sectors) / sizeof(stm32_flash_sectors[0]))
-static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) + 1 == SZ,
-        "STM32_FLASH_NUM_AREAS does not match flash sectors");
-
 #if MYNEWT_VAL(UART_0)
 const struct stm32_uart_cfg os_bsp_uart0_cfg = {
     .suc_uart = USART3,
diff --git a/hw/mcu/stm/stm32_common/src/hal_flash.c b/hw/mcu/stm/stm32_common/src/hal_flash.c
index 9301df4..d4f04ac 100644
--- a/hw/mcu/stm/stm32_common/src/hal_flash.c
+++ b/hw/mcu/stm/stm32_common/src/hal_flash.c
@@ -35,6 +35,9 @@
 #else
 #define FLASH_SECTOR_SIZE  FLASH_PAGE_SIZE
 #endif
+#elif defined(FLASH_SECTOR_SIZE)
+#undef FLASH_IS_LINEAR
+#define FLASH_IS_LINEAR 1
 #endif
 
 static int stm32_flash_read(const struct hal_flash *dev, uint32_t address,
@@ -80,11 +83,13 @@
 }
 
 #if FLASH_IS_LINEAR
+#define VAL_SIZE (((MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) - 1) / 8) + 1)
+
 static int
 stm32_flash_write_linear(const struct hal_flash *dev, uint32_t address,
         const void *src, uint32_t num_bytes)
 {
-    uint64_t val;
+    uint64_t val[VAL_SIZE];
     uint32_t i;
     int rc;
     uint8_t align;
@@ -102,6 +107,8 @@
     num_words = ((num_bytes - 1) >> 3) + 1;
 #elif MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) == 16
     num_words = ((num_bytes - 1) >> 4) + 1;
+#elif MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) == 32
+    num_words = ((num_bytes - 1) >> 5) + 1;
 #else
     #error "Unsupported MCU_FLASH_MIN_WRITE_SIZE"
 #endif
@@ -121,10 +128,10 @@
         /* FIXME: L1 was previously unlocking flash before erasing/programming,
          * and locking again afterwards. Maybe all MCUs should do the same?
          */
-#if MYNEWT_VAL(MCU_STM32U5)
+#if MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) > 8
         rc = HAL_FLASH_Program(FLASH_PROGRAM_TYPE, address, (uint32_t)&val);
 #else
-        rc = HAL_FLASH_Program(FLASH_PROGRAM_TYPE, address, val);
+        rc = HAL_FLASH_Program(FLASH_PROGRAM_TYPE, address, val[0]);
 #endif
         if (rc != HAL_OK) {
             return rc;
@@ -165,11 +172,7 @@
     STM32_HAL_FLASH_CLEAR_ERRORS();
 
     for (i = 0; i < num_bytes; i += inc) {
-#if MYNEWT_VAL(MCU_STM32H7)
-        rc = HAL_FLASH_Program(FLASH_PROGRAM_TYPE, address, (uint32_t)(sptr + i));
-#else
         rc = HAL_FLASH_Program(FLASH_PROGRAM_TYPE, address, sptr[i]);
-#endif
         if (rc != 0) {
             return rc;
         }
diff --git a/hw/mcu/stm/stm32h7xx/src/hal_flash.c b/hw/mcu/stm/stm32h7xx/src/hal_flash.c
new file mode 100644
index 0000000..0029c0a
--- /dev/null
+++ b/hw/mcu/stm/stm32h7xx/src/hal_flash.c
@@ -0,0 +1,58 @@
+/*
+ * 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 <syscfg/syscfg.h>
+#include <mcu/stm32_hal.h>
+#include "hal/hal_flash_int.h"
+
+#define STM32_FLASH_SIZE      (MYNEWT_VAL(STM32_FLASH_SIZE_KB) * 1024)
+
+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;
+
+    if (!(sector_address & (FLASH_SECTOR_SIZE - 1))) {
+        eraseinit.TypeErase = FLASH_TYPEERASE_SECTORS;
+#ifdef FLASH_BANK_2
+        if ((sector_address - dev->hf_base_addr) < (STM32_FLASH_SIZE / 2)) {
+            eraseinit.Banks = FLASH_BANK_1;
+        } else {
+            eraseinit.Banks = FLASH_BANK_2;
+        }
+#else
+        eraseinit.Banks = FLASH_BANK_1;
+#endif
+        eraseinit.Sector = (sector_address - dev->hf_base_addr) / FLASH_SECTOR_SIZE;
+        eraseinit.NbSectors = 1;
+#if defined(FLASH_CR_PSIZE)
+        eraseinit.VoltageRange = FLASH_VOLTAGE_RANGE_3;
+#endif
+        rc = HAL_FLASHEx_Erase(&eraseinit, &PageError);
+        if (rc == HAL_OK) {
+            return 0;
+        }
+    }
+
+    return -1;
+}