diff --git a/src/flash/nor/str9x.c b/src/flash/nor/str9x.c index 528e52e26..cfe6a7770 100644 --- a/src/flash/nor/str9x.c +++ b/src/flash/nor/str9x.c @@ -223,6 +223,7 @@ static int str9x_erase(struct flash_bank *bank, int first, int last) uint32_t adr; uint8_t status; uint8_t erase_cmd; + int total_timeout; if (bank->target->state != TARGET_HALTED) { @@ -230,16 +231,27 @@ static int str9x_erase(struct flash_bank *bank, int first, int last) return ERROR_TARGET_NOT_HALTED; } - /*A slower but stable way of erasing*/ - /* Erase sector command */ - erase_cmd = 0x20; + /* Check if we can erase whole bank */ + if ((first == 0) && (last == (bank->num_sectors - 1))) + { + /* Optimize to run erase bank command instead of sector */ + erase_cmd = 0x80; + /* Add timeout duration since erase bank takes more time */ + total_timeout = 1000 * bank->num_sectors; + } + else + { + /* Erase sector command */ + erase_cmd = 0x20; + total_timeout = 1000; + } for (i = first; i <= last; i++) { int retval; adr = bank->base + bank->sectors[i].offset; - /* erase sectors */ + /* erase sectors or block */ if ((retval = target_write_u16(target, adr, erase_cmd)) != ERROR_OK) { return retval; @@ -256,7 +268,8 @@ static int str9x_erase(struct flash_bank *bank, int first, int last) } int timeout; - for (timeout = 0; timeout < 1000; timeout++) { + for (timeout = 0; timeout < total_timeout; timeout++) + { if ((retval = target_read_u8(target, adr, &status)) != ERROR_OK) { return retval; @@ -265,7 +278,7 @@ static int str9x_erase(struct flash_bank *bank, int first, int last) break; alive_sleep(1); } - if (timeout == 1000) + if (timeout == total_timeout) { LOG_ERROR("erase timed out"); return ERROR_FAIL; @@ -288,6 +301,10 @@ static int str9x_erase(struct flash_bank *bank, int first, int last) LOG_ERROR("error erasing flash bank, status: 0x%x", status); return ERROR_FLASH_OPERATION_FAILED; } + + /* If we ran erase bank command, we are finished */ + if (erase_cmd == 0x80) + break; } for (i = first; i <= last; i++)