Skip to main content

Crate sdhci_host

Crate sdhci_host 

Source
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§

BlockBufferConfig
Buffer and address constraints exposed by a host block queue.
BlockRequest
BlockRequestId
Stable identifier returned by a host block queue after submission.
BlockRequestSlot
DataRequest
Sdhci
Generic SD Host Controller (SDHCI) backend.

Enums§

BlockPoll
Result of advancing a submitted transfer without blocking.
BlockTransferDirection
Direction of a block request.
BlockTransferMode
Data engine used by an in-flight block request.
BlockTransferState
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§

HostClock
Platform clock capability for hosts whose controller divider is unusable.

Type Aliases§

RequestId