Skip to content

Commit 2142d4d

Browse files
committed
sdio: initial SDIO HAL implementation
Provides the initial skeleton for the `embedded_hal::mmc::MmcOps` implementation for the SDIO peripherals on the ESP32C6 microcontroller.
1 parent aeaab9a commit 2142d4d

File tree

9 files changed

+286
-6
lines changed

9 files changed

+286
-6
lines changed

esp-hal/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3030
- Implemented `embedded_io::WriteReady` for `Uart` and `UartTx` (#3423)
3131
- ESP32-H2: Support for ADC calibration (#3414)
3232
- Added `UartInterrupt::RxTimeout` support (#3493)
33+
- Added `Sdio` support
3334

3435
### Changed
3536

esp-hal/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ bitflags = "2.9.0"
2727
bytemuck = "1.22.0"
2828
cfg-if = "1.0.0"
2929
critical-section = { version = "1.2.0", features = ["restore-state-u32"] }
30-
embedded-hal = "1.0.0"
31-
embedded-hal-async = "1.0.0"
30+
embedded-hal = { version = "1.0.0", git = "https://github.com/rmsyn/embedded-hal", branch = "embedded-hal/mmc" }
31+
embedded-hal-async = { version = "1.0.0", git = "https://github.com/rmsyn/embedded-hal", branch = "embedded-hal/mmc" }
3232
enumset = "1.1.5"
3333
paste = "1.0.15"
3434
portable-atomic = { version = "1.11.0", default-features = false }

esp-hal/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ pub mod i2c;
226226
pub mod peripheral;
227227
#[cfg(all(feature = "unstable", any(hmac, sha)))]
228228
mod reg_access;
229+
#[cfg(any(feature = "esp32", feature = "esp32c6"))]
230+
pub mod sdio;
229231
#[cfg(any(spi0, spi1, spi2, spi3))]
230232
pub mod spi;
231233
pub mod system;

esp-hal/src/sdio.rs

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
//! # Secure Digital I/O - Slave Mode
2+
//!
3+
//! ## Overiew
4+
//!
5+
//! The peripheral can be used to transfer data over the SDIO bus in `Slave`
6+
//! mode.
7+
8+
use embedded_hal::mmc::{
9+
CardMode,
10+
CardType,
11+
FifoStatus,
12+
MmcOps,
13+
Reset,
14+
command::MmcCommand,
15+
response::MmcResponse,
16+
tuning::{TuningMode, TuningWidth},
17+
};
18+
19+
mod slc;
20+
mod slchost;
21+
22+
pub use slc::*;
23+
pub use slchost::*;
24+
25+
/// SDIO peripheral instance.
26+
pub trait PeripheralInstance: crate::private::Sealed {
27+
/// Represents the peripheral information type containing the register
28+
/// block.
29+
type Info;
30+
31+
/// Gets a static shared reference to the peripheral information.
32+
fn info(&self) -> &'static Self::Info;
33+
}
34+
35+
/// Represents the SDIO 2.0 peripheral for the microcontroller.
36+
#[derive(Debug)]
37+
pub struct Sdio<'d> {
38+
slc: AnySlc<'d>,
39+
slchost: AnySlchost<'d>,
40+
}
41+
42+
impl<'d> Sdio<'d> {
43+
/// Creates a new [Sdio].
44+
///
45+
/// # Example
46+
///
47+
/// ```rust,no_run
48+
/// use esp_hal::sdio::Sdio;
49+
///
50+
/// use crate::peripheral::Peripherals;
51+
///
52+
/// let dp = Peripheral::take().unwrap();
53+
/// let _sdio = Sdio::new(dp.slc, dp.slchost);
54+
/// ```
55+
pub fn new(slc: impl SlcInstance + 'd, slchost: impl SlchostInstance + 'd) -> Self {
56+
Self {
57+
slc: slc.degrade(),
58+
slchost: slchost.degrade(),
59+
}
60+
}
61+
62+
/// Gets a static reference to the SLC information.
63+
pub fn slc(&self) -> &'static SlcInfo {
64+
self.slc.info()
65+
}
66+
67+
/// Gets a static reference to the SLCHOST information.
68+
pub fn slchost(&self) -> &'static SlchostInfo {
69+
self.slchost.info()
70+
}
71+
}
72+
73+
/// Represents the error variants for SDIO peripherals.
74+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
75+
pub enum Error {
76+
/// Indicates a general error occured.
77+
General,
78+
/// Indicates use of an illegal command.
79+
IllegalCommand,
80+
/// Indicates a CRC error from the previous command.
81+
Crc,
82+
/// The function and/or type is unimplemented.
83+
Unimplemented,
84+
}
85+
86+
impl Error {
87+
/// Creates a new [Error].
88+
pub const fn new() -> Self {
89+
Self::Unimplemented
90+
}
91+
92+
/// Creates an general [Error].
93+
#[inline]
94+
pub const fn general() -> Self {
95+
Self::General
96+
}
97+
98+
/// Creates an illegal command [Error].
99+
#[inline]
100+
pub const fn illegal_command() -> Self {
101+
Self::IllegalCommand
102+
}
103+
104+
/// Creates an crc [Error].
105+
#[inline]
106+
pub const fn crc() -> Self {
107+
Self::Crc
108+
}
109+
110+
/// Creates an unimplemented [Error].
111+
#[inline]
112+
pub const fn unimplemented() -> Self {
113+
Self::Unimplemented
114+
}
115+
}
116+
117+
impl Default for Error {
118+
fn default() -> Self {
119+
Self::new()
120+
}
121+
}
122+
123+
impl core::fmt::Display for Error {
124+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
125+
match self {
126+
Self::General => write!(f, "general"),
127+
Self::IllegalCommand => write!(f, "illegal command"),
128+
Self::Crc => write!(f, "CRC"),
129+
Self::Unimplemented => write!(f, "unimplemented"),
130+
}
131+
}
132+
}
133+
134+
impl core::error::Error for Error {}
135+
136+
impl<'d> MmcOps for Sdio<'d> {
137+
type Error = Error;
138+
139+
fn card_type(&self) -> CardType {
140+
CardType::Sd
141+
}
142+
143+
fn card_mode(&self) -> CardMode {
144+
CardMode::Sdio
145+
}
146+
147+
fn setup_bus(&mut self) -> Result<(), Self::Error> {
148+
Err(Error::unimplemented())
149+
}
150+
151+
fn init(&mut self) -> Result<(), Self::Error> {
152+
Err(Error::unimplemented())
153+
}
154+
155+
fn set_sample_phase(&mut self, _sample_phase: u8) {}
156+
157+
fn fifo_ready(&self, _fifo_status: FifoStatus) -> Result<(), Self::Error> {
158+
Err(Error::unimplemented())
159+
}
160+
161+
fn wait_for_reset(&mut self, _reset: Reset, _timeout: u64) -> Result<(), Self::Error> {
162+
Err(Error::unimplemented())
163+
}
164+
165+
fn wait_while_busy(&mut self, _timout_us: u64) -> Result<(), Self::Error> {
166+
Err(Error::unimplemented())
167+
}
168+
169+
fn write_command<C: MmcCommand>(&mut self, _cmd: &C) -> Result<(), Self::Error> {
170+
Err(Error::unimplemented())
171+
}
172+
173+
fn read_response<C: MmcCommand, R: MmcResponse>(&mut self, _cmd: &C) -> Result<R, Self::Error> {
174+
Err(Error::unimplemented())
175+
}
176+
177+
fn response_bytes<const N: usize>(&mut self, _exp_crc: bool) -> Result<[u8; N], Self::Error> {
178+
Err(Error::unimplemented())
179+
}
180+
181+
fn read_data(&mut self, _data: &mut [u8]) -> Result<(), Self::Error> {
182+
Err(Error::unimplemented())
183+
}
184+
185+
fn write_data(&mut self, _data: &[u8]) -> Result<(), Self::Error> {
186+
Err(Error::unimplemented())
187+
}
188+
189+
fn send_tuning(&mut self, _mode: TuningMode, _width: TuningWidth) -> Result<(), Self::Error> {
190+
Err(Error::unimplemented())
191+
}
192+
193+
fn interrupt(&self) -> u32 {
194+
0
195+
}
196+
197+
fn set_interrupt(&mut self, _int: u32) {}
198+
199+
fn clear_all_interrupt(&mut self) {}
200+
201+
fn response_interrupt(&self) -> u32 {
202+
0
203+
}
204+
205+
fn set_response_interrupt(&mut self, _int: u32) {}
206+
207+
fn clear_all_response_interrupt(&mut self) {}
208+
}

