|
|
|
|
|
|
|
|
void SerialFlashChip::read(uint32_t addr, void *buf, uint32_t len) |
|
|
void SerialFlashChip::read(uint32_t addr, void *buf, uint32_t len) |
|
|
{ |
|
|
{ |
|
|
uint8_t *p = (uint8_t *)buf; |
|
|
uint8_t *p = (uint8_t *)buf; |
|
|
uint8_t b, f, status; |
|
|
|
|
|
|
|
|
uint8_t b, f, status, cmd; |
|
|
|
|
|
|
|
|
memset(p, 0, len); |
|
|
memset(p, 0, len); |
|
|
f = flags; |
|
|
f = flags; |
|
|
|
|
|
|
|
|
SPI.transfer(0x06); // write enable (Micron req'd) |
|
|
SPI.transfer(0x06); // write enable (Micron req'd) |
|
|
CSRELEASE(); |
|
|
CSRELEASE(); |
|
|
delayMicroseconds(1); |
|
|
delayMicroseconds(1); |
|
|
|
|
|
cmd = 0x75; //Suspend program/erase for almost all chips |
|
|
|
|
|
// but Spansion just has to be different for program suspend! |
|
|
|
|
|
if ((f & FLAG_DIFF_SUSPEND) && (b == 1)) cmd = 0x85; |
|
|
CSASSERT(); |
|
|
CSASSERT(); |
|
|
SPI.transfer(0x75); // Suspend program/erase |
|
|
|
|
|
|
|
|
SPI.transfer(cmd); // Suspend command |
|
|
CSRELEASE(); |
|
|
CSRELEASE(); |
|
|
if (f & FLAG_STATUS_CMD70) { |
|
|
if (f & FLAG_STATUS_CMD70) { |
|
|
// Micron chips don't actually suspend until flags read |
|
|
// Micron chips don't actually suspend until flags read |
|
|
|
|
|
|
|
|
} while (!(status & 0x80)); |
|
|
} while (!(status & 0x80)); |
|
|
CSRELEASE(); |
|
|
CSRELEASE(); |
|
|
} else { |
|
|
} else { |
|
|
delayMicroseconds(20); // Tsus = 20us (Winbond) |
|
|
|
|
|
|
|
|
CSASSERT(); |
|
|
|
|
|
SPI.transfer(0x05); |
|
|
|
|
|
do { |
|
|
|
|
|
status = SPI.transfer(0); |
|
|
|
|
|
} while ((status & 0x01)); |
|
|
|
|
|
CSRELEASE(); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
// chip is busy with an operation that can not suspend |
|
|
// chip is busy with an operation that can not suspend |
|
|
|
|
|
|
|
|
} while (len > 0); |
|
|
} while (len > 0); |
|
|
if (b) { |
|
|
if (b) { |
|
|
CSASSERT(); |
|
|
CSASSERT(); |
|
|
SPI.transfer(0x06); // write enable (Micro req'd) |
|
|
|
|
|
|
|
|
SPI.transfer(0x06); // write enable (Micron req'd) |
|
|
CSRELEASE(); |
|
|
CSRELEASE(); |
|
|
delayMicroseconds(1); |
|
|
delayMicroseconds(1); |
|
|
|
|
|
cmd = 0x7A; |
|
|
|
|
|
if ((f & FLAG_DIFF_SUSPEND) && (b == 1)) cmd = 0x8A; |
|
|
CSASSERT(); |
|
|
CSASSERT(); |
|
|
SPI.transfer(0x7A); // Resume program/erase |
|
|
|
|
|
|
|
|
SPI.transfer(cmd); // Resume program/erase |
|
|
CSRELEASE(); |
|
|
CSRELEASE(); |
|
|
} |
|
|
} |
|
|
SPI.endTransaction(); |
|
|
SPI.endTransaction(); |