diff options
author | Mathias K <kesmtp@freenet.de> | 2011-12-16 07:51:17 +0100 |
---|---|---|
committer | Spencer Oliver <spen@spen-soft.co.uk> | 2011-12-19 12:39:42 +0000 |
commit | c132304ee9fe43c3078caaf64ae0ee2f3a9542fe (patch) | |
tree | fb3555e72018927a88b3ae042f7cad1a39494497 /src | |
parent | 73e3ea47aad4a46826f8680183935c97e307bb60 (diff) | |
download | riscv-openocd-c132304ee9fe43c3078caaf64ae0ee2f3a9542fe.zip riscv-openocd-c132304ee9fe43c3078caaf64ae0ee2f3a9542fe.tar.gz riscv-openocd-c132304ee9fe43c3078caaf64ae0ee2f3a9542fe.tar.bz2 |
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')
-rw-r--r-- | src/flash/nor/stm32f2x.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/flash/nor/stm32f2x.c b/src/flash/nor/stm32f2x.c index 6f041b1..7c07c53 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 }; |