From 08efd91dd406ccb813618296ba897ea8d88f874a 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/cache.rs | 2 +- zynq/zynq7000-hal/src/gic.rs | 5 +- zynq/zynq7000-hal/src/gpio/ll.rs | 2 +- zynq/zynq7000-hal/src/i2c.rs | 4 +- zynq/zynq7000-hal/src/sdio.rs | 153 +++++++++++++++++++++++++++++- zynq/zynq7000-hal/src/spi/mod.rs | 4 +- zynq/zynq7000-hal/src/uart/mod.rs | 4 +- zynq/zynq7000/src/lib.rs | 2 +- zynq/zynq7000/src/mpcore.rs | 7 +- 9 files changed, 168 insertions(+), 15 deletions(-) diff --git a/zynq/zynq7000-hal/src/cache.rs b/zynq/zynq7000-hal/src/cache.rs index 7e7e8c0..d3357d8 100644 --- a/zynq/zynq7000-hal/src/cache.rs +++ b/zynq/zynq7000-hal/src/cache.rs @@ -11,7 +11,7 @@ use cortex_ar::{ invalidate_data_cache_line_to_poc, }, }; -use zynq7000::l2_cache::{Registers, MmioRegisters}; +use zynq7000::l2_cache::{MmioRegisters, Registers}; pub const CACHE_LINE_SIZE: usize = 32; diff --git a/zynq/zynq7000-hal/src/gic.rs b/zynq/zynq7000-hal/src/gic.rs index 14fd089..d6ad473 100644 --- a/zynq/zynq7000-hal/src/gic.rs +++ b/zynq/zynq7000-hal/src/gic.rs @@ -10,8 +10,9 @@ use arbitrary_int::prelude::*; use cortex_ar::interrupt; use zynq7000::gic::{ - DistributorControlRegister, GicCpuInterfaceRegisters, GicDistributorRegisters, InterfaceControl, - InterruptSignalRegister, MmioGicCpuInterfaceRegisters, MmioGicDistributorRegisters, PriorityRegister, + DistributorControlRegister, GicCpuInterfaceRegisters, GicDistributorRegisters, + InterfaceControl, InterruptSignalRegister, MmioGicCpuInterfaceRegisters, + MmioGicDistributorRegisters, PriorityRegister, }; const SPURIOUS_INTERRUPT_ID: u32 = 1023; diff --git a/zynq/zynq7000-hal/src/gpio/ll.rs b/zynq/zynq7000-hal/src/gpio/ll.rs index 271c12b..7b4c265 100644 --- a/zynq/zynq7000-hal/src/gpio/ll.rs +++ b/zynq/zynq7000-hal/src/gpio/ll.rs @@ -1,6 +1,6 @@ //! Low-level GPIO access module. use embedded_hal::digital::PinState; -use zynq7000::gpio::{Registers, MaskedOutput, MmioRegisters}; +use zynq7000::gpio::{MaskedOutput, MmioRegisters, Registers}; use crate::slcr::Slcr; diff --git a/zynq/zynq7000-hal/src/i2c.rs b/zynq/zynq7000-hal/src/i2c.rs index 47aa7ec..9a5e599 100644 --- a/zynq/zynq7000-hal/src/i2c.rs +++ b/zynq/zynq7000-hal/src/i2c.rs @@ -2,7 +2,9 @@ use arbitrary_int::{u2, u3, u6}; use embedded_hal::i2c::NoAcknowledgeSource; use zynq7000::{ - i2c::{Control, I2C_0_BASE_ADDR, I2C_1_BASE_ADDR, InterruptStatus, MmioRegisters, TransferSize}, + i2c::{ + Control, I2C_0_BASE_ADDR, I2C_1_BASE_ADDR, InterruptStatus, MmioRegisters, TransferSize, + }, slcr::reset::DualClockReset, }; 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-hal/src/spi/mod.rs b/zynq/zynq7000-hal/src/spi/mod.rs index fa636ed..8bb9db0 100644 --- a/zynq/zynq7000-hal/src/spi/mod.rs +++ b/zynq/zynq7000-hal/src/spi/mod.rs @@ -25,8 +25,8 @@ pub use embedded_hal::spi::Mode; use embedded_hal::spi::SpiBus as _; use zynq7000::slcr::reset::DualRefAndClockReset; use zynq7000::spi::{ - BaudDivSel, DelayControl, FifoWrite, InterruptControl, InterruptMask, InterruptStatus, MmioRegisters, - SPI_0_BASE_ADDR, SPI_1_BASE_ADDR, + BaudDivSel, DelayControl, FifoWrite, InterruptControl, InterruptMask, InterruptStatus, + MmioRegisters, SPI_0_BASE_ADDR, SPI_1_BASE_ADDR, }; pub const FIFO_DEPTH: usize = 128; diff --git a/zynq/zynq7000-hal/src/uart/mod.rs b/zynq/zynq7000-hal/src/uart/mod.rs index 454b3b7..29e362b 100644 --- a/zynq/zynq7000-hal/src/uart/mod.rs +++ b/zynq/zynq7000-hal/src/uart/mod.rs @@ -14,8 +14,8 @@ use libm::round; use zynq7000::{ slcr::reset::DualRefAndClockReset, uart::{ - BaudRateDivisor, Baudgen, ChMode, ClockSelect, FifoTrigger, InterruptControl, MmioRegisters, - Mode, UART_0_BASE, UART_1_BASE, + BaudRateDivisor, Baudgen, ChMode, ClockSelect, FifoTrigger, InterruptControl, + MmioRegisters, Mode, UART_0_BASE, UART_1_BASE, }, }; 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); diff --git a/zynq/zynq7000/src/mpcore.rs b/zynq/zynq7000/src/mpcore.rs index 2fe6545..8b875bb 100644 --- a/zynq/zynq7000/src/mpcore.rs +++ b/zynq/zynq7000/src/mpcore.rs @@ -4,8 +4,11 @@ use static_assertions::const_assert_eq; use crate::{ - gic::{GicCpuInterfaceRegisters, GicDistributorRegisters, MmioGicCpuInterfaceRegisters, MmioGicDistributorRegisters}, - gtc::{Registers, MmioRegisters}, + gic::{ + GicCpuInterfaceRegisters, GicDistributorRegisters, MmioGicCpuInterfaceRegisters, + MmioGicDistributorRegisters, + }, + gtc::{MmioRegisters, Registers}, }; pub const MPCORE_BASE_ADDR: usize = 0xF8F0_0000;