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>
This commit is contained in:
parent
73e3ea47aa
commit
c132304ee9
|
@ -233,6 +233,8 @@ static int stm32x_wait_status_busy(struct flash_bank *bank, int timeout)
|
||||||
|
|
||||||
static int stm32x_unlock_reg(struct target *target)
|
static int stm32x_unlock_reg(struct target *target)
|
||||||
{
|
{
|
||||||
|
uint32_t ctrl;
|
||||||
|
|
||||||
/* unlock flash registers */
|
/* unlock flash registers */
|
||||||
int retval = target_write_u32(target, STM32_FLASH_KEYR, KEY1);
|
int retval = target_write_u32(target, STM32_FLASH_KEYR, KEY1);
|
||||||
if (retval != ERROR_OK)
|
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);
|
retval = target_write_u32(target, STM32_FLASH_KEYR, KEY2);
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
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;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,7 +687,76 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
|
||||||
return ERROR_OK;
|
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[] = {
|
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
|
COMMAND_REGISTRATION_DONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue