diff --git a/spi25.c b/spi25.c index b7e8189e1..083d85f5d 100644 --- a/spi25.c +++ b/spi25.c @@ -764,63 +764,19 @@ int spi_write_status_enable(struct flashctx *flash) * This is according the SST25VF016 datasheet, who knows it is more * generic that this... */ -static int spi_write_status_register_ewsr(struct flashctx *flash, int status) +static int spi_write_status_register_flag(struct flashctx *flash, int status, const unsigned char enable_opcode) { int result; int i = 0; - struct spi_command cmds[] = { - { - /* WRSR requires either EWSR or WREN depending on chip type. */ - .writecnt = JEDEC_EWSR_OUTSIZE, - .writearr = (const unsigned char[]){ JEDEC_EWSR }, - .readcnt = 0, - .readarr = NULL, - }, { - .writecnt = JEDEC_WRSR_OUTSIZE, - .writearr = (const unsigned char[]){ JEDEC_WRSR, (unsigned char) status }, - .readcnt = 0, - .readarr = NULL, - }, { - .writecnt = 0, - .writearr = NULL, - .readcnt = 0, - .readarr = NULL, - }}; - - result = spi_send_multicommand(flash, cmds); - if (result) { - msg_cerr("%s failed during command execution\n", - __func__); - /* No point in waiting for the command to complete if execution - * failed. - */ - return result; - } - /* WRSR performs a self-timed erase before the changes take effect. - * This may take 50-85 ms in most cases, and some chips apparently - * allow running RDSR only once. Therefore pick an initial delay of - * 100 ms, then wait in 10 ms steps until a total of 5 s have elapsed. + /* + * WRSR requires either EWSR or WREN depending on chip type. + * The code below relies on the fact hat EWSR and WREN have the same + * INSIZE and OUTSIZE. */ - programmer_delay(100 * 1000); - while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP) { - if (++i > 490) { - msg_cerr("Error: WIP bit after WRSR never cleared\n"); - return TIMEOUT_ERROR; - } - programmer_delay(10 * 1000); - } - return 0; -} - -static int spi_write_status_register_wren(struct flashctx *flash, int status) -{ - int result; - int i = 0; struct spi_command cmds[] = { { - /* WRSR requires either EWSR or WREN depending on chip type. */ .writecnt = JEDEC_WREN_OUTSIZE, - .writearr = (const unsigned char[]){ JEDEC_WREN }, + .writearr = (const unsigned char[]){ enable_opcode }, .readcnt = 0, .readarr = NULL, }, { @@ -837,8 +793,7 @@ static int spi_write_status_register_wren(struct flashctx *flash, int status) result = spi_send_multicommand(flash, cmds); if (result) { - msg_cerr("%s failed during command execution\n", - __func__); + msg_cerr("%s failed during command execution\n", __func__); /* No point in waiting for the command to complete if execution * failed. */ @@ -862,17 +817,18 @@ static int spi_write_status_register_wren(struct flashctx *flash, int status) int spi_write_status_register(struct flashctx *flash, int status) { + int feature_bits = flash->feature_bits; int ret = 1; - if (!(flash->feature_bits & (FEATURE_WRSR_WREN | FEATURE_WRSR_EWSR))) { + if (!(feature_bits & (FEATURE_WRSR_WREN | FEATURE_WRSR_EWSR))) { msg_cdbg("Missing status register write definition, assuming " "EWSR is needed\n"); - flash->feature_bits |= FEATURE_WRSR_EWSR; + feature_bits |= FEATURE_WRSR_EWSR; } - if (flash->feature_bits & FEATURE_WRSR_WREN) - ret = spi_write_status_register_wren(flash, status); - if (ret && (flash->feature_bits & FEATURE_WRSR_EWSR)) - ret = spi_write_status_register_ewsr(flash, status); + if (feature_bits & FEATURE_WRSR_WREN) + ret = spi_write_status_register_flag(flash, status, JEDEC_WREN); + if (ret && (feature_bits & FEATURE_WRSR_EWSR)) + ret = spi_write_status_register_flag(flash, status, JEDEC_EWSR); return ret; }