]> git.sur5r.net Git - openocd/commitdiff
STM32F2x: check flash unlock, add mass erase
authorMathias K <kesmtp@freenet.de>
Fri, 16 Dec 2011 06:51:17 +0000 (07:51 +0100)
committerSpencer Oliver <spen@spen-soft.co.uk>
Mon, 19 Dec 2011 12:39:42 +0000 (12:39 +0000)
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>
src/flash/nor/stm32f2x.c

index 6f041b10f8c85c3c9d1a93be843393621840d8d3..7c07c5365abd74e1c289ce9c4c0d3253428feff4 100644 (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
 };