Skip to content

Commit bc0c396

Browse files
committed
fixup: sdio: pac-specific init functions
Uses conditional compilation to perform PAC-specific initialization routines. Mainly handles different register naming conventions.
1 parent 69ec4b9 commit bc0c396

File tree

1 file changed

+121
-20
lines changed

1 file changed

+121
-20
lines changed

esp-hal/src/sdio.rs

Lines changed: 121 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ use embedded_hal_sdmmc::{
1818
tuning::{TuningMode, TuningWidth},
1919
};
2020

21-
use crate::gpio::{InputConfig, OutputConfig, Pull};
21+
use crate::{
22+
gpio::{InputConfig, OutputConfig, Pull},
23+
pac,
24+
};
2225

2326
mod config;
2427
mod hinf;
@@ -145,16 +148,31 @@ impl<'d> Sdio<'d> {
145148
self.slc.info()
146149
}
147150

151+
/// Convenience function to get a reference to the SLC register block.
152+
fn slc_block(&self) -> &'_ pac::slc::RegisterBlock {
153+
unsafe { &*self.slc().register_block }
154+
}
155+
148156
/// Gets a static reference to the SLCHOST information.
149157
pub fn slchost(&self) -> &'static SlchostInfo {
150158
self.slchost.info()
151159
}
152160

161+
/// Convenience function to get a reference to the SLCHOST register block.
162+
fn slchost_block(&self) -> &'_ pac::slchost::RegisterBlock {
163+
unsafe { &*self.slchost().register_block }
164+
}
165+
153166
/// Gets a static reference to the HINF information.
154167
pub fn hinf(&self) -> &'static HinfInfo {
155168
self.hinf.info()
156169
}
157170

