Skip to content

sdcardio: fix card size for SDXC cards > 32 GB (forward-port of #11013 to main) - #11243

Merged
dhalbert merged 2 commits into
adafruit:mainfrom
mikeysklar:fix-sdxc-csd-v2-sector-count-main
Aug 25, 2026
Merged

dhalbert merged 2 commits into
adafruit:mainfrom
mikeysklar:fix-sdxc-csd-v2-sector-count-main

Conversation

@mikeysklar

Copy link
Copy Markdown
Collaborator

What

Forward-port of #11013 to main. Reads all 22 bits of the CSD v2.0 C_SIZE field instead of the bottom 16, so SDXC cards over 32 GB report their real capacity. Both 10.2.x commits are cherry-picked with -x, including @dhalbert's cast cleanup, so the decode line here is identical to 10.2.x.

Why

#11012 (same fix, targeted at main) was closed in favor of #11013 on 10.2.x, expecting the routine 10.2.x to main merge. That merge has not happened since May, so 10.3.0 alphas still truncate. git log main..10.2.x is 10 commits and this fix is the only substantive change missing from main, the rest is 10.2.1 release mechanics and backports of commits already on main. Happy to close this if you would rather do the branch merge instead.

Related context, no file overlap: #11240 (Memento CIRCUITPY_SDCARD_USB default), since SD over USB is where users see the wrong size.

Hardware tested

Adafruit MEMENTO (adafruit_esp32s3_camera), 64 GB SDXC card formatted exFAT, macOS 26.6.2 host, CIRCUITPY_SDCARD_USB = true. A/B builds from main tip 8caf4ca and from this branch, same card, same host, 2026-08-24. Not tested: CSD v1 cards (that path is untouched) and other boards.

How I tested it

import board, sdcardio, storage, os, displayio, digitalio
displayio.release_displays()
tft = digitalio.DigitalInOut(board.TFT_CS)
tft.switch_to_output(value=True)
sd = sdcardio.SDCard(board.SPI(), board.CARD_CS, baudrate=20_000_000)
storage.mount(storage.VfsFat(sd), "/sd")
print("count:", sd.count())
main tip (no fix) this branch
sd.count() on device not read 123596800
diskutil partition size over USB MSC 28.9 GB (56485888 sectors) 63.3 GB (123594752 sectors)
macOS mounts the volume yes yes
md5 of all 138 files on card via USB all read clean all read clean, checksums identical to no-fix run

56485888 sectors is exactly the truncated decode of this card's C_SIZE (0x1D779 with the top bits dropped). The failure mode without the fix is quiet: macOS mounts the volume and df shows the exFAT structures' 63 GB, but the device only offers 28.9 GB of sectors over USB, so anything stored past that boundary is unreachable from the host and host-side tools see free space that does not exist.

AI assistance

The original fix and this forward-port were done with Claude assistance (commit trailer retained from 10.2.x). The capacity numbers, diskutil output, and checksum runs above are from the card and board on my desk, verified by me.

🤖 Generated with Claude Code

mikeysklar and others added 2 commits August 24, 2026 20:02
The CSD v2.0 C_SIZE field is 22 bits but only the bottom 16 were
being read. Cards > 32 GB reported roughly half their actual block
count over USB MSC. Fix reads all 22 bits.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
(cherry picked from commit b9a43e6)
(cherry picked from commit 26427a2)

@dhalbert dhalbert left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Confirmed that this is the only interesting unmerged commit from 10.2.x by doing a trial merge from 10.2.x locally.

@dhalbert
dhalbert merged commit 7a76081 into adafruit:main Aug 25, 2026
594 checks passed
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.

2 participants