diff options
author | Fredrik Hederstierna <fredrik.hederstierna@securitas-direct.com> | 2010-08-12 08:53:29 +0200 |
---|---|---|
committer | Øyvind Harboe <oyvind.harboe@zylin.com> | 2010-08-12 08:53:29 +0200 |
commit | a8c8c238f2dd1abe102f83bfa392ac40f313dd73 (patch) | |
tree | 095bfef36224c8b6e7a1ec1dbc5f8316715b4e4f /src | |
parent | 8f779cf66bf459616b7dad88e871c2f4a7315371 (diff) | |
download | openocd+libswd-a8c8c238f2dd1abe102f83bfa392ac40f313dd73.tar.gz openocd+libswd-a8c8c238f2dd1abe102f83bfa392ac40f313dd73.tar.bz2 openocd+libswd-a8c8c238f2dd1abe102f83bfa392ac40f313dd73.tar.xz openocd+libswd-a8c8c238f2dd1abe102f83bfa392ac40f313dd73.zip |
str9x: faster flash erase of entire chip
The patch improves flash erase for STR9x in case of a full bank erase.
Then the chip erase command is used instead which improves speed significantly.
Also I think it might help if e.g. STR912 enters some state where flash banks are locked, and a chip erase command is the key for unlocking the flash.
Diffstat (limited to 'src')
-rw-r--r-- | src/flash/nor/str9x.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/src/flash/nor/str9x.c b/src/flash/nor/str9x.c index 528e52e2..cfe6a777 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++) |