continue
This commit is contained in:
@@ -38,6 +38,7 @@ pub mod log;
|
||||
pub mod prelude;
|
||||
pub mod priv_tim;
|
||||
pub mod qspi;
|
||||
pub mod sdio;
|
||||
pub mod slcr;
|
||||
pub mod spi;
|
||||
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 devcfg: devcfg::MmioRegisters<'static>,
|
||||
pub xadc: xadc::MmioRegisters<'static>,
|
||||
pub sdio_0: sdio::MmioRegisters<'static>,
|
||||
pub sdio_1: sdio::MmioRegisters<'static>,
|
||||
}
|
||||
|
||||
impl Peripherals {
|
||||
@@ -104,6 +106,8 @@ impl Peripherals {
|
||||
qspi: qspi::Registers::new_mmio_fixed(),
|
||||
devcfg: devcfg::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)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum SdclkFrequencySelect {
|
||||
pub enum SdClockDivisor {
|
||||
Div256 = 0x80,
|
||||
Div128 = 0x40,
|
||||
Div64 = 0x20,
|
||||
@@ -277,7 +277,7 @@ pub struct ClockAndTimeoutAndSwResetControl {
|
||||
#[bits(16..=19, rw)]
|
||||
data_timeout_counter_value: u4,
|
||||
#[bits(8..=15, rw)]
|
||||
sdclk_frequency_select: Option<SdclkFrequencySelect>,
|
||||
sdclk_frequency_select: Option<SdClockDivisor>,
|
||||
#[bit(2, rw)]
|
||||
sd_clock_enable: bool,
|
||||
#[bit(1, r)]
|
||||
@@ -388,7 +388,6 @@ pub struct InterruptMask {
|
||||
transfer_complete: bool,
|
||||
#[bit(0, rw)]
|
||||
command_complete: bool,
|
||||
|
||||
}
|
||||
|
||||
#[derive(derive_mmio::Mmio)]
|
||||
@@ -430,3 +429,15 @@ pub struct Registers {
|
||||
}
|
||||
|
||||
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