aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/sdmmc/mod.rs26
-rw-r--r--examples/stm32f4/src/bin/sdmmc.rs8
2 files changed, 9 insertions, 25 deletions
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs
index 7548b799c..18e53ce10 100644
--- a/embassy-stm32/src/sdmmc/mod.rs
+++ b/embassy-stm32/src/sdmmc/mod.rs
@@ -133,6 +133,7 @@ cfg_if::cfg_if! {
133 _ => Err(Error::BadClock), 133 _ => Err(Error::BadClock),
134 }?; 134 }?;
135 135
136 // SDIO_CK frequency = SDIOCLK / [CLKDIV + 2]
136 let clk_f = Hertz(ker_ck.0 / (clk_div as u32 + 2)); 137 let clk_f = Hertz(ker_ck.0 / (clk_div as u32 + 2));
137 Ok((clk_div, clk_f)) 138 Ok((clk_div, clk_f))
138 } 139 }
@@ -159,18 +160,10 @@ cfg_if::cfg_if! {
159 160
160/// SDMMC configuration 161/// SDMMC configuration
161/// 162///
162/// You should probably change the default clock values to match your configuration
163///
164/// Default values: 163/// Default values:
165/// hclk = 400_000_000 Hz
166/// kernel_clk: 100_000_000 Hz
167/// data_transfer_timeout: 5_000_000 164/// data_transfer_timeout: 5_000_000
168#[non_exhaustive] 165#[non_exhaustive]
169pub struct Config { 166pub struct Config {
170 /// AHB clock
171 pub hclk: Hertz,
172 /// SDMMC kernel clock
173 pub kernel_clk: Hertz,
174 /// The timeout to be set for data transfers, in card bus clock periods 167 /// The timeout to be set for data transfers, in card bus clock periods
175 pub data_transfer_timeout: u32, 168 pub data_transfer_timeout: u32,
176} 169}
@@ -178,8 +171,6 @@ pub struct Config {
178impl Default for Config { 171impl Default for Config {
179 fn default() -> Self { 172 fn default() -> Self {
180 Self { 173 Self {
181 hclk: Hertz(400_000_000),
182 kernel_clk: Hertz(100_000_000),
183 data_transfer_timeout: 5_000_000, 174 data_transfer_timeout: 5_000_000,
184 } 175 }
185 } 176 }
@@ -219,7 +210,7 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdioDma<T>> Sdmmc<'d, T, P, Dma> {
219 T::reset(); 210 T::reset();
220 211
221 let inner = T::inner(); 212 let inner = T::inner();
222 let clock = inner.new_inner(config.kernel_clk); 213 let clock = inner.new_inner(T::frequency());
223 214
224 irq.set_handler(Self::on_interrupt); 215 irq.set_handler(Self::on_interrupt);
225 irq.unpend(); 216 irq.unpend();
@@ -248,8 +239,7 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdioDma<T>> Sdmmc<'d, T, P, Dma> {
248 P::BUSWIDTH, 239 P::BUSWIDTH,
249 &mut self.card, 240 &mut self.card,
250 &mut self.signalling, 241 &mut self.signalling,
251 self.config.hclk, 242 T::frequency(),
252 self.config.kernel_clk,
253 &mut self.clock, 243 &mut self.clock,
254 T::state(), 244 T::state(),
255 self.config.data_transfer_timeout, 245 self.config.data_transfer_timeout,
@@ -371,7 +361,6 @@ impl SdmmcInner {
371 bus_width: BusWidth, 361 bus_width: BusWidth,
372 old_card: &mut Option<Card>, 362 old_card: &mut Option<Card>,
373 signalling: &mut Signalling, 363 signalling: &mut Signalling,
374 hclk: Hertz,
375 ker_ck: Hertz, 364 ker_ck: Hertz,
376 clock: &mut Hertz, 365 clock: &mut Hertz,
377 waker_reg: &AtomicWaker, 366 waker_reg: &AtomicWaker,
@@ -474,10 +463,10 @@ impl SdmmcInner {
474 // Set Clock 463 // Set Clock
475 if freq.0 <= 25_000_000 { 464 if freq.0 <= 25_000_000 {
476 // Final clock frequency 465 // Final clock frequency
477 self.clkcr_set_clkdiv(freq.0, width, hclk, ker_ck, clock)?; 466 self.clkcr_set_clkdiv(freq.0, width, ker_ck, clock)?;
478 } else { 467 } else {
479 // Switch to max clock for SDR12 468 // Switch to max clock for SDR12
480 self.clkcr_set_clkdiv(25_000_000, width, hclk, ker_ck, clock)?; 469 self.clkcr_set_clkdiv(25_000_000, width, ker_ck, clock)?;
481 } 470 }
482 471
483 // Read status 472 // Read status
@@ -497,7 +486,7 @@ impl SdmmcInner {
497 486
498 if *signalling == Signalling::SDR25 { 487 if *signalling == Signalling::SDR25 {
499 // Set final clock frequency 488 // Set final clock frequency
500 self.clkcr_set_clkdiv(freq.0, width, hclk, ker_ck, clock)?; 489 self.clkcr_set_clkdiv(freq.0, width, ker_ck, clock)?;
501 490
502 if self.read_status(&card)?.state() != CurrentState::Transfer { 491 if self.read_status(&card)?.state() != CurrentState::Transfer {
503 return Err(Error::SignalingSwitchFailed); 492 return Err(Error::SignalingSwitchFailed);
@@ -804,7 +793,6 @@ impl SdmmcInner {
804 &self, 793 &self,
805 freq: u32, 794 freq: u32,
806 width: BusWidth, 795 width: BusWidth,
807 hclk: Hertz,
808 ker_ck: Hertz, 796 ker_ck: Hertz,
809 clock: &mut Hertz, 797 clock: &mut Hertz,
810 ) -> Result<(), Error> { 798 ) -> Result<(), Error> {
@@ -814,7 +802,7 @@ impl SdmmcInner {
814 // Enforce AHB and SDMMC_CK clock relation. See RM0433 Rev 7 802 // Enforce AHB and SDMMC_CK clock relation. See RM0433 Rev 7
815 // Section 55.5.8 803 // Section 55.5.8
816 let sdmmc_bus_bandwidth = new_clock.0 * (width as u32); 804 let sdmmc_bus_bandwidth = new_clock.0 * (width as u32);
817 assert!(hclk.0 > 3 * sdmmc_bus_bandwidth / 32); 805 assert!(ker_ck.0 > 3 * sdmmc_bus_bandwidth / 32);
818 *clock = new_clock; 806 *clock = new_clock;
819 807
820 // NOTE(unsafe) We have exclusive access to the regblock 808 // NOTE(unsafe) We have exclusive access to the regblock
diff --git a/examples/stm32f4/src/bin/sdmmc.rs b/examples/stm32f4/src/bin/sdmmc.rs
index d941584be..46ac44500 100644
--- a/examples/stm32f4/src/bin/sdmmc.rs
+++ b/examples/stm32f4/src/bin/sdmmc.rs
@@ -6,7 +6,7 @@
6mod example_common; 6mod example_common;
7 7
8use embassy::executor::Spawner; 8use embassy::executor::Spawner;
9use embassy_stm32::sdmmc::{self, Sdmmc}; 9use embassy_stm32::sdmmc::Sdmmc;
10use embassy_stm32::time::U32Ext; 10use embassy_stm32::time::U32Ext;
11use embassy_stm32::{interrupt, Config, Peripherals}; 11use embassy_stm32::{interrupt, Config, Peripherals};
12use example_common::*; 12use example_common::*;
@@ -26,16 +26,12 @@ async fn main(_spawner: Spawner, p: Peripherals) -> ! {
26 26
27 let irq = interrupt::take!(SDIO); 27 let irq = interrupt::take!(SDIO);
28 28
29 let mut config = sdmmc::Config::default();
30 config.hclk = 48.mhz().into();
31 config.kernel_clk = 48.mhz().into();
32
33 let mut sdmmc = unsafe { 29 let mut sdmmc = unsafe {
34 Sdmmc::new( 30 Sdmmc::new(
35 p.SDIO, 31 p.SDIO,
36 (p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11), 32 (p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11),
37 irq, 33 irq,
38 config, 34 Default::default(),
39 p.DMA2_CH3, 35 p.DMA2_CH3,
40 ) 36 )
41 }; 37 };