summaryrefslogtreecommitdiffstats
path: root/spi25.c
diff options
context:
space:
mode:
Diffstat (limited to 'spi25.c')
-rw-r--r--spi25.c72
1 files changed, 14 insertions, 58 deletions
diff --git a/spi25.c b/spi25.c
index b7e8189..083d85f 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;
}
OpenPOWER on IntegriCloud