aboutsummaryrefslogtreecommitdiff
path: root/src/flash/nor/stm32f2x.c
diff options
context:
space:
mode:
authorMathias K <kesmtp@freenet.de>2011-12-16 07:51:17 +0100
committerSpencer Oliver <spen@spen-soft.co.uk>2011-12-19 12:39:42 +0000
commitc132304ee9fe43c3078caaf64ae0ee2f3a9542fe (patch)
treefb3555e72018927a88b3ae042f7cad1a39494497 /src/flash/nor/stm32f2x.c
parent73e3ea47aad4a46826f8680183935c97e307bb60 (diff)
STM32F2x: check flash unlock, add mass erase
Add verification of the flash unlock sequence and return an error if the flash is still locked. Add mass erase subcommand. Change-Id: Id586b1eaf983a3f25b933847dd6608c15bf0b07e Signed-off-by: Mathias K <kesmtp@freenet.de> Reviewed-on: http://openocd.zylin.com/281 Tested-by: jenkins Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
Diffstat (limited to 'src/flash/nor/stm32f2x.c')
-rw-r--r--src/flash/nor/stm32f2x.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/flash/nor/stm32f2x.c b/src/flash/nor/stm32f2x.c
index 6f041b10..7c07c536 100644
--- a/src/flash/nor/stm32f2x.c
+++ b/src/flash/nor/stm32f2x.c
@@ -233,6 +233,8 @@ static int stm32x_wait_status_busy(struct flash_bank *bank, int timeout)
static int stm32x_unlock_reg(struct target *target)
{
+ uint32_t ctrl;
+
/* unlock flash registers */
int retval = target_write_u32(target, STM32_FLASH_KEYR, KEY1);
if (retval != ERROR_OK)
@@ -241,6 +243,16 @@ static int stm32x_unlock_reg(struct target *target)
retval = target_write_u32(target, STM32_FLASH_KEYR, KEY2);
if (retval != ERROR_OK)
return retval;
+
+ retval = target_read_u32(target, STM32_FLASH_CR, &ctrl);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (ctrl & FLASH_LOCK) {
+ LOG_ERROR("flash not unlocked STM32_FLASH_CR: %x", ctrl);
+ return ERROR_TARGET_FAILURE;
+ }
+
return ERROR_OK;
}
@@ -675,7 +687,76 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
return ERROR_OK;
}
+static int stm32x_mass_erase(struct flash_bank *bank)
+{
+ int retval;
+ struct target *target = bank->target;
+
+ if (target->state != TARGET_HALTED) {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ retval = stm32x_unlock_reg(target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* mass erase flash memory */
+ retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_MER);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),
+ FLASH_MER | FLASH_STRT);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = stm32x_wait_status_busy(bank, 30000);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(stm32x_handle_mass_erase_command)
+{
+ int i;
+
+ if (CMD_ARGC < 1) {
+ command_print(CMD_CTX, "stm32x mass_erase <bank>");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ struct flash_bank *bank;
+ int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+ if (ERROR_OK != retval)
+ return retval;
+
+ retval = stm32x_mass_erase(bank);
+ if (retval == ERROR_OK) {
+ /* set all sectors as erased */
+ for (i = 0; i < bank->num_sectors; i++)
+ bank->sectors[i].is_erased = 1;
+
+ command_print(CMD_CTX, "stm32x mass erase complete");
+ } else {
+ command_print(CMD_CTX, "stm32x mass erase failed");
+ }
+
+ return retval;
+}
+
static const struct command_registration stm32x_exec_command_handlers[] = {
+ {
+ .name = "mass_erase",
+ .handler = stm32x_handle_mass_erase_command,
+ .mode = COMMAND_EXEC,
+ .usage = "bank_id",
+ .help = "Erase entire flash device.",
+ },
COMMAND_REGISTRATION_DONE
};