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),
}?;
// SDIO_CK frequency = SDIOCLK / [CLKDIV + 2]
let clk_f = Hertz(ker_ck.0 / (clk_div as u32 + 2));
Ok((clk_div, clk_f))
}
@ -159,18 +160,10 @@ cfg_if::cfg_if! {
/// SDMMC configuration
///
/// You should probably change the default clock values to match your configuration
///
/// Default values:
/// hclk = 400_000_000 Hz
/// kernel_clk: 100_000_000 Hz
/// data_transfer_timeout: 5_000_000
#[non_exhaustive]
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
pub data_transfer_timeout: u32,
}
@ -178,8 +171,6 @@ pub struct Config {
impl Default for Config {
fn default() -> Self {
Self {
hclk: Hertz(400_000_000),
kernel_clk: Hertz(100_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();
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.unpend();
@ -248,8 +239,7 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdioDma<T>> Sdmmc<'d, T, P, Dma> {
P::BUSWIDTH,
&mut self.card,
&mut self.signalling,
self.config.hclk,
self.config.kernel_clk,
T::frequency(),
&mut self.clock,
T::state(),
self.config.data_transfer_timeout,
@ -371,7 +361,6 @@ impl SdmmcInner {
bus_width: BusWidth,
old_card: &mut Option<Card>,
signalling: &mut Signalling,
hclk: Hertz,
ker_ck: Hertz,
clock: &mut Hertz,
waker_reg: &AtomicWaker,
@ -474,10 +463,10 @@ impl SdmmcInner {
// Set Clock
if freq.0 <= 25_000_000 {
// 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 {
// 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
@ -497,7 +486,7 @@ impl SdmmcInner {
if *signalling == Signalling::SDR25 {
// 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 {
return Err(Error::SignalingSwitchFailed);
@ -804,7 +793,6 @@ impl SdmmcInner {
&self,
freq: u32,
width: BusWidth,
hclk: Hertz,
ker_ck: Hertz,
clock: &mut Hertz,
) -> Result<(), Error> {
@ -814,7 +802,7 @@ impl SdmmcInner {
// Enforce AHB and SDMMC_CK clock relation. See RM0433 Rev 7
// Section 55.5.8
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;
// NOTE(unsafe) We have exclusive access to the regblock

View file

@ -6,7 +6,7 @@
mod example_common;
use embassy::executor::Spawner;
use embassy_stm32::sdmmc::{self, Sdmmc};
use embassy_stm32::sdmmc::Sdmmc;
use embassy_stm32::time::U32Ext;
use embassy_stm32::{interrupt, Config, Peripherals};
use example_common::*;
@ -26,16 +26,12 @@ async fn main(_spawner: Spawner, p: Peripherals) -> ! {
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 {
Sdmmc::new(
p.SDIO,
(p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11),
irq,
config,
Default::default(),
p.DMA2_CH3,
)
};