X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fstr9x.c;h=1e71753e67edc5110100dc6af989ba438886b79a;hp=3d8b84b3df2ef6187667386340ff6a215b41727e;hb=f1f8d9a6c9b1fd35d79627b568faa2409f13311f;hpb=6344f2ab98cf1fd1f92403de46b6e36b3b122ad5 diff --git a/src/flash/nor/str9x.c b/src/flash/nor/str9x.c index 3d8b84b3df..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 */ @@ -385,7 +404,7 @@ static int str9x_write_block(struct flash_bank *bank, (uint8_t*)str9x_flash_write_code); /* memory buffer */ - while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) + while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { buffer_size /= 2; if (buffer_size <= 256) @@ -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; @@ -564,7 +582,7 @@ static int str9x_write(struct flash_bank *bank, if (bytes_remaining) { uint8_t last_halfword[2] = {0xff, 0xff}; - int i = 0; + i = 0; while (bytes_remaining > 0) { @@ -621,7 +639,7 @@ COMMAND_HANDLER(str9x_handle_part_id_command) } #endif -static int str9x_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_str9x_info(struct flash_bank *bank, char *buf, int buf_size) { snprintf(buf, buf_size, "str9x flash driver info"); return ERROR_OK; @@ -701,9 +719,10 @@ struct flash_driver str9x_flash = { .erase = str9x_erase, .protect = str9x_protect, .write = str9x_write, + .read = default_flash_read, .probe = str9x_probe, .auto_probe = str9x_probe, .erase_check = default_flash_blank_check, .protect_check = str9x_protect_check, - .info = str9x_info, + .info = get_str9x_info, };