diff --git a/mmc.c b/mmc.c index 07f219e..a0e41e1 100644 --- a/mmc.c +++ b/mmc.c @@ -99,6 +99,15 @@ #define STATE_ADDR_ERR (1 << 5) #define STATE_PARAM_ERR (1 << 6) +// data response token for write operations +// format: xxx0sss1 (8 bits), where bits [3:1] (sss) indicate status: +// - sss=010: Data accepted → full token masked = 0x05 (xxx00101) +// - sss=101: CRC error → full token masked = 0x0B (xxx01011) +// - sss=110: Write error → full token masked = 0x0D (xxx01101) +// mask extracts bits [4:0] to include the fixed bit 0 (always 1) and bit 4 (always 0) +#define DATA_RESPONSE_MASK 0x1F +#define DATA_RESPONSE_ACCEPTED 0x05 + #define TIMEOUT 0x7fff // private helper functions @@ -332,7 +341,16 @@ void drive_write_block(uint32_t blkno, const uint8_t *data) { spi_send_byte(0xff); spi_send_byte(0xff); - // wait while card is busy + // read and verify data response token + // the card responds with a token indicating if data was accepted + uint8_t response = spi_rec_byte(); + if ((response & DATA_RESPONSE_MASK) != DATA_RESPONSE_ACCEPTED) { + // data rejected: either CRC error (0x0B) or write error (0x0D) + tfs_last_error = TFS_ERR_IO; + return; + } + + // wait while card is busy (card pulls line low during programming) if (!wait_byte(0xff)) { tfs_last_error = TFS_ERR_IO; return;