esp-hal/src/sdio/slc.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use super::PeripheralInstance;
2+
use crate::pac::slc;
3+
4+
crate::any_peripheral! {
5+
/// Any SDIO SLC peripheral.
6+
pub peripheral AnySlc<'d> {
7+
Slc(crate::peripherals::SLC<'d>)
8+
}
9+
}
10+
11+
/// Represents the SLC registers for SDIO peripherals.
12+
pub struct SlcInfo {
13+
/// Represents the SLC register block.
14+
pub register_block: *const slc::RegisterBlock,
15+
}
16+
17+
unsafe impl Sync for SlcInfo {}
18+
19+
impl PeripheralInstance for AnySlc<'_> {
20+
type Info = SlcInfo;
21+
22+
fn info(&self) -> &'static Self::Info {
23+
static INFO: SlcInfo = SlcInfo {
24+
register_block: crate::peripherals::SLC::ptr(),
25+
};
26+
27+
&INFO
28+
}
29+
}
30+
31+
/// A peripheral singleton compatible with the SDIO SLC driver.
32+
pub trait SlcInstance: PeripheralInstance + IntoAnySlc {}
33+
34+
impl<'d> SlcInstance for AnySlc<'d> {}

esp-hal/src/sdio/slchost.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use super::PeripheralInstance;
2+
use crate::pac::slchost;
3+
4+
crate::any_peripheral! {
5+
/// Any SDIO peripheral.
6+
pub peripheral AnySlchost<'d> {
7+
Slchost(crate::peripherals::SLCHOST<'d>)
8+
}
9+
}
10+
11+
/// Represents the SLCHOST registers for SDIO peripherals.
12+
pub struct SlchostInfo {
13+
/// Represents the SLCHOST register block.
14+
pub register_block: *const slchost::RegisterBlock,
15+
}
16+
17+
unsafe impl Sync for SlchostInfo {}
18+
19+
impl PeripheralInstance for AnySlchost<'_> {
20+
type Info = SlchostInfo;
21+
22+
fn info(&self) -> &'static Self::Info {
23+
static INFO: SlchostInfo = SlchostInfo {
24+
register_block: crate::peripherals::SLCHOST::ptr(),
25+
};
26+
27+
&INFO
28+
}
29+
}
30+
31+
/// A peripheral singleton compatible with the SDIO SLCHOST driver.
32+
pub trait SlchostInstance: PeripheralInstance + IntoAnySlchost {}
33+
34+
impl<'d> SlchostInstance for AnySlchost<'d> {}

