Skip to content

Commit c3cdd4f

Browse files
committed
stm32/sdmmc: update example and add helper funcs
1 parent 6dccb68 commit c3cdd4f

File tree

2 files changed

+73
-4
lines changed

2 files changed

+73
-4
lines changed

embassy-stm32/src/sdmmc/sd.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,20 @@ impl<'a, 'b> StorageDevice<'a, 'b, Card> {
139139
Ok(s)
140140
}
141141

142+
/// Create a new uninitialized card
143+
pub fn new_uninit_sd_card(sdmmc: &'a mut Sdmmc<'b>) -> Self {
144+
Self {
145+
info: Card::default(),
146+
sdmmc,
147+
}
148+
}
149+
150+
/// Re-acquire an sd card
151+
pub async fn reacquire(&mut self, cmd_block: &mut CmdBlock, freq: Hertz) -> Result<(), Error> {
152+
self.sdmmc.on_drop();
153+
self.acquire(cmd_block, freq).await
154+
}
155+
142156
/// Initializes the card into a known state (or at least tries to).
143157
async fn acquire(&mut self, cmd_block: &mut CmdBlock, freq: Hertz) -> Result<(), Error> {
144158
let _scoped_wake_guard = self.sdmmc.info.rcc.wake_guard();
@@ -347,6 +361,20 @@ impl<'a, 'b> StorageDevice<'a, 'b, Emmc> {
347361
Ok(s)
348362
}
349363

364+
/// Create a new uninitialized emmc
365+
pub fn new_uninit_emmc(sdmmc: &'a mut Sdmmc<'b>) -> Self {
366+
Self {
367+
info: Emmc::default(),
368+
sdmmc,
369+
}
370+
}
371+
372+
/// Re-acquire an emmc
373+
pub async fn reacquire(&mut self, cmd_block: &mut CmdBlock, freq: Hertz) -> Result<(), Error> {
374+
self.sdmmc.on_drop();
375+
self.acquire(cmd_block, freq).await
376+
}
377+
350378
async fn acquire(&mut self, _cmd_block: &mut CmdBlock, freq: Hertz) -> Result<(), Error> {
351379
let _scoped_wake_guard = self.sdmmc.info.rcc.wake_guard();
352380

examples/stm32f4/src/bin/sdmmc.rs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
use defmt::*;
55
use embassy_executor::Spawner;
66
use embassy_stm32::sdmmc::Sdmmc;
7-
use embassy_stm32::sdmmc::sd::{CmdBlock, DataBlock, StorageDevice};
7+
use embassy_stm32::sdmmc::sd::{Card, CmdBlock, DataBlock, StorageDevice};
88
use embassy_stm32::time::{Hertz, mhz};
99
use embassy_stm32::{Config, bind_interrupts, dma, peripherals, sdmmc};
10+
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
11+
use embassy_sync::channel::Channel;
12+
use embassy_time::{Duration, Timer};
1013
use {defmt_rtt as _, panic_probe as _};
1114

1215
/// This is a safeguard to not overwrite any data on the SD card.
@@ -18,6 +21,42 @@ bind_interrupts!(struct Irqs {
1821
DMA2_STREAM3 => dma::InterruptHandler<peripherals::DMA2_CH3>;
1922
});
2023

24+
pub enum StorageRequest {
25+
WriteRequest(u32, &'static DataBlock),
26+
ReadRequest,
27+
}
28+
29+
pub async fn run_storage<'a>(mut sdmmc: Sdmmc<'a>, channel: &'static Channel<NoopRawMutex, StorageRequest, 3>) {
30+
loop {
31+
let storage = loop {
32+
if let Ok(storage) = StorageDevice::new_sd_card(&mut sdmmc, &mut CmdBlock::new(), mhz(24)).await {
33+
break storage;
34+
}
35+
36+
// Wait 1/2 second to avoid saturating the core
37+
Timer::after(Duration::from_millis(500)).await;
38+
};
39+
40+
let _ = run_storage_inner(storage, channel).await;
41+
}
42+
}
43+
44+
pub async fn run_storage_inner<'a, 'b>(
45+
mut storage: StorageDevice<'a, 'b, Card>,
46+
channel: &'static Channel<NoopRawMutex, StorageRequest, 3>,
47+
) -> Result<(), ()> {
48+
// Or, instead of receiving from a channel, you can read/write files here
49+
50+
loop {
51+
match channel.receive().await {
52+
StorageRequest::WriteRequest(block_idx, buffer) => {
53+
storage.write_block(block_idx, buffer).await.map_err(|_| ())?;
54+
}
55+
StorageRequest::ReadRequest => {}
56+
}
57+
}
58+
}
59+
2160
#[embassy_executor::main]
2261
async fn main(_spawner: Spawner) {
2362
let mut config = Config::default();
@@ -58,9 +97,11 @@ async fn main(_spawner: Spawner) {
5897

5998
let mut cmd_block = CmdBlock::new();
6099

61-
let mut storage = StorageDevice::new_sd_card(&mut sdmmc, &mut cmd_block, mhz(24))
62-
.await
63-
.unwrap();
100+
let mut storage = loop {
101+
if let Ok(storage) = StorageDevice::new_sd_card(&mut sdmmc, &mut cmd_block, mhz(24)).await {
102+
break storage;
103+
}
104+
};
64105

65106
let card = storage.card();
66107

0 commit comments

Comments
 (0)