From b9da052e51d13d3bb84e20f494de7b98e9f9f770 Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Mon, 11 May 2020 10:51:05 +0100 Subject: [PATCH] drivers: flash: Remove redundant code in STM32 drivers Several STM32 chips have identical chip-specific code that has been duplicated in different source files. Unify the F0x, F1x, and F3x to use a single implementation. Signed-off-by: Andreas Sandberg --- drivers/flash/CMakeLists.txt | 4 +- drivers/flash/Kconfig.stm32 | 16 +- .../{flash_stm32f0x.c => flash_stm32_v1.c} | 22 ++- drivers/flash/flash_stm32f1x.c | 167 ------------------ drivers/flash/flash_stm32f3x.c | 163 ----------------- 5 files changed, 24 insertions(+), 348 deletions(-) rename drivers/flash/{flash_stm32f0x.c => flash_stm32_v1.c} (86%) delete mode 100644 drivers/flash/flash_stm32f1x.c delete mode 100644 drivers/flash/flash_stm32f3x.c diff --git a/drivers/flash/CMakeLists.txt b/drivers/flash/CMakeLists.txt index 04a8afe6c76..1d6fe1ecc3c 100644 --- a/drivers/flash/CMakeLists.txt +++ b/drivers/flash/CMakeLists.txt @@ -20,9 +20,7 @@ zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_RV32M1 soc_flash_rv32m1.c) if(CONFIG_SOC_FLASH_STM32) zephyr_sources(flash_stm32.c) - zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32F0X flash_stm32f0x.c) - zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32F1X flash_stm32f1x.c) - zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32F3X flash_stm32f3x.c) + zephyr_sources_ifdef(CONFIG_SOC_FLASH_STM32_V1 flash_stm32_v1.c) zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32F4X flash_stm32f4x.c) zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32F7X flash_stm32f7x.c) zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32L4X flash_stm32l4x.c) diff --git a/drivers/flash/Kconfig.stm32 b/drivers/flash/Kconfig.stm32 index 96f9f5e5842..9b9a072891f 100644 --- a/drivers/flash/Kconfig.stm32 +++ b/drivers/flash/Kconfig.stm32 @@ -10,18 +10,15 @@ config SOC_FLASH_STM32 depends on (SOC_SERIES_STM32F0X || SOC_SERIES_STM32F1X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X || SOC_SERIES_STM32L4X || SOC_SERIES_STM32WBX || SOC_SERIES_STM32G0X || SOC_SERIES_STM32G4X) select FLASH_HAS_DRIVER_ENABLED default y - select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32F0X - select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32F1X - select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32F3X + select SOC_FLASH_STM32_V1 if SOC_SERIES_STM32F0X + select SOC_FLASH_STM32_V1 if SOC_SERIES_STM32F1X + select SOC_FLASH_STM32_V1 if SOC_SERIES_STM32F3X select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32G0X select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32F4X select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32F7X select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32L4X select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32WBX select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32G4X - select FLASH_HAS_PAGE_LAYOUT if SOC_SERIES_STM32F0X - select FLASH_HAS_PAGE_LAYOUT if SOC_SERIES_STM32F1X - select FLASH_HAS_PAGE_LAYOUT if SOC_SERIES_STM32F3X select FLASH_HAS_PAGE_LAYOUT if SOC_SERIES_STM32G0X select FLASH_HAS_PAGE_LAYOUT if SOC_SERIES_STM32F4X select FLASH_HAS_PAGE_LAYOUT if SOC_SERIES_STM32F7X @@ -31,3 +28,10 @@ config SOC_FLASH_STM32 help Enable STM32F0x, STM32F3x, STM32F4x, STM32F7x, STM32L4x, STM32WBx, STM32G0x or STM32G4x series flash driver. + +config SOC_FLASH_STM32_V1 + bool + select FLASH_PAGE_LAYOUT + select FLASH_HAS_PAGE_LAYOUT + help + Enable the generic backend for the STM32 flash driver. diff --git a/drivers/flash/flash_stm32f0x.c b/drivers/flash/flash_stm32_v1.c similarity index 86% rename from drivers/flash/flash_stm32f0x.c rename to drivers/flash/flash_stm32_v1.c index 1a313152b82..b32dfff06ea 100644 --- a/drivers/flash/flash_stm32f0x.c +++ b/drivers/flash/flash_stm32_v1.c @@ -1,13 +1,12 @@ /* * Copyright (c) 2017 BayLibre, SAS + * Copyright (c) 2019 Linaro Limited * * SPDX-License-Identifier: Apache-2.0 */ -#define LOG_DOMAIN flash_stm32f0 -#define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL #include -LOG_MODULE_REGISTER(LOG_DOMAIN); +LOG_MODULE_REGISTER(flash_stm32generic, CONFIG_FLASH_LOG_LEVEL); #include #include @@ -148,19 +147,24 @@ void flash_stm32_page_layout(struct device *dev, const struct flash_pages_layout **layout, size_t *layout_size) { - static struct flash_pages_layout stm32f0_flash_layout = { + static struct flash_pages_layout flash_layout = { .pages_count = 0, .pages_size = 0, }; ARG_UNUSED(dev); - if (stm32f0_flash_layout.pages_count == 0) { - stm32f0_flash_layout.pages_count = (CONFIG_FLASH_SIZE * 1024) / - FLASH_PAGE_SIZE; - stm32f0_flash_layout.pages_size = FLASH_PAGE_SIZE; + if (flash_layout.pages_count == 0) { +#if defined(CONFIG_SOC_SERIES_STM32F3X) + flash_layout.pages_count = + DT_REG_SIZE(DT_INST(0, soc_nv_flash)) / FLASH_PAGE_SIZE; +#else + flash_layout.pages_count = (CONFIG_FLASH_SIZE * 1024) / + FLASH_PAGE_SIZE; +#endif + flash_layout.pages_size = FLASH_PAGE_SIZE; } - *layout = &stm32f0_flash_layout; + *layout = &flash_layout; *layout_size = 1; } diff --git a/drivers/flash/flash_stm32f1x.c b/drivers/flash/flash_stm32f1x.c deleted file mode 100644 index 5049e5cecec..00000000000 --- a/drivers/flash/flash_stm32f1x.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2017 BayLibre, SAS - * Copyright (c) 2019 Feng Cheng - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define LOG_DOMAIN flash_stm32f1 -#define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL -#include -LOG_MODULE_REGISTER(LOG_DOMAIN); - -#include -#include -#include -#include -#include -#include - -#include "flash_stm32.h" - -/* offset and len must be aligned on 2 for write - * positive and not beyond end of flash - */ -bool flash_stm32_valid_range(struct device *dev, off_t offset, uint32_t len, - bool write) -{ - return (!write || (offset % 2 == 0 && len % 2 == 0U)) && - flash_stm32_range_exists(dev, offset, len); -} - -static unsigned int get_page(off_t offset) -{ - return offset / FLASH_PAGE_SIZE; -} - -static int write_hword(struct device *dev, off_t offset, uint16_t val) -{ - volatile uint16_t *flash = (uint16_t *)(offset + CONFIG_FLASH_BASE_ADDRESS); - FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); - uint32_t tmp; - int rc; - - /* if the control register is locked, do not fail silently */ - if (regs->CR & FLASH_CR_LOCK) { - return -EIO; - } - - /* Check that no Flash main memory operation is ongoing */ - rc = flash_stm32_wait_flash_idle(dev); - if (rc < 0) { - return rc; - } - - /* Check if this half word is erased */ - if (*flash != 0xFFFF) { - return -EIO; - } - - /* Set the PG bit */ - regs->CR |= FLASH_CR_PG; - - /* Flush the register write */ - tmp = regs->CR; - - /* Perform the data write operation at the desired memory address */ - *flash = val; - - /* Wait until the BSY bit is cleared */ - rc = flash_stm32_wait_flash_idle(dev); - - /* Clear the PG bit */ - regs->CR &= (~FLASH_CR_PG); - - return rc; -} - -static int erase_page(struct device *dev, unsigned int page) -{ - FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); - uint32_t page_address = CONFIG_FLASH_BASE_ADDRESS; - uint32_t tmp; - int rc; - - /* if the control register is locked, do not fail silently */ - if (regs->CR & FLASH_CR_LOCK) { - return -EIO; - } - - /* Check that no Flash memory operation is ongoing */ - rc = flash_stm32_wait_flash_idle(dev); - if (rc < 0) { - return rc; - } - - /* Calculate the flash page address */ - page_address += page * FLASH_PAGE_SIZE; - - /* Set the PER bit and select the page you wish to erase */ - regs->CR |= FLASH_CR_PER; - regs->AR = page_address; - - /* Set the STRT bit */ - regs->CR |= FLASH_CR_STRT; - - /* flush the register write */ - tmp = regs->CR; - - /* Wait for the BSY bit */ - rc = flash_stm32_wait_flash_idle(dev); - - regs->CR &= ~FLASH_CR_PER; - - return rc; -} - -int flash_stm32_block_erase_loop(struct device *dev, unsigned int offset, - unsigned int len) -{ - int i, rc = 0; - - i = get_page(offset); - for (; i <= get_page(offset + len - 1) ; ++i) { - rc = erase_page(dev, i); - if (rc < 0) { - break; - } - } - - return rc; -} - -int flash_stm32_write_range(struct device *dev, unsigned int offset, - const void *data, unsigned int len) -{ - int i, rc = 0; - - for (i = 0; i < len; i += 2, offset += 2U) { - rc = write_hword(dev, offset, ((const uint16_t *) data)[i>>1]); - if (rc < 0) { - return rc; - } - } - - return rc; -} - -void flash_stm32_page_layout(struct device *dev, - const struct flash_pages_layout **layout, - size_t *layout_size) -{ - static struct flash_pages_layout stm32f0_flash_layout = { - .pages_count = 0, - .pages_size = 0, - }; - - ARG_UNUSED(dev); - - if (stm32f0_flash_layout.pages_count == 0) { - stm32f0_flash_layout.pages_count = (CONFIG_FLASH_SIZE * 1024) / - FLASH_PAGE_SIZE; - stm32f0_flash_layout.pages_size = FLASH_PAGE_SIZE; - } - - *layout = &stm32f0_flash_layout; - *layout_size = 1; -} diff --git a/drivers/flash/flash_stm32f3x.c b/drivers/flash/flash_stm32f3x.c deleted file mode 100644 index 7de25ccd41f..00000000000 --- a/drivers/flash/flash_stm32f3x.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2019 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define LOG_DOMAIN flash_stm32f3 -#define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL -#include -LOG_MODULE_REGISTER(LOG_DOMAIN); - -#include -#include -#include -#include -#include -#include - -#include "flash_stm32.h" - - -/* offset and len must be aligned on 2 for write - * , positive and not beyond end of flash */ -bool flash_stm32_valid_range(struct device *dev, off_t offset, uint32_t len, - bool write) -{ - return (!write || (offset % 2 == 0 && len % 2 == 0U)) && - flash_stm32_range_exists(dev, offset, len); -} - -static unsigned int get_page(off_t offset) -{ - return offset / FLASH_PAGE_SIZE; -} - -static int erase_page(struct device *dev, unsigned int page) -{ - FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); - uint32_t page_address = CONFIG_FLASH_BASE_ADDRESS; - int rc; - - /* if the control register is locked, do not fail silently */ - if (regs->CR & FLASH_CR_LOCK) { - return -EIO; - } - - /* Check that no Flash memory operation is ongoing */ - rc = flash_stm32_wait_flash_idle(dev); - if (rc < 0) { - return rc; - } - - page_address += page * FLASH_PAGE_SIZE; - - /* Set the PER bit and select the page you wish to erase */ - regs->CR |= FLASH_CR_PER; - /* Set page address */ - regs->AR = page_address; - /* Set the STRT bit */ - regs->CR |= FLASH_CR_STRT; - - /* Wait for the BSY bit */ - rc = flash_stm32_wait_flash_idle(dev); - - regs->CR &= ~FLASH_CR_PER; - - return rc; -} - -int flash_stm32_block_erase_loop(struct device *dev, unsigned int offset, - unsigned int len) -{ - int i, rc = 0; - - i = get_page(offset); - for (; i <= get_page(offset + len - 1) ; ++i) { - rc = erase_page(dev, i); - if (rc < 0) { - break; - } - } - - return rc; -} - - -static int write_hword(struct device *dev, off_t offset, uint16_t val) -{ - volatile uint16_t *flash = (uint16_t *)(offset + CONFIG_FLASH_BASE_ADDRESS); - FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); - uint32_t tmp; - int rc; - - /* if the control register is locked, do not fail silently */ - if (regs->CR & FLASH_CR_LOCK) { - return -EIO; - } - - /* Check that no Flash main memory operation is ongoing */ - rc = flash_stm32_wait_flash_idle(dev); - if (rc < 0) { - return rc; - } - - /* Check if this half word is erased */ - if (*flash != 0xFFFF) { - return -EIO; - } - - /* Set the PG bit */ - regs->CR |= FLASH_CR_PG; - - /* Flush the register write */ - tmp = regs->CR; - - /* Perform the data write operation at the desired memory address */ - *flash = val; - - /* Wait until the BSY bit is cleared */ - rc = flash_stm32_wait_flash_idle(dev); - - /* Clear the PG bit */ - regs->CR &= (~FLASH_CR_PG); - - return rc; -} - - -int flash_stm32_write_range(struct device *dev, unsigned int offset, - const void *data, unsigned int len) -{ - int i, rc = 0; - - for (i = 0; i < len; i += 2, offset += 2U) { - rc = write_hword(dev, offset, ((const uint16_t *) data)[i>>1]); - if (rc < 0) { - return rc; - } - } - - return rc; -} - -void flash_stm32_page_layout(struct device *dev, - const struct flash_pages_layout **layout, - size_t *layout_size) -{ - static struct flash_pages_layout stm32f3_flash_layout = { - .pages_count = 0, - .pages_size = 0, - }; - - ARG_UNUSED(dev); - - if (stm32f3_flash_layout.pages_count == 0) { - stm32f3_flash_layout.pages_count = - DT_REG_SIZE(DT_INST(0, soc_nv_flash)) / FLASH_PAGE_SIZE; - stm32f3_flash_layout.pages_size = FLASH_PAGE_SIZE; - } - - *layout = &stm32f3_flash_layout; - *layout_size = 1; -}