Hello,
I have added a new command for stm32x : mass_erase_unlock
This function combine "stm32x unlock 0" + reset to apply unlock + "stm32x mass_erase 0" In this way, it is more easier to handle the unlock sequence and makes the (annoying) reset procedure transparent.
After calling mass_erase_unlock, flash write_image can immediately  called.
Here is an example of my flashing procedure :

init
jtag_khz 1000
reset_config trst_and_srst
halt
flash probe 0
flash protect 0 0 last off
stm32x mass_erase_unlock 0
flash write_bank 0 file.bin 0
flash protect 0 0 last on
verify_image file.bin 0

Thanks
Gaƫtan
---
stm32x.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)
---
o
diff --git a/src/flash/nor/stm32x.c b/src/flash/nor/stm32x.c
index d11a8ed..2e31b62 100644
--- a/src/flash/nor/stm32x.c
+++ b/src/flash/nor/stm32x.c
@@ -1235,6 +1235,71 @@ COMMAND_HANDLER(stm32x_handle_mass_erase_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(stm32x_handle_mass_erase_unlock_command)
+{
+       uint32_t status;
+       struct flash_bank *bank;
+       int retval;
+
+       if (CMD_ARGC < 1)
+       {
+               command_print(CMD_CTX, "stm32x mass_erase_unlock <bank>");
+               return ERROR_OK;
+       }
+
+       retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+       if (ERROR_OK != retval)
+               return retval;
+
+       struct target *target = bank->target;
+       if (target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       /* unlock option flash registers */
+       target_write_u32(target, STM32_FLASH_KEYR, KEY1);
+       target_write_u32(target, STM32_FLASH_KEYR, KEY2);
+
+       /* Reset to apply no settings */
+       target_write_u32(target, 0xE000ED0C, 0x05FA0004);
+       usleep(1000);
+
+       /* unlock option flash registers */
+       target_write_u32(target, STM32_FLASH_KEYR, KEY1);
+       target_write_u32(target, STM32_FLASH_KEYR, KEY2);
+
+       /* mass erase flash memory */
+       target_write_u32(target, STM32_FLASH_CR, FLASH_MER);
+       target_write_u32(target, STM32_FLASH_CR, FLASH_MER | FLASH_STRT);
+
+       status = stm32x_wait_status_busy(bank, 100);
+       target_read_u32(target, STM32_FLASH_SR, &status);
+
+       target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
+
+       if (status & FLASH_WRPRTERR)
+       {
+               LOG_ERROR("stm32x device protected");
+               return ERROR_FLASH_OPERATION_FAILED;
+       }
+
+       if (status & FLASH_PGERR)
+       {
+               LOG_ERROR("stm32x device programming failed");
+               return ERROR_FLASH_OPERATION_FAILED;
+       }
+       /* set all sectors as erased */
+       for (int i = 0; i < bank->num_sectors; i++)
+       {
+               bank->sectors[i].is_erased = 1;
+       }
+       command_print(CMD_CTX, "stm32x mass erase with unlock complete");
+
+       return ERROR_OK;
+}
+
 static const struct command_registration stm32x_exec_command_handlers[] = {
        {
                .name = "lock",
@@ -1258,6 +1323,15 @@ static const struct command_registration 
stm32x_exec_command_handlers[] = {
                .help = "Erase entire flash device.",
        },
        {
+               .name = "mass_erase_unlock",
+               .handler = stm32x_handle_mass_erase_unlock_command,
+               .mode = COMMAND_EXEC,
+               .usage = "bank_id",
+               .help = "Erase entire flash device with auto-unlock. "
+                       "This will unlock, reset and then mass erase stm32x. "
+                       "This is an improve version of unlock + mass_erase",
+       },
+       {
                .name = "options_read",
                .handler = stm32x_handle_options_read_command,
                .mode = COMMAND_EXEC,
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to