esp-hal/src/soc/esp32c6/peripherals.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ crate::peripherals! {
7979
RNG <= RNG,
8080
RSA <= RSA,
8181
SHA <= SHA,
82+
SLC <= SLC,
8283
SLCHOST <= SLCHOST,
8384
SOC_ETM <= SOC_ETM,
8485
SPI0 <= SPI0,

examples/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ embassy-net = { version = "0.6.0", features = [ "tcp", "udp", "dhcpv4", "medium-
1717
embassy-sync = "0.6.2"
1818
embassy-time = "0.4.0"
1919
embassy-usb = { version = "0.4.0", default-features = false }
20-
embedded-hal-async = "1.0.0"
20+
embedded-hal-async = { version = "1.0.0", git = "https://github.com/rmsyn/embedded-hal", branch = "embedded-hal/mmc" }
2121
embedded-io = { version = "0.6.1", default-features = false }
2222
embedded-io-async = "0.6.1"
2323
embedded-storage = "0.3.1"

hil-test/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,12 +230,12 @@ embassy-futures = "0.1.1"
230230
embedded-storage = "0.3.1"
231231
embassy-sync = "0.6.0"
232232
embassy-time = "0.4.0"
233-
embedded-hal = "1.0.0"
233+
embedded-hal = { version = "1.0.0", git = "https://github.com/rmsyn/embedded-hal", branch = "embedded-hal/mmc" }
234234
embedded-io = "0.6.1"
235235
embedded-io-async = "0.6.1"
236236
embedded-can = "0.4.1"
237-
embedded-hal-async = "1.0.0"
238-
embedded-hal-nb = "1.0.0"
237+
embedded-hal-async = { version = "1.0.0", git = "https://github.com/rmsyn/embedded-hal", branch = "embedded-hal/mmc" }
238+
embedded-hal-nb = { version = "1.0.0", git = "https://github.com/rmsyn/embedded-hal", branch = "embedded-hal/mmc" }
239239
esp-alloc = { path = "../esp-alloc", optional = true }
240240
esp-backtrace = { path = "../esp-backtrace", default-features = false, features = ["exception-handler", "defmt", "semihosting"] }
241241
esp-hal = { path = "../esp-hal", optional = true }

0 commit comments

Comments
 (0)