+
+static int stellaris_mass_erase(struct flash_bank_s *bank)
+{
+ target_t *target = NULL;
+ stellaris_flash_bank_t *stellaris_info = NULL;
+ uint32_t flash_fmc;
+
+ stellaris_info = bank->driver_priv;
+ target = bank->target;
+
+ if (target->state != TARGET_HALTED)
+ {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ if (stellaris_info->did1 == 0)
+ {
+ stellaris_read_part_info(bank);
+ }
+
+ if (stellaris_info->did1 == 0)
+ {
+ LOG_WARNING("Cannot identify target as Stellaris");
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+
+ /* Configure the flash controller timing */
+ stellaris_read_clock_info(bank);
+ stellaris_set_flash_mode(bank, 0);
+
+ /* Clear and disable flash programming interrupts */
+ target_write_u32(target, FLASH_CIM, 0);
+ target_write_u32(target, FLASH_MISC, PMISC | AMISC);
+
+ target_write_u32(target, FLASH_FMA, 0);
+ target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
+ /* Wait until erase complete */
+ do
+ {
+ target_read_u32(target, FLASH_FMC, &flash_fmc);
+ }
+ while (flash_fmc & FMC_MERASE);
+
+ /* if device has > 128k, then second erase cycle is needed
+ * this is only valid for older devices, but will not hurt */
+ if (stellaris_info->num_pages * stellaris_info->pagesize > 0x20000)
+ {
+ target_write_u32(target, FLASH_FMA, 0x20000);
+ target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
+ /* Wait until erase complete */
+ do
+ {
+ target_read_u32(target, FLASH_FMC, &flash_fmc);
+ }
+ while (flash_fmc & FMC_MERASE);
+ }
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(stellaris_handle_mass_erase_command)
+{
+ int i;
+
+ if (argc < 1)
+ {
+ command_print(cmd_ctx, "stellaris mass_erase <bank>");
+ return ERROR_OK;
+ }
+
+ flash_bank_t *bank;
+ int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
+ if (ERROR_OK != retval)
+ return retval;
+
+ if (stellaris_mass_erase(bank) == 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, "stellaris mass erase complete");
+ }
+ else
+ {
+ command_print(cmd_ctx, "stellaris mass erase failed");
+ }
+
+ return ERROR_OK;
+}
+
+static int stellaris_register_commands(struct command_context_s *cmd_ctx)
+{
+ command_t *stm32x_cmd = register_command(cmd_ctx, NULL, "stellaris",
+ NULL, COMMAND_ANY, "stellaris flash specific commands");
+
+ register_command(cmd_ctx, stm32x_cmd, "mass_erase",
+ stellaris_handle_mass_erase_command, COMMAND_EXEC,
+ "mass erase device");
+ return ERROR_OK;
+}
+
+
+flash_driver_t stellaris_flash = {
+ .name = "stellaris",
+ .register_commands = &stellaris_register_commands,
+ .flash_bank_command = &stellaris_flash_bank_command,
+ .erase = &stellaris_erase,
+ .protect = &stellaris_protect,
+ .write = &stellaris_write,
+ .probe = &stellaris_probe,
+ .auto_probe = &stellaris_auto_probe,
+ .erase_check = &default_flash_mem_blank_check,
+ .protect_check = &stellaris_protect_check,
+ .info = &stellaris_info,
+ };