From 64809fcb31c13290ee66d12e0bf76d14eb6d0953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phanie=20Amati?= Date: Thu, 8 Oct 2026 23:30:54 +0100 Subject: [PATCH] Corrected F4 sector number calculation for F413 and F423. --- src/stlink-lib/calculate.c | 23 +++++++++++++++++++---- src/stlink-lib/calculate.h | 2 +- src/stlink-lib/common_flash.c | 10 ++-------- src/stlink-lib/common_legacy.c | 9 ++++++--- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/stlink-lib/calculate.c b/src/stlink-lib/calculate.c index b90c7a7b..ea446d48 100644 --- a/src/stlink-lib/calculate.c +++ b/src/stlink-lib/calculate.c @@ -17,13 +17,28 @@ #include "read_write.h" -uint32_t calculate_F4_sectornum(uint32_t flashaddr) { +uint32_t calculate_F4_sectornum(stlink_t *sl, uint32_t flashaddr) { uint32_t offset = 0; flashaddr &= ~STM32_FLASH_BASE; // page now holding the actual flash address - if(flashaddr >= 0x100000) { - offset = 12; - flashaddr -= 0x100000; + /* The F413 and F423 chips have a single bank flash */ + if (sl->chip_id != STM32_CHIPID_F413) { + /* Dual bank flash of 1MB have a discontinuity in their sector + numbering. Sector 7 is the last from the first bank and sector 12 is + the first from the second bank. */ + if (sl->flash_size <= 1024*1024) { + if (flashaddr >= 0x080000) { + offset = 12; + flashaddr -= 0x080000; + } + } + /* Dual bank flash of 2MB */ + else { + if (flashaddr >= 0x100000) { + offset = 12; + flashaddr -= 0x100000; + } + } } if(flashaddr < 0x4000) { diff --git a/src/stlink-lib/calculate.h b/src/stlink-lib/calculate.h index 726f027a..527d8f06 100644 --- a/src/stlink-lib/calculate.h +++ b/src/stlink-lib/calculate.h @@ -19,7 +19,7 @@ #include -uint32_t calculate_F4_sectornum(uint32_t); +uint32_t calculate_F4_sectornum(stlink_t *, uint32_t); uint32_t calculate_F7_sectornum(uint32_t); uint32_t calculate_H7_sectornum(stlink_t *, uint32_t, uint32_t); uint32_t calculate_L4_page(stlink_t *, uint32_t); diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 570ab78c..36e16942 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -1234,17 +1234,11 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { // STM32F4 } else { // calculate the actual page from the address - uint32_t sector = calculate_F4_sectornum(flashaddr); + uint32_t sector = calculate_F4_sectornum(sl, flashaddr); fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, stlink_calculate_pagesize(sl, flashaddr)); - // the SNB values for flash sectors in the second bank do not directly - // follow the values for the first bank on 2mb devices... - if(sector >= 12) { - sector += 4; - } - write_flash_cr_snb(sl, sector, BANK_1); } @@ -1567,7 +1561,7 @@ int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, uint32_ return (-1); } - fprintf(stdout, "-> Flash page at %#x erased (size: %#x)\n", addr, page_size); + fprintf(stdout, "-> Flash sector at %#x erased (size: %#x)\n", addr, page_size); fflush(stdout); // check the next page is within the range to erase diff --git a/src/stlink-lib/common_legacy.c b/src/stlink-lib/common_legacy.c index ea92851d..08985560 100644 --- a/src/stlink-lib/common_legacy.c +++ b/src/stlink-lib/common_legacy.c @@ -1047,10 +1047,13 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { (sl->chip_id == STM32_CHIPID_F412) || (sl->chip_id == STM32_CHIPID_F410) || (sl->chip_id == STM32_CHIPID_F413)) { - uint32_t sector = calculate_F4_sectornum(flashaddr); + uint32_t sector = calculate_F4_sectornum(sl, flashaddr); - if(sector >= 12) { - sector -= 12; + /* Correct sector for dual bank flash memories only */ + if (sl->chip_id != STM32_CHIPID_F413) { + if(sector >= 12) { + sector -= 12; + } } if(sector < 4) {