Use RCC frequency instead of config

This commit is contained in:
chemicstry 2022-03-16 19:09:37 +02:00
parent 6d547b1143
commit bf4a38ac06
2 changed files with 9 additions and 25 deletions

View file

@ -133,6 +133,7 @@ cfg_if::cfg_if! {
_ => Err(Error::BadClock), _ => Err(Error::BadClock),
}?; }?;
// SDIO_CK frequency = SDIOCLK / [CLKDIV + 2]
let clk_f = Hertz(ker_ck.0 / (clk_div as u32 + 2)); let clk_f = Hertz(ker_ck.0 / (clk_div as u32 + 2));
Ok((clk_div, clk_f)) Ok((clk_div, clk_f))
} }
@ -159,18 +160,10 @@ cfg_if::cfg_if! {
/// SDMMC configuration /// SDMMC configuration
/// ///
/// You should probably change the default clock values to match your configuration
///
/// Default values: /// Default values:
/// hclk = 400_000_000 Hz
/// kernel_clk: 100_000_000 Hz
/// data_transfer_timeout: 5_000_000 /// data_transfer_timeout: 5_000_000
#[non_exhaustive] #[non_exhaustive]
pub struct Config { pub struct Config {
/// AHB clock
pub hclk: Hertz,
/// SDMMC kernel clock
pub kernel_clk: Hertz,
/// The timeout to be set for data transfers, in card bus clock periods /// The timeout to be set for data transfers, in card bus clock periods
pub data_transfer_timeout: u32, pub data_transfer_timeout: u32,
} }
@ -178,8 +171,6 @@ pub struct Config {
impl Default for Config { impl Default for Config {
fn default() -> Self { fn default() -> Self {
Self { Self {
hclk: Hertz(400_000_000),
kernel_clk: Hertz(100_000_000),
data_transfer_timeout: 5_000_000, data_transfer_timeout: 5_000_000,
} }
} }
@ -219,7 +210,7 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdioDma<T>> Sdmmc<'d, T, P, Dma> {
T::reset(); T::reset();
let inner = T::inner(); let inner = T::inner();
let clock = inner.new_inner(config.kernel_clk); let clock = inner.new_inner(T::frequency());
irq.set_handler(Self::on_interrupt); irq.set_handler(Self::on_interrupt);
irq.unpend(); irq.unpend();
@ -248,8 +239,7 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdioDma<T>> Sdmmc<'d, T, P, Dma> {
P::BUSWIDTH, P::BUSWIDTH,
&mut self.card, &mut self.card,
&mut self.signalling, &mut self.signalling,
self.config.hclk, T::frequency(),
self.config.kernel_clk,
&mut self.clock, &mut self.clock,
T::state(), T::state(),
self.config.data_transfer_timeout, self.config.data_transfer_timeout,
@ -371,7 +361,6 @@ impl SdmmcInner {
bus_width: BusWidth, bus_width: BusWidth,
old_card: &mut Option<Card>, old_card: &mut Option<Card>,
signalling: &mut Signalling, signalling: &mut Signalling,
hclk: Hertz,
ker_ck: Hertz, ker_ck: Hertz,
clock: &mut Hertz, clock: &mut Hertz,
waker_reg: &AtomicWaker, waker_reg: &AtomicWaker,
@ -474,10 +463,10 @@ impl SdmmcInner {
// Set Clock // Set Clock
if freq.0 <= 25_000_000 { if freq.0 <= 25_000_000 {
// Final clock frequency // Final clock frequency
self.clkcr_set_clkdiv(freq.0, width, hclk, ker_ck, clock)?; self.clkcr_set_clkdiv(freq.0, width, ker_ck, clock)?;
} else { } else {
// Switch to max clock for SDR12 // Switch to max clock for SDR12
self.clkcr_set_clkdiv(25_000_000, width, hclk, ker_ck, clock)?; self.clkcr_set_clkdiv(25_000_000, width, ker_ck, clock)?;
} }
// Read status // Read status
@ -497,7 +486,7 @@ impl SdmmcInner {
if *signalling == Signalling::SDR25 { if *signalling == Signalling::SDR25 {
// Set final clock frequency // Set final clock frequency
self.clkcr_set_clkdiv(freq.0, width, hclk, ker_ck, clock)?; self.clkcr_set_clkdiv(freq.0, width, ker_ck, clock)?;
if self.read_status(&card)?.state() != CurrentState::Transfer { if self.read_status(&card)?.state() != CurrentState::Transfer {
return Err(Error::SignalingSwitchFailed); return Err(Error::SignalingSwitchFailed);
@ -804,7 +793,6 @@ impl SdmmcInner {
&self, &self,
freq: u32, freq: u32,
width: BusWidth, width: BusWidth,
hclk: Hertz,
ker_ck: Hertz, ker_ck: Hertz,
clock: &mut Hertz, clock: &mut Hertz,
) -> Result<(), Error> { ) -> Result<(), Error> {
@ -814,7 +802,7 @@ impl SdmmcInner {
// Enforce AHB and SDMMC_CK clock relation. See RM0433 Rev 7 // Enforce AHB and SDMMC_CK clock relation. See RM0433 Rev 7
// Section 55.5.8 // Section 55.5.8
let sdmmc_bus_bandwidth = new_clock.0 * (width as u32); let sdmmc_bus_bandwidth = new_clock.0 * (width as u32);
assert!(hclk.0 > 3 * sdmmc_bus_bandwidth / 32); assert!(ker_ck.0 > 3 * sdmmc_bus_bandwidth / 32);
*clock = new_clock; *clock = new_clock;
// NOTE(unsafe) We have exclusive access to the regblock // NOTE(unsafe) We have exclusive access to the regblock

View file

@ -6,7 +6,7 @@
mod example_common; mod example_common;
use embassy::executor::Spawner; use embassy::executor::Spawner;
use embassy_stm32::sdmmc::{self, Sdmmc}; use embassy_stm32::sdmmc::Sdmmc;
use embassy_stm32::time::U32Ext; use embassy_stm32::time::U32Ext;
use embassy_stm32::{interrupt, Config, Peripherals}; use embassy_stm32::{interrupt, Config, Peripherals};
use example_common::*; use example_common::*;
@ -26,16 +26,12 @@ async fn main(_spawner: Spawner, p: Peripherals) -> ! {
let irq = interrupt::take!(SDIO); let irq = interrupt::take!(SDIO);
let mut config = sdmmc::Config::default();
config.hclk = 48.mhz().into();
config.kernel_clk = 48.mhz().into();
let mut sdmmc = unsafe { let mut sdmmc = unsafe {
Sdmmc::new( Sdmmc::new(
p.SDIO, p.SDIO,
(p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11), (p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11),
irq, irq,
config, Default::default(),
p.DMA2_CH3, p.DMA2_CH3,
) )
}; };