diff --git a/zynq7000/src/slcr.rs b/zynq7000/src/slcr.rs index 265018b..ed309e1 100644 --- a/zynq7000/src/slcr.rs +++ b/zynq7000/src/slcr.rs @@ -3,6 +3,8 @@ const SLCR_BASE_ADDR: usize = 0xF8000000; const CLOCK_CONTROL_OFFSET: usize = 0x100; const RESET_BLOCK_OFFSET: usize = 0x200; +const GPIOB_OFFSET: usize = 0xB00; +const DDRIOB_OFFSET: usize = 0xB40; #[derive(derive_mmio::Mmio)] #[repr(C)] @@ -44,6 +46,14 @@ pub struct ResetControl { } impl ResetControl { + /// Create a new handle to this peripheral. + /// + /// Writing to this register requires unlocking the SLCR registers first. + /// + /// # Safety + /// + /// If you create multiple instances of this handle at the same time, you are responsible for + /// ensuring that there are no read-modify-write races on any of the registers. pub fn new_mmio_fixed() -> MmioResetControl<'static> { MmioResetControl { ptr: (SLCR_BASE_ADDR + RESET_BLOCK_OFFSET) as *mut ResetControl, @@ -107,7 +117,15 @@ pub struct ClockControl { } impl ClockControl { - pub fn new_mmio_fixed() -> MmioClockControl<'static> { + /// Create a new handle to this peripheral. + /// + /// Writing to this register requires unlocking the SLCR registers first. + /// + /// # Safety + /// + /// If you create multiple instances of this handle at the same time, you are responsible for + /// ensuring that there are no read-modify-write races on any of the registers. + pub unsafe fn new_mmio_fixed() -> MmioClockControl<'static> { MmioClockControl { ptr: (SLCR_BASE_ADDR + CLOCK_CONTROL_OFFSET) as *mut ClockControl, phantom: core::marker::PhantomData, @@ -124,6 +142,89 @@ impl ClockControl { static_assertions::const_assert_eq!(core::mem::size_of::(), 0xC8); +#[derive(derive_mmio::Mmio)] +#[mmio(no_ctors)] +#[repr(C)] +pub struct DdrIoB { + ddriob_addr0: u32, + ddriob_addr1: u32, + ddriob_data0: u32, + ddriob_data1: u32, + ddriob_diff0: u32, + ddriob_diff1: u32, + ddriob_clock: u32, + ddriob_drive_slew_addr: u32, + ddriob_drive_slew_data: u32, + ddriob_drive_slew_diff: u32, + ddriob_drive_slew_clock: u32, + ddriob_ddr_ctrl: u32, + ddriob_dci_ctrl: u32, + ddriob_dci_status: u32, +} + +impl DdrIoB { + /// Create a new handle to this peripheral. + /// + /// Writing to this register requires unlocking the SLCR registers first. + /// + /// # Safety + /// + /// If you create multiple instances of this handle at the same time, you are responsible for + /// ensuring that there are no read-modify-write races on any of the registers. + pub fn new_mmio_fixed() -> MmioDdrIoB<'static> { + MmioDdrIoB { + ptr: (SLCR_BASE_ADDR + DDRIOB_OFFSET) as *mut _, + phantom: core::marker::PhantomData, + } + } + + fn new_mmio(reg: *mut DdrIoB) -> MmioDdrIoB<'static> { + MmioDdrIoB { + ptr: reg, + phantom: core::marker::PhantomData, + } + } +} + +static_assertions::const_assert_eq!(core::mem::size_of::(), 0x38); + +#[derive(derive_mmio::Mmio)] +#[mmio(no_ctors)] +#[repr(C)] +pub struct GpiobCtrl { + ctrl: u32, + cfg_cmos18: u32, + cfg_cmos25: u32, + cfg_cmos33: u32, + _gap17: u32, + cfg_hstl: u32, + drvr_bias_ctrl: u32, +} + +impl GpiobCtrl { + /// Create a new handle to this peripheral. + /// + /// Writing to this register requires unlocking the SLCR registers first. + /// + /// # Safety + /// + /// If you create multiple instances of this handle at the same time, you are responsible for + /// ensuring that there are no read-modify-write races on any of the registers. + pub fn new_mmio_fixed() -> MmioGpiobCtrl<'static> { + MmioGpiobCtrl { + ptr: (SLCR_BASE_ADDR + GPIOB_OFFSET) as *mut _, + phantom: core::marker::PhantomData, + } + } + + fn new_mmio(reg: *mut Self) -> MmioGpiobCtrl<'static> { + MmioGpiobCtrl { + ptr: reg, + phantom: core::marker::PhantomData, + } + } +} + #[derive(derive_mmio::Mmio)] #[mmio(no_ctors)] #[repr(C)] @@ -178,7 +279,7 @@ pub struct Slcr { ddr_urgent_sel: u32, ddr_dfi_status: u32, - _gap9: [u32; 56], + _gap9: [u32; 55], mio_pins: [u32; 54], @@ -188,15 +289,15 @@ pub struct Slcr { _gap11: u32, mio_mst_tri_0: u32, mio_mst_tri_1: u32, - _gap12: [u32; 8], + _gap12: [u32; 7], sd_0_wp_cd_sel: u32, sd_1_wp_cd_sel: u32, - _gap13: [u32; 51], + _gap13: [u32; 50], lvl_shftr_en: u32, - _gap14: [u32; 4], + _gap14: [u32; 3], ocm_cfg: u32, @@ -206,32 +307,15 @@ pub struct Slcr { _gap16: [u32; 56], - gpiob_ctrl: u32, - gpiob_cfg_cmos18: u32, - gpiob_cfg_cmos25: u32, - gpiob_cfg_cmos33: u32, - _gap17: u32, - gpiob_cfg_hstl: u32, - gpiob_drvr_bias_ctrl: u32, - _gap18: [u32; 9], - ddriob_addr0: u32, - ddriob_addr1: u32, - ddriob_data0: u32, - ddriob_data1: u32, - ddriob_diff0: u32, - ddriob_diff1: u32, - ddriob_clock: u32, - ddriob_drive_slew_addr: u32, - ddriob_drive_slew_data: u32, - ddriob_drive_slew_diff: u32, - ddriob_drive_slew_clock: u32, - ddriob_ddr_ctrl: u32, - ddriob_dci_ctrl: u32, - ddriob_dci_status: u32, + #[mmio(inner)] + gpiob: GpiobCtrl, + + #[mmio(inner)] + ddriob: DdrIoB, } -//static_assertions::const_assert_eq!(core::mem::size_of::(), 0xB78); +static_assertions::const_assert_eq!(core::mem::size_of::(), 0xB78); pub type SystemLevelControlRegisters = Slcr;