embassy-rs / embassy

Modern embedded framework, using Rust and async.
https://embassy.dev
Apache License 2.0
5.61k stars 777 forks source link

STM32 Sdmmc blocks on write_block #3540

Open bluespider42 opened 1 week ago

bluespider42 commented 1 week ago

The function write_block in the sdmmc module currently blocks while waiting for the SD card after the block has been written. This can be several milliseconds depending on the SD card. The relevant section of code is: https://github.com/embassy-rs/embassy/blob/6c4b3d82b637fce5ab6efdc312d7852381d8ddeb/embassy-stm32/src/sdmmc/mod.rs#L1310-L1319 I added a yield and this seems to work well as a quick fix, but I'll admit I'm well out of my depth here to know if there may be undesirable side effects. I guess ideally one would await that entire section and wake on D0 going high - but I don't know if that would be feasible.

use embassy_futures::yield_now();
...
// Try to read card status (ACMD13)
while timeout > 0 {
    match self.read_sd_status().await {
        Ok(_) => return Ok(()),
        Err(Error::Timeout) => (yield_now().await), // Try again
        Err(e) => return Err(e),
    }
    timeout -= 1;
}
Err(Error::SoftwareTimeout)

Attached is the output of a logic analyser (1ms/div) showing the effect of the change (A different type of SD card was used for the two tests which seem to have different wait times). SD_Card_Blocking SD_Card_NotBlocking