summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2023-11-01 19:12:09 +1100
committerDamien George <damien@micropython.org>2024-01-08 12:33:34 +1100
commitb6ab9e420b0a874eb2f8f6b7597430ed9e526bf7 (patch)
treec323b9c7839b3037169a4ae1f28eafcade531fb0
parentcf115918e66bea460256661848d9198ca6ca994d (diff)
stm32/flash: Change flash_erase to only erase a single sector at a time.
An erase sector sits in a given flash bank and some MCUs have two flash banks. If trying to erase a range of sectors and that range crosses from one flash bank into the next, the original implementation of `flash_erase()` would not handle this case and would do the wrong thing. This commit changes `flash_erase()` to only erase a single sector, which sidesteps the need to handle flash-bank-crossing. Most callers of this function only need to erase a single sector anyway. Signed-off-by: Damien George <damien@micropython.org>
-rw-r--r--ports/stm32/flash.c21
-rw-r--r--ports/stm32/flash.h2
-rw-r--r--ports/stm32/flashbdev.c2
-rw-r--r--ports/stm32/mboot/main.c2
4 files changed, 13 insertions, 14 deletions
diff --git a/ports/stm32/flash.c b/ports/stm32/flash.c
index d9f7af8a2..fb1e6059c 100644
--- a/ports/stm32/flash.c
+++ b/ports/stm32/flash.c
@@ -272,11 +272,10 @@ int32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *siz
return -1;
}
-int flash_erase(uint32_t flash_dest, uint32_t num_word32) {
- // check there is something to write
- if (num_word32 == 0) {
- return 0;
- }
+// Erase a single flash page which starts at the given address.
+// The address will be converted to a bank and sector number.
+int flash_erase(uint32_t flash_dest) {
+ const unsigned int num_sectors = 1;
#if MICROPY_HW_STM32WB_FLASH_SYNCRONISATION
// Acquire lock on the flash peripheral.
@@ -306,23 +305,23 @@ int flash_erase(uint32_t flash_dest, uint32_t num_word32) {
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = flash_dest;
- EraseInitStruct.NbPages = (4 * num_word32 + FLASH_PAGE_SIZE - 4) / FLASH_PAGE_SIZE;
+ EraseInitStruct.NbPages = num_sectors;
#elif defined(STM32G0) || defined(STM32G4)
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Page = get_page(flash_dest);
EraseInitStruct.Banks = get_bank(flash_dest);
- EraseInitStruct.NbPages = (4 * num_word32 + FLASH_PAGE_SIZE - 4) / FLASH_PAGE_SIZE;
+ EraseInitStruct.NbPages = num_sectors;
#elif defined(STM32L0) || defined(STM32L1)
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR);
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = flash_dest;
- EraseInitStruct.NbPages = (4 * num_word32 + FLASH_PAGE_SIZE - 4) / FLASH_PAGE_SIZE;
+ EraseInitStruct.NbPages = num_sectors;
#elif (defined(STM32L4) && !defined(SYSCFG_MEMRMP_FB_MODE)) || defined(STM32WB) || defined(STM32WL)
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Page = get_page(flash_dest);
- EraseInitStruct.NbPages = (4 * num_word32 + FLASH_PAGE_SIZE - 4) / FLASH_PAGE_SIZE;
+ EraseInitStruct.NbPages = num_sectors;
#elif defined(STM32L4)
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
// The sector returned by flash_get_sector_info can not be used
@@ -330,7 +329,7 @@ int flash_erase(uint32_t flash_dest, uint32_t num_word32) {
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Banks = get_bank(flash_dest);
EraseInitStruct.Page = get_page(flash_dest);
- EraseInitStruct.NbPages = get_page(flash_dest + 4 * num_word32 - 1) - EraseInitStruct.Page + 1;
+ EraseInitStruct.NbPages = num_sectors;
#else
#if defined(STM32H5)
@@ -354,7 +353,7 @@ int flash_erase(uint32_t flash_dest, uint32_t num_word32) {
EraseInitStruct.Banks = get_bank(flash_dest);
#endif
EraseInitStruct.Sector = flash_get_sector_info(flash_dest, NULL, NULL);
- EraseInitStruct.NbSectors = flash_get_sector_info(flash_dest + 4 * num_word32 - 1, NULL, NULL) - EraseInitStruct.Sector + 1;
+ EraseInitStruct.NbSectors = num_sectors;
#if defined(STM32H5)
EraseInitStruct.Sector &= 0x7f; // second bank should start counting at 0
#endif
diff --git a/ports/stm32/flash.h b/ports/stm32/flash.h
index ecda923db..e5ba35cf7 100644
--- a/ports/stm32/flash.h
+++ b/ports/stm32/flash.h
@@ -28,7 +28,7 @@
bool flash_is_valid_addr(uint32_t addr);
int32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size);
-int flash_erase(uint32_t flash_dest, uint32_t num_word32);
+int flash_erase(uint32_t flash_dest);
int flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32);
#endif // MICROPY_INCLUDED_STM32_FLASH_H
diff --git a/ports/stm32/flashbdev.c b/ports/stm32/flashbdev.c
index 19edde210..e96c54e79 100644
--- a/ports/stm32/flashbdev.c
+++ b/ports/stm32/flashbdev.c
@@ -161,7 +161,7 @@ static void flash_bdev_irq_handler(void) {
// This code erases the flash directly, waiting for it to finish
if (!(flash_flags & FLASH_FLAG_ERASED)) {
- flash_erase(flash_cache_sector_start, flash_cache_sector_size / 4);
+ flash_erase(flash_cache_sector_start);
flash_flags |= FLASH_FLAG_ERASED;
return;
}
diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c
index 117553087..2424b37da 100644
--- a/ports/stm32/mboot/main.c
+++ b/ports/stm32/mboot/main.c
@@ -465,7 +465,7 @@ static int mboot_flash_page_erase(uint32_t addr, uint32_t *next_addr) {
}
// Erase the flash page.
- ret = flash_erase(sector_start, sector_size / sizeof(uint32_t));
+ ret = flash_erase(sector_start);
if (ret != 0) {
return ret;
}