Skip to content

Commit 7a221ce

Browse files
committed
sdio: add set timing method
Adds the `Timing` struct to represent SDIO timing settings. Adds a method to set low-level timing configuration for the SDIO peripheral.
1 parent 72a31b3 commit 7a221ce

File tree

3 files changed

+109
-4
lines changed

3 files changed

+109
-4
lines changed

esp-hal/src/sdio.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ mod pins;
2727
mod slc;
2828
mod slchost;
2929
mod state;
30+
mod timing;
3031

3132
pub use config::Config;
3233
pub use hinf::{AnyHinf, HinfInfo, HinfInstance};
@@ -35,6 +36,7 @@ pub use pins::Pins;
3536
pub use slc::{AnySlc, SlcInfo, SlcInstance};
3637
pub use slchost::{AnySlchost, SlchostInfo, SlchostInstance};
3738
pub use state::State;
39+
pub use timing::Timing;
3840

3941
/// SDIO peripheral instance.
4042
pub trait PeripheralInstance: crate::private::Sealed {
@@ -192,6 +194,7 @@ impl<'d> Sdio<'d> {
192194
pub(crate) fn hardware_init(&mut self) -> Result<(), Error> {
193195
self.low_level_init()?;
194196
self.low_level_enable_hs()?;
197+
self.low_level_set_timing()?;
195198

196199
Err(Error::unimplemented())
197200
}
@@ -226,7 +229,48 @@ impl<'d> Sdio<'d> {
226229
let hinf = unsafe { &*self.hinf.info().register_block };
227230

228231
hinf.cfg_data1()
229-
.modify(|_, w| w.highspeed_enable().variant(self.config.hs));
232+
.modify(|_, w| w.highspeed_enable().variant(self.config.hs()));
233+
234+
Ok(())
235+
}
236+
237+
fn low_level_set_timing(&mut self) -> Result<(), Error> {
238+
let host = unsafe { &*self.slchost.info().register_block };
239+
240+
match self.config.timing() {
241+
Timing::PsendPsample => {
242+
host.conf().modify(|_, w| unsafe {
243+
w.frc_sdio20().bits(0x1f);
244+
w.frc_sdio11().bits(0x0);
245+
w.frc_pos_samp().bits(0x1f);
246+
w.frc_neg_samp().bits(0x0)
247+
});
248+
}
249+
Timing::PsendNsample => {
250+
host.conf().modify(|_, w| unsafe {
251+
w.frc_sdio20().bits(0x1f);
252+
w.frc_sdio11().bits(0x0);
253+
w.frc_pos_samp().bits(0x0);
254+
w.frc_neg_samp().bits(0x1f)
255+
});
256+
}
257+
Timing::NsendPsample => {
258+
host.conf().modify(|_, w| unsafe {
259+
w.frc_sdio20().bits(0x0);
260+
w.frc_sdio11().bits(0x1f);
261+
w.frc_pos_samp().bits(0x1f);
262+
w.frc_neg_samp().bits(0x0)
263+
});
264+
}
265+
Timing::NsendNsample => {
266+
host.conf().modify(|_, w| unsafe {
267+
w.frc_sdio20().bits(0x0);
268+
w.frc_sdio11().bits(0x1f);
269+
w.frc_pos_samp().bits(0x0);
270+
w.frc_neg_samp().bits(0x1f)
271+
});
272+
}
273+
}
230274

231275
Ok(())
232276
}

esp-hal/src/sdio/config.rs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,50 @@
1+
use super::Timing;
2+
13
/// Represents SDIO configuration parameters.
24
#[repr(C)]
35
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
46
pub struct Config {
5-
/// Indicates support for high-speed mode.
6-
pub hs: bool,
7+
hs: bool,
8+
timing: Timing,
79
}
810

911
impl Config {
1012
/// Creates a new [Config].
1113
pub const fn new() -> Self {
12-
Self { hs: false }
14+
Self {
15+
hs: false,
16+
timing: Timing::new(),
17+
}
18+
}
19+
20+
/// Gets the highspeed enable setting.
21+
pub const fn hs(&self) -> bool {
22+
self.hs
23+
}
24+
25+
/// Sets the highspeed enable setting.
26+
pub fn set_hs(&mut self, hs: bool) {
27+
self.hs = hs;
28+
}
29+
30+
/// Builder funciton that sets the highspeed enable setting.
31+
pub fn with_hs(self, hs: bool) -> Self {
32+
Self { hs, ..self }
33+
}
34+
35+
/// Gets the timing setting.
36+
pub const fn timing(&self) -> Timing {
37+
self.timing
38+
}
39+
40+
/// Sets the timing setting.
41+
pub fn set_timing(&mut self, timing: Timing) {
42+
self.timing = timing;
43+
}
44+
45+
/// Builder funciton that sets the timing setting.
46+
pub fn with_timing(self, timing: Timing) -> Self {
47+
Self { timing, ..self }
1348
}
1449
}
1550

esp-hal/src/sdio/timing.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/// Represents SDIO device timing settings.
2+
#[repr(u8)]
3+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4+
pub enum Timing {
5+
/// Send at posedge, and sample at posedge. Default for HS.
6+
PsendPsample = 0,
7+
/// Send at negedge, and sample at posedge. Default for DS.
8+
NsendPsample,
9+
/// Send at posedge, and sample at negedge.
10+
PsendNsample,
11+
/// Send at negedge, and sample at negedge.
12+
NsendNsample,
13+
}
14+
15+
impl Timing {
16+
/// Creates a new [Timing].
17+
pub const fn new() -> Self {
18+
Self::PsendPsample
19+
}
20+
}
21+
22+
impl Default for Timing {
23+
fn default() -> Self {
24+
Self::new()
25+
}
26+
}

0 commit comments

Comments
 (0)