continue
This commit is contained in:
@@ -38,6 +38,7 @@ pub mod log;
|
|||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
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 time;
|
pub mod time;
|
||||||
|
|||||||
59
zynq/zynq7000-hal/src/sdio.rs
Normal file
59
zynq/zynq7000-hal/src/sdio.rs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
use zynq7000::{
|
||||||
|
sdio::SdClockDivisor,
|
||||||
|
slcr::{clocks::SrcSelIo, reset::DualRefAndClockReset},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{clocks::Clocks, slcr::Slcr, time::Hertz};
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
pub enum SdioId {
|
||||||
|
Sdio0,
|
||||||
|
Sdio1,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SdioDivisors {
|
||||||
|
/// Divisor which will be used during the initialization phase when ACMD41 is issued.
|
||||||
|
///
|
||||||
|
/// The SD card specification mentions that the clock needs to be between 100 and 400 kHz for
|
||||||
|
/// that phase.
|
||||||
|
pub divisor_init_phase: SdClockDivisor,
|
||||||
|
/// Divisor for the regular data transfer phase. Common target speeds are 25 MHz or 50 MHz.
|
||||||
|
pub divisor_normal: SdClockDivisor,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SdioDivisors {
|
||||||
|
pub fn calculate(src_sel: SrcSelIo, clocks: &Clocks, target_speed: Hertz) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Reset the UART peripheral using the SLCR reset register for UART.
|
||||||
|
///
|
||||||
|
/// Please note that this function will interfere with an already configured
|
||||||
|
/// UART instance.
|
||||||
|
#[inline]
|
||||||
|
pub fn reset(id: SdioId, cycles: u32) {
|
||||||
|
let assert_reset = match id {
|
||||||
|
SdioId::Sdio0 => DualRefAndClockReset::builder()
|
||||||
|
.with_periph1_ref_rst(false)
|
||||||
|
.with_periph0_ref_rst(true)
|
||||||
|
.with_periph1_cpu1x_rst(false)
|
||||||
|
.with_periph0_cpu1x_rst(true)
|
||||||
|
.build(),
|
||||||
|
SdioId::Sdio1 => DualRefAndClockReset::builder()
|
||||||
|
.with_periph1_ref_rst(true)
|
||||||
|
.with_periph0_ref_rst(false)
|
||||||
|
.with_periph1_cpu1x_rst(true)
|
||||||
|
.with_periph0_cpu1x_rst(false)
|
||||||
|
.build(),
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
Slcr::with(|regs| {
|
||||||
|
regs.reset_ctrl().write_sdio(assert_reset);
|
||||||
|
// Keep it in reset for a few cycle.. not sure if this is necessary.
|
||||||
|
for _ in 0..cycles {
|
||||||
|
cortex_ar::asm::nop();
|
||||||
|
}
|
||||||
|
regs.reset_ctrl().write_sdio(DualRefAndClockReset::DEFAULT);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -64,6 +64,8 @@ pub struct Peripherals {
|
|||||||
pub qspi: qspi::MmioRegisters<'static>,
|
pub qspi: qspi::MmioRegisters<'static>,
|
||||||
pub devcfg: devcfg::MmioRegisters<'static>,
|
pub devcfg: devcfg::MmioRegisters<'static>,
|
||||||
pub xadc: xadc::MmioRegisters<'static>,
|
pub xadc: xadc::MmioRegisters<'static>,
|
||||||
|
pub sdio_0: sdio::MmioRegisters<'static>,
|
||||||
|
pub sdio_1: sdio::MmioRegisters<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Peripherals {
|
impl Peripherals {
|
||||||
@@ -104,6 +106,8 @@ impl Peripherals {
|
|||||||
qspi: qspi::Registers::new_mmio_fixed(),
|
qspi: qspi::Registers::new_mmio_fixed(),
|
||||||
devcfg: devcfg::Registers::new_mmio_fixed(),
|
devcfg: devcfg::Registers::new_mmio_fixed(),
|
||||||
xadc: xadc::Registers::new_mmio_fixed(),
|
xadc: xadc::Registers::new_mmio_fixed(),
|
||||||
|
sdio_0: sdio::Registers::new_mmio_fixed_0(),
|
||||||
|
sdio_1: sdio::Registers::new_mmio_fixed_1(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ pub struct HostPowerBlockgapWakeupControl {
|
|||||||
|
|
||||||
#[bitbybit::bitenum(u8, exhaustive = false)]
|
#[bitbybit::bitenum(u8, exhaustive = false)]
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum SdclkFrequencySelect {
|
pub enum SdClockDivisor {
|
||||||
Div256 = 0x80,
|
Div256 = 0x80,
|
||||||
Div128 = 0x40,
|
Div128 = 0x40,
|
||||||
Div64 = 0x20,
|
Div64 = 0x20,
|
||||||
@@ -277,7 +277,7 @@ pub struct ClockAndTimeoutAndSwResetControl {
|
|||||||
#[bits(16..=19, rw)]
|
#[bits(16..=19, rw)]
|
||||||
data_timeout_counter_value: u4,
|
data_timeout_counter_value: u4,
|
||||||
#[bits(8..=15, rw)]
|
#[bits(8..=15, rw)]
|
||||||
sdclk_frequency_select: Option<SdclkFrequencySelect>,
|
sdclk_frequency_select: Option<SdClockDivisor>,
|
||||||
#[bit(2, rw)]
|
#[bit(2, rw)]
|
||||||
sd_clock_enable: bool,
|
sd_clock_enable: bool,
|
||||||
#[bit(1, r)]
|
#[bit(1, r)]
|
||||||
@@ -388,7 +388,6 @@ pub struct InterruptMask {
|
|||||||
transfer_complete: bool,
|
transfer_complete: bool,
|
||||||
#[bit(0, rw)]
|
#[bit(0, rw)]
|
||||||
command_complete: bool,
|
command_complete: bool,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
@@ -430,3 +429,15 @@ pub struct Registers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0x100);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0x100);
|
||||||
|
|
||||||
|
impl Registers {
|
||||||
|
#[inline]
|
||||||
|
pub fn new_mmio_fixed_0() -> MmioRegisters<'static> {
|
||||||
|
unsafe { Self::new_mmio_at(SDIO_BASE_ADDR_0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn new_mmio_fixed_1() -> MmioRegisters<'static> {
|
||||||
|
unsafe { Self::new_mmio_at(SDIO_BASE_ADDR_1) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user