stlink-org/stlink

STM32G491: programming flash error, non-erased value. (was #1310)

salyzyn opened this issue · 1 comments

See #1310

issue was not resolved. The following does fix it, but I recommend a full test of all legacy supported devices to make sure we did not break anything.

I have worked on a fix, and here is the changes required:

Subject: Support Category 4 device (stm32g491)

Signed-off-by: Mark Salyzyn <mark.salyzyn@gmail.com>

diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c
index 70ecdd3..ac8b12a 100644
--- a/src/stlink-lib/common.c
+++ b/src/stlink-lib/common.c
@@ -296,8 +296,7 @@ int32_t stlink_load_device_params(stlink_t *sl) {
     sl->sram_size = 0x1000;
   }
 
-  if (sl->chip_id == STM32_CHIPID_G4_CAT3 ||
-      sl->chip_id == STM32_CHIPID_G4_CAT4) {
+  if (sl->chip_id == STM32_CHIPID_G4_CAT3) {
     uint32_t flash_optr;
     stlink_read_debug32(sl, FLASH_Gx_OPTR, &flash_optr);
 
diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c
index f2281ac..d6bb366 100644
--- a/src/stlink-lib/common_flash.c
+++ b/src/stlink-lib/common_flash.c
@@ -1077,8 +1077,8 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) {
       uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz);
       stlink_read_debug32(sl, FLASH_Gx_CR, &val);
       // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2.
-      val &= ~(0x7F << 3);
-      val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER);
+      val &= ~(0xFF << 3);
+      val |= ((flash_page & 0xFF) << 3) | (1 << FLASH_CR_PER);
       stlink_write_debug32(sl, FLASH_Gx_CR, val);
     } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) {
       uint32_t flash_page;

I have explored some cargo cult suggested by STM surrounding invalidating the Category 4 flash cache as part of erasing, but found it unnecessary in the context of the tool, especially since erase cycle goes to completion from start to end, then the flash of the device from start to end.

The mask change from 0x7F to 0xFF might need to be gated on whether CAT3 or CAT4 device, but only if in your infinite wisdom we do not want to make an assumption that the bit is zero and needs to be maintained.

eg:

      uint32_t mask = (sl->chip_id == STM32_CHIPID_G4_CAT4) ? 0xFF : 0x7F;
      val &= ~(mask << 3);
      val |= ((flash_page & mask) << 3) | (1 << FLASH_CR_PER);