From 82296ecc79bbadaa4eac046dd7fd2ce2768a6be1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 26 Oct 2025 23:58:18 +0100 Subject: [PATCH] continue SDIO --- zynq/zynq7000-hal/src/sdio.rs | 153 +++++++++++++++++++++++++++++++++- zynq/zynq7000/src/lib.rs | 2 +- 2 files changed, 151 insertions(+), 4 deletions(-) diff --git a/zynq/zynq7000-hal/src/sdio.rs b/zynq/zynq7000-hal/src/sdio.rs index 3b78cf9..a861df1 100644 --- a/zynq/zynq7000-hal/src/sdio.rs +++ b/zynq/zynq7000-hal/src/sdio.rs @@ -3,7 +3,110 @@ use zynq7000::{ slcr::{clocks::SrcSelIo, reset::DualRefAndClockReset}, }; -use crate::{clocks::Clocks, slcr::Slcr, time::Hertz}; +#[cfg(not(feature = "7z010-7z007s-clg225"))] +use crate::gpio::mio::{ + Mio16, Mio17, Mio18, Mio19, Mio20, Mio21, Mio22, Mio23, Mio24, Mio25, Mio26, Mio27, Mio40, + Mio41, Mio42, Mio43, Mio44, Mio45, Mio46, Mio47, Mio50, Mio51, +}; +use crate::{ + clocks::Clocks, + gpio::mio::{ + Mio10, Mio11, Mio12, Mio13, Mio14, Mio15, Mio28, Mio29, Mio30, Mio31, Mio32, Mio33, Mio34, + Mio35, Mio36, Mio37, Mio38, Mio39, Mio48, Mio49, Pin, + }, + slcr::Slcr, + time::Hertz, +}; + +pub trait Sdio0ClockPin {} +pub trait Sdio0CommandPin {} +pub trait Sdio0Data0Pin {} +pub trait Sdio0Data1Pin {} +pub trait Sdio0Data2Pin {} +pub trait Sdio0Data3Pin {} + +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio0ClockPin for Pin {} +impl Sdio0ClockPin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio0ClockPin for Pin {} + +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio0CommandPin for Pin {} +impl Sdio0CommandPin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio0CommandPin for Pin {} + +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio0Data0Pin for Pin {} +impl Sdio0Data0Pin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio0Data0Pin for Pin {} + +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio0Data1Pin for Pin {} +impl Sdio0Data1Pin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio0Data1Pin for Pin {} + +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio0Data2Pin for Pin {} +impl Sdio0Data2Pin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio0Data2Pin for Pin {} + +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio0Data3Pin for Pin {} +impl Sdio0Data3Pin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio0Data3Pin for Pin {} + +pub trait Sdio1ClockPin {} +pub trait Sdio1CommandPin {} +pub trait Sdio1Data0Pin {} +pub trait Sdio1Data1Pin {} +pub trait Sdio1Data2Pin {} +pub trait Sdio1Data3Pin {} + +impl Sdio1ClockPin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio1ClockPin for Pin {} +impl Sdio1ClockPin for Pin {} +impl Sdio1ClockPin for Pin {} + +impl Sdio1CommandPin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio1CommandPin for Pin {} +impl Sdio1CommandPin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio1CommandPin for Pin {} + +impl Sdio1Data0Pin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio1Data0Pin for Pin {} +impl Sdio1Data0Pin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio1Data0Pin for Pin {} + +impl Sdio1Data1Pin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio1Data1Pin for Pin {} +impl Sdio1Data1Pin for Pin {} +impl Sdio1Data1Pin for Pin {} + +impl Sdio1Data2Pin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio1Data2Pin for Pin {} +impl Sdio1Data2Pin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio1Data2Pin for Pin {} + +impl Sdio1Data2Pin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio1Data3Pin for Pin {} +impl Sdio1Data3Pin for Pin {} +#[cfg(not(feature = "7z010-7z007s-clg225"))] +impl Sdio1Data3Pin for Pin {} #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum SdioId { @@ -11,6 +114,10 @@ pub enum SdioId { Sdio1, } +pub struct Sdio {} + +impl Sdio {} + pub struct SdioDivisors { /// Divisor which will be used during the initialization phase when ACMD41 is issued. /// @@ -22,10 +129,50 @@ pub struct SdioDivisors { } impl SdioDivisors { - pub fn calculate(src_sel: SrcSelIo, clocks: &Clocks, target_speed: Hertz) { - + pub fn calculate(src_sel: SrcSelIo, clocks: &Clocks, target_speed: Hertz) -> Self { + const INIT_CLOCK_HZ: u32 = 400_000; + let ref_clk = match src_sel { + SrcSelIo::IoPll | SrcSelIo::IoPllAlt => clocks.io_clocks().ref_clk(), + SrcSelIo::ArmPll => clocks.arm_clocks().ref_clk(), + SrcSelIo::DdrPll => clocks.ddr_clocks().ref_clk(), + }; + let divisor_select_from_value = |value: u32| match value { + 0..=1 => SdClockDivisor::Div1, + 2 => SdClockDivisor::Div2, + 3..=4 => SdClockDivisor::Div4, + 5..=8 => SdClockDivisor::Div8, + 9..=16 => SdClockDivisor::Div16, + 17..=32 => SdClockDivisor::Div32, + 33..=64 => SdClockDivisor::Div64, + 65..=128 => SdClockDivisor::Div128, + 129.. => SdClockDivisor::Div256, + }; + Self { + divisor_init_phase: divisor_select_from_value(ref_clk.raw().div_ceil(INIT_CLOCK_HZ)), + divisor_normal: divisor_select_from_value(ref_clk.raw().div_ceil(target_speed.raw())), + } } } + +pub struct SdioClockConfig { + src_sel: SrcSelIo, + divisors: SdioDivisors, +} + +impl SdioClockConfig { + pub fn new(src_sel: SrcSelIo, divisors: SdioDivisors) -> Self { + Self { src_sel, divisors } + } + + pub fn calculate_for_io_clock(clocks: &Clocks, target_speed: Hertz) -> Self { + let divisors = SdioDivisors::calculate(SrcSelIo::IoPll, clocks, target_speed); + Self { + src_sel: SrcSelIo::IoPll, + divisors, + } + } +} + /// Reset the UART peripheral using the SLCR reset register for UART. /// /// Please note that this function will interfere with an already configured diff --git a/zynq/zynq7000/src/lib.rs b/zynq/zynq7000/src/lib.rs index 8718c33..8326ba3 100644 --- a/zynq/zynq7000/src/lib.rs +++ b/zynq/zynq7000/src/lib.rs @@ -29,11 +29,11 @@ pub mod l2_cache; pub mod mpcore; pub mod priv_tim; pub mod qspi; +pub mod sdio; pub mod slcr; pub mod spi; pub mod ttc; pub mod uart; -pub mod sdio; pub mod xadc; static PERIPHERALS_TAKEN: AtomicBool = AtomicBool::new(false);