Skip to content

Fix SD cards that send a bit-shifted CMD12 response (SdError 0XC,0X1F) - #1

Open
travisccook wants to merge 2 commits into
joymonkey:mainfrom
travisccook:fix/sdfat-bitshifted-cmd12
Open

travisccook wants to merge 2 commits into
joymonkey:mainfrom
travisccook:fix/sdfat-bitshifted-cmd12

Conversation

@travisccook

Copy link
Copy Markdown

Summary

Some microSD cards make the CHIRP Audio Trigger halt at boot with 3 flashing red LEDs and "SD card not detected", even though the card is fine and freshly formatted:

Initializing SD Card... FAILED at 25MHz, trying 4MHz...
FAILED!
begin() failed
Do not reformat the SD.
SdError: 0XC,0X1F

The cause is a card quirk that SdFat doesn't handle. This PR adds a patched copy of the core's SdFat so these cards work.

Cause

These cards answer CMD12 (STOP_TRANSMISSION) with a correct R1 response (0x00) that is not byte-aligned: it starts 3 bits late. SdFat reads responses byte-aligned, sees 0x1F, and fails every multi-block read stop. SdFat reports 0x0C (CMD18) because the failed CMD12 happens inside the next read's syncDevice(); 0x1F is the misread CMD12 response.

Raw MISO bytes captured on a Rev.B board right after CMD12:

3F       E0       1F       FF
00111111 11100000 00011111 11111111
            R1 = 00000000 starts 3 bits into the byte

The Linux mmc_spi driver already handles this ("ugly card with a bit-shifted response"). SdFat 2.3.1 (bundled with arduino-pico 5.4.4, greiman/SdFat cda0573, which is also the latest upstream) does not.

How it was narrowed down

On a Rev.B board (firmware v20260308) with a 16GB SDHC card (CID MID 0x9C, OEM "SO", product "USD00", 2018-07), using raw SPI test builds:

Hypothesis Result
Missing MISO pull-up (RP2350 pads reset with pull-down) Ruled out: same failure with pull-up, pull-down or none
Signal integrity / clock speed Ruled out: raw CMD17/CMD18 reads of sector 0 succeed at 400 kHz, 1 MHz, 4 MHz and 25 MHz; SdFat fails even at 400 kHz
Command CRC Ruled out: raw reads work with SdFat's fixed 0x87 CRC; SdFat built with USE_SD_CRC=1 still fails
CMD12 response parsing Confirmed: 3F E0 1F FF after CMD12, identical at 400 kHz, 4 MHz and 25 MHz, with valid or 0x87 CRC

A 1GB SDSC card works with stock firmware, which is why this doesn't show up with every card.

Changes

  • CHIRP_Audio_Trigger/Arduino_Sketches/libraries/SdFat/ — SdFat 2.3.1 copied verbatim from arduino-pico 5.4.4 (first commit, unmodified, so the fix is a small diff), plus a 17-line change in SdSpiCard::cardCommand() (second commit). For CMD12 only: skip 0xFF bytes, and if the first non-0xFF byte has its top bit set, combine it with the next byte and shift out the leading one bits. Byte-aligned responses are handled as before; all other commands are untouched.
  • CHIRP_Audio/platformio.inilib_extra_dirs = ../libraries so PlatformIO builds use the patched copy.
  • libraries/SdFat/CHIRP_PATCH.md — the problem, the evidence, the diff, Arduino IDE instructions, and how to drop the copy if SdFat fixes this upstream.

Arduino IDE: it doesn't read platformio.ini. Copy libraries/SdFat into the sketchbook libraries folder; a sketchbook library outranks a platform-bundled one of the same name and architecture per the Arduino CLI dependency resolution rules.

Testing

  • PlatformIO build of this branch succeeds; the UF2 is byte-identical to the build tested on the board
  • Rev.B + 16GB "USD00" card: stock firmware fails with SdError: 0XC,0X1F; patched firmware prints Initializing SD Card... OK (25MHz), reads/writes CHIRP.INI, scans banks and reaches System Ready
  • Rev.B + a card that already worked (1GB SDSC) on the patched firmware — not yet tested
  • Audio playback from the 16GB card (the card had no sounds loaded yet) — not yet tested
  • USB MSC (MUSB) with the 16GB card — not yet tested

Notes

  • This probably belongs in SdFat itself; greiman/SdFat#430 reports the same CMD18 / 0x1F error with other cards. If it gets fixed upstream and arduino-pico picks it up, libraries/SdFat and the lib_extra_dirs line can be removed.
  • No firmware UF2 is included; I have a build of this branch if you'd like one.

🤖 Generated with Claude Code

https://claude.ai/code/session_01U1RDDneTekTuqmAkSXEVGY

travisccook and others added 2 commits September 14, 2026 22:50
Verbatim copy of the SdFat library bundled with the Earle Philhower
arduino-pico core 5.4.4 (greiman/SdFat cda0573), limited to src/,
library.properties, LICENSE.md and README.md. Added unchanged so the
following fix can be reviewed as a small diff.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U1RDDneTekTuqmAkSXEVGY
Some SD cards answer CMD12 (STOP_TRANSMISSION) in SPI mode with a
correct R1 that is not byte-aligned. SdFat reads it byte-aligned, sees
a bogus status and fails every multi-block read stop, so the Audio
Trigger halts at boot with "SdError: 0XC,0X1F" ("SD card not detected").

Seen on a 16GB SDHC card (MID 0x9C, OEM "SO", product "USD00"): MISO
after CMD12 is 3F E0 1F FF, i.e. R1 = 0x00 starting 3 bits late, at
400 kHz, 4 MHz and 25 MHz alike. Raw CMD17/CMD18 reads of the same card
work at all speeds.

For CMD12 only, realign a bit-shifted response the way the Linux
mmc_spi driver does. Byte-aligned responses are handled as before.
Point PlatformIO at the patched copy with lib_extra_dirs and document
the change and Arduino IDE usage in CHIRP_PATCH.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U1RDDneTekTuqmAkSXEVGY
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant