sdmmc_protocol/lib.rs
1//! `no_std` SD/MMC protocol building blocks for embedded systems.
2//!
3//! This crate provides protocol-level types and driver skeletons for SD,
4//! MMC and SDIO cards. It is transport-agnostic at the trait level and
5//! brings its own SPI-mode driver plus an SDIO host-controller abstraction.
6//!
7//! # What you get
8//!
9//! - [`cmd::Command`] / [`cmd::DataDirection`]: SD/MMC command opcodes,
10//! argument encoding and per-command data direction.
11//! - [`response::Response`] and friends ([`response::CidResponse`],
12//! [`response::CsdResponse`], [`response::SwitchStatus`], ...): typed
13//! parsers for the response formats defined in the SD spec.
14//! - [`error::Error`]: a single error enum the drivers and parsers return.
15//! - [`spi`] *(feature `spi`, on by default)*: a [`spi::SpiTransport`] trait
16//! plus the [`spi::SpiSdmmc`] driver for SPI-mode SD cards. Includes a
17//! thin [`spi::SpiDeviceWrapper`] adapter for `embedded-hal` 1.0
18//! `SpiDevice<u8>` implementations.
19//! - [`sdio`] *(feature `sdio`)*: a [`sdio::SdioHost`] trait that abstracts
20//! a host controller and the [`sdio::SdioSdmmc`] driver that drives it
21//! through card initialization, block I/O and bus-speed selection.
22//! - [`rdif`] *(feature `rdif`)*: a [`rdif::BlockDevice`] bridge that exposes
23//! an SDIO-backed card through `rdif-block` queues.
24//!
25//! # Cargo features
26//!
27//! | Feature | Default | Purpose |
28//! |----------|---------|-------------------------------------------------|
29//! | `spi` | yes | Enables [`spi::SpiTransport`] and [`spi::SpiSdmmc`]. |
30//! | `sdio` | no | Enables the host trait and submit/poll data-command contract. |
31//! | `rdif` | no | Enables the RDIF block-device bridge over `sdio`. |
32//!
33//! Diagnostic output goes through the [`log`] crate; configure a logger in
34//! your application to capture it.
35//!
36//! # Example
37//!
38//! ```rust,ignore
39//! use embedded_hal::delay::DelayNs;
40//! use sdmmc_protocol::{
41//! Error,
42//! spi::{SpiSdmmc, SpiTransport},
43//! };
44//!
45//! struct MySpi;
46//!
47//! impl SpiTransport for MySpi {
48//! fn transfer_byte(&mut self, byte: u8) -> Result<u8, Error> {
49//! # let _ = byte;
50//! # Ok(0)
51//! }
52//! }
53//!
54//! fn boot<D: DelayNs>(spi: MySpi, delay: D) -> Result<(), Error> {
55//! let mut card = SpiSdmmc::new(spi, delay);
56//! let _info = card.init()?;
57//! let mut block = [0u8; 512];
58//! card.read_block(0, &mut block)?;
59//! Ok(())
60//! }
61//! ```
62//!
63//! # Maturity
64//!
65//! The SPI path has protocol-level unit tests and basic block read/write
66//! support. The SDIO path has been validated end-to-end against several host
67//! controller / SoC combinations through the dedicated host backends in this
68//! workspace:
69//!
70//! | Host crate | SoC / controller | Mode | Status |
71//! |--------------------|-------------------------|-----------------------|--------|
72//! | `sdhci-host` | RK3568 (dwcmshc) | eMMC HS@52, FIFO/DMA | OK |
73//! | `sdhci-host` | RK3588 (dwcmshc) | eMMC HS@52, FIFO/DMA | OK |
74//! | `dwmmc-host` | RK3568 SD (dw_mshc) | SD HS, DMA | OK |
75//! | `phytium-mci-host` | Phytium MCI | SD HS, DMA | OK |
76//!
77//! UHS-I / HS200 / HS400 paths exist in the state machine but have not yet
78//! been signed off on a real card + IO regulator combination. See
79//! `drivers/blk/sdmmc-protocol/docs/REVIEW.md` for the remaining roadmap.
80//!
81//! # MSRV
82//!
83//! Rust 1.85 (the first stable to ship edition 2024).
84
85#![no_std]
86
87#[cfg(any(feature = "sdio", feature = "rdif"))]
88extern crate alloc;
89
90pub mod block;
91pub mod cmd;
92mod common;
93pub mod error;
94pub mod ext_csd;
95pub mod response;
96
97#[cfg(feature = "spi")]
98pub mod spi;
99
100#[cfg(feature = "sdio")]
101pub mod sdio;
102
103#[cfg(feature = "rdif")]
104pub mod rdif;
105
106pub use block::{
107 BlockBufferConfig, BlockPoll, BlockRequestId, BlockTransferDirection, BlockTransferMode,
108 BlockTransferState, CommandPoll, CommandResponsePoll, DataCommandDirection, DataCommandPoll,
109 DataCommandState, OperationPoll,
110};
111pub use cmd::{Command, DataDirection};
112pub use error::{Error, ErrorContext, Phase};
113pub use response::{CidResponse, CsdResponse, Response, SwitchStatus};