continue SDIO
This commit is contained in:
@@ -11,7 +11,7 @@ use cortex_ar::{
|
|||||||
invalidate_data_cache_line_to_poc,
|
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;
|
pub const CACHE_LINE_SIZE: usize = 32;
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ use arbitrary_int::prelude::*;
|
|||||||
|
|
||||||
use cortex_ar::interrupt;
|
use cortex_ar::interrupt;
|
||||||
use zynq7000::gic::{
|
use zynq7000::gic::{
|
||||||
DistributorControlRegister, GicCpuInterfaceRegisters, GicDistributorRegisters, InterfaceControl,
|
DistributorControlRegister, GicCpuInterfaceRegisters, GicDistributorRegisters,
|
||||||
InterruptSignalRegister, MmioGicCpuInterfaceRegisters, MmioGicDistributorRegisters, PriorityRegister,
|
InterfaceControl, InterruptSignalRegister, MmioGicCpuInterfaceRegisters,
|
||||||
|
MmioGicDistributorRegisters, PriorityRegister,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SPURIOUS_INTERRUPT_ID: u32 = 1023;
|
const SPURIOUS_INTERRUPT_ID: u32 = 1023;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! Low-level GPIO access module.
|
//! Low-level GPIO access module.
|
||||||
use embedded_hal::digital::PinState;
|
use embedded_hal::digital::PinState;
|
||||||
use zynq7000::gpio::{Registers, MaskedOutput, MmioRegisters};
|
use zynq7000::gpio::{MaskedOutput, MmioRegisters, Registers};
|
||||||
|
|
||||||
use crate::slcr::Slcr;
|
use crate::slcr::Slcr;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
use arbitrary_int::{u2, u3, u6};
|
use arbitrary_int::{u2, u3, u6};
|
||||||
use embedded_hal::i2c::NoAcknowledgeSource;
|
use embedded_hal::i2c::NoAcknowledgeSource;
|
||||||
use zynq7000::{
|
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,
|
slcr::reset::DualClockReset,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,110 @@ use zynq7000::{
|
|||||||
slcr::{clocks::SrcSelIo, reset::DualRefAndClockReset},
|
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<Mio16> {}
|
||||||
|
impl Sdio0ClockPin for Pin<Mio28> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio0ClockPin for Pin<Mio40> {}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio0CommandPin for Pin<Mio17> {}
|
||||||
|
impl Sdio0CommandPin for Pin<Mio29> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio0CommandPin for Pin<Mio41> {}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio0Data0Pin for Pin<Mio18> {}
|
||||||
|
impl Sdio0Data0Pin for Pin<Mio30> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio0Data0Pin for Pin<Mio42> {}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio0Data1Pin for Pin<Mio19> {}
|
||||||
|
impl Sdio0Data1Pin for Pin<Mio31> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio0Data1Pin for Pin<Mio43> {}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio0Data2Pin for Pin<Mio20> {}
|
||||||
|
impl Sdio0Data2Pin for Pin<Mio32> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio0Data2Pin for Pin<Mio44> {}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio0Data3Pin for Pin<Mio21> {}
|
||||||
|
impl Sdio0Data3Pin for Pin<Mio33> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio0Data3Pin for Pin<Mio45> {}
|
||||||
|
|
||||||
|
pub trait Sdio1ClockPin {}
|
||||||
|
pub trait Sdio1CommandPin {}
|
||||||
|
pub trait Sdio1Data0Pin {}
|
||||||
|
pub trait Sdio1Data1Pin {}
|
||||||
|
pub trait Sdio1Data2Pin {}
|
||||||
|
pub trait Sdio1Data3Pin {}
|
||||||
|
|
||||||
|
impl Sdio1ClockPin for Pin<Mio12> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio1ClockPin for Pin<Mio24> {}
|
||||||
|
impl Sdio1ClockPin for Pin<Mio36> {}
|
||||||
|
impl Sdio1ClockPin for Pin<Mio48> {}
|
||||||
|
|
||||||
|
impl Sdio1CommandPin for Pin<Mio11> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio1CommandPin for Pin<Mio23> {}
|
||||||
|
impl Sdio1CommandPin for Pin<Mio35> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio1CommandPin for Pin<Mio47> {}
|
||||||
|
|
||||||
|
impl Sdio1Data0Pin for Pin<Mio10> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio1Data0Pin for Pin<Mio22> {}
|
||||||
|
impl Sdio1Data0Pin for Pin<Mio34> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio1Data0Pin for Pin<Mio46> {}
|
||||||
|
|
||||||
|
impl Sdio1Data1Pin for Pin<Mio13> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio1Data1Pin for Pin<Mio25> {}
|
||||||
|
impl Sdio1Data1Pin for Pin<Mio37> {}
|
||||||
|
impl Sdio1Data1Pin for Pin<Mio49> {}
|
||||||
|
|
||||||
|
impl Sdio1Data2Pin for Pin<Mio14> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio1Data2Pin for Pin<Mio26> {}
|
||||||
|
impl Sdio1Data2Pin for Pin<Mio38> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio1Data2Pin for Pin<Mio50> {}
|
||||||
|
|
||||||
|
impl Sdio1Data2Pin for Pin<Mio15> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio1Data3Pin for Pin<Mio27> {}
|
||||||
|
impl Sdio1Data3Pin for Pin<Mio39> {}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl Sdio1Data3Pin for Pin<Mio51> {}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum SdioId {
|
pub enum SdioId {
|
||||||
@@ -11,6 +114,10 @@ pub enum SdioId {
|
|||||||
Sdio1,
|
Sdio1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Sdio {}
|
||||||
|
|
||||||
|
impl Sdio {}
|
||||||
|
|
||||||
pub struct SdioDivisors {
|
pub struct SdioDivisors {
|
||||||
/// Divisor which will be used during the initialization phase when ACMD41 is issued.
|
/// Divisor which will be used during the initialization phase when ACMD41 is issued.
|
||||||
///
|
///
|
||||||
@@ -22,10 +129,50 @@ pub struct SdioDivisors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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.
|
/// Reset the UART peripheral using the SLCR reset register for UART.
|
||||||
///
|
///
|
||||||
/// Please note that this function will interfere with an already configured
|
/// Please note that this function will interfere with an already configured
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ pub use embedded_hal::spi::Mode;
|
|||||||
use embedded_hal::spi::SpiBus as _;
|
use embedded_hal::spi::SpiBus as _;
|
||||||
use zynq7000::slcr::reset::DualRefAndClockReset;
|
use zynq7000::slcr::reset::DualRefAndClockReset;
|
||||||
use zynq7000::spi::{
|
use zynq7000::spi::{
|
||||||
BaudDivSel, DelayControl, FifoWrite, InterruptControl, InterruptMask, InterruptStatus, MmioRegisters,
|
BaudDivSel, DelayControl, FifoWrite, InterruptControl, InterruptMask, InterruptStatus,
|
||||||
SPI_0_BASE_ADDR, SPI_1_BASE_ADDR,
|
MmioRegisters, SPI_0_BASE_ADDR, SPI_1_BASE_ADDR,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const FIFO_DEPTH: usize = 128;
|
pub const FIFO_DEPTH: usize = 128;
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ use libm::round;
|
|||||||
use zynq7000::{
|
use zynq7000::{
|
||||||
slcr::reset::DualRefAndClockReset,
|
slcr::reset::DualRefAndClockReset,
|
||||||
uart::{
|
uart::{
|
||||||
BaudRateDivisor, Baudgen, ChMode, ClockSelect, FifoTrigger, InterruptControl, MmioRegisters,
|
BaudRateDivisor, Baudgen, ChMode, ClockSelect, FifoTrigger, InterruptControl,
|
||||||
Mode, UART_0_BASE, UART_1_BASE,
|
MmioRegisters, Mode, UART_0_BASE, UART_1_BASE,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ pub mod l2_cache;
|
|||||||
pub mod mpcore;
|
pub mod mpcore;
|
||||||
pub mod priv_tim;
|
pub mod priv_tim;
|
||||||
pub mod qspi;
|
pub mod qspi;
|
||||||
|
pub mod sdio;
|
||||||
pub mod slcr;
|
pub mod slcr;
|
||||||
pub mod spi;
|
pub mod spi;
|
||||||
pub mod ttc;
|
pub mod ttc;
|
||||||
pub mod uart;
|
pub mod uart;
|
||||||
pub mod sdio;
|
|
||||||
pub mod xadc;
|
pub mod xadc;
|
||||||
|
|
||||||
static PERIPHERALS_TAKEN: AtomicBool = AtomicBool::new(false);
|
static PERIPHERALS_TAKEN: AtomicBool = AtomicBool::new(false);
|
||||||
|
|||||||
@@ -4,8 +4,11 @@
|
|||||||
use static_assertions::const_assert_eq;
|
use static_assertions::const_assert_eq;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
gic::{GicCpuInterfaceRegisters, GicDistributorRegisters, MmioGicCpuInterfaceRegisters, MmioGicDistributorRegisters},
|
gic::{
|
||||||
gtc::{Registers, MmioRegisters},
|
GicCpuInterfaceRegisters, GicDistributorRegisters, MmioGicCpuInterfaceRegisters,
|
||||||
|
MmioGicDistributorRegisters,
|
||||||
|
},
|
||||||
|
gtc::{MmioRegisters, Registers},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const MPCORE_BASE_ADDR: usize = 0xF8F0_0000;
|
pub const MPCORE_BASE_ADDR: usize = 0xF8F0_0000;
|
||||||
|
|||||||
Reference in New Issue
Block a user