Discard undefined byte at end of write multiple block

This byte needs to be read before the card goes busy, but more importantly,
it would otherwise be read out by sd_wait_ready():

For cards where this byte is 0xff, sd_wait_ready() would think the card is
immediately ready and let the code send it the next command, while the read
actually made the card go busy.

This makes the card end up in a state the code cannot recover it from - even
if you reboot the machine so spisd.device is restarted, it still requires
the card to be power cycled by ejecting and re-inserting it.

How to reproduce for affected cards:
1. Use spisd.device v2.2
2. Mount SD0:
3. Write a file larger than 512Bytes to trigger a write multiple block
4. Write or read another file, this will trigger the next command and show
   the issue as a read or write error
This commit is contained in:
Patrik Axelsson 2023-08-29 21:47:48 +02:00 committed by Niklas Ekström
parent a8488355cb
commit d56fbaaaf4

View File

@ -239,8 +239,16 @@ static int sd_write_block(const uint8_t *buf, uint8_t token)
/* Send token */
spi_write(&token, 1);
if (token != 0xfd) {
/* Send data, except for STOP_TRAN */
if (token == 0xfd) {
/* After sending STOP_TRAN, a byte needs to be read before the card
* goes busy. This byte is undefined, so unless we read it now, the
* next sd_wait_ready() will read it and could erronously decide
* that the card is immediately ready.
*/
spi_read(&resp, 1);
}
else {
/* Send data */
spi_write(buf, SD_SECTOR_SIZE);
spi_write(crc, 2); /* dummy */