-
Notifications
You must be signed in to change notification settings - Fork 232
sdmmc: add HAL traits for SD/MMC peripherals #662
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
rmsyn
wants to merge
1
commit into
rust-embedded:master
Choose a base branch
from
rmsyn:embedded-hal/mmc
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+380
−0
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
pub mod delay; | ||
pub mod digital; | ||
pub mod i2c; | ||
pub mod mmc; | ||
pub mod pwm; | ||
pub mod spi; | ||
|
||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
//! Types and traits for SD/MMC peripherals. | ||
mod bus_width; | ||
mod fifo_status; | ||
mod reset; | ||
|
||
pub mod command; | ||
pub mod response; | ||
pub mod tuning; | ||
|
||
pub use bus_width::BusWidth; | ||
pub use fifo_status::FifoStatus; | ||
pub use reset::Reset; | ||
|
||
use command::MmcCommand; | ||
use response::MmcResponse; | ||
use tuning::TuningMode; | ||
|
||
/// Common operations for DesignWare MMC controllers on JH7110 SoCs. | ||
pub trait MmcOps { | ||
/// Associated error type for the SD/MMC trait. | ||
type Error; | ||
|
||
/// Gets whether the device is a MMC card. | ||
fn is_mmc(&self) -> bool; | ||
|
||
/// Gets whether the device is a SD card. | ||
fn is_sd(&self) -> bool { | ||
!self.is_mmc() | ||
} | ||
|
||
/// Gets whether the device is configured for SPI mode. | ||
fn is_spi(&self) -> bool; | ||
|
||
/// Performs bus setup for the SD/MMC device. | ||
fn setup_bus(&mut self) -> Result<(), Self::Error>; | ||
|
||
/// Performs device initialization sequence. | ||
fn init(&mut self) -> Result<(), Self::Error>; | ||
|
||
/// Sets the sample phase for the MMC controller. | ||
fn set_sample_phase(&mut self, sample_phase: u8); | ||
|
||
/// Waits for the FIFO to indicate readiness for read/write operations. | ||
fn fifo_ready(&self, fifo_status: FifoStatus) -> Result<(), Self::Error>; | ||
|
||
/// Waits for the CMD line to reset (usually during power-up). | ||
fn wait_for_reset(&mut self, reset: Reset, timeout: u64) -> Result<(), Self::Error>; | ||
|
||
/// Waits for the busy signal to clear for maximum `timeout_us` microseconds. | ||
fn wait_while_busy(&mut self, timout_us: u64) -> Result<(), Self::Error>; | ||
|
||
/// Writes a SD/MMC command to the card. | ||
fn write_command<C: MmcCommand>(&mut self, cmd: &C) -> Result<(), Self::Error>; | ||
|
||
/// Reads a SD/MMC response based on the provided command argument. | ||
/// | ||
/// # Note | ||
/// | ||
/// `cmd` should match the last call to `write_command`. | ||
fn read_response<C: MmcCommand, R: MmcResponse>(&mut self, cmd: &C) -> Result<R, Self::Error>; | ||
|
||
/// Reads the raw response bytes from the MMC controller. | ||
/// | ||
/// # Note | ||
/// | ||
/// Set `exp_crc` to true if a CRC checksum is expected in the response. | ||
/// | ||
/// The generic `N` parameter is for the expected length (in bytes) of the response. | ||
fn response_bytes<const N: usize>(&mut self, exp_crc: bool) -> Result<[u8; N], Self::Error>; | ||
|
||
/// Reads data from the MMC data lines. | ||
fn read_data(&mut self, data: &mut [u8]) -> Result<(), Self::Error>; | ||
|
||
/// Writes data to the MMC data lines. | ||
fn write_data(&mut self, data: &[u8]) -> Result<(), Self::Error>; | ||
|
||
/// Requests the card to send a tuning block. | ||
fn send_tuning(&mut self, bus_width: BusWidth, mode: TuningMode) -> Result<(), Self::Error>; | ||
|
||
/// Executes MMC tuning. | ||
fn execute_tuning(&mut self, bus_width: BusWidth, mode: TuningMode) -> Result<(), Self::Error>; | ||
|
||
/// Gets the interrupts status as a 32-bit bitfield. | ||
fn interrupt(&self) -> u32; | ||
|
||
/// Sets the interrupts based on a 32-bit bitfield. | ||
fn set_interrupt(&mut self, int: u32); | ||
|
||
/// Clear all interrupts. | ||
fn clear_all_interrupt(&mut self); | ||
|
||
/// Gets the response interrupts status as a 32-bit bitfield. | ||
fn response_interrupt(&self) -> u32; | ||
|
||
/// Sets the response interrupts based on a 32-bit bitfield. | ||
fn set_response_interrupt(&mut self, int: u32); | ||
|
||
/// Clear all interrupts. | ||
fn clear_all_response_interrupt(&mut self); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/// Represents the variants of the `bus width` field of the [Argument](super::Argument). | ||
#[repr(u8)] | ||
#[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
pub enum BusWidth { | ||
/// Represents the selection of a 1-bit bus width. | ||
Bits1 = 0b00, | ||
/// Represents the selection of a 4-bit bus width. | ||
Bits4 = 0b10, | ||
/// Represents the selection of a 8-bit bus width. | ||
Bits8 = 0b11, | ||
} | ||
|
||
impl BusWidth { | ||
/// Creates a new [BusWidth]. | ||
pub const fn new() -> Self { | ||
Self::Bits1 | ||
} | ||
} | ||
|
||
impl Default for BusWidth { | ||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
//! SD/MMC command types. | ||
|
||
use super::response::ResponseType; | ||
|
||
mod types; | ||
|
||
pub use types::*; | ||
|
||
/// Represents common functionality for SD/MMC command types. | ||
pub trait MmcCommand { | ||
/// Gets the SD/MMC command type. | ||
fn command_type(&self) -> CommandType; | ||
|
||
/// Gets the SD/MMC response type expected for the command. | ||
fn response_type(&self) -> ResponseType; | ||
|
||
/// Gets the SD/MMC command argument. | ||
/// | ||
/// # Note | ||
/// | ||
/// Returns `0` for commands that do not expect an argument. | ||
fn argument(&self) -> u32; | ||
|
||
/// Gets the SD/MMC command argument. | ||
/// | ||
/// # Note | ||
/// | ||
/// No effect for commands that do not expect an argument. | ||
fn set_argument(&mut self, arg: u32); | ||
|
||
/// Gets the CRC-7 of the command. | ||
fn crc(&self) -> u8; | ||
|
||
/// Sets the CRC-7 of the command. | ||
fn set_crc(&mut self, crc: u8); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/// Represents SD/MMC command types. | ||
#[repr(C)] | ||
#[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
pub enum CommandType { | ||
/// Addressed commands: point-to-point, no data transfer on DAT. | ||
Ac = 0, | ||
/// Addressed commands: point-to-point, data transfer on DAT. | ||
Adtc = 1, | ||
/// Broadcast commands no response. Only available if all CMD lines connected. | ||
Bc = 2, | ||
/// Broadcast commands with response. Only available if all CMD lines separated. | ||
Bcr = 3, | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
//! FIFO status types. | ||
|
||
/// Represents the FIFO status of the host controller. | ||
#[repr(u8)] | ||
#[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
pub enum FifoStatus { | ||
/// MMC FIFO is empty. | ||
Empty = 0, | ||
/// MMC FIFO is full. | ||
Full = 1, | ||
} | ||
|
||
impl FifoStatus { | ||
/// Creates a new [FifoStatus]. | ||
pub const fn new() -> Self { | ||
Self::Empty | ||
} | ||
} | ||
|
||
impl Default for FifoStatus { | ||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
//! SD/MMC reset types. | ||
/// Represents the resets to enable on the MMC host controller. | ||
#[repr(u8)] | ||
#[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
pub enum Reset { | ||
/// Reset the MMC peripheral. | ||
Mmc = 1, | ||
/// Reset the FIFO peripheral. | ||
Fifo = 2, | ||
/// Reset the DMA peripheral. | ||
Dma = 4, | ||
/// Reset the MMC + FIFO peripherals. | ||
MmcFifo = 3, | ||
/// Reset the MMC + DMA peripherals. | ||
MmcDma = 5, | ||
/// Reset the FIFO + DMA peripherals. | ||
FifoDma = 6, | ||
/// Reset all peripherals. | ||
All = 7, | ||
} | ||
|
||
impl Reset { | ||
/// Creates a new [Reset]. | ||
pub const fn new() -> Self { | ||
Self::Mmc | ||
} | ||
} | ||
|
||
impl Default for Reset { | ||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
//! SD/MMC response types. | ||
|
||
mod mode; | ||
mod types; | ||
|
||
pub use mode::*; | ||
pub use types::*; | ||
|
||
/// Represents common functionality for SD/MMC response types. | ||
pub trait MmcResponse { | ||
/// Gets the SD/MMC response type. | ||
fn response_type(&self) -> ResponseType; | ||
|
||
/// Gets the SD/MMC response mode. | ||
fn response_mode(&self) -> ResponseMode; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/// Represents the response mode of the SD/MMC protocol. | ||
#[repr(C)] | ||
#[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
pub enum ResponseMode { | ||
/// Standard SD mode of operation. | ||
Sd, | ||
/// SDIO mode of operation. | ||
Sdio, | ||
/// SPI mode of operation. | ||
Spi, | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
//! SD/MMC response types. | ||
|
||
use super::ResponseMode; | ||
|
||
/// Represents the response types used in the SD/MMC protocol. | ||
#[repr(C)] | ||
#[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
pub enum ResponseType { | ||
/// No response type. | ||
None, | ||
/// The standard response sent for most command types. | ||
R1, | ||
/// The same as the `R1` response, but drives a `BUSY` signal on the `DAT` line(s). | ||
R1b, | ||
/// 136-bit response that includes the contents of the card `CID` or `CSD` register. | ||
R2, | ||
/// Returns the contents of the card `OCR` register. | ||
R3, | ||
/// SDIO response to the `IO_SEND_OP_COND` command. | ||
/// | ||
/// Returns the card `IO_OCR` register contents, and other operating conditions. | ||
R4, | ||
/// SDIO response to the `IO_RW_DIRECT` commands. | ||
R5, | ||
/// Response containing the published RCA information. | ||
R6, | ||
/// Response containing the card interface condition. | ||
R7, | ||
} | ||
|
||
impl ResponseType { | ||
/// Represents the byte length for an 8-bit response. | ||
pub const LEN_8BIT: usize = 1; | ||
/// Represents the byte length for an 16-bit response. | ||
pub const LEN_16BIT: usize = 2; | ||
/// Represents the byte length for an 40-bit response. | ||
pub const LEN_40BIT: usize = 5; | ||
/// Represents the byte length for an 48-bit response. | ||
pub const LEN_48BIT: usize = 6; | ||
/// Represents the byte length for an 136-bit response. | ||
pub const LEN_136BIT: usize = 17; | ||
/// Represents the byte length for no response. | ||
pub const LEN_NONE: usize = 0; | ||
|
||
/// Creates a new [ResponseType]. | ||
pub const fn new() -> Self { | ||
Self::R1 | ||
} | ||
|
||
/// Gets the byte length of the [ResponseType] based on the operation mode. | ||
pub const fn len(&self, mode: ResponseMode) -> usize { | ||
match (mode, self) { | ||
( | ||
ResponseMode::Sd, | ||
Self::R1 | Self::R1b | Self::R3 | Self::R4 | Self::R6 | Self::R7, | ||
) => Self::LEN_48BIT, | ||
(ResponseMode::Sd | ResponseMode::Sdio, Self::R2) => Self::LEN_136BIT, | ||
(ResponseMode::Sdio, Self::R1 | Self::R1b | Self::R4 | Self::R5 | Self::R6) => { | ||
Self::LEN_48BIT | ||
} | ||
(ResponseMode::Spi, Self::R1 | Self::R1b) => Self::LEN_8BIT, | ||
(ResponseMode::Spi, Self::R2 | Self::R5) => Self::LEN_16BIT, | ||
(ResponseMode::Spi, Self::R3 | Self::R4 | Self::R7) => Self::LEN_40BIT, | ||
_ => Self::LEN_NONE, | ||
} | ||
} | ||
|
||
/// Gets whether the response type includes a `CRC-7` checksum field. | ||
pub const fn has_crc(&self, mode: ResponseMode) -> bool { | ||
matches!( | ||
(mode, self), | ||
( | ||
ResponseMode::Sd, | ||
Self::R1 | Self::R1b | Self::R2 | Self::R4 | Self::R5 | Self::R6 | Self::R7 | ||
) | ||
) || matches!((mode, self), (ResponseMode::Sdio, Self::R5 | Self::R6)) | ||
} | ||
} | ||
|
||
impl Default for ResponseType { | ||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
//! Tuning data for SD/MMC peripherals. | ||
/// Represents the tuning mode for the SD/MMC device. | ||
#[repr(u8)] | ||
#[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
pub enum TuningMode { | ||
/// Represents a 4-bit tuning block. | ||
Block4bit = 0, | ||
/// Represents a 8-bit tuning block. | ||
Block8bit = 1, | ||
} | ||
|
||
/// Represents the byte length of the 4-bit tuning block. | ||
pub const TUNING_BLOCK_4BIT_LEN: usize = 64; | ||
/// Represents the byte length of the 8-bit tuning block. | ||
pub const TUNING_BLOCK_8BIT_LEN: usize = 128; | ||
|
||
/// Represents the tuning pattern used for 4-bit SD/MMC cards. | ||
pub const TUNING_BLOCK_PATTERN_4BIT: [u8; TUNING_BLOCK_4BIT_LEN] = [ | ||
0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, | ||
0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, | ||
0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, | ||
0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, | ||
]; | ||
|
||
/// Represents the tuning pattern used for 8-bit SD/MMC cards. | ||
pub const TUNING_BLOCK_PATTERN_8BIT: [u8; TUNING_BLOCK_8BIT_LEN] = [ | ||
0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, | ||
0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, | ||
0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, | ||
0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, | ||
0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, | ||
0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, | ||
0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, | ||
0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, | ||
]; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imo all these bools should be enums, like
CardType::Sd
andTransportMode::Spi