Skip to content

Implement the SD memory protocol and dmdrvi device model - #1

Closed
JaxCalder wants to merge 1 commit into
mainfrom
feature/sd-protocol-driver
Closed

JaxCalder wants to merge 1 commit into
mainfrom
feature/sd-protocol-driver

Conversation

@JaxCalder

Copy link
Copy Markdown

Closes choco-technologies/dmod-ecosystem#11.

Summary

Replaces the dmsdio placeholder with a complete, hardware-independent SDSC/SDHC/SDXC driver.

  • dmsdio_port.h: a thin, protocol-free Module API - send a raw command and capture whichever response shape the caller expects, move already block-aligned data in/out, set bus width/speed mode. Every SD command sequence, response field, and byte<->block address translation lives in dmsdio.c, never in a port.
  • dmsdio.c: card identification (CMD0/CMD8/ACMD41/CMD2/CMD3/CMD9/CMD7), CID/CSD/SCR parsing, ACMD6 bus-width negotiation, a CMD6 High Speed switch that actually decodes the Switch Function Status response (not just "did the command itself succeed"), single/multi-block read/write with CMD12 stop, ERASE, CMD13-based READY_FOR_DATA polling after a write/erase, retry policy for transient CRC/timeout errors, and a dmdrvi device model: a persistent host node plus a hot-plugged card sub-node (/dev/dmsdioN/0) announced/unannounced via dmdrvi_device_available()/_unavailable(). Byte-offset reads/writes handle non-block-aligned ranges via read-modify-write on the boundary blocks. A dmsdio_generation_t on every open handle rejects stale access once a card is gone.
  • Card detect is an optional dmgpio friend (the same friend_group pattern dmspi uses for its chip-select) with edge-interrupt → queue → dmosi worker-thread debounce, so ISR context never touches the bus. No CD friend configured just means presence is re-checked by attempting identification itself.
  • src/port/stm32f7: a real SDMMC1 register-level implementation (command/response state machine, data phase via SDMMC's own internal IDMA - no dmdma involved, since F7's SDMMC has an internal DMA engine unlike F4's older SDIO peripheral) using dmclk_port's sdio clock domain for divider calculation.
  • src/port/x86_64: a mocked SD card (mock_control.h) simulating SDSC v1/v2, SDHC, and SDXC identification, configurable error injection (CRC/timeout/removal), and a small backing store for real read/write round-trips. tests/dmsdio_test.c drives it exactly the way a real consumer (dmdevfs) would: through the dmdrvi DIF, looked up by module name at runtime, not a direct/linked call.

Test plan

  • Host cross-compile clean for dmsdio core + stm32f7 port
  • Mocked protocol test suite (tests/dmsdio_test.c) covers: SDSC v1/v2/SDHC/SDXC identification, 64-bit capacity reported without truncation, full-sector round-trip, unaligned read-modify-write preserving surrounding bytes, transient-CRC-recovered-by-retry vs. retry-exhaustion, card-removed-during-transfer, and identification timeout (no card) - CI job "Build and Test dmsdio (core)"
  • Real-hardware verification on STM32F746G-DISCO on-board microSD - in progress, will report back on this PR

Note on scope

dmsdio_port for STM32F4 (SDIO, which needs a real dmdma stream rather than an internal IDMA engine) is not part of this PR - only STM32F7/SDMMC, matching the epic's board list for this stage. STM32F4 support can follow as its own port once this core/dmdrvi-model/STM32F7 combination is validated on real hardware.

Replaces the dmsdio placeholder with a complete, hardware-independent
SDSC/SDHC/SDXC driver:

- dmsdio_port.h: a thin, protocol-free Module API - send a raw command and
  capture whichever response shape the caller says to expect, move already
  block-aligned data in/out, set bus width/speed mode. Every SD command
  sequence, response field, and byte<->block address translation lives in
  dmsdio.c, never in a port.
- dmsdio.c: card identification (CMD0/CMD8/ACMD41/CMD2/CMD3/CMD9/CMD7),
  CID/CSD/SCR parsing, ACMD6 bus-width negotiation, CMD6 High Speed switch
  (with real Switch Function Status decoding, not just "did the command
  itself succeed"), single/multi-block read/write with CMD12 stop, ERASE,
  CMD13-based READY_FOR_DATA polling after a write/erase instead of
  guessing at a raw DAT0 busy bit, retry policy for transient CRC/timeout
  errors, and a dmdrvi device model: a persistent host node plus a
  hot-plugged card sub-node (/dev/dmsdioN/0) announced/unannounced via
  dmdrvi_device_available()/_unavailable(). Byte-offset reads/writes handle
  non-block-aligned ranges via read-modify-write on the boundary blocks,
  going straight to/from the card for interior full sectors. A
  dmsdio_generation_t on every open handle rejects stale access once a card
  is gone.
- Card detect is an optional dmgpio friend (the same friend_group pattern
  dmspi uses for its chip-select) with edge-interrupt -> queue -> dmosi
  worker-thread debounce, so ISR context never touches the bus - see
  dmsdio.c's hotplug_worker(). No CD friend configured just means presence
  is only re-checked by attempting identification itself.
- src/port/stm32f7: a real SDMMC1 register-level implementation (command/
  response state machine, data phase via SDMMC's own internal IDMA - no
  dmdma involved, matching real hardware: F7's SDMMC has an internal DMA
  engine unlike F4's older SDIO peripheral) using dmclk_port's
  "sdio" clock domain for divider calculation.
- src/port/x86_64: a mocked SD card (mock_control.h) simulating SDSC v1/v2,
  SDHC, and SDXC identification, configurable error injection (CRC/timeout/
  removal), and a small backing store for real read/write round-trips -
  driving dmsdio.c through the exact CMD/ACMD sequence a real card would
  see. tests/dmsdio_test.c exercises it exactly the way a real consumer
  (dmdevfs) would: through the dmdrvi DIF, looked up by module name, not a
  direct/linked call.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.

[dmsdio 6/9] Implement the SD memory protocol and dmdrvi device model

2 participants