From 589e2446a1b667f367ba40f56c4f153e82f293db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20DUBOIN?= Date: Thu, 8 Aug 2024 19:32:23 +0200 Subject: [PATCH 1/2] STM32Gx: flash: Set BKER bit for multi-bank products before erasing Products of the Gx series with more than 128K of flash use 2 banks. In this case we need to specify which bank to erase using the BKER bit. Reference: 3.7.5 - BKER --- inc/stm32flash.h | 1 + src/stlink-lib/common_flash.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/inc/stm32flash.h b/inc/stm32flash.h index 56fac5af..fb10f0e1 100644 --- a/inc/stm32flash.h +++ b/inc/stm32flash.h @@ -181,6 +181,7 @@ #define FLASH_Gx_CR_PNB (3) /* Page number */ #define FLASH_G0_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ #define FLASH_G4_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ +#define FLASH_Gx_CR_BKER (13) /* Bank selection for erase operation */ #define FLASH_Gx_CR_MER2 (15) /* Mass erase (2nd bank)*/ #define FLASH_Gx_CR_STRT (16) /* Start */ #define FLASH_Gx_CR_OPTSTRT (17) /* Start of modification of option bytes */ diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 31506c66..726f2630 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -1122,6 +1122,14 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { stlink_read_debug32(sl, FLASH_Gx_CR, &val); // sec 3.7.5 - PNB[9:0] is offset by 3. PER is 0x2. val &= ~(0x7FF << 3); + // Products of the Gx series with more than 128K of flash use 2 banks. + // In this case we need to specify which bank to erase (sec 3.7.5 - BKER) + if (sl->flash_size > (128 * 1024) && + ((flashaddr - STM32_FLASH_BASE) >= sl->flash_size / 2)) { + val |= (1 << FLASH_Gx_CR_BKER); // erase bank 2 + } else { + val &= ~(1 << FLASH_Gx_CR_BKER); // erase bank 1 + } val |= ((flash_page & 0x7FF) << 3) | (1 << FLASH_CR_PER); stlink_write_debug32(sl, FLASH_Gx_CR, val); // STM32L5x2xx has two banks with 2k pages or single with 4k pages From bff61510b154efd1759bf99dd87c98c8c9cfcaa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20DUBOIN?= Date: Thu, 8 Aug 2024 19:34:15 +0200 Subject: [PATCH 2/2] STM32Gx: flash: clear programming mode before erasing As described in 3.3.8, if erasing while another mode's "enable" bit is set, a programming sequence error will be raised. This change makes sure this will not happen for an erase operation. --- src/stlink-lib/common_flash.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 726f2630..70d3e7df 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -1122,6 +1122,10 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { stlink_read_debug32(sl, FLASH_Gx_CR, &val); // sec 3.7.5 - PNB[9:0] is offset by 3. PER is 0x2. val &= ~(0x7FF << 3); + // sec 3.3.8 - Error PGSERR + // * In the page erase sequence: PG, FSTPG and MER1 are not cleared when PER is set + val &= ~(1 << FLASH_Gx_CR_MER1 | 1 << FLASH_Gx_CR_MER2); + val &= ~(1 << FLASH_Gx_CR_PG); // Products of the Gx series with more than 128K of flash use 2 banks. // In this case we need to specify which bank to erase (sec 3.7.5 - BKER) if (sl->flash_size > (128 * 1024) &&