aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/dma/util.rs58
-rw-r--r--embassy-stm32/src/sdmmc/mod.rs1005
-rw-r--r--embassy-stm32/src/time.rs2
-rw-r--r--examples/stm32f4/src/bin/sdmmc.rs35
-rw-r--r--examples/stm32f7/src/bin/sdmmc.rs12
-rw-r--r--examples/stm32h7/src/bin/sdmmc.rs14
-rw-r--r--tests/stm32/src/bin/sdmmc.rs37
7 files changed, 636 insertions, 527 deletions
diff --git a/embassy-stm32/src/dma/util.rs b/embassy-stm32/src/dma/util.rs
index 3245887c1..304268963 100644
--- a/embassy-stm32/src/dma/util.rs
+++ b/embassy-stm32/src/dma/util.rs
@@ -20,6 +20,16 @@ impl<'d> ChannelAndRequest<'d> {
20 Transfer::new_read(self.channel.reborrow(), self.request, peri_addr, buf, options) 20 Transfer::new_read(self.channel.reborrow(), self.request, peri_addr, buf, options)
21 } 21 }
22 22
23 #[allow(dead_code)]
24 pub unsafe fn read_unchecked<'a, W: Word>(
25 &'a self,
26 peri_addr: *mut W,
27 buf: &'a mut [W],
28 options: TransferOptions,
29 ) -> Transfer<'a> {
30 Transfer::new_read(self.channel.clone_unchecked(), self.request, peri_addr, buf, options)
31 }
32
23 pub unsafe fn read_raw<'a, MW: Word, PW: Word>( 33 pub unsafe fn read_raw<'a, MW: Word, PW: Word>(
24 &'a mut self, 34 &'a mut self,
25 peri_addr: *mut PW, 35 peri_addr: *mut PW,
@@ -29,6 +39,16 @@ impl<'d> ChannelAndRequest<'d> {
29 Transfer::new_read_raw(self.channel.reborrow(), self.request, peri_addr, buf, options) 39 Transfer::new_read_raw(self.channel.reborrow(), self.request, peri_addr, buf, options)
30 } 40 }
31 41
42 #[allow(dead_code)]
43 pub unsafe fn read_raw_unchecked<'a, MW: Word, PW: Word>(
44 &'a self,
45 peri_addr: *mut PW,
46 buf: *mut [MW],
47 options: TransferOptions,
48 ) -> Transfer<'a> {
49 Transfer::new_read_raw(self.channel.clone_unchecked(), self.request, peri_addr, buf, options)
50 }
51
32 pub unsafe fn write<'a, W: Word>( 52 pub unsafe fn write<'a, W: Word>(
33 &'a mut self, 53 &'a mut self,
34 buf: &'a [W], 54 buf: &'a [W],
@@ -38,6 +58,16 @@ impl<'d> ChannelAndRequest<'d> {
38 Transfer::new_write(self.channel.reborrow(), self.request, buf, peri_addr, options) 58 Transfer::new_write(self.channel.reborrow(), self.request, buf, peri_addr, options)
39 } 59 }
40 60
61 #[allow(dead_code)]
62 pub unsafe fn write_unchecked<'a, W: Word>(
63 &'a self,
64 buf: &'a [W],
65 peri_addr: *mut W,
66 options: TransferOptions,
67 ) -> Transfer<'a> {
68 Transfer::new_write(self.channel.clone_unchecked(), self.request, buf, peri_addr, options)
69 }
70
41 pub unsafe fn write_raw<'a, MW: Word, PW: Word>( 71 pub unsafe fn write_raw<'a, MW: Word, PW: Word>(
42 &'a mut self, 72 &'a mut self,
43 buf: *const [MW], 73 buf: *const [MW],
@@ -48,6 +78,16 @@ impl<'d> ChannelAndRequest<'d> {
48 } 78 }
49 79
50 #[allow(dead_code)] 80 #[allow(dead_code)]
81 pub unsafe fn write_raw_unchecked<'a, MW: Word, PW: Word>(
82 &'a self,
83 buf: *const [MW],
84 peri_addr: *mut PW,
85 options: TransferOptions,
86 ) -> Transfer<'a> {
87 Transfer::new_write_raw(self.channel.clone_unchecked(), self.request, buf, peri_addr, options)
88 }
89
90 #[allow(dead_code)]
51 pub unsafe fn write_repeated<'a, W: Word>( 91 pub unsafe fn write_repeated<'a, W: Word>(
52 &'a mut self, 92 &'a mut self,
53 repeated: &'a W, 93 repeated: &'a W,
@@ -64,4 +104,22 @@ impl<'d> ChannelAndRequest<'d> {
64 options, 104 options,
65 ) 105 )
66 } 106 }
107
108 #[allow(dead_code)]
109 pub unsafe fn write_repeated_unchecked<'a, W: Word>(
110 &'a self,
111 repeated: &'a W,
112 count: usize,
113 peri_addr: *mut W,
114 options: TransferOptions,
115 ) -> Transfer<'a> {
116 Transfer::new_write_repeated(
117 self.channel.clone_unchecked(),
118 self.request,
119 repeated,
120 count,
121 peri_addr,
122 options,
123 )
124 }
67} 125}
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs
index 37ef7099f..ad00b4398 100644
--- a/embassy-stm32/src/sdmmc/mod.rs
+++ b/embassy-stm32/src/sdmmc/mod.rs
@@ -22,7 +22,7 @@ use crate::gpio::Pull;
22use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; 22use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed};
23use crate::interrupt::typelevel::Interrupt; 23use crate::interrupt::typelevel::Interrupt;
24use crate::pac::sdmmc::Sdmmc as RegBlock; 24use crate::pac::sdmmc::Sdmmc as RegBlock;
25use crate::rcc::{self, RccPeripheral}; 25use crate::rcc::{self, RccInfo, RccPeripheral, SealedRccPeripheral};
26use crate::time::Hertz; 26use crate::time::Hertz;
27use crate::{interrupt, peripherals}; 27use crate::{interrupt, peripherals};
28 28
@@ -31,28 +31,11 @@ pub struct InterruptHandler<T: Instance> {
31 _phantom: PhantomData<T>, 31 _phantom: PhantomData<T>,
32} 32}
33 33
34impl<T: Instance> InterruptHandler<T> {
35 fn enable_interrupts() {
36 let regs = T::regs();
37 regs.maskr().write(|w| {
38 w.set_dcrcfailie(true);
39 w.set_dtimeoutie(true);
40 w.set_dataendie(true);
41 w.set_dbckendie(true);
42
43 #[cfg(sdmmc_v1)]
44 w.set_stbiterre(true);
45 #[cfg(sdmmc_v2)]
46 w.set_dabortie(true);
47 });
48 }
49}
50
51impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { 34impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
52 unsafe fn on_interrupt() { 35 unsafe fn on_interrupt() {
53 T::state().wake(); 36 T::state().waker.wake();
54 let status = T::regs().star().read(); 37 let status = T::info().regs.star().read();
55 T::regs().maskr().modify(|w| { 38 T::info().regs.maskr().modify(|w| {
56 if status.dcrcfail() { 39 if status.dcrcfail() {
57 w.set_dcrcfailie(false) 40 w.set_dcrcfailie(false)
58 } 41 }
@@ -181,6 +164,76 @@ pub enum Error {
181 StBitErr, 164 StBitErr,
182} 165}
183 166
167/// Represents either an SD or EMMC card
168pub trait Addressable: Sized + Clone {
169 /// Associated type
170 type Ext;
171
172 /// Get this peripheral's address on the SDMMC bus
173 fn get_address(&self) -> u16;
174
175 /// Is this a standard or high capacity peripheral?
176 fn get_capacity(&self) -> CardCapacity;
177
178 /// Size in bytes
179 fn size(&self) -> u64;
180}
181
182/// Storage Device
183pub struct StorageDevice<'a, 'b, T: Addressable> {
184 info: T,
185 /// Inner member
186 pub sdmmc: &'a mut Sdmmc<'b>,
187}
188
189/// Card Storage Device
190impl<'a, 'b> StorageDevice<'a, 'b, Card> {
191 /// Create a new SD card
192 pub async fn new_sd_card(sdmmc: &'a mut Sdmmc<'b>, cmd_block: &mut CmdBlock, freq: Hertz) -> Result<Self, Error> {
193 let info = sdmmc.init_sd_card(cmd_block, freq).await?;
194
195 Ok(Self { info, sdmmc })
196 }
197}
198
199/// Emmc storage device
200impl<'a, 'b> StorageDevice<'a, 'b, Emmc> {
201 /// Create a new EMMC card
202 pub async fn new_emmc(sdmmc: &'a mut Sdmmc<'b>, cmd_block: &mut CmdBlock, freq: Hertz) -> Result<Self, Error> {
203 let info = sdmmc.init_emmc(cmd_block, freq).await?;
204
205 Ok(Self { info, sdmmc })
206 }
207}
208
209/// Card or Emmc storage device
210impl<'a, 'b, T: Addressable> StorageDevice<'a, 'b, T> {
211 /// Write a block
212 pub fn card(&self) -> T {
213 self.info.clone()
214 }
215
216 /// Write a block
217 pub async fn write_block(&mut self, block_idx: u32, buffer: &DataBlock) -> Result<(), Error> {
218 self.sdmmc.write_block(&mut self.info, block_idx, buffer).await
219 }
220
221 /// Write a block
222 pub async fn write_blocks(&mut self, block_idx: u32, blocks: &[DataBlock]) -> Result<(), Error> {
223 self.sdmmc.write_blocks(&mut self.info, block_idx, blocks).await
224 }
225
226 /// Read a block
227 pub async fn read_block(&mut self, block_idx: u32, buffer: &mut DataBlock) -> Result<(), Error> {
228 self.sdmmc.read_block(&mut self.info, block_idx, buffer).await
229 }
230
231 /// Read a block
232 pub async fn read_blocks(&mut self, block_idx: u32, blocks: &mut [DataBlock]) -> Result<(), Error> {
233 self.sdmmc.read_blocks(&mut self.info, block_idx, blocks).await
234 }
235}
236
184#[derive(Clone, Copy, Debug, Default)] 237#[derive(Clone, Copy, Debug, Default)]
185/// SD Card 238/// SD Card
186pub struct Card { 239pub struct Card {
@@ -200,6 +253,157 @@ pub struct Card {
200 pub status: SDStatus, 253 pub status: SDStatus,
201} 254}
202 255
256impl Card {
257 /// Switch mode using CMD6.
258 ///
259 /// Attempt to set a new signalling mode. The selected
260 /// signalling mode is returned. Expects the current clock
261 /// frequency to be > 12.5MHz.
262 ///
263 /// SD only.
264 async fn switch_signalling_mode<'a>(
265 &mut self,
266 sdmmc: &mut Sdmmc<'a>,
267 cmd_block: &mut CmdBlock,
268 signalling: Signalling,
269 ) -> Result<Signalling, Error> {
270 // NB PLSS v7_10 4.3.10.4: "the use of SET_BLK_LEN command is not
271 // necessary"
272
273 let set_function = 0x8000_0000
274 | match signalling {
275 // See PLSS v7_10 Table 4-11
276 Signalling::DDR50 => 0xFF_FF04,
277 Signalling::SDR104 => 0xFF_1F03,
278 Signalling::SDR50 => 0xFF_1F02,
279 Signalling::SDR25 => 0xFF_FF01,
280 Signalling::SDR12 => 0xFF_FF00,
281 };
282
283 // Arm `OnDrop` after the buffer, so it will be dropped first
284 let on_drop = OnDrop::new(|| sdmmc.on_drop());
285
286 let transfer = sdmmc.prepare_datapath_read(&sdmmc.config, cmd_block.as_mut(), 64, 6);
287 sdmmc.enable_interrupts();
288 sdmmc.cmd(sd_cmd::cmd6(set_function), true)?; // CMD6
289
290 let res = sdmmc.complete_datapath_transfer(true).await;
291
292 // Host is allowed to use the new functions at least 8
293 // clocks after the end of the switch command
294 // transaction. We know the current clock period is < 80ns,
295 // so a total delay of 640ns is required here
296 for _ in 0..300 {
297 cortex_m::asm::nop();
298 }
299
300 match res {
301 Ok(_) => {
302 on_drop.defuse();
303 sdmmc.stop_datapath();
304 drop(transfer);
305
306 // Function Selection of Function Group 1
307 let selection = (u32::from_be(cmd_block[4]) >> 24) & 0xF;
308
309 match selection {
310 0 => Ok(Signalling::SDR12),
311 1 => Ok(Signalling::SDR25),
312 2 => Ok(Signalling::SDR50),
313 3 => Ok(Signalling::SDR104),
314 4 => Ok(Signalling::DDR50),
315 _ => Err(Error::UnsupportedCardType),
316 }
317 }
318 Err(e) => Err(e),
319 }
320 }
321
322 /// Reads the SCR register.
323 ///
324 /// SD only.
325 async fn get_scr<'a>(&mut self, sdmmc: &mut Sdmmc<'a>, cmd_block: &mut CmdBlock) -> Result<(), Error> {
326 // Read the 64-bit SCR register
327 sdmmc.cmd(common_cmd::set_block_length(8), false)?; // CMD16
328 sdmmc.cmd(common_cmd::app_cmd(self.rca), false)?;
329
330 let scr = &mut cmd_block.0[..2];
331
332 // Arm `OnDrop` after the buffer, so it will be dropped first
333 let on_drop = OnDrop::new(|| sdmmc.on_drop());
334
335 let transfer = sdmmc.prepare_datapath_read(&sdmmc.config, scr, 8, 3);
336 sdmmc.enable_interrupts();
337 sdmmc.cmd(sd_cmd::send_scr(), true)?;
338
339 let res = sdmmc.complete_datapath_transfer(true).await;
340
341 if res.is_ok() {
342 on_drop.defuse();
343 sdmmc.stop_datapath();
344 drop(transfer);
345
346 unsafe {
347 let scr_bytes = &*(&scr as *const _ as *const [u8; 8]);
348 self.scr = SCR(u64::from_be_bytes(*scr_bytes));
349 }
350 }
351 res
352 }
353
354 /// Reads the SD Status (ACMD13)
355 ///
356 /// SD only.
357 async fn read_sd_status<'a>(&mut self, sdmmc: &mut Sdmmc<'a>, cmd_block: &mut CmdBlock) -> Result<(), Error> {
358 let rca = self.rca;
359
360 sdmmc.cmd(common_cmd::set_block_length(64), false)?; // CMD16
361 sdmmc.cmd(common_cmd::app_cmd(rca), false)?; // APP
362
363 let status = cmd_block;
364
365 // Arm `OnDrop` after the buffer, so it will be dropped first
366 let on_drop = OnDrop::new(|| sdmmc.on_drop());
367
368 let transfer = sdmmc.prepare_datapath_read(&sdmmc.config, status.as_mut(), 64, 6);
369 sdmmc.enable_interrupts();
370 sdmmc.cmd(sd_cmd::sd_status(), true)?;
371
372 let res = sdmmc.complete_datapath_transfer(true).await;
373
374 if res.is_ok() {
375 on_drop.defuse();
376 sdmmc.stop_datapath();
377 drop(transfer);
378
379 for byte in status.iter_mut() {
380 *byte = u32::from_be(*byte);
381 }
382 self.status = status.0.into();
383 }
384 res
385 }
386}
387
388impl Addressable for Card {
389 type Ext = SD;
390
391 /// Get this peripheral's address on the SDMMC bus
392 fn get_address(&self) -> u16 {
393 self.rca
394 }
395
396 /// Is this a standard or high capacity peripheral?
397 fn get_capacity(&self) -> CardCapacity {
398 self.card_type
399 }
400
401 /// Size in bytes
402 fn size(&self) -> u64 {
403 u64::from(self.csd.block_count()) * 512
404 }
405}
406
203#[derive(Clone, Copy, Debug, Default)] 407#[derive(Clone, Copy, Debug, Default)]
204/// eMMC storage 408/// eMMC storage
205pub struct Emmc { 409pub struct Emmc {
@@ -217,6 +421,59 @@ pub struct Emmc {
217 pub ext_csd: ExtCSD, 421 pub ext_csd: ExtCSD,
218} 422}
219 423
424impl Emmc {
425 /// Gets the EXT_CSD register.
426 ///
427 /// eMMC only.
428 async fn read_ext_csd<'a>(&mut self, sdmmc: &mut Sdmmc<'a>) -> Result<(), Error> {
429 // Note: cmd_block can't be used because ExtCSD is too long to fit.
430 let mut data_block = DataBlock([0u8; 512]);
431
432 // NOTE(unsafe) DataBlock uses align 4
433 let buffer = unsafe { &mut *((&mut data_block.0) as *mut [u8; 512] as *mut [u32; 128]) };
434
435 sdmmc.cmd(common_cmd::set_block_length(512), false).unwrap(); // CMD16
436
437 let transfer = sdmmc.prepare_datapath_read(&sdmmc.config, buffer, 512, 9);
438 sdmmc.enable_interrupts();
439 sdmmc.cmd(emmc_cmd::send_ext_csd(), true)?;
440
441 // Arm `OnDrop` after the buffer, so it will be dropped first
442 let on_drop = OnDrop::new(|| sdmmc.on_drop());
443
444 let res = sdmmc.complete_datapath_transfer(true).await;
445
446 if res.is_ok() {
447 on_drop.defuse();
448 sdmmc.stop_datapath();
449 drop(transfer);
450
451 self.ext_csd = unsafe { core::mem::transmute::<_, [u32; 128]>(data_block.0) }.into();
452 }
453
454 res
455 }
456}
457
458impl Addressable for Emmc {
459 type Ext = EMMC;
460
461 /// Get this peripheral's address on the SDMMC bus
462 fn get_address(&self) -> u16 {
463 self.rca
464 }
465
466 /// Is this a standard or high capacity peripheral?
467 fn get_capacity(&self) -> CardCapacity {
468 self.capacity
469 }
470
471 /// Size in bytes
472 fn size(&self) -> u64 {
473 u64::from(self.ext_csd.sector_count()) * 512
474 }
475}
476
220#[repr(u8)] 477#[repr(u8)]
221enum PowerCtrl { 478enum PowerCtrl {
222 Off = 0b00, 479 Off = 0b00,
@@ -340,47 +597,13 @@ impl SdmmcPeripheral {
340 Self::Emmc(e) => e.rca, 597 Self::Emmc(e) => e.rca,
341 } 598 }
342 } 599 }
343 /// Is this a standard or high capacity peripheral?
344 fn get_capacity(&self) -> CardCapacity {
345 match self {
346 Self::SdCard(c) => c.card_type,
347 Self::Emmc(e) => e.capacity,
348 }
349 }
350 /// Size in bytes
351 fn size(&self) -> u64 {
352 match self {
353 // SDHC / SDXC / SDUC
354 Self::SdCard(c) => u64::from(c.csd.block_count()) * 512,
355 // capacity > 2GB
356 Self::Emmc(e) => u64::from(e.ext_csd.sector_count()) * 512,
357 }
358 }
359
360 /// Get a mutable reference to the SD Card.
361 ///
362 /// Panics if there is another peripheral instead.
363 fn get_sd_card(&mut self) -> &mut Card {
364 match *self {
365 Self::SdCard(ref mut c) => c,
366 _ => unreachable!("SD only"),
367 }
368 }
369
370 /// Get a mutable reference to the eMMC.
371 ///
372 /// Panics if there is another peripheral instead.
373 fn get_emmc(&mut self) -> &mut Emmc {
374 match *self {
375 Self::Emmc(ref mut e) => e,
376 _ => unreachable!("eMMC only"),
377 }
378 }
379} 600}
380 601
381/// Sdmmc device 602/// Sdmmc device
382pub struct Sdmmc<'d, T: Instance> { 603pub struct Sdmmc<'d> {
383 _peri: Peri<'d, T>, 604 info: &'static Info,
605 state: &'static State,
606 ker_clk: Hertz,
384 #[cfg(sdmmc_v1)] 607 #[cfg(sdmmc_v1)]
385 dma: ChannelAndRequest<'d>, 608 dma: ChannelAndRequest<'d>,
386 609
@@ -400,12 +623,6 @@ pub struct Sdmmc<'d, T: Instance> {
400 clock: Hertz, 623 clock: Hertz,
401 /// Current signalling scheme to card 624 /// Current signalling scheme to card
402 signalling: Signalling, 625 signalling: Signalling,
403 /// Card
404 card: Option<SdmmcPeripheral>,
405
406 /// An optional buffer to be used for commands
407 /// This should be used if there are special memory location requirements for dma
408 cmd_block: Option<&'d mut CmdBlock>,
409} 626}
410 627
411const CLK_AF: AfType = AfType::output(OutputType::PushPull, Speed::VeryHigh); 628const CLK_AF: AfType = AfType::output(OutputType::PushPull, Speed::VeryHigh);
@@ -416,9 +633,9 @@ const CMD_AF: AfType = AfType::output_pull(OutputType::PushPull, Speed::VeryHigh
416const DATA_AF: AfType = CMD_AF; 633const DATA_AF: AfType = CMD_AF;
417 634
418#[cfg(sdmmc_v1)] 635#[cfg(sdmmc_v1)]
419impl<'d, T: Instance> Sdmmc<'d, T> { 636impl<'d> Sdmmc<'d> {
420 /// Create a new SDMMC driver, with 1 data lane. 637 /// Create a new SDMMC driver, with 1 data lane.
421 pub fn new_1bit( 638 pub fn new_1bit<T: Instance>(
422 sdmmc: Peri<'d, T>, 639 sdmmc: Peri<'d, T>,
423 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 640 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
424 dma: Peri<'d, impl SdmmcDma<T>>, 641 dma: Peri<'d, impl SdmmcDma<T>>,
@@ -451,7 +668,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
451 } 668 }
452 669
453 /// Create a new SDMMC driver, with 4 data lanes. 670 /// Create a new SDMMC driver, with 4 data lanes.
454 pub fn new_4bit( 671 pub fn new_4bit<T: Instance>(
455 sdmmc: Peri<'d, T>, 672 sdmmc: Peri<'d, T>,
456 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 673 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
457 dma: Peri<'d, impl SdmmcDma<T>>, 674 dma: Peri<'d, impl SdmmcDma<T>>,
@@ -491,9 +708,9 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
491} 708}
492 709
493#[cfg(sdmmc_v1)] 710#[cfg(sdmmc_v1)]
494impl<'d, T: Instance> Sdmmc<'d, T> { 711impl<'d> Sdmmc<'d> {
495 /// Create a new SDMMC driver, with 8 data lanes. 712 /// Create a new SDMMC driver, with 8 data lanes.
496 pub fn new_8bit( 713 pub fn new_8bit<T: Instance>(
497 sdmmc: Peri<'d, T>, 714 sdmmc: Peri<'d, T>,
498 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 715 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
499 dma: Peri<'d, impl SdmmcDma<T>>, 716 dma: Peri<'d, impl SdmmcDma<T>>,
@@ -541,9 +758,9 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
541} 758}
542 759
543#[cfg(sdmmc_v2)] 760#[cfg(sdmmc_v2)]
544impl<'d, T: Instance> Sdmmc<'d, T> { 761impl<'d> Sdmmc<'d> {
545 /// Create a new SDMMC driver, with 1 data lane. 762 /// Create a new SDMMC driver, with 1 data lane.
546 pub fn new_1bit( 763 pub fn new_1bit<T: Instance>(
547 sdmmc: Peri<'d, T>, 764 sdmmc: Peri<'d, T>,
548 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 765 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
549 clk: Peri<'d, impl CkPin<T>>, 766 clk: Peri<'d, impl CkPin<T>>,
@@ -574,7 +791,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
574 } 791 }
575 792
576 /// Create a new SDMMC driver, with 4 data lanes. 793 /// Create a new SDMMC driver, with 4 data lanes.
577 pub fn new_4bit( 794 pub fn new_4bit<T: Instance>(
578 sdmmc: Peri<'d, T>, 795 sdmmc: Peri<'d, T>,
579 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 796 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
580 clk: Peri<'d, impl CkPin<T>>, 797 clk: Peri<'d, impl CkPin<T>>,
@@ -612,9 +829,9 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
612} 829}
613 830
614#[cfg(sdmmc_v2)] 831#[cfg(sdmmc_v2)]
615impl<'d, T: Instance> Sdmmc<'d, T> { 832impl<'d> Sdmmc<'d> {
616 /// Create a new SDMMC driver, with 8 data lanes. 833 /// Create a new SDMMC driver, with 8 data lanes.
617 pub fn new_8bit( 834 pub fn new_8bit<T: Instance>(
618 sdmmc: Peri<'d, T>, 835 sdmmc: Peri<'d, T>,
619 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 836 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
620 clk: Peri<'d, impl CkPin<T>>, 837 clk: Peri<'d, impl CkPin<T>>,
@@ -659,9 +876,24 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
659 } 876 }
660} 877}
661 878
662impl<'d, T: Instance> Sdmmc<'d, T> { 879impl<'d> Sdmmc<'d> {
663 fn new_inner( 880 fn enable_interrupts(&self) {
664 sdmmc: Peri<'d, T>, 881 let regs = self.info.regs;
882 regs.maskr().write(|w| {
883 w.set_dcrcfailie(true);
884 w.set_dtimeoutie(true);
885 w.set_dataendie(true);
886 w.set_dbckendie(true);
887
888 #[cfg(sdmmc_v1)]
889 w.set_stbiterre(true);
890 #[cfg(sdmmc_v2)]
891 w.set_dabortie(true);
892 });
893 }
894
895 fn new_inner<T: Instance>(
896 _sdmmc: Peri<'d, T>,
665 #[cfg(sdmmc_v1)] dma: ChannelAndRequest<'d>, 897 #[cfg(sdmmc_v1)] dma: ChannelAndRequest<'d>,
666 clk: Peri<'d, AnyPin>, 898 clk: Peri<'d, AnyPin>,
667 cmd: Peri<'d, AnyPin>, 899 cmd: Peri<'d, AnyPin>,
@@ -680,8 +912,11 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
680 T::Interrupt::unpend(); 912 T::Interrupt::unpend();
681 unsafe { T::Interrupt::enable() }; 913 unsafe { T::Interrupt::enable() };
682 914
683 let regs = T::regs(); 915 let info = T::info();
684 regs.clkcr().write(|w| { 916 let state = T::state();
917 let ker_clk = T::frequency();
918
919 info.regs.clkcr().write(|w| {
685 w.set_pwrsav(false); 920 w.set_pwrsav(false);
686 w.set_negedge(false); 921 w.set_negedge(false);
687 922
@@ -698,10 +933,12 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
698 933
699 // Power off, writen 00: Clock to the card is stopped; 934 // Power off, writen 00: Clock to the card is stopped;
700 // D[7:0], CMD, and CK are driven high. 935 // D[7:0], CMD, and CK are driven high.
701 regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::Off as u8)); 936 info.regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::Off as u8));
702 937
703 Self { 938 Self {
704 _peri: sdmmc, 939 info,
940 state,
941 ker_clk,
705 #[cfg(sdmmc_v1)] 942 #[cfg(sdmmc_v1)]
706 dma, 943 dma,
707 944
@@ -719,15 +956,13 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
719 config, 956 config,
720 clock: SD_INIT_FREQ, 957 clock: SD_INIT_FREQ,
721 signalling: Default::default(), 958 signalling: Default::default(),
722 card: None,
723 cmd_block: None,
724 } 959 }
725 } 960 }
726 961
727 /// Data transfer is in progress 962 /// Data transfer is in progress
728 #[inline] 963 #[inline]
729 fn data_active() -> bool { 964 fn data_active(&self) -> bool {
730 let regs = T::regs(); 965 let regs = self.info.regs;
731 966
732 let status = regs.star().read(); 967 let status = regs.star().read();
733 #[cfg(sdmmc_v1)] 968 #[cfg(sdmmc_v1)]
@@ -738,8 +973,8 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
738 973
739 /// Coammand transfer is in progress 974 /// Coammand transfer is in progress
740 #[inline] 975 #[inline]
741 fn cmd_active() -> bool { 976 fn cmd_active(&self) -> bool {
742 let regs = T::regs(); 977 let regs = self.info.regs;
743 978
744 let status = regs.star().read(); 979 let status = regs.star().read();
745 #[cfg(sdmmc_v1)] 980 #[cfg(sdmmc_v1)]
@@ -750,8 +985,8 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
750 985
751 /// Wait idle on CMDACT, RXACT and TXACT (v1) or DOSNACT and CPSMACT (v2) 986 /// Wait idle on CMDACT, RXACT and TXACT (v1) or DOSNACT and CPSMACT (v2)
752 #[inline] 987 #[inline]
753 fn wait_idle() { 988 fn wait_idle(&self) {
754 while Self::data_active() || Self::cmd_active() {} 989 while self.data_active() || self.cmd_active() {}
755 } 990 }
756 991
757 /// # Safety 992 /// # Safety
@@ -759,23 +994,27 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
759 /// `buffer` must be valid for the whole transfer and word aligned 994 /// `buffer` must be valid for the whole transfer and word aligned
760 #[allow(unused_variables)] 995 #[allow(unused_variables)]
761 fn prepare_datapath_read<'a>( 996 fn prepare_datapath_read<'a>(
997 &'a self,
762 config: &Config, 998 config: &Config,
763 #[cfg(sdmmc_v1)] dma: &'a mut ChannelAndRequest<'d>,
764 buffer: &'a mut [u32], 999 buffer: &'a mut [u32],
765 length_bytes: u32, 1000 length_bytes: u32,
766 block_size: u8, 1001 block_size: u8,
767 ) -> Transfer<'a> { 1002 ) -> Transfer<'a> {
768 assert!(block_size <= 14, "Block size up to 2^14 bytes"); 1003 assert!(block_size <= 14, "Block size up to 2^14 bytes");
769 let regs = T::regs(); 1004 let regs = self.info.regs;
770 1005
771 // Command AND Data state machines must be idle 1006 // Command AND Data state machines must be idle
772 Self::wait_idle(); 1007 self.wait_idle();
773 Self::clear_interrupt_flags(); 1008 self.clear_interrupt_flags();
774 1009
775 regs.dlenr().write(|w| w.set_datalength(length_bytes)); 1010 regs.dlenr().write(|w| w.set_datalength(length_bytes));
776 1011
1012 // SAFETY: No other functions use the dma
777 #[cfg(sdmmc_v1)] 1013 #[cfg(sdmmc_v1)]
778 let transfer = unsafe { dma.read(regs.fifor().as_ptr() as *mut u32, buffer, DMA_TRANSFER_OPTIONS) }; 1014 let transfer = unsafe {
1015 self.dma
1016 .read_unchecked(regs.fifor().as_ptr() as *mut u32, buffer, DMA_TRANSFER_OPTIONS)
1017 };
779 #[cfg(sdmmc_v2)] 1018 #[cfg(sdmmc_v2)]
780 let transfer = { 1019 let transfer = {
781 regs.idmabase0r().write(|w| w.set_idmabase0(buffer.as_mut_ptr() as u32)); 1020 regs.idmabase0r().write(|w| w.set_idmabase0(buffer.as_mut_ptr() as u32));
@@ -801,20 +1040,21 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
801 /// # Safety 1040 /// # Safety
802 /// 1041 ///
803 /// `buffer` must be valid for the whole transfer and word aligned 1042 /// `buffer` must be valid for the whole transfer and word aligned
804 fn prepare_datapath_write<'a>(&'a mut self, buffer: &'a [u32], length_bytes: u32, block_size: u8) -> Transfer<'a> { 1043 fn prepare_datapath_write<'a>(&'a self, buffer: &'a [u32], length_bytes: u32, block_size: u8) -> Transfer<'a> {
805 assert!(block_size <= 14, "Block size up to 2^14 bytes"); 1044 assert!(block_size <= 14, "Block size up to 2^14 bytes");
806 let regs = T::regs(); 1045 let regs = self.info.regs;
807 1046
808 // Command AND Data state machines must be idle 1047 // Command AND Data state machines must be idle
809 Self::wait_idle(); 1048 self.wait_idle();
810 Self::clear_interrupt_flags(); 1049 self.clear_interrupt_flags();
811 1050
812 regs.dlenr().write(|w| w.set_datalength(length_bytes)); 1051 regs.dlenr().write(|w| w.set_datalength(length_bytes));
813 1052
1053 // SAFETY: No other functions use the dma
814 #[cfg(sdmmc_v1)] 1054 #[cfg(sdmmc_v1)]
815 let transfer = unsafe { 1055 let transfer = unsafe {
816 self.dma 1056 self.dma
817 .write(buffer, regs.fifor().as_ptr() as *mut u32, DMA_TRANSFER_OPTIONS) 1057 .write_unchecked(buffer, regs.fifor().as_ptr() as *mut u32, DMA_TRANSFER_OPTIONS)
818 }; 1058 };
819 #[cfg(sdmmc_v2)] 1059 #[cfg(sdmmc_v2)]
820 let transfer = { 1060 let transfer = {
@@ -839,8 +1079,8 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
839 } 1079 }
840 1080
841 /// Stops the DMA datapath 1081 /// Stops the DMA datapath
842 fn stop_datapath() { 1082 fn stop_datapath(&self) {
843 let regs = T::regs(); 1083 let regs = self.info.regs;
844 1084
845 #[cfg(sdmmc_v1)] 1085 #[cfg(sdmmc_v1)]
846 regs.dctrl().modify(|w| { 1086 regs.dctrl().modify(|w| {
@@ -853,7 +1093,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
853 1093
854 /// Sets the CLKDIV field in CLKCR. Updates clock field in self 1094 /// Sets the CLKDIV field in CLKCR. Updates clock field in self
855 fn clkcr_set_clkdiv(&mut self, freq: u32, width: BusWidth) -> Result<(), Error> { 1095 fn clkcr_set_clkdiv(&mut self, freq: u32, width: BusWidth) -> Result<(), Error> {
856 let regs = T::regs(); 1096 let regs = self.info.regs;
857 1097
858 let width_u32 = match width { 1098 let width_u32 = match width {
859 BusWidth::One => 1u32, 1099 BusWidth::One => 1u32,
@@ -862,17 +1102,16 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
862 _ => panic!("Invalid Bus Width"), 1102 _ => panic!("Invalid Bus Width"),
863 }; 1103 };
864 1104
865 let ker_ck = T::frequency(); 1105 let (_bypass, clkdiv, new_clock) = clk_div(self.ker_clk, freq)?;
866 let (_bypass, clkdiv, new_clock) = clk_div(ker_ck, freq)?;
867 1106
868 // Enforce AHB and SDMMC_CK clock relation. See RM0433 Rev 7 1107 // Enforce AHB and SDMMC_CK clock relation. See RM0433 Rev 7
869 // Section 55.5.8 1108 // Section 55.5.8
870 let sdmmc_bus_bandwidth = new_clock.0 * width_u32; 1109 let sdmmc_bus_bandwidth = new_clock.0 * width_u32;
871 assert!(ker_ck.0 > 3 * sdmmc_bus_bandwidth / 32); 1110 assert!(self.ker_clk.0 > 3 * sdmmc_bus_bandwidth / 32);
872 self.clock = new_clock; 1111 self.clock = new_clock;
873 1112
874 // CPSMACT and DPSMACT must be 0 to set CLKDIV 1113 // CPSMACT and DPSMACT must be 0 to set CLKDIV
875 Self::wait_idle(); 1114 self.wait_idle();
876 regs.clkcr().modify(|w| { 1115 regs.clkcr().modify(|w| {
877 w.set_clkdiv(clkdiv); 1116 w.set_clkdiv(clkdiv);
878 #[cfg(sdmmc_v1)] 1117 #[cfg(sdmmc_v1)]
@@ -883,14 +1122,14 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
883 } 1122 }
884 1123
885 /// Query the card status (CMD13, returns R1) 1124 /// Query the card status (CMD13, returns R1)
886 fn read_status<Ext>(&self, card: &SdmmcPeripheral) -> Result<CardStatus<Ext>, Error> 1125 fn read_status<A: Addressable>(&self, card: &A) -> Result<CardStatus<A::Ext>, Error>
887 where 1126 where
888 CardStatus<Ext>: From<u32>, 1127 CardStatus<A::Ext>: From<u32>,
889 { 1128 {
890 let regs = T::regs(); 1129 let regs = self.info.regs;
891 let rca = card.get_address(); 1130 let rca = card.get_address();
892 1131
893 Self::cmd(common_cmd::card_status(rca, false), false)?; // CMD13 1132 self.cmd(common_cmd::card_status(rca, false), false)?; // CMD13
894 1133
895 let r1 = regs.respr(0).read().cardstatus(); 1134 let r1 = regs.respr(0).read().cardstatus();
896 Ok(r1.into()) 1135 Ok(r1.into())
@@ -904,7 +1143,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
904 // Determine Relative Card Address (RCA) of given card 1143 // Determine Relative Card Address (RCA) of given card
905 let rca = rca.unwrap_or(0); 1144 let rca = rca.unwrap_or(0);
906 1145
907 let r = Self::cmd(common_cmd::select_card(rca), false); 1146 let r = self.cmd(common_cmd::select_card(rca), false);
908 match (r, rca) { 1147 match (r, rca) {
909 (Err(Error::Timeout), 0) => Ok(()), 1148 (Err(Error::Timeout), 0) => Ok(()),
910 _ => r, 1149 _ => r,
@@ -913,8 +1152,8 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
913 1152
914 /// Clear flags in interrupt clear register 1153 /// Clear flags in interrupt clear register
915 #[inline] 1154 #[inline]
916 fn clear_interrupt_flags() { 1155 fn clear_interrupt_flags(&self) {
917 let regs = T::regs(); 1156 let regs = self.info.regs;
918 regs.icr().write(|w| { 1157 regs.icr().write(|w| {
919 w.set_ccrcfailc(true); 1158 w.set_ccrcfailc(true);
920 w.set_dcrcfailc(true); 1159 w.set_dcrcfailc(true);
@@ -947,12 +1186,12 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
947 1186
948 /// Send command to card 1187 /// Send command to card
949 #[allow(unused_variables)] 1188 #[allow(unused_variables)]
950 fn cmd<R: Resp>(cmd: Cmd<R>, data: bool) -> Result<(), Error> { 1189 fn cmd<R: Resp>(&self, cmd: Cmd<R>, data: bool) -> Result<(), Error> {
951 let regs = T::regs(); 1190 let regs = self.info.regs;
952 1191
953 Self::clear_interrupt_flags(); 1192 self.clear_interrupt_flags();
954 // CP state machine must be idle 1193 // CP state machine must be idle
955 while Self::cmd_active() {} 1194 while self.cmd_active() {}
956 1195
957 // Command arg 1196 // Command arg
958 regs.argr().write(|w| w.set_cmdarg(cmd.arg)); 1197 regs.argr().write(|w| w.set_cmdarg(cmd.arg));
@@ -997,13 +1236,13 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
997 Ok(()) 1236 Ok(())
998 } 1237 }
999 1238
1000 fn on_drop() { 1239 fn on_drop(&self) {
1001 let regs = T::regs(); 1240 let regs = self.info.regs;
1002 if Self::data_active() { 1241 if self.data_active() {
1003 Self::clear_interrupt_flags(); 1242 self.clear_interrupt_flags();
1004 // Send abort 1243 // Send abort
1005 // CP state machine must be idle 1244 // CP state machine must be idle
1006 while Self::cmd_active() {} 1245 while self.cmd_active() {}
1007 1246
1008 // Command arg 1247 // Command arg
1009 regs.argr().write(|w| w.set_cmdarg(0)); 1248 regs.argr().write(|w| w.set_cmdarg(0));
@@ -1023,22 +1262,22 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1023 }); 1262 });
1024 1263
1025 // Wait for the abort 1264 // Wait for the abort
1026 while Self::data_active() {} 1265 while self.data_active() {}
1027 } 1266 }
1028 regs.maskr().write(|_| ()); // disable irqs 1267 regs.maskr().write(|_| ()); // disable irqs
1029 Self::clear_interrupt_flags(); 1268 self.clear_interrupt_flags();
1030 Self::stop_datapath(); 1269 self.stop_datapath();
1031 } 1270 }
1032 1271
1033 /// Wait for a previously started datapath transfer to complete from an interrupt. 1272 /// Wait for a previously started datapath transfer to complete from an interrupt.
1034 #[inline] 1273 #[inline]
1035 #[allow(unused)] 1274 #[allow(unused)]
1036 async fn complete_datapath_transfer(block: bool) -> Result<(), Error> { 1275 async fn complete_datapath_transfer(&self, block: bool) -> Result<(), Error> {
1037 let res = poll_fn(|cx| { 1276 let res = poll_fn(|cx| {
1038 // Compiler might not be sufficiently constrained here 1277 // Compiler might not be sufficiently constrained here
1039 // https://github.com/embassy-rs/embassy/issues/4723 1278 // https://github.com/embassy-rs/embassy/issues/4723
1040 T::state().register(cx.waker()); 1279 self.state.waker.register(cx.waker());
1041 let status = T::regs().star().read(); 1280 let status = self.info.regs.star().read();
1042 1281
1043 if status.dcrcfail() { 1282 if status.dcrcfail() {
1044 return Poll::Ready(Err(Error::Crc)); 1283 return Poll::Ready(Err(Error::Crc));
@@ -1067,16 +1306,21 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1067 }) 1306 })
1068 .await; 1307 .await;
1069 1308
1070 Self::clear_interrupt_flags(); 1309 self.clear_interrupt_flags();
1071 1310
1072 res 1311 res
1073 } 1312 }
1074 1313
1075 /// Read a data block. 1314 /// Read a data block.
1076 #[inline] 1315 #[inline]
1077 pub async fn read_block(&mut self, block_idx: u32, buffer: &mut DataBlock) -> Result<(), Error> { 1316 pub async fn read_block(
1078 let _scoped_block_stop = T::RCC_INFO.block_stop(); 1317 &mut self,
1079 let card_capacity = self.card()?.get_capacity(); 1318 card: &mut impl Addressable,
1319 block_idx: u32,
1320 buffer: &mut DataBlock,
1321 ) -> Result<(), Error> {
1322 let _scoped_block_stop = self.info.rcc.block_stop();
1323 let card_capacity = card.get_capacity();
1080 1324
1081 // NOTE(unsafe) DataBlock uses align 4 1325 // NOTE(unsafe) DataBlock uses align 4
1082 let buffer = unsafe { &mut *((&mut buffer.0) as *mut [u8; 512] as *mut [u32; 128]) }; 1326 let buffer = unsafe { &mut *((&mut buffer.0) as *mut [u8; 512] as *mut [u32; 128]) };
@@ -1087,26 +1331,19 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1087 CardCapacity::StandardCapacity => block_idx * 512, 1331 CardCapacity::StandardCapacity => block_idx * 512,
1088 _ => block_idx, 1332 _ => block_idx,
1089 }; 1333 };
1090 Self::cmd(common_cmd::set_block_length(512), false)?; // CMD16 1334 self.cmd(common_cmd::set_block_length(512), false)?; // CMD16
1091 1335
1092 let on_drop = OnDrop::new(|| Self::on_drop()); 1336 let on_drop = OnDrop::new(|| self.on_drop());
1093 1337
1094 let transfer = Self::prepare_datapath_read( 1338 let transfer = self.prepare_datapath_read(&self.config, buffer, 512, 9);
1095 &self.config, 1339 self.enable_interrupts();
1096 #[cfg(sdmmc_v1)] 1340 self.cmd(common_cmd::read_single_block(address), true)?;
1097 &mut self.dma,
1098 buffer,
1099 512,
1100 9,
1101 );
1102 InterruptHandler::<T>::enable_interrupts();
1103 Self::cmd(common_cmd::read_single_block(address), true)?;
1104 1341
1105 let res = Self::complete_datapath_transfer(true).await; 1342 let res = self.complete_datapath_transfer(true).await;
1106 1343
1107 if res.is_ok() { 1344 if res.is_ok() {
1108 on_drop.defuse(); 1345 on_drop.defuse();
1109 Self::stop_datapath(); 1346 self.stop_datapath();
1110 drop(transfer); 1347 drop(transfer);
1111 } 1348 }
1112 res 1349 res
@@ -1114,9 +1351,14 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1114 1351
1115 /// Read multiple data blocks. 1352 /// Read multiple data blocks.
1116 #[inline] 1353 #[inline]
1117 pub async fn read_blocks(&mut self, block_idx: u32, blocks: &mut [DataBlock]) -> Result<(), Error> { 1354 pub async fn read_blocks(
1118 let _scoped_block_stop = T::RCC_INFO.block_stop(); 1355 &mut self,
1119 let card_capacity = self.card()?.get_capacity(); 1356 card: &mut impl Addressable,
1357 block_idx: u32,
1358 blocks: &mut [DataBlock],
1359 ) -> Result<(), Error> {
1360 let _scoped_block_stop = self.info.rcc.block_stop();
1361 let card_capacity = card.get_capacity();
1120 1362
1121 // NOTE(unsafe) reinterpret buffer as &mut [u32] 1363 // NOTE(unsafe) reinterpret buffer as &mut [u32]
1122 let buffer = unsafe { 1364 let buffer = unsafe {
@@ -1131,39 +1373,39 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1131 CardCapacity::StandardCapacity => block_idx * 512, 1373 CardCapacity::StandardCapacity => block_idx * 512,
1132 _ => block_idx, 1374 _ => block_idx,
1133 }; 1375 };
1134 Self::cmd(common_cmd::set_block_length(512), false)?; // CMD16 1376 self.cmd(common_cmd::set_block_length(512), false)?; // CMD16
1135 1377
1136 let on_drop = OnDrop::new(|| Self::on_drop()); 1378 let on_drop = OnDrop::new(|| self.on_drop());
1137 1379
1138 let transfer = Self::prepare_datapath_read( 1380 let transfer = self.prepare_datapath_read(&self.config, buffer, 512 * blocks.len() as u32, 9);
1139 &self.config, 1381 self.enable_interrupts();
1140 #[cfg(sdmmc_v1)]
1141 &mut self.dma,
1142 buffer,
1143 512 * blocks.len() as u32,
1144 9,
1145 );
1146 InterruptHandler::<T>::enable_interrupts();
1147 1382
1148 Self::cmd(common_cmd::read_multiple_blocks(address), true)?; 1383 self.cmd(common_cmd::read_multiple_blocks(address), true)?;
1149 1384
1150 let res = Self::complete_datapath_transfer(false).await; 1385 let res = self.complete_datapath_transfer(false).await;
1151 1386
1152 Self::cmd(common_cmd::stop_transmission(), false)?; // CMD12 1387 self.cmd(common_cmd::stop_transmission(), false)?; // CMD12
1153 Self::clear_interrupt_flags(); 1388 self.clear_interrupt_flags();
1154 1389
1155 if res.is_ok() { 1390 if res.is_ok() {
1156 on_drop.defuse(); 1391 on_drop.defuse();
1157 Self::stop_datapath(); 1392 self.stop_datapath();
1158 drop(transfer); 1393 drop(transfer);
1159 } 1394 }
1160 res 1395 res
1161 } 1396 }
1162 1397
1163 /// Write a data block. 1398 /// Write a data block.
1164 pub async fn write_block(&mut self, block_idx: u32, buffer: &DataBlock) -> Result<(), Error> { 1399 pub async fn write_block<A: Addressable>(
1165 let _scoped_block_stop = T::RCC_INFO.block_stop(); 1400 &mut self,
1166 let card = self.card.as_mut().ok_or(Error::NoCard)?; 1401 card: &mut A,
1402 block_idx: u32,
1403 buffer: &DataBlock,
1404 ) -> Result<(), Error>
1405 where
1406 CardStatus<A::Ext>: From<u32>,
1407 {
1408 let _scoped_block_stop = self.info.rcc.block_stop();
1167 1409
1168 // NOTE(unsafe) DataBlock uses align 4 1410 // NOTE(unsafe) DataBlock uses align 4
1169 let buffer = unsafe { &*((&buffer.0) as *const [u8; 512] as *const [u32; 128]) }; 1411 let buffer = unsafe { &*((&buffer.0) as *const [u8; 512] as *const [u32; 128]) };
@@ -1174,38 +1416,33 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1174 CardCapacity::StandardCapacity => block_idx * 512, 1416 CardCapacity::StandardCapacity => block_idx * 512,
1175 _ => block_idx, 1417 _ => block_idx,
1176 }; 1418 };
1177 Self::cmd(common_cmd::set_block_length(512), false)?; // CMD16 1419 self.cmd(common_cmd::set_block_length(512), false)?; // CMD16
1178 1420
1179 let on_drop = OnDrop::new(|| Self::on_drop()); 1421 let on_drop = OnDrop::new(|| self.on_drop());
1180 1422
1181 // sdmmc_v1 uses different cmd/dma order than v2, but only for writes 1423 // sdmmc_v1 uses different cmd/dma order than v2, but only for writes
1182 #[cfg(sdmmc_v1)] 1424 #[cfg(sdmmc_v1)]
1183 Self::cmd(common_cmd::write_single_block(address), true)?; 1425 self.cmd(common_cmd::write_single_block(address), true)?;
1184 1426
1185 let transfer = self.prepare_datapath_write(buffer, 512, 9); 1427 let transfer = self.prepare_datapath_write(buffer, 512, 9);
1186 InterruptHandler::<T>::enable_interrupts(); 1428 self.enable_interrupts();
1187 1429
1188 #[cfg(sdmmc_v2)] 1430 #[cfg(sdmmc_v2)]
1189 Self::cmd(common_cmd::write_single_block(address), true)?; 1431 self.cmd(common_cmd::write_single_block(address), true)?;
1190 1432
1191 let res = Self::complete_datapath_transfer(true).await; 1433 let res = self.complete_datapath_transfer(true).await;
1192 1434
1193 match res { 1435 match res {
1194 Ok(_) => { 1436 Ok(_) => {
1195 on_drop.defuse(); 1437 on_drop.defuse();
1196 Self::stop_datapath(); 1438 self.stop_datapath();
1197 drop(transfer); 1439 drop(transfer);
1198 1440
1199 // TODO: Make this configurable 1441 // TODO: Make this configurable
1200 let mut timeout: u32 = 0x00FF_FFFF; 1442 let mut timeout: u32 = 0x00FF_FFFF;
1201 1443
1202 let card = self.card.as_ref().unwrap();
1203 while timeout > 0 { 1444 while timeout > 0 {
1204 let ready_for_data = match card { 1445 let ready_for_data = self.read_status(card)?.ready_for_data();
1205 SdmmcPeripheral::Emmc(_) => self.read_status::<EMMC>(card)?.ready_for_data(),
1206 SdmmcPeripheral::SdCard(_) => self.read_status::<SD>(card)?.ready_for_data(),
1207 };
1208
1209 if ready_for_data { 1446 if ready_for_data {
1210 return Ok(()); 1447 return Ok(());
1211 } 1448 }
@@ -1218,9 +1455,16 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1218 } 1455 }
1219 1456
1220 /// Write multiple data blocks. 1457 /// Write multiple data blocks.
1221 pub async fn write_blocks(&mut self, block_idx: u32, blocks: &[DataBlock]) -> Result<(), Error> { 1458 pub async fn write_blocks<A: Addressable>(
1222 let _scoped_block_stop = T::RCC_INFO.block_stop(); 1459 &mut self,
1223 let card = self.card.as_mut().ok_or(Error::NoCard)?; 1460 card: &mut A,
1461 block_idx: u32,
1462 blocks: &[DataBlock],
1463 ) -> Result<(), Error>
1464 where
1465 CardStatus<A::Ext>: From<u32>,
1466 {
1467 let _scoped_block_stop = self.info.rcc.block_stop();
1224 1468
1225 // NOTE(unsafe) reinterpret buffer as &[u32] 1469 // NOTE(unsafe) reinterpret buffer as &[u32]
1226 let buffer = unsafe { 1470 let buffer = unsafe {
@@ -1236,42 +1480,41 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1236 _ => block_idx, 1480 _ => block_idx,
1237 }; 1481 };
1238 1482
1239 Self::cmd(common_cmd::set_block_length(512), false)?; // CMD16 1483 self.cmd(common_cmd::set_block_length(512), false)?; // CMD16
1240 1484
1241 let block_count = blocks.len(); 1485 let block_count = blocks.len();
1242 1486
1243 let on_drop = OnDrop::new(|| Self::on_drop()); 1487 let on_drop = OnDrop::new(|| self.on_drop());
1244 1488
1245 #[cfg(sdmmc_v1)] 1489 #[cfg(sdmmc_v1)]
1246 Self::cmd(common_cmd::write_multiple_blocks(address), true)?; // CMD25 1490 self.cmd(common_cmd::write_multiple_blocks(address), true)?; // CMD25
1247 1491
1248 // Setup write command 1492 // Setup write command
1249 let transfer = self.prepare_datapath_write(buffer, 512 * block_count as u32, 9); 1493 let transfer = self.prepare_datapath_write(buffer, 512 * block_count as u32, 9);
1250 InterruptHandler::<T>::enable_interrupts(); 1494 self.enable_interrupts();
1251 1495
1252 #[cfg(sdmmc_v2)] 1496 #[cfg(sdmmc_v2)]
1253 Self::cmd(common_cmd::write_multiple_blocks(address), true)?; // CMD25 1497 self.cmd(common_cmd::write_multiple_blocks(address), true)?; // CMD25
1254 1498
1255 let res = Self::complete_datapath_transfer(false).await; 1499 let res = self.complete_datapath_transfer(false).await;
1256 1500
1257 Self::cmd(common_cmd::stop_transmission(), false)?; // CMD12 1501 self.cmd(common_cmd::stop_transmission(), false)?; // CMD12
1258 Self::clear_interrupt_flags(); 1502 self.clear_interrupt_flags();
1259 1503
1260 match res { 1504 match res {
1261 Ok(_) => { 1505 Ok(_) => {
1262 on_drop.defuse(); 1506 on_drop.defuse();
1263 Self::stop_datapath(); 1507 self.stop_datapath();
1264 drop(transfer); 1508 drop(transfer);
1265 1509
1266 // TODO: Make this configurable 1510 // TODO: Make this configurable
1267 let mut timeout: u32 = 0x00FF_FFFF; 1511 let mut timeout: u32 = 0x00FF_FFFF;
1268 1512
1269 // Try to read card status (ACMD13)
1270 while timeout > 0 { 1513 while timeout > 0 {
1271 match self.read_sd_status().await { 1514 let ready_for_data = self.read_status(card)?.ready_for_data();
1272 Ok(_) => return Ok(()), 1515
1273 Err(Error::Timeout) => (), // Try again 1516 if ready_for_data {
1274 Err(e) => return Err(e), 1517 return Ok(());
1275 } 1518 }
1276 timeout -= 1; 1519 timeout -= 1;
1277 } 1520 }
@@ -1281,33 +1524,20 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1281 } 1524 }
1282 } 1525 }
1283 1526
1284 /// Get a reference to the initialized card
1285 ///
1286 /// # Errors
1287 ///
1288 /// Returns Error::NoCard if [`init_sd_card`](#method.init_sd_card) or
1289 /// [`init_emmc`](#method.init_emmc) has not previously succeeded
1290 #[inline]
1291 pub fn card(&self) -> Result<&SdmmcPeripheral, Error> {
1292 self.card.as_ref().ok_or(Error::NoCard)
1293 }
1294
1295 /// Get the current SDMMC bus clock 1527 /// Get the current SDMMC bus clock
1296 pub fn clock(&self) -> Hertz { 1528 pub fn clock(&self) -> Hertz {
1297 self.clock 1529 self.clock
1298 } 1530 }
1299 1531
1300 /// Set a specific cmd buffer rather than using the default stack allocated one. 1532 async fn init_internal(
1301 /// This is required if stack RAM cannot be used with DMA and usually manifests 1533 &mut self,
1302 /// itself as an indefinite wait on a dma transfer because the dma peripheral 1534 cmd_block: &mut CmdBlock,
1303 /// cannot access the memory. 1535 freq: Hertz,
1304 pub fn set_cmd_block(&mut self, cmd_block: &'d mut CmdBlock) { 1536 card: &mut SdmmcPeripheral,
1305 self.cmd_block = Some(cmd_block) 1537 ) -> Result<(), Error> {
1306 } 1538 let _scoped_block_stop = self.info.rcc.block_stop();
1307 1539
1308 async fn init_internal(&mut self, freq: Hertz, mut card: SdmmcPeripheral) -> Result<(), Error> { 1540 let regs = self.info.regs;
1309 let regs = T::regs();
1310 let ker_ck = T::frequency();
1311 1541
1312 let bus_width = match (self.d3.is_some(), self.d7.is_some()) { 1542 let bus_width = match (self.d3.is_some(), self.d7.is_some()) {
1313 (true, true) => { 1543 (true, true) => {
@@ -1322,11 +1552,11 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1322 1552
1323 // While the SD/SDIO card or eMMC is in identification mode, 1553 // While the SD/SDIO card or eMMC is in identification mode,
1324 // the SDMMC_CK frequency must be no more than 400 kHz. 1554 // the SDMMC_CK frequency must be no more than 400 kHz.
1325 let (_bypass, clkdiv, init_clock) = unwrap!(clk_div(ker_ck, SD_INIT_FREQ.0)); 1555 let (_bypass, clkdiv, init_clock) = unwrap!(clk_div(self.ker_clk, SD_INIT_FREQ.0));
1326 self.clock = init_clock; 1556 self.clock = init_clock;
1327 1557
1328 // CPSMACT and DPSMACT must be 0 to set WIDBUS 1558 // CPSMACT and DPSMACT must be 0 to set WIDBUS
1329 Self::wait_idle(); 1559 self.wait_idle();
1330 1560
1331 regs.clkcr().modify(|w| { 1561 regs.clkcr().modify(|w| {
1332 w.set_widbus(0); 1562 w.set_widbus(0);
@@ -1338,12 +1568,12 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1338 .write(|w| w.set_datatime(self.config.data_transfer_timeout)); 1568 .write(|w| w.set_datatime(self.config.data_transfer_timeout));
1339 1569
1340 regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::On as u8)); 1570 regs.power().modify(|w| w.set_pwrctrl(PowerCtrl::On as u8));
1341 Self::cmd(common_cmd::idle(), false)?; 1571 self.cmd(common_cmd::idle(), false)?;
1342 1572
1343 match card { 1573 match card {
1344 SdmmcPeripheral::SdCard(ref mut card) => { 1574 SdmmcPeripheral::SdCard(card) => {
1345 // Check if cards supports CMD8 (with pattern) 1575 // Check if cards supports CMD8 (with pattern)
1346 Self::cmd(sd_cmd::send_if_cond(1, 0xAA), false)?; 1576 self.cmd(sd_cmd::send_if_cond(1, 0xAA), false)?;
1347 let cic = CIC::from(regs.respr(0).read().cardstatus()); 1577 let cic = CIC::from(regs.respr(0).read().cardstatus());
1348 1578
1349 if cic.pattern() != 0xAA { 1579 if cic.pattern() != 0xAA {
@@ -1356,12 +1586,12 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1356 1586
1357 let ocr = loop { 1587 let ocr = loop {
1358 // Signal that next command is a app command 1588 // Signal that next command is a app command
1359 Self::cmd(common_cmd::app_cmd(0), false)?; // CMD55 1589 self.cmd(common_cmd::app_cmd(0), false)?; // CMD55
1360 1590
1361 // 3.2-3.3V 1591 // 3.2-3.3V
1362 let voltage_window = 1 << 5; 1592 let voltage_window = 1 << 5;
1363 // Initialize card 1593 // Initialize card
1364 match Self::cmd(sd_cmd::sd_send_op_cond(true, false, true, voltage_window), false) { 1594 match self.cmd(sd_cmd::sd_send_op_cond(true, false, true, voltage_window), false) {
1365 // ACMD41 1595 // ACMD41
1366 Ok(_) => (), 1596 Ok(_) => (),
1367 Err(Error::Crc) => (), 1597 Err(Error::Crc) => (),
@@ -1382,13 +1612,13 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1382 } 1612 }
1383 card.ocr = ocr; 1613 card.ocr = ocr;
1384 } 1614 }
1385 SdmmcPeripheral::Emmc(ref mut emmc) => { 1615 SdmmcPeripheral::Emmc(emmc) => {
1386 let ocr = loop { 1616 let ocr = loop {
1387 let high_voltage = 0b0 << 7; 1617 let high_voltage = 0b0 << 7;
1388 let access_mode = 0b10 << 29; 1618 let access_mode = 0b10 << 29;
1389 let op_cond = high_voltage | access_mode | 0b1_1111_1111 << 15; 1619 let op_cond = high_voltage | access_mode | 0b1_1111_1111 << 15;
1390 // Initialize card 1620 // Initialize card
1391 match Self::cmd(emmc_cmd::send_op_cond(op_cond), false) { 1621 match self.cmd(emmc_cmd::send_op_cond(op_cond), false) {
1392 Ok(_) => (), 1622 Ok(_) => (),
1393 Err(Error::Crc) => (), 1623 Err(Error::Crc) => (),
1394 Err(err) => return Err(err), 1624 Err(err) => return Err(err),
@@ -1410,7 +1640,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1410 } 1640 }
1411 } 1641 }
1412 1642
1413 Self::cmd(common_cmd::all_send_cid(), false)?; // CMD2 1643 self.cmd(common_cmd::all_send_cid(), false)?; // CMD2
1414 let cid0 = regs.respr(0).read().cardstatus() as u128; 1644 let cid0 = regs.respr(0).read().cardstatus() as u128;
1415 let cid1 = regs.respr(1).read().cardstatus() as u128; 1645 let cid1 = regs.respr(1).read().cardstatus() as u128;
1416 let cid2 = regs.respr(2).read().cardstatus() as u128; 1646 let cid2 = regs.respr(2).read().cardstatus() as u128;
@@ -1418,22 +1648,22 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1418 let cid = (cid0 << 96) | (cid1 << 64) | (cid2 << 32) | (cid3); 1648 let cid = (cid0 << 96) | (cid1 << 64) | (cid2 << 32) | (cid3);
1419 1649
1420 match card { 1650 match card {
1421 SdmmcPeripheral::SdCard(ref mut card) => { 1651 SdmmcPeripheral::SdCard(card) => {
1422 card.cid = cid.into(); 1652 card.cid = cid.into();
1423 1653
1424 Self::cmd(sd_cmd::send_relative_address(), false)?; 1654 self.cmd(sd_cmd::send_relative_address(), false)?;
1425 let rca = RCA::<SD>::from(regs.respr(0).read().cardstatus()); 1655 let rca = RCA::<SD>::from(regs.respr(0).read().cardstatus());
1426 card.rca = rca.address(); 1656 card.rca = rca.address();
1427 } 1657 }
1428 SdmmcPeripheral::Emmc(ref mut emmc) => { 1658 SdmmcPeripheral::Emmc(emmc) => {
1429 emmc.cid = cid.into(); 1659 emmc.cid = cid.into();
1430 1660
1431 emmc.rca = 1u16.into(); 1661 emmc.rca = 1u16.into();
1432 Self::cmd(emmc_cmd::assign_relative_address(emmc.rca), false)?; 1662 self.cmd(emmc_cmd::assign_relative_address(emmc.rca), false)?;
1433 } 1663 }
1434 } 1664 }
1435 1665
1436 Self::cmd(common_cmd::send_csd(card.get_address()), false)?; 1666 self.cmd(common_cmd::send_csd(card.get_address()), false)?;
1437 let csd0 = regs.respr(0).read().cardstatus() as u128; 1667 let csd0 = regs.respr(0).read().cardstatus() as u128;
1438 let csd1 = regs.respr(1).read().cardstatus() as u128; 1668 let csd1 = regs.respr(1).read().cardstatus() as u128;
1439 let csd2 = regs.respr(2).read().cardstatus() as u128; 1669 let csd2 = regs.respr(2).read().cardstatus() as u128;
@@ -1443,10 +1673,10 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1443 self.select_card(Some(card.get_address()))?; 1673 self.select_card(Some(card.get_address()))?;
1444 1674
1445 let bus_width = match card { 1675 let bus_width = match card {
1446 SdmmcPeripheral::SdCard(ref mut card) => { 1676 SdmmcPeripheral::SdCard(card) => {
1447 card.csd = csd.into(); 1677 card.csd = csd.into();
1448 1678
1449 self.get_scr(card).await?; 1679 card.get_scr(self, cmd_block).await?;
1450 1680
1451 if !card.scr.bus_width_four() { 1681 if !card.scr.bus_width_four() {
1452 BusWidth::One 1682 BusWidth::One
@@ -1454,7 +1684,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1454 BusWidth::Four 1684 BusWidth::Four
1455 } 1685 }
1456 } 1686 }
1457 SdmmcPeripheral::Emmc(ref mut emmc) => { 1687 SdmmcPeripheral::Emmc(emmc) => {
1458 emmc.csd = csd.into(); 1688 emmc.csd = csd.into();
1459 1689
1460 bus_width 1690 bus_width
@@ -1470,24 +1700,24 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1470 }; 1700 };
1471 1701
1472 match card { 1702 match card {
1473 SdmmcPeripheral::SdCard(ref mut card) => { 1703 SdmmcPeripheral::SdCard(card) => {
1474 let acmd_arg = match bus_width { 1704 let acmd_arg = match bus_width {
1475 BusWidth::Four if card.scr.bus_width_four() => 2, 1705 BusWidth::Four if card.scr.bus_width_four() => 2,
1476 _ => 0, 1706 _ => 0,
1477 }; 1707 };
1478 Self::cmd(common_cmd::app_cmd(card.rca), false)?; 1708 self.cmd(common_cmd::app_cmd(card.rca), false)?;
1479 Self::cmd(sd_cmd::cmd6(acmd_arg), false)?; 1709 self.cmd(sd_cmd::cmd6(acmd_arg), false)?;
1480 } 1710 }
1481 SdmmcPeripheral::Emmc(_) => { 1711 SdmmcPeripheral::Emmc(emmc) => {
1482 // Write bus width to ExtCSD byte 183 1712 // Write bus width to ExtCSD byte 183
1483 Self::cmd( 1713 self.cmd(
1484 emmc_cmd::modify_ext_csd(emmc_cmd::AccessMode::WriteByte, 183, widbus), 1714 emmc_cmd::modify_ext_csd(emmc_cmd::AccessMode::WriteByte, 183, widbus),
1485 false, 1715 false,
1486 )?; 1716 )?;
1487 1717
1488 // Wait for ready after R1b response 1718 // Wait for ready after R1b response
1489 loop { 1719 loop {
1490 let status = self.read_status::<EMMC>(&card)?; 1720 let status = self.read_status(emmc)?;
1491 1721
1492 if status.ready_for_data() { 1722 if status.ready_for_data() {
1493 break; 1723 break;
@@ -1497,7 +1727,7 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1497 } 1727 }
1498 1728
1499 // CPSMACT and DPSMACT must be 0 to set WIDBUS 1729 // CPSMACT and DPSMACT must be 0 to set WIDBUS
1500 Self::wait_idle(); 1730 self.wait_idle();
1501 1731
1502 regs.clkcr().modify(|w| w.set_widbus(widbus)); 1732 regs.clkcr().modify(|w| w.set_widbus(widbus));
1503 1733
@@ -1510,32 +1740,30 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1510 self.clkcr_set_clkdiv(25_000_000, bus_width)?; 1740 self.clkcr_set_clkdiv(25_000_000, bus_width)?;
1511 } 1741 }
1512 1742
1513 self.card = Some(card);
1514
1515 match card { 1743 match card {
1516 SdmmcPeripheral::SdCard(_) => { 1744 SdmmcPeripheral::SdCard(card) => {
1517 // Read status 1745 // Read status
1518 self.read_sd_status().await?; 1746 card.read_sd_status(self, cmd_block).await?;
1519 1747
1520 if freq.0 > 25_000_000 { 1748 if freq.0 > 25_000_000 {
1521 // Switch to SDR25 1749 // Switch to SDR25
1522 self.signalling = self.switch_signalling_mode(Signalling::SDR25).await?; 1750 self.signalling = card.switch_signalling_mode(self, cmd_block, Signalling::SDR25).await?;
1523 1751
1524 if self.signalling == Signalling::SDR25 { 1752 if self.signalling == Signalling::SDR25 {
1525 // Set final clock frequency 1753 // Set final clock frequency
1526 self.clkcr_set_clkdiv(freq.0, bus_width)?; 1754 self.clkcr_set_clkdiv(freq.0, bus_width)?;
1527 1755
1528 if self.read_status::<SD>(self.card.as_ref().unwrap())?.state() != CurrentState::Transfer { 1756 if self.read_status(card)?.state() != CurrentState::Transfer {
1529 return Err(Error::SignalingSwitchFailed); 1757 return Err(Error::SignalingSwitchFailed);
1530 } 1758 }
1531 } 1759 }
1532 } 1760 }
1533 1761
1534 // Read status after signalling change 1762 // Read status after signalling change
1535 self.read_sd_status().await?; 1763 card.read_sd_status(self, cmd_block).await?;
1536 } 1764 }
1537 SdmmcPeripheral::Emmc(_) => { 1765 SdmmcPeripheral::Emmc(emmc) => {
1538 self.read_ext_csd().await?; 1766 emmc.read_ext_csd(self).await?;
1539 } 1767 }
1540 } 1768 }
1541 1769
@@ -1545,228 +1773,38 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
1545 /// Initializes card (if present) and sets the bus at the specified frequency. 1773 /// Initializes card (if present) and sets the bus at the specified frequency.
1546 /// 1774 ///
1547 /// SD only. 1775 /// SD only.
1548 pub async fn init_sd_card(&mut self, freq: Hertz) -> Result<(), Error> { 1776 async fn init_sd_card(&mut self, cmd_block: &mut CmdBlock, freq: Hertz) -> Result<Card, Error> {
1549 let _scoped_block_stop = T::RCC_INFO.block_stop(); 1777 let mut card = SdmmcPeripheral::SdCard(Card::default());
1550 1778 self.init_internal(cmd_block, freq, &mut card).await?;
1551 self.init_internal(freq, SdmmcPeripheral::SdCard(Card::default())).await
1552 }
1553
1554 /// Switch mode using CMD6.
1555 ///
1556 /// Attempt to set a new signalling mode. The selected
1557 /// signalling mode is returned. Expects the current clock
1558 /// frequency to be > 12.5MHz.
1559 ///
1560 /// SD only.
1561 async fn switch_signalling_mode(&mut self, signalling: Signalling) -> Result<Signalling, Error> {
1562 let _ = self.card.as_mut().ok_or(Error::NoCard)?.get_sd_card();
1563 // NB PLSS v7_10 4.3.10.4: "the use of SET_BLK_LEN command is not
1564 // necessary"
1565
1566 let set_function = 0x8000_0000
1567 | match signalling {
1568 // See PLSS v7_10 Table 4-11
1569 Signalling::DDR50 => 0xFF_FF04,
1570 Signalling::SDR104 => 0xFF_1F03,
1571 Signalling::SDR50 => 0xFF_1F02,
1572 Signalling::SDR25 => 0xFF_FF01,
1573 Signalling::SDR12 => 0xFF_FF00,
1574 };
1575
1576 let status = match self.cmd_block.as_deref_mut() {
1577 Some(x) => x,
1578 None => &mut CmdBlock::new(),
1579 };
1580
1581 // Arm `OnDrop` after the buffer, so it will be dropped first
1582 let on_drop = OnDrop::new(|| Self::on_drop());
1583
1584 let transfer = Self::prepare_datapath_read(
1585 &self.config,
1586 #[cfg(sdmmc_v1)]
1587 &mut self.dma,
1588 status.as_mut(),
1589 64,
1590 6,
1591 );
1592 InterruptHandler::<T>::enable_interrupts();
1593 Self::cmd(sd_cmd::cmd6(set_function), true)?; // CMD6
1594 1779
1595 let res = Self::complete_datapath_transfer(true).await; 1780 let card = match card {
1596 1781 SdmmcPeripheral::SdCard(card) => card,
1597 // Host is allowed to use the new functions at least 8 1782 _ => unreachable!(),
1598 // clocks after the end of the switch command
1599 // transaction. We know the current clock period is < 80ns,
1600 // so a total delay of 640ns is required here
1601 for _ in 0..300 {
1602 cortex_m::asm::nop();
1603 }
1604
1605 match res {
1606 Ok(_) => {
1607 on_drop.defuse();
1608 Self::stop_datapath();
1609 drop(transfer);
1610
1611 // Function Selection of Function Group 1
1612 let selection = (u32::from_be(status[4]) >> 24) & 0xF;
1613
1614 match selection {
1615 0 => Ok(Signalling::SDR12),
1616 1 => Ok(Signalling::SDR25),
1617 2 => Ok(Signalling::SDR50),
1618 3 => Ok(Signalling::SDR104),
1619 4 => Ok(Signalling::DDR50),
1620 _ => Err(Error::UnsupportedCardType),
1621 }
1622 }
1623 Err(e) => Err(e),
1624 }
1625 }
1626
1627 /// Reads the SCR register.
1628 ///
1629 /// SD only.
1630 async fn get_scr(&mut self, card: &mut Card) -> Result<(), Error> {
1631 // Read the 64-bit SCR register
1632 Self::cmd(common_cmd::set_block_length(8), false)?; // CMD16
1633 Self::cmd(common_cmd::app_cmd(card.rca), false)?;
1634
1635 let cmd_block = match self.cmd_block.as_deref_mut() {
1636 Some(x) => x,
1637 None => &mut CmdBlock::new(),
1638 }; 1783 };
1639 let scr = &mut cmd_block.0[..2];
1640
1641 // Arm `OnDrop` after the buffer, so it will be dropped first
1642 let on_drop = OnDrop::new(|| Self::on_drop());
1643
1644 let transfer = Self::prepare_datapath_read(
1645 &self.config,
1646 #[cfg(sdmmc_v1)]
1647 &mut self.dma,
1648 scr,
1649 8,
1650 3,
1651 );
1652 InterruptHandler::<T>::enable_interrupts();
1653 Self::cmd(sd_cmd::send_scr(), true)?;
1654
1655 let res = Self::complete_datapath_transfer(true).await;
1656 1784
1657 if res.is_ok() { 1785 Ok(card)
1658 on_drop.defuse();
1659 Self::stop_datapath();
1660 drop(transfer);
1661
1662 unsafe {
1663 let scr_bytes = &*(&scr as *const _ as *const [u8; 8]);
1664 card.scr = SCR(u64::from_be_bytes(*scr_bytes));
1665 }
1666 }
1667 res
1668 }
1669
1670 /// Reads the SD Status (ACMD13)
1671 ///
1672 /// SD only.
1673 async fn read_sd_status(&mut self) -> Result<(), Error> {
1674 let card = self.card.as_mut().ok_or(Error::NoCard)?.get_sd_card();
1675 let rca = card.rca;
1676
1677 let cmd_block = match self.cmd_block.as_deref_mut() {
1678 Some(x) => x,
1679 None => &mut CmdBlock::new(),
1680 };
1681
1682 Self::cmd(common_cmd::set_block_length(64), false)?; // CMD16
1683 Self::cmd(common_cmd::app_cmd(rca), false)?; // APP
1684
1685 let status = cmd_block;
1686
1687 // Arm `OnDrop` after the buffer, so it will be dropped first
1688 let on_drop = OnDrop::new(|| Self::on_drop());
1689
1690 let transfer = Self::prepare_datapath_read(
1691 &self.config,
1692 #[cfg(sdmmc_v1)]
1693 &mut self.dma,
1694 status.as_mut(),
1695 64,
1696 6,
1697 );
1698 InterruptHandler::<T>::enable_interrupts();
1699 Self::cmd(sd_cmd::sd_status(), true)?;
1700
1701 let res = Self::complete_datapath_transfer(true).await;
1702
1703 if res.is_ok() {
1704 on_drop.defuse();
1705 Self::stop_datapath();
1706 drop(transfer);
1707
1708 for byte in status.iter_mut() {
1709 *byte = u32::from_be(*byte);
1710 }
1711 card.status = status.0.into();
1712 }
1713 res
1714 } 1786 }
1715 1787
1716 /// Initializes eMMC and sets the bus at the specified frequency. 1788 /// Initializes eMMC and sets the bus at the specified frequency.
1717 /// 1789 ///
1718 /// eMMC only. 1790 /// eMMC only.
1719 pub async fn init_emmc(&mut self, freq: Hertz) -> Result<(), Error> { 1791 async fn init_emmc(&mut self, cmd_block: &mut CmdBlock, freq: Hertz) -> Result<Emmc, Error> {
1720 let _scoped_block_stop = T::RCC_INFO.block_stop(); 1792 let mut card = SdmmcPeripheral::Emmc(Emmc::default());
1721 1793 self.init_internal(cmd_block, freq, &mut card).await?;
1722 self.init_internal(freq, SdmmcPeripheral::Emmc(Emmc::default())).await
1723 }
1724
1725 /// Gets the EXT_CSD register.
1726 ///
1727 /// eMMC only.
1728 async fn read_ext_csd(&mut self) -> Result<(), Error> {
1729 let card = self.card.as_mut().ok_or(Error::NoCard)?.get_emmc();
1730
1731 // Note: cmd_block can't be used because ExtCSD is too long to fit.
1732 let mut data_block = DataBlock([0u8; 512]);
1733
1734 // NOTE(unsafe) DataBlock uses align 4
1735 let buffer = unsafe { &mut *((&mut data_block.0) as *mut [u8; 512] as *mut [u32; 128]) };
1736 1794
1737 Self::cmd(common_cmd::set_block_length(512), false).unwrap(); // CMD16 1795 let card = match card {
1738 1796 SdmmcPeripheral::Emmc(card) => card,
1739 // Arm `OnDrop` after the buffer, so it will be dropped first 1797 _ => unreachable!(),
1740 let on_drop = OnDrop::new(|| Self::on_drop()); 1798 };
1741
1742 let transfer = Self::prepare_datapath_read(
1743 &self.config,
1744 #[cfg(sdmmc_v1)]
1745 &mut self.dma,
1746 buffer,
1747 512,
1748 9,
1749 );
1750 InterruptHandler::<T>::enable_interrupts();
1751 Self::cmd(emmc_cmd::send_ext_csd(), true)?;
1752
1753 let res = Self::complete_datapath_transfer(true).await;
1754
1755 if res.is_ok() {
1756 on_drop.defuse();
1757 Self::stop_datapath();
1758 drop(transfer);
1759 1799
1760 card.ext_csd = unsafe { core::mem::transmute::<_, [u32; 128]>(data_block.0) }.into(); 1800 Ok(card)
1761 }
1762 res
1763 } 1801 }
1764} 1802}
1765 1803
1766impl<'d, T: Instance> Drop for Sdmmc<'d, T> { 1804impl<'d> Drop for Sdmmc<'d> {
1767 fn drop(&mut self) { 1805 fn drop(&mut self) {
1768 T::Interrupt::disable(); 1806 // T::Interrupt::disable();
1769 Self::on_drop(); 1807 self.on_drop();
1770 1808
1771 critical_section::with(|_| { 1809 critical_section::with(|_| {
1772 self.clk.set_as_disconnected(); 1810 self.clk.set_as_disconnected();
@@ -1799,9 +1837,28 @@ impl<'d, T: Instance> Drop for Sdmmc<'d, T> {
1799 1837
1800////////////////////////////////////////////////////// 1838//////////////////////////////////////////////////////
1801 1839
1840type Regs = RegBlock;
1841
1842struct Info {
1843 regs: Regs,
1844 rcc: RccInfo,
1845}
1846
1847struct State {
1848 waker: AtomicWaker,
1849}
1850
1851impl State {
1852 const fn new() -> Self {
1853 Self {
1854 waker: AtomicWaker::new(),
1855 }
1856 }
1857}
1858
1802trait SealedInstance { 1859trait SealedInstance {
1803 fn regs() -> RegBlock; 1860 fn info() -> &'static Info;
1804 fn state() -> &'static AtomicWaker; 1861 fn state() -> &'static State;
1805} 1862}
1806 1863
1807/// SDMMC instance trait. 1864/// SDMMC instance trait.
@@ -1828,13 +1885,17 @@ dma_trait!(SdmmcDma, Instance);
1828foreach_peripheral!( 1885foreach_peripheral!(
1829 (sdmmc, $inst:ident) => { 1886 (sdmmc, $inst:ident) => {
1830 impl SealedInstance for peripherals::$inst { 1887 impl SealedInstance for peripherals::$inst {
1831 fn regs() -> RegBlock { 1888 fn info() -> &'static Info {
1832 crate::pac::$inst 1889 static INFO: Info = Info {
1890 regs: unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) },
1891 rcc: crate::peripherals::$inst::RCC_INFO,
1892 };
1893 &INFO
1833 } 1894 }
1834 1895
1835 fn state() -> &'static ::embassy_sync::waitqueue::AtomicWaker { 1896 fn state() -> &'static State {
1836 static WAKER: ::embassy_sync::waitqueue::AtomicWaker = ::embassy_sync::waitqueue::AtomicWaker::new(); 1897 static STATE: State = State::new();
1837 &WAKER 1898 &STATE
1838 } 1899 }
1839 } 1900 }
1840 1901
@@ -1844,7 +1905,7 @@ foreach_peripheral!(
1844 }; 1905 };
1845); 1906);
1846 1907
1847impl<'d, T: Instance> block_device_driver::BlockDevice<512> for Sdmmc<'d, T> { 1908impl<'d, 'e, A: Addressable> block_device_driver::BlockDevice<512> for StorageDevice<'d, 'e, A> {
1848 type Error = Error; 1909 type Error = Error;
1849 type Align = aligned::A4; 1910 type Align = aligned::A4;
1850 1911
@@ -1853,7 +1914,6 @@ impl<'d, T: Instance> block_device_driver::BlockDevice<512> for Sdmmc<'d, T> {
1853 block_address: u32, 1914 block_address: u32,
1854 buf: &mut [aligned::Aligned<Self::Align, [u8; 512]>], 1915 buf: &mut [aligned::Aligned<Self::Align, [u8; 512]>],
1855 ) -> Result<(), Self::Error> { 1916 ) -> Result<(), Self::Error> {
1856 let _scoped_block_stop = T::RCC_INFO.block_stop();
1857 // TODO: I think block_address needs to be adjusted by the partition start offset 1917 // TODO: I think block_address needs to be adjusted by the partition start offset
1858 if buf.len() == 1 { 1918 if buf.len() == 1 {
1859 let block = unsafe { &mut *(&mut buf[0] as *mut _ as *mut crate::sdmmc::DataBlock) }; 1919 let block = unsafe { &mut *(&mut buf[0] as *mut _ as *mut crate::sdmmc::DataBlock) };
@@ -1871,7 +1931,6 @@ impl<'d, T: Instance> block_device_driver::BlockDevice<512> for Sdmmc<'d, T> {
1871 block_address: u32, 1931 block_address: u32,
1872 buf: &[aligned::Aligned<Self::Align, [u8; 512]>], 1932 buf: &[aligned::Aligned<Self::Align, [u8; 512]>],
1873 ) -> Result<(), Self::Error> { 1933 ) -> Result<(), Self::Error> {
1874 let _scoped_block_stop = T::RCC_INFO.block_stop();
1875 // TODO: I think block_address needs to be adjusted by the partition start offset 1934 // TODO: I think block_address needs to be adjusted by the partition start offset
1876 if buf.len() == 1 { 1935 if buf.len() == 1 {
1877 let block = unsafe { &*(&buf[0] as *const _ as *const crate::sdmmc::DataBlock) }; 1936 let block = unsafe { &*(&buf[0] as *const _ as *const crate::sdmmc::DataBlock) };
@@ -1885,6 +1944,6 @@ impl<'d, T: Instance> block_device_driver::BlockDevice<512> for Sdmmc<'d, T> {
1885 } 1944 }
1886 1945
1887 async fn size(&mut self) -> Result<u64, Self::Error> { 1946 async fn size(&mut self) -> Result<u64, Self::Error> {
1888 Ok(self.card()?.size()) 1947 Ok(self.info.size())
1889 } 1948 }
1890} 1949}
diff --git a/embassy-stm32/src/time.rs b/embassy-stm32/src/time.rs
index 532877f70..88a28ee3d 100644
--- a/embassy-stm32/src/time.rs
+++ b/embassy-stm32/src/time.rs
@@ -4,7 +4,7 @@ use core::fmt::Display;
4use core::ops::{Div, Mul}; 4use core::ops::{Div, Mul};
5 5
6/// Hertz 6/// Hertz
7#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug)] 7#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug, Default)]
8pub struct Hertz(pub u32); 8pub struct Hertz(pub u32);
9 9
10impl Display for Hertz { 10impl Display for Hertz {
diff --git a/examples/stm32f4/src/bin/sdmmc.rs b/examples/stm32f4/src/bin/sdmmc.rs
index fe0f887bf..897b0e05e 100644
--- a/examples/stm32f4/src/bin/sdmmc.rs
+++ b/examples/stm32f4/src/bin/sdmmc.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::sdmmc::{DataBlock, Sdmmc}; 6use embassy_stm32::sdmmc::{CmdBlock, DataBlock, Sdmmc, StorageDevice};
7use embassy_stm32::time::{Hertz, mhz}; 7use embassy_stm32::time::{Hertz, mhz};
8use embassy_stm32::{Config, bind_interrupts, peripherals, sdmmc}; 8use embassy_stm32::{Config, bind_interrupts, peripherals, sdmmc};
9use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
@@ -57,23 +57,16 @@ async fn main(_spawner: Spawner) {
57 // Should print 400kHz for initialization 57 // Should print 400kHz for initialization
58 info!("Configured clock: {}", sdmmc.clock().0); 58 info!("Configured clock: {}", sdmmc.clock().0);
59 59
60 let mut err = None; 60 let mut cmd_block = CmdBlock::new();
61 loop { 61
62 match sdmmc.init_sd_card(mhz(24)).await { 62 let mut storage = StorageDevice::new_sd_card(&mut sdmmc, &mut cmd_block, mhz(24))
63 Ok(_) => break, 63 .await
64 Err(e) => { 64 .unwrap();
65 if err != Some(e) {
66 info!("waiting for card error, retrying: {:?}", e);
67 err = Some(e);
68 }
69 }
70 }
71 }
72 65
73 let card = unwrap!(sdmmc.card()); 66 let card = storage.card();
74 67
75 info!("Card: {:#?}", Debug2Format(card)); 68 info!("Card: {:#?}", Debug2Format(&card));
76 info!("Clock: {}", sdmmc.clock()); 69 info!("Clock: {}", storage.sdmmc.clock());
77 70
78 // Arbitrary block index 71 // Arbitrary block index
79 let block_idx = 16; 72 let block_idx = 16;
@@ -81,7 +74,7 @@ async fn main(_spawner: Spawner) {
81 // SDMMC uses `DataBlock` instead of `&[u8]` to ensure 4 byte alignment required by the hardware. 74 // SDMMC uses `DataBlock` instead of `&[u8]` to ensure 4 byte alignment required by the hardware.
82 let mut block = DataBlock([0u8; 512]); 75 let mut block = DataBlock([0u8; 512]);
83 76
84 sdmmc.read_block(block_idx, &mut block).await.unwrap(); 77 storage.read_block(block_idx, &mut block).await.unwrap();
85 info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]); 78 info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]);
86 79
87 if !ALLOW_WRITES { 80 if !ALLOW_WRITES {
@@ -91,17 +84,17 @@ async fn main(_spawner: Spawner) {
91 84
92 info!("Filling block with 0x55"); 85 info!("Filling block with 0x55");
93 block.fill(0x55); 86 block.fill(0x55);
94 sdmmc.write_block(block_idx, &block).await.unwrap(); 87 storage.write_block(block_idx, &block).await.unwrap();
95 info!("Write done"); 88 info!("Write done");
96 89
97 sdmmc.read_block(block_idx, &mut block).await.unwrap(); 90 storage.read_block(block_idx, &mut block).await.unwrap();
98 info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]); 91 info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]);
99 92
100 info!("Filling block with 0xAA"); 93 info!("Filling block with 0xAA");
101 block.fill(0xAA); 94 block.fill(0xAA);
102 sdmmc.write_block(block_idx, &block).await.unwrap(); 95 storage.write_block(block_idx, &block).await.unwrap();
103 info!("Write done"); 96 info!("Write done");
104 97
105 sdmmc.read_block(block_idx, &mut block).await.unwrap(); 98 storage.read_block(block_idx, &mut block).await.unwrap();
106 info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]); 99 info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]);
107} 100}
diff --git a/examples/stm32f7/src/bin/sdmmc.rs b/examples/stm32f7/src/bin/sdmmc.rs
index 8809b5d0c..0dd4dd6f3 100644
--- a/examples/stm32f7/src/bin/sdmmc.rs
+++ b/examples/stm32f7/src/bin/sdmmc.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::sdmmc::Sdmmc; 6use embassy_stm32::sdmmc::{CmdBlock, Sdmmc, StorageDevice};
7use embassy_stm32::time::{Hertz, mhz}; 7use embassy_stm32::time::{Hertz, mhz};
8use embassy_stm32::{Config, bind_interrupts, peripherals, sdmmc}; 8use embassy_stm32::{Config, bind_interrupts, peripherals, sdmmc};
9use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
@@ -54,9 +54,13 @@ async fn main(_spawner: Spawner) {
54 // Should print 400kHz for initialization 54 // Should print 400kHz for initialization
55 info!("Configured clock: {}", sdmmc.clock().0); 55 info!("Configured clock: {}", sdmmc.clock().0);
56 56
57 unwrap!(sdmmc.init_sd_card(mhz(25)).await); 57 let mut cmd_block = CmdBlock::new();
58 58
59 let card = unwrap!(sdmmc.card()); 59 let storage = StorageDevice::new_sd_card(&mut sdmmc, &mut cmd_block, mhz(25))
60 .await
61 .unwrap();
60 62
61 info!("Card: {:#?}", Debug2Format(card)); 63 let card = storage.card();
64
65 info!("Card: {:#?}", Debug2Format(&card));
62} 66}
diff --git a/examples/stm32h7/src/bin/sdmmc.rs b/examples/stm32h7/src/bin/sdmmc.rs
index 4977fec79..548d0bd09 100644
--- a/examples/stm32h7/src/bin/sdmmc.rs
+++ b/examples/stm32h7/src/bin/sdmmc.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::sdmmc::Sdmmc; 6use embassy_stm32::sdmmc::{CmdBlock, Sdmmc, StorageDevice};
7use embassy_stm32::time::mhz; 7use embassy_stm32::time::mhz;
8use embassy_stm32::{Config, bind_interrupts, peripherals, sdmmc}; 8use embassy_stm32::{Config, bind_interrupts, peripherals, sdmmc};
9use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
@@ -13,7 +13,7 @@ bind_interrupts!(struct Irqs {
13}); 13});
14 14
15#[embassy_executor::main] 15#[embassy_executor::main]
16async fn main(_spawner: Spawner) -> ! { 16async fn main(_spawner: Spawner) {
17 let mut config = Config::default(); 17 let mut config = Config::default();
18 { 18 {
19 use embassy_stm32::rcc::*; 19 use embassy_stm32::rcc::*;
@@ -53,11 +53,13 @@ async fn main(_spawner: Spawner) -> ! {
53 // Should print 400kHz for initialization 53 // Should print 400kHz for initialization
54 info!("Configured clock: {}", sdmmc.clock().0); 54 info!("Configured clock: {}", sdmmc.clock().0);
55 55
56 unwrap!(sdmmc.init_sd_card(mhz(25)).await); 56 let mut cmd_block = CmdBlock::new();
57 57
58 let card = unwrap!(sdmmc.card()); 58 let storage = StorageDevice::new_sd_card(&mut sdmmc, &mut cmd_block, mhz(25))
59 .await
60 .unwrap();
59 61
60 info!("Card: {:#?}", Debug2Format(card)); 62 let card = storage.card();
61 63
62 loop {} 64 info!("Card: {:#?}", Debug2Format(&card));
63} 65}
diff --git a/tests/stm32/src/bin/sdmmc.rs b/tests/stm32/src/bin/sdmmc.rs
index 9f9c526e1..454d0dd57 100644
--- a/tests/stm32/src/bin/sdmmc.rs
+++ b/tests/stm32/src/bin/sdmmc.rs
@@ -7,7 +7,7 @@ mod common;
7use common::*; 7use common::*;
8use defmt::assert_eq; 8use defmt::assert_eq;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::sdmmc::{DataBlock, Sdmmc}; 10use embassy_stm32::sdmmc::{CmdBlock, DataBlock, Sdmmc, StorageDevice};
11use embassy_stm32::time::mhz; 11use embassy_stm32::time::mhz;
12use embassy_stm32::{bind_interrupts, peripherals, sdmmc}; 12use embassy_stm32::{bind_interrupts, peripherals, sdmmc};
13use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
@@ -54,43 +54,36 @@ async fn main(_spawner: Spawner) {
54 Default::default(), 54 Default::default(),
55 ); 55 );
56 56
57 let mut err = None; 57 let mut cmd_block = CmdBlock::new();
58 loop {
59 match s.init_sd_card(mhz(24)).await {
60 Ok(_) => break,
61 Err(e) => {
62 if err != Some(e) {
63 info!("waiting for card: {:?}", e);
64 err = Some(e);
65 }
66 }
67 }
68 }
69 58
70 let card = unwrap!(s.card()); 59 let mut storage = StorageDevice::new_sd_card(&mut s, &mut cmd_block, mhz(24))
60 .await
61 .unwrap();
71 62
72 info!("Card: {:#?}", Debug2Format(card)); 63 let card = storage.card();
73 info!("Clock: {}", s.clock()); 64
65 info!("Card: {:#?}", Debug2Format(&card));
66 info!("Clock: {}", storage.sdmmc.clock());
74 67
75 info!("writing pattern1..."); 68 info!("writing pattern1...");
76 s.write_block(block_idx, &pattern1).await.unwrap(); 69 storage.write_block(block_idx, &pattern1).await.unwrap();
77 70
78 info!("reading..."); 71 info!("reading...");
79 s.read_block(block_idx, &mut block).await.unwrap(); 72 storage.read_block(block_idx, &mut block).await.unwrap();
80 assert_eq!(block, pattern1); 73 assert_eq!(block, pattern1);
81 74
82 info!("writing pattern2..."); 75 info!("writing pattern2...");
83 s.write_block(block_idx, &pattern2).await.unwrap(); 76 storage.write_block(block_idx, &pattern2).await.unwrap();
84 77
85 info!("reading..."); 78 info!("reading...");
86 s.read_block(block_idx, &mut block).await.unwrap(); 79 storage.read_block(block_idx, &mut block).await.unwrap();
87 assert_eq!(block, pattern2); 80 assert_eq!(block, pattern2);
88 81
89 info!("writing blocks [pattern1, pattern2]..."); 82 info!("writing blocks [pattern1, pattern2]...");
90 s.write_blocks(block_idx, &patterns).await.unwrap(); 83 storage.write_blocks(block_idx, &patterns).await.unwrap();
91 84
92 info!("reading blocks..."); 85 info!("reading blocks...");
93 s.read_blocks(block_idx, &mut blocks).await.unwrap(); 86 storage.read_blocks(block_idx, &mut blocks).await.unwrap();
94 assert_eq!(&blocks, &patterns); 87 assert_eq!(&blocks, &patterns);
95 88
96 drop(s); 89 drop(s);