From d56fbaaaf437f6c2200d0a53402b9aa6ad15b733 Mon Sep 17 00:00:00 2001 From: Patrik Axelsson Date: Tue, 29 Aug 2023 21:47:48 +0200 Subject: [PATCH] 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 --- examples/spisd/sd.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/spisd/sd.c b/examples/spisd/sd.c index 5070d13..0339a93 100644 --- a/examples/spisd/sd.c +++ b/examples/spisd/sd.c @@ -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 */