Expand description
SDHCI host controller backend for the sdmmc-protocol driver crate.
This crate ports the SD Host Controller Standard Specification
v3.x register layout and PIO data path into a SdioHost implementation
that the sdmmc_protocol::sdio::SdioSdmmc driver can drive directly.
§Scope
- Implemented: PIO transfers, ADMA2 (32-bit) transfers, 1-bit / 4-bit bus, default-speed and high-speed clocking, 32-bit response slots, 136-bit R2 reconstruction, software reset / clock setup.
- Out of scope (for now): 64-bit ADMA2, 8-bit eMMC bus, HS200 /
SDR50 / SDR104 clocking, tuning (CMD19 / CMD21), eMMC-specific
commands. 1.8 V signaling is wired up at the register level but is
gated behind
Sdhci::enable_1v8_signaling— platforms that haven’t plumbed the IO-rail regulator MUST leave it off so the protocol layer falls back instead of corrupting transfers.
§Usage
use core::ptr::NonNull;
use sdhci_host::Sdhci;
use sdmmc_protocol::sdio::{SdioInitScratch, SdioSdmmc};
let mmio = NonNull::new(0xFE31_0000 as *mut u8).unwrap();
let host = unsafe { Sdhci::new(mmio) };
let mut card = SdioSdmmc::new(host);
let mut scratch = SdioInitScratch::new();
let mut request = card.submit_init(&mut scratch)?;
// Poll request here. Runtime code chooses spin, yield, IRQ wait, or timer.For block request I/O, use Sdhci::submit_read_blocks or
Sdhci::submit_write_blocks and complete the returned request with
Sdhci::poll_block_request. BlockTransferMode::Dma maps the request
buffer and builds the ADMA2 descriptor table; BlockTransferMode::Fifo
uses the controller FIFO with the same submit/poll contract:
ⓘ
use core::{num::NonZeroUsize, ptr::NonNull};
use dma_api::DeviceDma;
use sdhci_host::{BlockRequestSlot, BlockTransferMode, RequestId, Sdhci};
let dma = DeviceDma::new(u32::MAX as u64, &DmaImpl);
let mut host = unsafe { Sdhci::new_from_addr(0xFE31_0000) };
let mut block = [0u8; 512];
let ptr = NonNull::new(block.as_mut_ptr()).unwrap();
let mut slot = BlockRequestSlot::default();
let mut request = Some(host.submit_read_blocks(
0,
ptr,
NonZeroUsize::new(block.len()).unwrap(),
Some(&dma),
BlockTransferMode::Dma,
&mut slot,
)?);
let id = RequestId::new(0);
while matches!(host.poll_block_request(&mut request, id, &mut slot), Ok(BlockPoll::Pending)) {}Construction is unsafe because the caller must guarantee that the
supplied address is a valid, exclusively-owned SDHCI register file.
Structs§
- Block
Buffer Config - Buffer and address constraints exposed by a host block queue.
- Block
Request - Block
Request Id - Stable identifier returned by a host block queue after submission.
- Block
Request Slot - Data
Request - Sdhci
- Generic SD Host Controller (SDHCI) backend.
Enums§
- Block
Poll - Result of advancing a submitted transfer without blocking.
- Block
Transfer Direction - Direction of a block request.
- Block
Transfer Mode - Data engine used by an in-flight block request.
- Block
Transfer State - Observable state of one host block-transfer state machine.
- Event
- Stable controller event extracted from SDHCI interrupt-status registers.
Constants§
- ADMA2_
DESC_ ALIGN - ADMA2_
DESC_ COUNT - Caller-owned scratch region for the ADMA2 descriptor table.
Traits§
- Host
Clock - Platform clock capability for hosts whose controller divider is unusable.