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>
__archive__
Mathias K 2011-12-16 07:51:17 +01:00 committed by Spencer Oliver
parent 73e3ea47aa
commit c132304ee9
1 changed files with 81 additions and 0 deletions

View File

@ -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
};