Skip to content

Commit 7d23f4d

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 59cfe43 commit 7d23f4d

File tree

9 files changed

+285
-6
lines changed

9 files changed

+285
-6
lines changed

esp-hal/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3232
- Expose ADC asynchrounous functionalities where applicable (#3443)
3333
- Added `UartInterrupt::RxTimeout` support (#3493)
3434
- UART: Added HW and SW flow control config option (#3435)
35+
- Added `Sdio` support (#3503)
3536

3637
### Changed
3738

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

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-bootloader-esp-idf = { path = "../esp-bootloader-esp-idf" }

0 commit comments

Comments
 (0)