X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fstr9x.c;h=1e71753e67edc5110100dc6af989ba438886b79a;hb=d16dbaa0fc7b8a2f40cf9b283f716d2d7344504b;hp=103af16de5f42ecd74d17dd07d9c34adae67697b;hpb=f9acaa894fbb15ec93463bc4f5eaceb23e0ba3c1;p=openocd.git diff --git a/src/flash/nor/str9x.c b/src/flash/nor/str9x.c index 103af16de5..1e71753e67 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++) @@ -347,6 +364,8 @@ static int str9x_write_block(struct flash_bank *bank, struct arm_algorithm armv4_5_info; int retval = ERROR_OK; + /* see contib/loaders/flash/str9x.s for src */ + static const uint32_t str9x_flash_write_code[] = { /* write: */ 0xe3c14003, /* bic r4, r1, #3 */ @@ -369,7 +388,7 @@ static int str9x_write_block(struct flash_bank *bank, 0xe2522001, /* subs r2, r2, #1 */ 0x1affffed, /* bne write */ /* exit: */ - 0xeafffffe, /* b exit */ + 0xe1200070, /* bkpt #0 */ }; /* flash write code */ @@ -421,8 +440,7 @@ static int str9x_write_block(struct flash_bank *bank, if ((retval = target_run_algorithm(target, 0, NULL, 4, reg_params, str9x_info->write_algorithm->address, - str9x_info->write_algorithm->address + (sizeof(str9x_flash_write_code) - 4), - 10000, &armv4_5_info)) != ERROR_OK) + 0, 10000, &armv4_5_info)) != ERROR_OK) { LOG_ERROR("error executing str9x flash write algorithm"); retval = ERROR_FLASH_OPERATION_FAILED;