This is an automated email from the ASF dual-hosted git repository. jerzy pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
The following commit(s) were added to refs/heads/master by this push: new 3e287866e hw/mcu/stm32h7: Use linear sector flash driver 3e287866e is described below commit 3e287866ef76e5eccadf54f32c70a719123f54e4 Author: Jerzy Kasenberg <jerzy.kasenb...@codecoup.pl> AuthorDate: Sun Apr 14 17:44:45 2024 +0200 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.kasenb...@codecoup.pl> --- hw/bsp/nucleo-h723zg/src/hal_bsp.c | 16 --------- hw/mcu/stm/stm32_common/src/hal_flash.c | 17 ++++++---- hw/mcu/stm/stm32h7xx/src/hal_flash.c | 58 +++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 23 deletions(-) diff --git a/hw/bsp/nucleo-h723zg/src/hal_bsp.c b/hw/bsp/nucleo-h723zg/src/hal_bsp.c index d846fd6f0..6cbf95d1f 100644 --- a/hw/bsp/nucleo-h723zg/src/hal_bsp.c +++ b/hw/bsp/nucleo-h723zg/src/hal_bsp.c @@ -58,22 +58,6 @@ struct stm32_pwm_conf os_bsp_pwm2_cfg = { }; #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 9301df49f..d4f04ac51 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 @@ stm32_flash_read(const struct hal_flash *dev, uint32_t address, void *dst, } #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 @@ stm32_flash_write_linear(const struct hal_flash *dev, uint32_t address, 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 @@ stm32_flash_write_linear(const struct hal_flash *dev, uint32_t address, /* 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_flash_write_non_linear(const struct hal_flash *dev, uint32_t address, 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 000000000..0029c0ad4 --- /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; +}