171+
/// Convenience function to get a reference to the SLCHOST register block.
172+
fn hinf_block(&self) -> &'_ pac::hinf::RegisterBlock {
173+
unsafe { &*self.hinf().register_block }
174+
}
175+
158176
/// Gets a reference to the [Pins] information.
159177
pub const fn pins(&self) -> &Pins<'_> {
160178
&self.pins
@@ -192,16 +210,42 @@ impl<'d> Sdio<'d> {
192210

193211
/// Performs final low-level HAL hardware initialization.
194212
pub(crate) fn hardware_init(&mut self) -> Result<(), Error> {
195-
self.low_level_init()?;
196-
self.low_level_enable_hs()?;
197-
self.low_level_set_timing()?;
198-
self.low_level_set_timing()?;
199-
self.low_level_dev_interrupt_enable(0xffu8.into())
213+
self.pac_init()?;
214+
self.pac_enable_hs()?;
215+
self.pac_set_timing()?;
216+
self.pac_dev_interrupt_enable(0xffu8.into())
200217
}
201218

202219
/// Performs low-level initialization of the SDIO peripheral.
203-
pub(crate) fn low_level_init(&mut self) -> Result<(), Error> {
204-
let slc = unsafe { &*self.slc.info().register_block };
220+
#[cfg(feature = "esp32")]
221+
fn pac_init(&mut self) -> Result<(), Error> {
222+
let slc = self.slc_block();
223+
224+
slc.conf0().modify(|_, w| {
225+
w.slc0_rx_auto_wrback().set_bit();
226+
w.slc0_token_auto_clr().clear_bit();
227+
228+
w.slc0_rx_loop_test().clear_bit();
229+
w.slc0_tx_loop_test().clear_bit()
230+
});
231+
232+
slc.conf1().modify(|_, w| {
233+
w.slc0_rx_stitch_en().clear_bit();
234+
w.slc0_tx_stitch_en().clear_bit();
235+
236+
w.slc0_len_auto_clr().clear_bit()
237+
});
238+
239+
slc.rx_dscr_conf()
240+
.modify(|_, w| w.slc0_token_no_replace().set_bit());
241+
242+
Ok(())
243+
}
244+
245+
/// Performs low-level initialization of the SDIO peripheral.
246+
#[cfg(feature = "esp32c6")]
247+
fn pac_init(&mut self) -> Result<(), Error> {
248+
let slc = self.slc_block();
205249

206250
slc.slcconf0().modify(|_, w| {
207251
w.sdio_slc0_rx_auto_wrback().set_bit();
@@ -225,18 +269,62 @@ impl<'d> Sdio<'d> {
225269
}
226270

227271
/// Sets the high-speed supported bit to be read by the host.
228-
pub(crate) fn low_level_enable_hs(&mut self) -> Result<(), Error> {
229-
let hinf = unsafe { &*self.hinf.info().register_block };
230-
231-
hinf.cfg_data1()
272+
#[cfg(any(feature = "esp32", feature = "esp32c6"))]
273+
fn pac_enable_hs(&mut self) -> Result<(), Error> {
274+
self.hinf_block()
275+
.cfg_data1()
232276
.modify(|_, w| w.highspeed_enable().variant(self.config.hs()));
233277

234278
Ok(())
235279
}
236280

237281
/// Sets the communication timing.
238-
pub(crate) fn low_level_set_timing(&mut self) -> Result<(), Error> {
239-
let host = unsafe { &*self.slchost.info().register_block };
282+
#[cfg(feature = "esp32")]
283+
fn pac_set_timing(&mut self) -> Result<(), Error> {
284+
let host = self.slchost_block();
285+
286+
match self.config.timing() {
287+
Timing::PsendPsample => {
288+
host.host_slchost_conf().modify(|_, w| unsafe {
289+
w.host_frc_sdio20().bits(0x1f);
290+
w.host_frc_sdio11().bits(0x0);
291+
w.host_frc_pos_samp().bits(0x1f);
292+
w.host_frc_neg_samp().bits(0x0)
293+
});
294+
}
295+
Timing::PsendNsample => {
296+
host.host_slchost_conf().modify(|_, w| unsafe {
297+
w.host_frc_sdio20().bits(0x1f);
298+
w.host_frc_sdio11().bits(0x0);
299+
w.host_frc_pos_samp().bits(0x0);
300+
w.host_frc_neg_samp().bits(0x1f)
301+
});
302+
}
303+
Timing::NsendPsample => {
304+
host.host_slchost_conf().modify(|_, w| unsafe {
305+
w.host_frc_sdio20().bits(0x0);
306+
w.host_frc_sdio11().bits(0x1f);
307+
w.host_frc_pos_samp().bits(0x1f);
308+
w.host_frc_neg_samp().bits(0x0)
309+
});
310+
}
311+
Timing::NsendNsample => {
312+
host.host_slchost_conf().modify(|_, w| unsafe {
313+
w.host_frc_sdio20().bits(0x0);
314+
w.host_frc_sdio11().bits(0x1f);
315+
w.host_frc_pos_samp().bits(0x0);
316+
w.host_frc_neg_samp().bits(0x1f)
317+
});
318+
}
319+
}
320+
321+
Ok(())
322+
}
323+
324+
/// Sets the communication timing.
325+
#[cfg(feature = "esp32c6")]
326+
fn pac_set_timing(&mut self) -> Result<(), Error> {
327+
let host = self.slchost_block();
240328

241329
match self.config.timing() {
242330
Timing::PsendPsample => {
@@ -277,13 +365,26 @@ impl<'d> Sdio<'d> {
277365
}
278366

279367
/// Sets which device interrupts to enable based on the provided mask.
280-
pub(crate) fn low_level_dev_interrupt_enable(
281-
&self,
282-
mask: DeviceInterrupt,
283-
) -> Result<(), Error> {
284-
let slc = unsafe { &*self.slc.info().register_block };
368+
#[cfg(feature = "esp32")]
369+
fn pac_dev_interrupt_enable(&self, mask: DeviceInterrupt) -> Result<(), Error> {
370+
self.slc_block()._0int_ena().modify(|_, w| {
371+
w.frhost_bit0_int_ena().variant(mask.general0());
372+
w.frhost_bit1_int_ena().variant(mask.general1());
373+
w.frhost_bit2_int_ena().variant(mask.general2());
374+
w.frhost_bit3_int_ena().variant(mask.general3());
375+
w.frhost_bit4_int_ena().variant(mask.general4());
376+
w.frhost_bit5_int_ena().variant(mask.general5());
377+
w.frhost_bit6_int_ena().variant(mask.general6());
378+
w.frhost_bit7_int_ena().variant(mask.general7())
379+
});
285380

286-
slc.slc0int_ena().modify(|_, w| {
381+
Ok(())
382+
}
383+
384+
/// Sets which device interrupts to enable based on the provided mask.
385+
#[cfg(feature = "esp32c6")]
386+
fn pac_dev_interrupt_enable(&self, mask: DeviceInterrupt) -> Result<(), Error> {
387+
self.slc_block().slc0int_ena().modify(|_, w| {
287388
w.sdio_slc_frhost_bit0_int_ena().variant(mask.general0());
288389
w.sdio_slc_frhost_bit1_int_ena().variant(mask.general1());
289390
w.sdio_slc_frhost_bit2_int_ena().variant(mask.general2());

0 commit comments

Comments
 (0)