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