From 169c6c58334c605f3fb690b11c6a17ad6ed2b99d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 18 Dec 2025 12:22:19 +0000 Subject: [PATCH 1/3] Initial plan From f230fc3880bce12ca0f2182af09b6422397c498b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 18 Dec 2025 12:27:15 +0000 Subject: [PATCH 2/3] Add data response token validation in SD/MMC write operations Co-authored-by: sittner <1475582+sittner@users.noreply.github.com> --- mmc.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/mmc.c b/mmc.c index 07f219e..9a6e9e7 100644 --- a/mmc.c +++ b/mmc.c @@ -99,6 +99,14 @@ #define STATE_ADDR_ERR (1 << 5) #define STATE_PARAM_ERR (1 << 6) +// data response token for write operations +// format: xxx0sss1, where sss indicates: +// 010 (0x05 when masked with 0x1F) = Data accepted +// 101 (0x0B when masked with 0x1F) = Data rejected, CRC error +// 110 (0x0D when masked with 0x1F) = Data rejected, write error +#define DATA_RESPONSE_MASK 0x1F +#define DATA_RESPONSE_ACCEPTED 0x05 + #define TIMEOUT 0x7fff // private helper functions @@ -332,7 +340,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; From a8cee4b4ae562cd2dde73ac4505aa0cc834dfa8e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 18 Dec 2025 12:28:31 +0000 Subject: [PATCH 3/3] Improve data response token comment clarity Co-authored-by: sittner <1475582+sittner@users.noreply.github.com> --- mmc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mmc.c b/mmc.c index 9a6e9e7..a0e41e1 100644 --- a/mmc.c +++ b/mmc.c @@ -100,10 +100,11 @@ #define STATE_PARAM_ERR (1 << 6) // data response token for write operations -// format: xxx0sss1, where sss indicates: -// 010 (0x05 when masked with 0x1F) = Data accepted -// 101 (0x0B when masked with 0x1F) = Data rejected, CRC error -// 110 (0x0D when masked with 0x1F) = Data rejected, write error +// 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