diff --git a/examples/esp32c6/src/main.rs b/examples/esp32c6/src/main.rs index 8e00115..1d9a60b 100644 --- a/examples/esp32c6/src/main.rs +++ b/examples/esp32c6/src/main.rs @@ -22,7 +22,7 @@ use esp_hal::{ }, FlashSafeDma, IO, }; -use sdspi::SdSpi; +use sdspi::{self, SdSpi}; #[main] async fn main(_spawner: Spawner) { @@ -61,7 +61,19 @@ async fn main(_spawner: Spawner) { DmaPriority::Priority0, )); - let spi = FlashSafeDma::<_, 512>::new(spi); + let mut spi = FlashSafeDma::<_, 512>::new(spi); + + // Sd cards need to be clocked with a at least 74 cycles on their spi clock without the cs enabled, + // sd_init is a helper function that does this for us. + loop { + match sdspi::sd_init(&mut spi).await { + Ok(_) => break, + Err(e) => { + log::warn!("Sd init error: {:?}", e); + embassy_time::Timer::after_millis(10).await; + } + } + } let spid = ExclusiveDevice::new(spi, cs.into_push_pull_output(), embassy_time::Delay); let mut sd = SdSpi::<_, _, aligned::A1>::new(spid, embassy_time::Delay); diff --git a/examples/rp2040/Cargo.toml b/examples/rp2040/Cargo.toml index 303b4ad..3844a40 100644 --- a/examples/rp2040/Cargo.toml +++ b/examples/rp2040/Cargo.toml @@ -11,8 +11,6 @@ embassy-sync = { version = "0.5.0", features = ["defmt"] } embassy-executor = { version = "0.5.0", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", features = ["defmt", "defmt-timestamp-uptime"] } embassy-rp = { version = "0.1.0", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl"] } -embassy-usb = { version = "0.1.0", features = ["defmt"] } -embassy-net = { version = "0.4.0", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } embassy-futures = { version = "0.1.0" } cortex-m = { version = "0.7.6", features = ["inline-asm"] } @@ -39,3 +37,22 @@ embassy-time = {git = "https://github.com/embassy-rs/embassy", rev = "a009275875 embassy-rp = {git = "https://github.com/embassy-rs/embassy", rev = "a009275875228a3f9c59dcad114ef378b3f6f2ea" } embassy-futures = {git = "https://github.com/embassy-rs/embassy", rev = "a009275875228a3f9c59dcad114ef378b3f6f2ea" } embassy-embedded-hal = {git = "https://github.com/embassy-rs/embassy", rev = "a009275875228a3f9c59dcad114ef378b3f6f2ea" } + +# cargo build/run +[profile.dev] +codegen-units = 1 +debug = 2 +debug-assertions = true +incremental = false +opt-level = 3 +overflow-checks = true + +# cargo build/run --release +[profile.release] +codegen-units = 1 +debug = 2 +debug-assertions = false +incremental = false +lto = 'fat' +opt-level = 3 +overflow-checks = false diff --git a/examples/rp2040/src/main.rs b/examples/rp2040/src/main.rs index 7c4ba7a..b47f49a 100644 --- a/examples/rp2040/src/main.rs +++ b/examples/rp2040/src/main.rs @@ -14,7 +14,7 @@ use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex}; use embedded_fatfs::FsOptions; use embedded_hal_async::delay::DelayNs; use heapless::{String, Vec}; -use sdspi::SdSpi; +use sdspi::{sd_init, SdSpi}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -34,7 +34,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.frequency = 400_000; - let spi = Spi::new( + let mut spi = Spi::new( p.SPI0, clk, mosi, @@ -43,6 +43,19 @@ async fn main(_spawner: Spawner) { p.DMA_CH1, config.clone(), ); + + // Sd cards need to be clocked with a at least 74 cycles on their spi clock without the cs enabled, + // sd_init is a helper function that does this for us. + loop { + match sd_init(&mut spi).await { + Ok(_) => break, + Err(e) => { + defmt::warn!("Sd init error: {}", e); + embassy_time::Timer::after_millis(10).await; + } + } + } + let spi_bus = SPI_BUS.init(Mutex::new(spi)); let spid = SpiDeviceWithConfig::new(spi_bus, cs, config); diff --git a/sdspi/src/lib.rs b/sdspi/src/lib.rs index 50fb95d..57884fe 100644 --- a/sdspi/src/lib.rs +++ b/sdspi/src/lib.rs @@ -69,6 +69,19 @@ pub enum Error { WriteError, } +/// Must be called between powerup and [SdSpi::init] to ensure the sdcard is properly initialized. +pub async fn sd_init(spi: &mut SPI, cs: &mut CS) -> Result<(), Error> +where + SPI: embedded_hal_async::spi::SpiBus, + CS: embedded_hal::digital::OutputPin, +{ + // Supply minimum of 74 clock cycles without CS asserted. + cs.set_high().map_err(|_| Error::ChipSelect)?; + spi.write(&[0xFF; 10]).await.map_err(|_| Error::SpiError)?; + + Ok(()) +} + pub struct SdSpi where SPI: embedded_hal_async::spi::SpiDevice, @@ -96,14 +109,9 @@ where } } + /// To comply with the SD card spec, [sd_init] must be called between powerup and calling this function. pub async fn init(&mut self) -> Result<(), Error> { let r = async { - // Supply minimum of 74 clock cycles without CS asserted. - self.spi - .write(&[0xFF; 10]) - .await - .map_err(|_| Error::SpiError)?; - with_timeout(self.delay.clone(), 1000, async { loop { let r = self.cmd(idle()).await?;