rename register blocks
This commit is contained in:
8
tools/Cargo.lock
generated
8
tools/Cargo.lock
generated
@@ -744,7 +744,7 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zynq7000"
|
name = "zynq7000"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arbitrary-int 2.0.0",
|
"arbitrary-int 2.0.0",
|
||||||
"bitbybit",
|
"bitbybit",
|
||||||
@@ -766,8 +766,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zynq7000-mmu"
|
name = "zynq7000-mmu"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"arm-targets",
|
||||||
"cortex-ar",
|
"cortex-ar",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
@@ -788,9 +789,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zynq7000-rt"
|
name = "zynq7000-rt"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arbitrary-int 2.0.0",
|
"arbitrary-int 2.0.0",
|
||||||
|
"arm-targets",
|
||||||
"cortex-ar",
|
"cortex-ar",
|
||||||
"zynq7000-mmu",
|
"zynq7000-mmu",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
|||||||
|
|
||||||
#[unsafe(export_name = "main")]
|
#[unsafe(export_name = "main")]
|
||||||
pub fn main() -> ! {
|
pub fn main() -> ! {
|
||||||
l2_cache::init_with_defaults(&mut unsafe { zynq7000::l2_cache::L2Cache::new_mmio_fixed() });
|
l2_cache::init_with_defaults(&mut unsafe { zynq7000::l2_cache::Registers::new_mmio_fixed() });
|
||||||
match LIB {
|
match LIB {
|
||||||
Lib::Pac => {
|
Lib::Pac => {
|
||||||
let mut gpio = unsafe { zynq7000::gpio::Gpio::new_mmio_fixed() };
|
let mut gpio = unsafe { zynq7000::gpio::Registers::new_mmio_fixed() };
|
||||||
gpio.bank_0().modify_dirm(|v| v | ZEDBOARD_LED_MASK);
|
gpio.bank_0().modify_dirm(|v| v | ZEDBOARD_LED_MASK);
|
||||||
gpio.bank_0().modify_out_en(|v| v | ZEDBOARD_LED_MASK);
|
gpio.bank_0().modify_out_en(|v| v | ZEDBOARD_LED_MASK);
|
||||||
loop {
|
loop {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use cortex_ar::{
|
|||||||
invalidate_data_cache_line_to_poc,
|
invalidate_data_cache_line_to_poc,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use zynq7000::l2_cache::{L2Cache, MmioL2Cache};
|
use zynq7000::l2_cache::{MmioRegisters, Registers};
|
||||||
|
|
||||||
pub const CACHE_LINE_SIZE: usize = 32;
|
pub const CACHE_LINE_SIZE: usize = 32;
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ pub const CACHE_LINE_SIZE: usize = 32;
|
|||||||
#[error("alignment error, addresses and lengths must be aligned to 32 byte cache line length")]
|
#[error("alignment error, addresses and lengths must be aligned to 32 byte cache line length")]
|
||||||
pub struct AlignmentError;
|
pub struct AlignmentError;
|
||||||
|
|
||||||
pub fn clean_and_invalidate_l2c_line(l2c: &mut MmioL2Cache<'static>, addr: u32) {
|
pub fn clean_and_invalidate_l2c_line(l2c: &mut MmioRegisters<'static>, addr: u32) {
|
||||||
l2c.write_clean_by_pa(addr);
|
l2c.write_clean_by_pa(addr);
|
||||||
l2c.write_invalidate_by_pa(addr);
|
l2c.write_invalidate_by_pa(addr);
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ pub fn clean_and_invalidate_data_cache() {
|
|||||||
dsb();
|
dsb();
|
||||||
|
|
||||||
// Clean all ways in L2 cache.
|
// Clean all ways in L2 cache.
|
||||||
let mut l2c = unsafe { L2Cache::new_mmio_fixed() };
|
let mut l2c = unsafe { Registers::new_mmio_fixed() };
|
||||||
l2c.write_clean_invalidate_by_way(0xffff);
|
l2c.write_clean_invalidate_by_way(0xffff);
|
||||||
while l2c.read_cache_sync().busy() {}
|
while l2c.read_cache_sync().busy() {}
|
||||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
@@ -54,7 +54,7 @@ pub fn invalidate_data_cache_range(addr: u32, len: usize) -> Result<(), Alignmen
|
|||||||
}
|
}
|
||||||
let mut current_addr = addr;
|
let mut current_addr = addr;
|
||||||
let end_addr = addr.saturating_add(len as u32);
|
let end_addr = addr.saturating_add(len as u32);
|
||||||
let mut l2c = unsafe { L2Cache::new_mmio_fixed() };
|
let mut l2c = unsafe { Registers::new_mmio_fixed() };
|
||||||
|
|
||||||
dsb();
|
dsb();
|
||||||
// Invalidate outer caches lines first, see chapter 3.3.10 of the L2C technical reference
|
// Invalidate outer caches lines first, see chapter 3.3.10 of the L2C technical reference
|
||||||
@@ -103,7 +103,7 @@ pub fn clean_and_invalidate_data_cache_range(addr: u32, len: usize) -> Result<()
|
|||||||
dsb();
|
dsb();
|
||||||
|
|
||||||
// Clean and invalidates outer cache.
|
// Clean and invalidates outer cache.
|
||||||
let mut l2c = unsafe { L2Cache::new_mmio_fixed() };
|
let mut l2c = unsafe { Registers::new_mmio_fixed() };
|
||||||
current_addr = addr;
|
current_addr = addr;
|
||||||
while current_addr < end_addr {
|
while current_addr < end_addr {
|
||||||
// ARM errate 588369 specifies that clean and invalidate need to be separate, but the
|
// ARM errate 588369 specifies that clean and invalidate need to be separate, but the
|
||||||
@@ -155,7 +155,7 @@ pub fn clean_data_cache_range(addr: u32, len: usize) -> Result<(), AlignmentErro
|
|||||||
dsb();
|
dsb();
|
||||||
|
|
||||||
// Clean and invalidates outer cache.
|
// Clean and invalidates outer cache.
|
||||||
let mut l2c = unsafe { L2Cache::new_mmio_fixed() };
|
let mut l2c = unsafe { Registers::new_mmio_fixed() };
|
||||||
current_addr = addr;
|
current_addr = addr;
|
||||||
while current_addr < end_addr {
|
while current_addr < end_addr {
|
||||||
l2c.write_clean_by_pa(current_addr);
|
l2c.write_clean_by_pa(current_addr);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use arbitrary_int::{prelude::*, u6};
|
|||||||
pub mod pll;
|
pub mod pll;
|
||||||
|
|
||||||
use zynq7000::slcr::{
|
use zynq7000::slcr::{
|
||||||
ClockControl,
|
ClockControlRegisters,
|
||||||
clocks::{
|
clocks::{
|
||||||
ClockkRatioSelect, DualCommonPeriphIoClockControl, FpgaClockControl, GigEthClockControl,
|
ClockkRatioSelect, DualCommonPeriphIoClockControl, FpgaClockControl, GigEthClockControl,
|
||||||
SingleCommonPeriphIoClockControl,
|
SingleCommonPeriphIoClockControl,
|
||||||
@@ -254,7 +254,7 @@ impl Clocks {
|
|||||||
/// It assumes that the clock already has been configured, for example by a first-stage
|
/// It assumes that the clock already has been configured, for example by a first-stage
|
||||||
/// bootloader, or the PS7 initialization script.
|
/// bootloader, or the PS7 initialization script.
|
||||||
pub fn new_from_regs(ps_clk_freq: Hertz) -> Result<Self, ClockReadError> {
|
pub fn new_from_regs(ps_clk_freq: Hertz) -> Result<Self, ClockReadError> {
|
||||||
let mut clk_regs = unsafe { ClockControl::new_mmio_fixed() };
|
let mut clk_regs = unsafe { ClockControlRegisters::new_mmio_fixed() };
|
||||||
|
|
||||||
let arm_pll_cfg = clk_regs.read_arm_pll_ctrl();
|
let arm_pll_cfg = clk_regs.read_arm_pll_ctrl();
|
||||||
let io_pll_cfg = clk_regs.read_io_pll_ctrl();
|
let io_pll_cfg = clk_regs.read_io_pll_ctrl();
|
||||||
@@ -505,7 +505,7 @@ impl Clocks {
|
|||||||
/// The reference clock will only be the RX clock in loopback mode. For the TX block,
|
/// The reference clock will only be the RX clock in loopback mode. For the TX block,
|
||||||
/// the reference clock is used if the EMIO enable bit `GEM{0,1}_CLK_CTRL[6]` is set to 0.
|
/// the reference clock is used if the EMIO enable bit `GEM{0,1}_CLK_CTRL[6]` is set to 0.
|
||||||
pub fn calculate_gem_0_ref_clock(&self) -> Result<Hertz, DivisorZero> {
|
pub fn calculate_gem_0_ref_clock(&self) -> Result<Hertz, DivisorZero> {
|
||||||
let clk_regs = unsafe { ClockControl::new_mmio_fixed() };
|
let clk_regs = unsafe { ClockControlRegisters::new_mmio_fixed() };
|
||||||
self.calculate_gem_ref_clock(clk_regs.read_gem_0_clk_ctrl(), ClockModuleId::Gem0)
|
self.calculate_gem_ref_clock(clk_regs.read_gem_0_clk_ctrl(), ClockModuleId::Gem0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,7 +518,7 @@ impl Clocks {
|
|||||||
/// The reference clock will only be the RX clock in loopback mode. For the TX block,
|
/// The reference clock will only be the RX clock in loopback mode. For the TX block,
|
||||||
/// the reference clock is used if the EMIO enable bit `GEM{0,1}_CLK_CTRL[6]` is set to 0.
|
/// the reference clock is used if the EMIO enable bit `GEM{0,1}_CLK_CTRL[6]` is set to 0.
|
||||||
pub fn calculate_gem_1_ref_clock(&self) -> Result<Hertz, DivisorZero> {
|
pub fn calculate_gem_1_ref_clock(&self) -> Result<Hertz, DivisorZero> {
|
||||||
let clk_regs = unsafe { ClockControl::new_mmio_fixed() };
|
let clk_regs = unsafe { ClockControlRegisters::new_mmio_fixed() };
|
||||||
self.calculate_gem_ref_clock(clk_regs.read_gem_0_clk_ctrl(), ClockModuleId::Gem1)
|
self.calculate_gem_ref_clock(clk_regs.read_gem_0_clk_ctrl(), ClockModuleId::Gem1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ unsafe fn configure_pll_unchecked(
|
|||||||
boot_mode: BootMode,
|
boot_mode: BootMode,
|
||||||
cfg: PllConfig,
|
cfg: PllConfig,
|
||||||
pll_type: PllType,
|
pll_type: PllType,
|
||||||
slcr: &mut zynq7000::slcr::MmioSlcr<'static>,
|
slcr: &mut zynq7000::slcr::MmioRegisters<'static>,
|
||||||
pll_ctrl_reg: *mut zynq7000::slcr::clocks::PllControl,
|
pll_ctrl_reg: *mut zynq7000::slcr::clocks::PllControl,
|
||||||
pll_cfg_reg: *mut zynq7000::slcr::clocks::PllConfig,
|
pll_cfg_reg: *mut zynq7000::slcr::clocks::PllConfig,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! Low-level DDR configuration module.
|
//! Low-level DDR configuration module.
|
||||||
use arbitrary_int::{prelude::*, u2, u3, u6};
|
use arbitrary_int::{prelude::*, u2, u3, u6};
|
||||||
use zynq7000::ddrc::{MmioDdrController, regs::*};
|
use zynq7000::ddrc::{MmioRegisters, regs::*};
|
||||||
use zynq7000::slcr::{clocks::DciClockControl, ddriob::DdriobConfig};
|
use zynq7000::slcr::{clocks::DciClockControl, ddriob::DdriobConfig};
|
||||||
|
|
||||||
use crate::{clocks::DdrClocks, time::Hertz};
|
use crate::{clocks::DdrClocks, time::Hertz};
|
||||||
@@ -272,7 +272,7 @@ pub struct DdrcConfigSet {
|
|||||||
///
|
///
|
||||||
/// It does NOT take care of taking the DDR controller out of reset and polling for DDR
|
/// It does NOT take care of taking the DDR controller out of reset and polling for DDR
|
||||||
/// configuration completion.
|
/// configuration completion.
|
||||||
pub fn configure_ddr_config(ddrc: &mut MmioDdrController<'static>, cfg_set: &DdrcConfigSet) {
|
pub fn configure_ddr_config(ddrc: &mut MmioRegisters<'static>, cfg_set: &DdrcConfigSet) {
|
||||||
ddrc.write_ddrc_ctrl(cfg_set.ctrl);
|
ddrc.write_ddrc_ctrl(cfg_set.ctrl);
|
||||||
// Write all configuration registers.
|
// Write all configuration registers.
|
||||||
ddrc.write_two_rank_cfg(cfg_set.two_rank);
|
ddrc.write_two_rank_cfg(cfg_set.two_rank);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
//!
|
//!
|
||||||
//! - [Zedboard FSBL](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zedboard-fsbl)
|
//! - [Zedboard FSBL](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zedboard-fsbl)
|
||||||
use arbitrary_int::u6;
|
use arbitrary_int::u6;
|
||||||
use zynq7000::ddrc::MmioDdrController;
|
use zynq7000::ddrc::MmioRegisters;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
BootMode,
|
BootMode,
|
||||||
@@ -48,7 +48,7 @@ impl DdrClockSetupConfig {
|
|||||||
/// This function consumes the DDRC register block once and thus provides a safe interface for DDR
|
/// This function consumes the DDRC register block once and thus provides a safe interface for DDR
|
||||||
/// initialization.
|
/// initialization.
|
||||||
pub fn configure_ddr_for_ddr3(
|
pub fn configure_ddr_for_ddr3(
|
||||||
mut ddrc_regs: MmioDdrController<'static>,
|
mut ddrc_regs: MmioRegisters<'static>,
|
||||||
boot_mode: BootMode,
|
boot_mode: BootMode,
|
||||||
clk_setup_cfg: DdrClockSetupConfig,
|
clk_setup_cfg: DdrClockSetupConfig,
|
||||||
ddriob_cfg: &DdriobConfigSet,
|
ddriob_cfg: &DdriobConfigSet,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub fn configure_bitstream_non_secure(
|
|||||||
if bitstream.is_empty() {
|
if bitstream.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let mut devcfg = unsafe { zynq7000::devcfg::DevCfg::new_mmio_fixed() };
|
let mut devcfg = unsafe { zynq7000::devcfg::Registers::new_mmio_fixed() };
|
||||||
devcfg.modify_control(|mut val| {
|
devcfg.modify_control(|mut val| {
|
||||||
val.set_config_access_select(zynq7000::devcfg::PlConfigAccess::ConfigAccessPort);
|
val.set_config_access_select(zynq7000::devcfg::PlConfigAccess::ConfigAccessPort);
|
||||||
val.set_access_port_select(zynq7000::devcfg::ConfigAccessPortSelect::Pcap);
|
val.set_access_port_select(zynq7000::devcfg::ConfigAccessPortSelect::Pcap);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use super::{EthernetId, PsEthernet as _};
|
|||||||
|
|
||||||
pub struct EthernetLowLevel {
|
pub struct EthernetLowLevel {
|
||||||
id: EthernetId,
|
id: EthernetId,
|
||||||
pub regs: zynq7000::eth::MmioEthernet<'static>,
|
pub regs: zynq7000::eth::MmioRegisters<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
@@ -177,7 +177,7 @@ impl ClockDivSet {
|
|||||||
impl EthernetLowLevel {
|
impl EthernetLowLevel {
|
||||||
/// Creates a new instance of the Ethernet low-level interface.
|
/// Creates a new instance of the Ethernet low-level interface.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(regs: zynq7000::eth::MmioEthernet<'static>) -> Option<Self> {
|
pub fn new(regs: zynq7000::eth::MmioRegisters<'static>) -> Option<Self> {
|
||||||
regs.id()?;
|
regs.id()?;
|
||||||
Some(EthernetLowLevel {
|
Some(EthernetLowLevel {
|
||||||
id: regs.id().unwrap(),
|
id: regs.id().unwrap(),
|
||||||
@@ -196,8 +196,8 @@ impl EthernetLowLevel {
|
|||||||
id,
|
id,
|
||||||
regs: unsafe {
|
regs: unsafe {
|
||||||
match id {
|
match id {
|
||||||
EthernetId::Eth0 => zynq7000::eth::Ethernet::new_mmio_fixed_0(),
|
EthernetId::Eth0 => zynq7000::eth::Registers::new_mmio_fixed_0(),
|
||||||
EthernetId::Eth1 => zynq7000::eth::Ethernet::new_mmio_fixed_1(),
|
EthernetId::Eth1 => zynq7000::eth::Registers::new_mmio_fixed_1(),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use zynq7000::eth::{MdcClockDivisor, PhyMaintenance};
|
|||||||
use super::{EthernetId, ll::EthernetLowLevel};
|
use super::{EthernetId, ll::EthernetLowLevel};
|
||||||
|
|
||||||
pub struct Mdio {
|
pub struct Mdio {
|
||||||
regs: zynq7000::eth::MmioEthernet<'static>,
|
regs: zynq7000::eth::MmioRegisters<'static>,
|
||||||
clause22: bool,
|
clause22: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use arbitrary_int::{u2, u3};
|
|||||||
pub use zynq7000::eth::MdcClockDivisor;
|
pub use zynq7000::eth::MdcClockDivisor;
|
||||||
use zynq7000::eth::{
|
use zynq7000::eth::{
|
||||||
BurstLength, DmaRxBufSize, GEM_0_BASE_ADDR, GEM_1_BASE_ADDR, InterruptControl, InterruptStatus,
|
BurstLength, DmaRxBufSize, GEM_0_BASE_ADDR, GEM_1_BASE_ADDR, InterruptControl, InterruptStatus,
|
||||||
MmioEthernet, RxStatus, TxStatus,
|
MmioRegisters, RxStatus, TxStatus,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use ll::{ClockConfig, ClockDivSet, Duplex, EthernetLowLevel, Speed};
|
pub use ll::{ClockConfig, ClockDivSet, Duplex, EthernetLowLevel, Speed};
|
||||||
@@ -58,18 +58,18 @@ impl EthernetId {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// Circumvents ownership and safety guarantees of the HAL.
|
/// Circumvents ownership and safety guarantees of the HAL.
|
||||||
pub const unsafe fn steal_regs(&self) -> zynq7000::eth::MmioEthernet<'static> {
|
pub const unsafe fn steal_regs(&self) -> zynq7000::eth::MmioRegisters<'static> {
|
||||||
unsafe {
|
unsafe {
|
||||||
match self {
|
match self {
|
||||||
EthernetId::Eth0 => zynq7000::eth::Ethernet::new_mmio_fixed_0(),
|
EthernetId::Eth0 => zynq7000::eth::Registers::new_mmio_fixed_0(),
|
||||||
EthernetId::Eth1 => zynq7000::eth::Ethernet::new_mmio_fixed_1(),
|
EthernetId::Eth1 => zynq7000::eth::Registers::new_mmio_fixed_1(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clk_config_regs(
|
pub fn clk_config_regs(
|
||||||
&self,
|
&self,
|
||||||
slcr: &mut zynq7000::slcr::MmioSlcr<'static>,
|
slcr: &mut zynq7000::slcr::MmioRegisters<'static>,
|
||||||
) -> (
|
) -> (
|
||||||
*mut zynq7000::slcr::clocks::GigEthClockControl,
|
*mut zynq7000::slcr::clocks::GigEthClockControl,
|
||||||
*mut zynq7000::slcr::clocks::GigEthRclkControl,
|
*mut zynq7000::slcr::clocks::GigEthRclkControl,
|
||||||
@@ -88,13 +88,13 @@ impl EthernetId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait PsEthernet {
|
pub trait PsEthernet {
|
||||||
fn reg_block(&self) -> MmioEthernet<'static>;
|
fn reg_block(&self) -> MmioRegisters<'static>;
|
||||||
fn id(&self) -> Option<EthernetId>;
|
fn id(&self) -> Option<EthernetId>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PsEthernet for MmioEthernet<'static> {
|
impl PsEthernet for MmioRegisters<'static> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reg_block(&self) -> MmioEthernet<'static> {
|
fn reg_block(&self) -> MmioRegisters<'static> {
|
||||||
unsafe { self.clone() }
|
unsafe { self.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,7 +599,7 @@ impl Ethernet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn regs(&mut self) -> &MmioEthernet<'static> {
|
pub fn regs(&mut self) -> &MmioRegisters<'static> {
|
||||||
&self.ll.regs
|
&self.ll.regs
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,7 +613,7 @@ impl Ethernet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn regs_mut(&mut self) -> &mut MmioEthernet<'static> {
|
pub fn regs_mut(&mut self) -> &mut MmioRegisters<'static> {
|
||||||
&mut self.ll.regs
|
&mut self.ll.regs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ use arbitrary_int::prelude::*;
|
|||||||
|
|
||||||
use cortex_ar::interrupt;
|
use cortex_ar::interrupt;
|
||||||
use zynq7000::gic::{
|
use zynq7000::gic::{
|
||||||
DistributorControlRegister, GicCpuInterface, GicDistributor, InterfaceControl,
|
DistributorControlRegister, GicCpuInterfaceRegisters, GicDistributorRegisters,
|
||||||
InterruptSignalRegister, MmioGicCpuInterface, MmioGicDistributor, PriorityRegister,
|
InterfaceControl, InterruptSignalRegister, MmioGicCpuInterfaceRegisters,
|
||||||
|
MmioGicDistributorRegisters, PriorityRegister,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SPURIOUS_INTERRUPT_ID: u32 = 1023;
|
const SPURIOUS_INTERRUPT_ID: u32 = 1023;
|
||||||
@@ -224,8 +225,8 @@ pub struct InvalidSgiInterruptId(pub usize);
|
|||||||
/// For the handling of the interrupts, you can use the [GicInterruptHelper] which assumes a
|
/// For the handling of the interrupts, you can use the [GicInterruptHelper] which assumes a
|
||||||
/// properly configured GIC.
|
/// properly configured GIC.
|
||||||
pub struct GicConfigurator {
|
pub struct GicConfigurator {
|
||||||
pub gicc: MmioGicCpuInterface<'static>,
|
pub gicc: MmioGicCpuInterfaceRegisters<'static>,
|
||||||
pub gicd: MmioGicDistributor<'static>,
|
pub gicd: MmioGicDistributorRegisters<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GicConfigurator {
|
impl GicConfigurator {
|
||||||
@@ -233,8 +234,8 @@ impl GicConfigurator {
|
|||||||
/// strongly recommended initialization routines for the GIC.
|
/// strongly recommended initialization routines for the GIC.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_with_init(
|
pub fn new_with_init(
|
||||||
gicc: MmioGicCpuInterface<'static>,
|
gicc: MmioGicCpuInterfaceRegisters<'static>,
|
||||||
gicd: MmioGicDistributor<'static>,
|
gicd: MmioGicDistributorRegisters<'static>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut gic = GicConfigurator { gicc, gicd };
|
let mut gic = GicConfigurator { gicc, gicd };
|
||||||
gic.initialize();
|
gic.initialize();
|
||||||
@@ -251,8 +252,8 @@ impl GicConfigurator {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn steal() -> Self {
|
pub unsafe fn steal() -> Self {
|
||||||
GicConfigurator {
|
GicConfigurator {
|
||||||
gicc: unsafe { GicCpuInterface::new_mmio_fixed() },
|
gicc: unsafe { GicCpuInterfaceRegisters::new_mmio_fixed() },
|
||||||
gicd: unsafe { GicDistributor::new_mmio_fixed() },
|
gicd: unsafe { GicDistributorRegisters::new_mmio_fixed() },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,12 +489,12 @@ impl GicConfigurator {
|
|||||||
|
|
||||||
/// Helper structure which should only be used inside the interrupt handler once the GIC has
|
/// Helper structure which should only be used inside the interrupt handler once the GIC has
|
||||||
/// been configured with the [GicConfigurator].
|
/// been configured with the [GicConfigurator].
|
||||||
pub struct GicInterruptHelper(MmioGicCpuInterface<'static>);
|
pub struct GicInterruptHelper(MmioGicCpuInterfaceRegisters<'static>);
|
||||||
|
|
||||||
impl GicInterruptHelper {
|
impl GicInterruptHelper {
|
||||||
/// Create the interrupt helper with the fixed GICC MMIO instance.
|
/// Create the interrupt helper with the fixed GICC MMIO instance.
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
GicInterruptHelper(unsafe { GicCpuInterface::new_mmio_fixed() })
|
GicInterruptHelper(unsafe { GicCpuInterfaceRegisters::new_mmio_fixed() })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Acknowledges an interrupt by reading the IAR register and returning the interrupt context
|
/// Acknowledges an interrupt by reading the IAR register and returning the interrupt context
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//! EMIO (Extended Multiplexed I/O) resource management module.
|
//! EMIO (Extended Multiplexed I/O) resource management module.
|
||||||
use zynq7000::gpio::MmioGpio;
|
use zynq7000::gpio::MmioRegisters;
|
||||||
|
|
||||||
pub use crate::gpio::PinState;
|
pub use crate::gpio::PinState;
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ impl Pins {
|
|||||||
/// This structure is supposed to be used as a singleton. It will configure all
|
/// This structure is supposed to be used as a singleton. It will configure all
|
||||||
/// EMIO pins as inputs. If you want to retrieve individual pins without this structure,
|
/// EMIO pins as inputs. If you want to retrieve individual pins without this structure,
|
||||||
/// use [EmioPin::steal] instead.
|
/// use [EmioPin::steal] instead.
|
||||||
pub fn new(mut mmio: MmioGpio) -> Self {
|
pub fn new(mut mmio: MmioRegisters) -> Self {
|
||||||
let mut emios = [const { None }; 64];
|
let mut emios = [const { None }; 64];
|
||||||
// Configure all EMIO pins as inputs.
|
// Configure all EMIO pins as inputs.
|
||||||
mmio.bank_2().write_dirm(0);
|
mmio.bank_2().write_dirm(0);
|
||||||
|
|||||||
@@ -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::{Gpio, MaskedOutput, MmioGpio};
|
use zynq7000::gpio::{MaskedOutput, MmioRegisters, Registers};
|
||||||
|
|
||||||
use crate::slcr::Slcr;
|
use crate::slcr::Slcr;
|
||||||
|
|
||||||
@@ -48,14 +48,14 @@ impl PinOffset {
|
|||||||
|
|
||||||
pub struct LowLevelGpio {
|
pub struct LowLevelGpio {
|
||||||
offset: PinOffset,
|
offset: PinOffset,
|
||||||
regs: MmioGpio<'static>,
|
regs: MmioRegisters<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LowLevelGpio {
|
impl LowLevelGpio {
|
||||||
pub fn new(offset: PinOffset) -> Self {
|
pub fn new(offset: PinOffset) -> Self {
|
||||||
Self {
|
Self {
|
||||||
offset,
|
offset,
|
||||||
regs: unsafe { Gpio::new_mmio_fixed() },
|
regs: unsafe { Registers::new_mmio_fixed() },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ impl LowLevelGpio {
|
|||||||
/// Set the MIO pin configuration with an unlocked SLCR.
|
/// Set the MIO pin configuration with an unlocked SLCR.
|
||||||
pub fn set_mio_pin_config_with_unlocked_slcr(
|
pub fn set_mio_pin_config_with_unlocked_slcr(
|
||||||
&mut self,
|
&mut self,
|
||||||
slcr: &mut zynq7000::slcr::MmioSlcr<'static>,
|
slcr: &mut zynq7000::slcr::MmioRegisters<'static>,
|
||||||
config: zynq7000::slcr::mio::Config,
|
config: zynq7000::slcr::mio::Config,
|
||||||
) {
|
) {
|
||||||
let raw_offset = self.offset.offset();
|
let raw_offset = self.offset.offset();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
//! also allows associating the pins, their modes and their IDs to the peripherals they are able to
|
//! also allows associating the pins, their modes and their IDs to the peripherals they are able to
|
||||||
//! serve.
|
//! serve.
|
||||||
use arbitrary_int::{u2, u3};
|
use arbitrary_int::{u2, u3};
|
||||||
use zynq7000::gpio::MmioGpio;
|
use zynq7000::gpio::MmioRegisters;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct MuxConfig {
|
pub struct MuxConfig {
|
||||||
@@ -291,7 +291,7 @@ pub struct Pins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Pins {
|
impl Pins {
|
||||||
pub const fn new(_mmio: MmioGpio) -> Self {
|
pub const fn new(_mmio: MmioRegisters) -> Self {
|
||||||
Self {
|
Self {
|
||||||
mio0: unsafe { Pin::new() },
|
mio0: unsafe { Pin::new() },
|
||||||
mio1: unsafe { Pin::new() },
|
mio1: unsafe { Pin::new() },
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use mio::{MioPin, MuxConfig};
|
|||||||
use crate::gpio::ll::LowLevelGpio;
|
use crate::gpio::ll::LowLevelGpio;
|
||||||
use crate::{enable_amba_peripheral_clock, slcr::Slcr};
|
use crate::{enable_amba_peripheral_clock, slcr::Slcr};
|
||||||
pub use embedded_hal::digital::PinState;
|
pub use embedded_hal::digital::PinState;
|
||||||
use zynq7000::{gpio::MmioGpio, slcr::reset::GpioClockReset};
|
use zynq7000::{gpio::MmioRegisters, slcr::reset::GpioClockReset};
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
#[error("MIO pins 7 and 8 can only be output pins")]
|
#[error("MIO pins 7 and 8 can only be output pins")]
|
||||||
@@ -32,7 +32,7 @@ pub struct GpioPins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GpioPins {
|
impl GpioPins {
|
||||||
pub fn new(gpio: MmioGpio) -> Self {
|
pub fn new(gpio: MmioRegisters) -> Self {
|
||||||
enable_amba_peripheral_clock(crate::PeriphSelect::Gpio);
|
enable_amba_peripheral_clock(crate::PeriphSelect::Gpio);
|
||||||
Self {
|
Self {
|
||||||
mio: mio::Pins::new(unsafe { gpio.clone() }),
|
mio: mio::Pins::new(unsafe { gpio.clone() }),
|
||||||
@@ -413,7 +413,7 @@ impl IoPeriphPin {
|
|||||||
/// Constructor to fully configure an IO peripheral pin with a specific MIO pin configuration.
|
/// Constructor to fully configure an IO peripheral pin with a specific MIO pin configuration.
|
||||||
pub fn new_with_full_config_and_unlocked_slcr(
|
pub fn new_with_full_config_and_unlocked_slcr(
|
||||||
pin: impl MioPin,
|
pin: impl MioPin,
|
||||||
slcr: &mut zynq7000::slcr::MmioSlcr<'static>,
|
slcr: &mut zynq7000::slcr::MmioRegisters<'static>,
|
||||||
config: zynq7000::slcr::mio::Config,
|
config: zynq7000::slcr::mio::Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut low_level = LowLevelGpio::new(PinOffset::Mio(pin.offset()));
|
let mut low_level = LowLevelGpio::new(PinOffset::Mio(pin.offset()));
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
//!
|
//!
|
||||||
//! - [GTC ticks example](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/examples/simple/src/bin/gtc-ticks.rs)
|
//! - [GTC ticks example](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/examples/simple/src/bin/gtc-ticks.rs)
|
||||||
//! - [Embassy Timer Driver](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zynq7000-embassy/src/lib.rs)
|
//! - [Embassy Timer Driver](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zynq7000-embassy/src/lib.rs)
|
||||||
use zynq7000::gtc::MmioGlobalTimerCounter;
|
use zynq7000::gtc::MmioRegisters;
|
||||||
|
|
||||||
use crate::{clocks::ArmClocks, time::Hertz};
|
use crate::{clocks::ArmClocks, time::Hertz};
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ use crate::{clocks::ArmClocks, time::Hertz};
|
|||||||
/// [frequency_to_ticks] function and the [embedded_hal::delay::DelayNs] implementation
|
/// [frequency_to_ticks] function and the [embedded_hal::delay::DelayNs] implementation
|
||||||
/// to work.
|
/// to work.
|
||||||
pub struct GlobalTimerCounter {
|
pub struct GlobalTimerCounter {
|
||||||
regs: MmioGlobalTimerCounter<'static>,
|
regs: MmioRegisters<'static>,
|
||||||
cpu_3x2x_clock: Option<Hertz>,
|
cpu_3x2x_clock: Option<Hertz>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ pub const fn frequency_to_ticks(clock: Hertz, frequency: Hertz) -> u32 {
|
|||||||
impl GlobalTimerCounter {
|
impl GlobalTimerCounter {
|
||||||
/// Create a peripheral driver from a MMIO GTC block.
|
/// Create a peripheral driver from a MMIO GTC block.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn new(_regs: MmioGlobalTimerCounter<'static>, clocks: &ArmClocks) -> Self {
|
pub const fn new(_regs: MmioRegisters<'static>, clocks: &ArmClocks) -> Self {
|
||||||
unsafe { Self::steal_fixed(Some(clocks.cpu_3x2x_clk())) }
|
unsafe { Self::steal_fixed(Some(clocks.cpu_3x2x_clk())) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ impl GlobalTimerCounter {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub const unsafe fn steal_fixed(cpu_3x2x_clk: Option<Hertz>) -> Self {
|
pub const unsafe fn steal_fixed(cpu_3x2x_clk: Option<Hertz>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
regs: unsafe { zynq7000::gtc::GlobalTimerCounter::new_mmio_fixed() },
|
regs: unsafe { zynq7000::gtc::Registers::new_mmio_fixed() },
|
||||||
cpu_3x2x_clock: cpu_3x2x_clk,
|
cpu_3x2x_clock: cpu_3x2x_clk,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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, MmioI2c, TransferSize},
|
i2c::{
|
||||||
|
Control, I2C_0_BASE_ADDR, I2C_1_BASE_ADDR, InterruptStatus, MmioRegisters, TransferSize,
|
||||||
|
},
|
||||||
slcr::reset::DualClockReset,
|
slcr::reset::DualClockReset,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,13 +39,13 @@ pub enum I2cId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait PsI2c {
|
pub trait PsI2c {
|
||||||
fn reg_block(&self) -> MmioI2c<'static>;
|
fn reg_block(&self) -> MmioRegisters<'static>;
|
||||||
fn id(&self) -> Option<I2cId>;
|
fn id(&self) -> Option<I2cId>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PsI2c for MmioI2c<'static> {
|
impl PsI2c for MmioRegisters<'static> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reg_block(&self) -> MmioI2c<'static> {
|
fn reg_block(&self) -> MmioRegisters<'static> {
|
||||||
unsafe { self.clone() }
|
unsafe { self.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +311,7 @@ pub enum I2cConstructionError {
|
|||||||
InvalidPinConf,
|
InvalidPinConf,
|
||||||
}
|
}
|
||||||
pub struct I2c {
|
pub struct I2c {
|
||||||
regs: MmioI2c<'static>,
|
regs: MmioRegisters<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl I2c {
|
impl I2c {
|
||||||
@@ -344,7 +346,7 @@ impl I2c {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_generic(id: I2cId, mut regs: MmioI2c<'static>, clk_cfg: ClockConfig) -> Self {
|
pub fn new_generic(id: I2cId, mut regs: MmioRegisters<'static>, clk_cfg: ClockConfig) -> Self {
|
||||||
let periph_sel = match id {
|
let periph_sel = match id {
|
||||||
I2cId::I2c0 => crate::PeriphSelect::I2c0,
|
I2cId::I2c0 => crate::PeriphSelect::I2c0,
|
||||||
I2cId::I2c1 => crate::PeriphSelect::I2c1,
|
I2cId::I2c1 => crate::PeriphSelect::I2c1,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use core::sync::atomic::compiler_fence;
|
|||||||
use arbitrary_int::{u2, u3};
|
use arbitrary_int::{u2, u3};
|
||||||
pub use zynq7000::l2_cache::LatencyConfig;
|
pub use zynq7000::l2_cache::LatencyConfig;
|
||||||
use zynq7000::l2_cache::{
|
use zynq7000::l2_cache::{
|
||||||
Associativity, AuxControl, Control, InterruptControl, MmioL2Cache, ReplacementPolicy, WaySize,
|
Associativity, AuxControl, Control, InterruptControl, MmioRegisters, ReplacementPolicy, WaySize,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::slcr::Slcr;
|
use crate::slcr::Slcr;
|
||||||
@@ -48,7 +48,7 @@ pub const DEFAULT_DATA_RAM_LATENCY: LatencyConfig = LatencyConfig::builder()
|
|||||||
pub const SLCR_L2C_CONFIG_MAGIC_VALUE: u32 = 0x00020202;
|
pub const SLCR_L2C_CONFIG_MAGIC_VALUE: u32 = 0x00020202;
|
||||||
|
|
||||||
/// Similar to [init], but uses Xilinx/AMD defaults for the latency configurations.
|
/// Similar to [init], but uses Xilinx/AMD defaults for the latency configurations.
|
||||||
pub fn init_with_defaults(l2c_mmio: &mut MmioL2Cache<'static>) {
|
pub fn init_with_defaults(l2c_mmio: &mut MmioRegisters<'static>) {
|
||||||
init(l2c_mmio, DEFAULT_TAG_RAM_LATENCY, DEFAULT_DATA_RAM_LATENCY);
|
init(l2c_mmio, DEFAULT_TAG_RAM_LATENCY, DEFAULT_DATA_RAM_LATENCY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ pub fn init_with_defaults(l2c_mmio: &mut MmioL2Cache<'static>) {
|
|||||||
/// This function is based on the initialization sequence specified in the TRM p.94 and on
|
/// This function is based on the initialization sequence specified in the TRM p.94 and on
|
||||||
/// the runtime initialization provided by Xilinx/AMD.
|
/// the runtime initialization provided by Xilinx/AMD.
|
||||||
pub fn init(
|
pub fn init(
|
||||||
l2c_mmio: &mut MmioL2Cache<'static>,
|
l2c_mmio: &mut MmioRegisters<'static>,
|
||||||
tag_ram_latency: LatencyConfig,
|
tag_ram_latency: LatencyConfig,
|
||||||
data_ram_latency: LatencyConfig,
|
data_ram_latency: LatencyConfig,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ impl BootMode {
|
|||||||
/// fixed SLCR block.
|
/// fixed SLCR block.
|
||||||
pub fn new_from_regs() -> Self {
|
pub fn new_from_regs() -> Self {
|
||||||
// Safety: Only read a read-only register here.
|
// Safety: Only read a read-only register here.
|
||||||
Self::new_with_reg(unsafe { zynq7000::slcr::Slcr::new_mmio_fixed() }.read_boot_mode())
|
Self::new_with_reg(unsafe { zynq7000::slcr::Registers::new_mmio_fixed() }.read_boot_mode())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_with_reg(boot_mode_reg: BootModeRegister) -> Self {
|
fn new_with_reg(boot_mode_reg: BootModeRegister) -> Self {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ static CORE_1_TIM_TAKEN: AtomicBool = AtomicBool::new(false);
|
|||||||
|
|
||||||
/// High-level CPU private timer driver.
|
/// High-level CPU private timer driver.
|
||||||
pub struct CpuPrivateTimer {
|
pub struct CpuPrivateTimer {
|
||||||
regs: zynq7000::priv_tim::MmioCpuPrivateTimer<'static>,
|
regs: zynq7000::priv_tim::MmioRegisters<'static>,
|
||||||
cpu_3x2x_clock: Hertz,
|
cpu_3x2x_clock: Hertz,
|
||||||
// Add this marker to explicitely opt-out of Send and Sync.
|
// Add this marker to explicitely opt-out of Send and Sync.
|
||||||
//
|
//
|
||||||
@@ -49,7 +49,7 @@ impl CpuPrivateTimer {
|
|||||||
/// It also does not check the current core ID.
|
/// It also does not check the current core ID.
|
||||||
pub fn steal(clocks: &ArmClocks) -> Self {
|
pub fn steal(clocks: &ArmClocks) -> Self {
|
||||||
Self {
|
Self {
|
||||||
regs: unsafe { zynq7000::priv_tim::CpuPrivateTimer::new_mmio_fixed() },
|
regs: unsafe { zynq7000::priv_tim::Registers::new_mmio_fixed() },
|
||||||
cpu_3x2x_clock: clocks.cpu_3x2x_clk(),
|
cpu_3x2x_clock: clocks.cpu_3x2x_clk(),
|
||||||
_not_send: PhantomData,
|
_not_send: PhantomData,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -284,15 +284,15 @@ impl ClockConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct QspiLowLevel(zynq7000::qspi::MmioQspi<'static>);
|
pub struct QspiLowLevel(zynq7000::qspi::MmioRegisters<'static>);
|
||||||
|
|
||||||
impl QspiLowLevel {
|
impl QspiLowLevel {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(regs: zynq7000::qspi::MmioQspi<'static>) -> Self {
|
pub fn new(regs: zynq7000::qspi::MmioRegisters<'static>) -> Self {
|
||||||
Self(regs)
|
Self(regs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn regs(&mut self) -> &mut zynq7000::qspi::MmioQspi<'static> {
|
pub fn regs(&mut self) -> &mut zynq7000::qspi::MmioRegisters<'static> {
|
||||||
&mut self.0
|
&mut self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,7 +399,7 @@ impl Qspi {
|
|||||||
Io3: Qspi0Io3Pin,
|
Io3: Qspi0Io3Pin,
|
||||||
Clock: Qspi0ClockPin,
|
Clock: Qspi0ClockPin,
|
||||||
>(
|
>(
|
||||||
regs: zynq7000::qspi::MmioQspi<'static>,
|
regs: zynq7000::qspi::MmioRegisters<'static>,
|
||||||
clock_config: ClockConfig,
|
clock_config: ClockConfig,
|
||||||
mode: embedded_hal::spi::Mode,
|
mode: embedded_hal::spi::Mode,
|
||||||
voltage: IoType,
|
voltage: IoType,
|
||||||
@@ -452,7 +452,7 @@ impl Qspi {
|
|||||||
Clock: Qspi0ClockPin,
|
Clock: Qspi0ClockPin,
|
||||||
Feedback: FeedbackClockPin,
|
Feedback: FeedbackClockPin,
|
||||||
>(
|
>(
|
||||||
regs: zynq7000::qspi::MmioQspi<'static>,
|
regs: zynq7000::qspi::MmioRegisters<'static>,
|
||||||
clock_config: ClockConfig,
|
clock_config: ClockConfig,
|
||||||
mode: embedded_hal::spi::Mode,
|
mode: embedded_hal::spi::Mode,
|
||||||
voltage: IoType,
|
voltage: IoType,
|
||||||
@@ -479,7 +479,7 @@ impl Qspi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn regs(&mut self) -> &mut zynq7000::qspi::MmioQspi<'static> {
|
pub fn regs(&mut self) -> &mut zynq7000::qspi::MmioRegisters<'static> {
|
||||||
&mut self.ll.0
|
&mut self.ll.0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,7 +500,7 @@ pub struct QspiIoMode {
|
|||||||
|
|
||||||
impl QspiIoMode {
|
impl QspiIoMode {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn regs(&mut self) -> &mut zynq7000::qspi::MmioQspi<'static> {
|
pub fn regs(&mut self) -> &mut zynq7000::qspi::MmioRegisters<'static> {
|
||||||
&mut self.ll.0
|
&mut self.ll.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
//! # System Level Control Register (SLCR) module
|
//! # System Level Control Register (SLCR) module
|
||||||
use zynq7000::slcr::MmioSlcr;
|
use zynq7000::slcr::MmioRegisters;
|
||||||
|
|
||||||
pub const LOCK_KEY: u32 = 0x767B;
|
pub const LOCK_KEY: u32 = 0x767B;
|
||||||
pub const UNLOCK_KEY: u32 = 0xDF0D;
|
pub const UNLOCK_KEY: u32 = 0xDF0D;
|
||||||
|
|
||||||
pub struct Slcr(zynq7000::slcr::MmioSlcr<'static>);
|
pub struct Slcr(zynq7000::slcr::MmioRegisters<'static>);
|
||||||
|
|
||||||
impl Slcr {
|
impl Slcr {
|
||||||
/// Modify the SLCR register.
|
/// Modify the SLCR register.
|
||||||
@@ -14,15 +14,15 @@ impl Slcr {
|
|||||||
/// This method unsafely steals the SLCR MMIO block and then calls a user provided function
|
/// This method unsafely steals the SLCR MMIO block and then calls a user provided function
|
||||||
/// with the [SLCR MMIO][MmioSlcr] block as an input argument. It is the user's responsibility
|
/// with the [SLCR MMIO][MmioSlcr] block as an input argument. It is the user's responsibility
|
||||||
/// that the SLCR is not used concurrently in a way which leads to data races.
|
/// that the SLCR is not used concurrently in a way which leads to data races.
|
||||||
pub unsafe fn with<F: FnOnce(&mut MmioSlcr<'static>)>(f: F) {
|
pub unsafe fn with<F: FnOnce(&mut MmioRegisters<'static>)>(f: F) {
|
||||||
let mut slcr = unsafe { zynq7000::slcr::Slcr::new_mmio_fixed() };
|
let mut slcr = unsafe { zynq7000::slcr::Registers::new_mmio_fixed() };
|
||||||
slcr.write_unlock(UNLOCK_KEY);
|
slcr.write_unlock(UNLOCK_KEY);
|
||||||
f(&mut slcr);
|
f(&mut slcr);
|
||||||
slcr.write_lock(LOCK_KEY);
|
slcr.write_lock(LOCK_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new SLCR peripheral wrapper.
|
/// Create a new SLCR peripheral wrapper.
|
||||||
pub fn new(slcr: zynq7000::slcr::MmioSlcr<'static>) -> Self {
|
pub fn new(slcr: zynq7000::slcr::MmioRegisters<'static>) -> Self {
|
||||||
Self(slcr)
|
Self(slcr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,13 +34,13 @@ impl Slcr {
|
|||||||
/// responsibility that these wrappers are not used concurrently in a way which leads to
|
/// responsibility that these wrappers are not used concurrently in a way which leads to
|
||||||
/// data races.
|
/// data races.
|
||||||
pub unsafe fn steal() -> Self {
|
pub unsafe fn steal() -> Self {
|
||||||
Self::new(unsafe { zynq7000::slcr::Slcr::new_mmio_fixed() })
|
Self::new(unsafe { zynq7000::slcr::Registers::new_mmio_fixed() })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a mutable reference to the SLCR MMIO block.
|
/// Returns a mutable reference to the SLCR MMIO block.
|
||||||
///
|
///
|
||||||
/// The MMIO block will not be unlocked. However, the registers can still be read.
|
/// The MMIO block will not be unlocked. However, the registers can still be read.
|
||||||
pub fn regs(&self) -> &MmioSlcr<'static> {
|
pub fn regs(&self) -> &MmioRegisters<'static> {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ impl Slcr {
|
|||||||
/// This method unlocks the SLCR registers and then calls a user provided function
|
/// This method unlocks the SLCR registers and then calls a user provided function
|
||||||
/// with the [SLCR MMIO][MmioSlcr] block as an input argument. This allows the user
|
/// with the [SLCR MMIO][MmioSlcr] block as an input argument. This allows the user
|
||||||
/// to safely modify the SLCR registers. The SLCR will be locked afte the operation.
|
/// to safely modify the SLCR registers. The SLCR will be locked afte the operation.
|
||||||
pub fn modify<F: FnMut(&mut MmioSlcr)>(&mut self, mut f: F) {
|
pub fn modify<F: FnMut(&mut MmioRegisters)>(&mut self, mut f: F) {
|
||||||
self.0.write_unlock(UNLOCK_KEY);
|
self.0.write_unlock(UNLOCK_KEY);
|
||||||
f(&mut self.0);
|
f(&mut self.0);
|
||||||
self.0.write_lock(LOCK_KEY);
|
self.0.write_lock(LOCK_KEY);
|
||||||
|
|||||||
@@ -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, MmioSpi,
|
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;
|
||||||
@@ -42,13 +42,13 @@ pub enum SpiId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait PsSpi {
|
pub trait PsSpi {
|
||||||
fn reg_block(&self) -> MmioSpi<'static>;
|
fn reg_block(&self) -> MmioRegisters<'static>;
|
||||||
fn id(&self) -> Option<SpiId>;
|
fn id(&self) -> Option<SpiId>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PsSpi for MmioSpi<'static> {
|
impl PsSpi for MmioRegisters<'static> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reg_block(&self) -> MmioSpi<'static> {
|
fn reg_block(&self) -> MmioRegisters<'static> {
|
||||||
unsafe { self.clone() }
|
unsafe { self.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,7 +392,7 @@ impl Config {
|
|||||||
/// Thin re-usable low-level helper to interface with the SPI.
|
/// Thin re-usable low-level helper to interface with the SPI.
|
||||||
pub struct SpiLowLevel {
|
pub struct SpiLowLevel {
|
||||||
id: SpiId,
|
id: SpiId,
|
||||||
regs: zynq7000::spi::MmioSpi<'static>,
|
regs: zynq7000::spi::MmioRegisters<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpiLowLevel {
|
impl SpiLowLevel {
|
||||||
@@ -406,8 +406,8 @@ impl SpiLowLevel {
|
|||||||
pub unsafe fn steal(id: SpiId) -> Self {
|
pub unsafe fn steal(id: SpiId) -> Self {
|
||||||
let regs = unsafe {
|
let regs = unsafe {
|
||||||
match id {
|
match id {
|
||||||
SpiId::Spi0 => zynq7000::spi::Spi::new_mmio_fixed_0(),
|
SpiId::Spi0 => zynq7000::spi::Registers::new_mmio_fixed_0(),
|
||||||
SpiId::Spi1 => zynq7000::spi::Spi::new_mmio_fixed_1(),
|
SpiId::Spi1 => zynq7000::spi::Registers::new_mmio_fixed_1(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Self { id, regs }
|
Self { id, regs }
|
||||||
@@ -808,7 +808,7 @@ impl Spi {
|
|||||||
|
|
||||||
pub fn new_generic_unchecked(
|
pub fn new_generic_unchecked(
|
||||||
id: SpiId,
|
id: SpiId,
|
||||||
regs: MmioSpi<'static>,
|
regs: MmioRegisters<'static>,
|
||||||
clocks: &IoClocks,
|
clocks: &IoClocks,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -863,7 +863,7 @@ impl Spi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn regs(&mut self) -> &mut MmioSpi<'static> {
|
pub fn regs(&mut self) -> &mut MmioRegisters<'static> {
|
||||||
&mut self.inner.regs
|
&mut self.inner.regs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
use core::convert::Infallible;
|
use core::convert::Infallible;
|
||||||
|
|
||||||
use arbitrary_int::{prelude::*, u3, u4};
|
use arbitrary_int::{prelude::*, u3, u4};
|
||||||
use zynq7000::ttc::{MmioTtc, TTC_0_BASE_ADDR, TTC_1_BASE_ADDR};
|
use zynq7000::ttc::{MmioRegisters, TTC_0_BASE_ADDR, TTC_1_BASE_ADDR};
|
||||||
|
|
||||||
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
use crate::gpio::mio::{Mio16, Mio17, Mio18, Mio19, Mio40, Mio41, Mio42, Mio43};
|
use crate::gpio::mio::{Mio16, Mio17, Mio18, Mio19, Mio40, Mio41, Mio42, Mio43};
|
||||||
@@ -37,13 +37,13 @@ pub enum ChannelId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait PsTtc {
|
pub trait PsTtc {
|
||||||
fn reg_block(&self) -> MmioTtc<'static>;
|
fn reg_block(&self) -> MmioRegisters<'static>;
|
||||||
fn id(&self) -> Option<TtcId>;
|
fn id(&self) -> Option<TtcId>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PsTtc for MmioTtc<'static> {
|
impl PsTtc for MmioRegisters<'static> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reg_block(&self) -> MmioTtc<'static> {
|
fn reg_block(&self) -> MmioRegisters<'static> {
|
||||||
unsafe { self.clone() }
|
unsafe { self.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,12 +152,12 @@ impl Ttc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct TtcChannel {
|
pub struct TtcChannel {
|
||||||
regs: MmioTtc<'static>,
|
regs: MmioRegisters<'static>,
|
||||||
id: ChannelId,
|
id: ChannelId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TtcChannel {
|
impl TtcChannel {
|
||||||
pub fn regs_mut(&mut self) -> &mut MmioTtc<'static> {
|
pub fn regs_mut(&mut self) -> &mut MmioRegisters<'static> {
|
||||||
&mut self.regs
|
&mut self.regs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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, MmioUart,
|
BaudRateDivisor, Baudgen, ChMode, ClockSelect, FifoTrigger, InterruptControl,
|
||||||
Mode, UART_0_BASE, UART_1_BASE,
|
MmioRegisters, Mode, UART_0_BASE, UART_1_BASE,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -60,13 +60,13 @@ pub enum UartId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait PsUart {
|
pub trait PsUart {
|
||||||
fn reg_block(&self) -> MmioUart<'static>;
|
fn reg_block(&self) -> MmioRegisters<'static>;
|
||||||
fn uart_id(&self) -> Option<UartId>;
|
fn uart_id(&self) -> Option<UartId>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PsUart for MmioUart<'static> {
|
impl PsUart for MmioRegisters<'static> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reg_block(&self) -> MmioUart<'static> {
|
fn reg_block(&self) -> MmioRegisters<'static> {
|
||||||
unsafe { self.clone() }
|
unsafe { self.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,10 +87,10 @@ impl UartId {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// Circumvents ownership and safety guarantees by the HAL.
|
/// Circumvents ownership and safety guarantees by the HAL.
|
||||||
pub const unsafe fn regs(&self) -> MmioUart<'static> {
|
pub const unsafe fn regs(&self) -> MmioRegisters<'static> {
|
||||||
match self {
|
match self {
|
||||||
UartId::Uart0 => unsafe { zynq7000::uart::Uart::new_mmio_fixed_0() },
|
UartId::Uart0 => unsafe { zynq7000::uart::Registers::new_mmio_fixed_0() },
|
||||||
UartId::Uart1 => unsafe { zynq7000::uart::Uart::new_mmio_fixed_1() },
|
UartId::Uart1 => unsafe { zynq7000::uart::Registers::new_mmio_fixed_1() },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -469,7 +469,7 @@ impl Uart {
|
|||||||
/// It does not do any pin checks and resource control. It is recommended to use the other
|
/// It does not do any pin checks and resource control. It is recommended to use the other
|
||||||
/// constructors instead.
|
/// constructors instead.
|
||||||
pub fn new_generic_unchecked(
|
pub fn new_generic_unchecked(
|
||||||
mut reg_block: MmioUart<'static>,
|
mut reg_block: MmioRegisters<'static>,
|
||||||
uart_id: UartId,
|
uart_id: UartId,
|
||||||
cfg: Config,
|
cfg: Config,
|
||||||
) -> Uart {
|
) -> Uart {
|
||||||
@@ -558,7 +558,7 @@ impl Uart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn regs(&mut self) -> &mut MmioUart<'static> {
|
pub const fn regs(&mut self) -> &mut MmioRegisters<'static> {
|
||||||
&mut self.rx.regs
|
&mut self.rx.regs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
use core::convert::Infallible;
|
use core::convert::Infallible;
|
||||||
|
|
||||||
use arbitrary_int::prelude::*;
|
use arbitrary_int::prelude::*;
|
||||||
use zynq7000::uart::{InterruptControl, InterruptStatus, MmioUart};
|
use zynq7000::uart::{InterruptControl, InterruptStatus, MmioRegisters};
|
||||||
|
|
||||||
use super::FIFO_DEPTH;
|
use super::FIFO_DEPTH;
|
||||||
|
|
||||||
pub struct Rx {
|
pub struct Rx {
|
||||||
pub(crate) regs: MmioUart<'static>,
|
pub(crate) regs: MmioRegisters<'static>,
|
||||||
}
|
}
|
||||||
// TODO: Remove once this is impelemnted for MmioUart
|
// TODO: Remove once this is impelemnted for MmioUart
|
||||||
unsafe impl Send for Rx {}
|
unsafe impl Send for Rx {}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use core::convert::Infallible;
|
use core::convert::Infallible;
|
||||||
|
|
||||||
use zynq7000::uart::{Fifo, InterruptControl, InterruptStatus, MmioUart};
|
use zynq7000::uart::{Fifo, InterruptControl, InterruptStatus, MmioRegisters};
|
||||||
|
|
||||||
use super::UartId;
|
use super::UartId;
|
||||||
|
|
||||||
pub struct Tx {
|
pub struct Tx {
|
||||||
pub(crate) regs: MmioUart<'static>,
|
pub(crate) regs: MmioRegisters<'static>,
|
||||||
pub(crate) idx: UartId,
|
pub(crate) idx: UartId,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ impl Tx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn regs(&mut self) -> &mut MmioUart<'static> {
|
pub const fn regs(&mut self) -> &mut MmioRegisters<'static> {
|
||||||
&mut self.regs
|
&mut self.regs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
# [unreleased]
|
# [unreleased]
|
||||||
|
|
||||||
|
- Renamed all register blocks to `Registers` to subblocks to `<Subblock>Registers`
|
||||||
|
- Added SDIO registers
|
||||||
|
|
||||||
# [v0.1.1] 2025-10-09
|
# [v0.1.1] 2025-10-09
|
||||||
|
|
||||||
Documentation fix
|
Documentation fix
|
||||||
|
|||||||
@@ -728,7 +728,7 @@ use regs::*;
|
|||||||
/// DDR controller register access.
|
/// DDR controller register access.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct DdrController {
|
pub struct Registers {
|
||||||
ddrc_ctrl: DdrcControl,
|
ddrc_ctrl: DdrcControl,
|
||||||
two_rank_cfg: TwoRankConfig,
|
two_rank_cfg: TwoRankConfig,
|
||||||
hpr_queue_ctrl: LprHprQueueControl,
|
hpr_queue_ctrl: LprHprQueueControl,
|
||||||
@@ -871,9 +871,9 @@ pub struct DdrController {
|
|||||||
lpddr_ctrl_3: LpddrControl3,
|
lpddr_ctrl_3: LpddrControl3,
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<DdrController>(), 0x2B8);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0x2B8);
|
||||||
|
|
||||||
impl DdrController {
|
impl Registers {
|
||||||
/// Create a new DDR MMIO instance for the DDR controller at address [DDRC_BASE_ADDR].
|
/// Create a new DDR MMIO instance for the DDR controller at address [DDRC_BASE_ADDR].
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -881,7 +881,7 @@ impl DdrController {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub const unsafe fn new_mmio_fixed() -> MmioDdrController<'static> {
|
pub const unsafe fn new_mmio_fixed() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(DDRC_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(DDRC_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ pub struct Status {
|
|||||||
/// Device configuration register access.
|
/// Device configuration register access.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct DevCfg {
|
pub struct Registers {
|
||||||
control: Control,
|
control: Control,
|
||||||
lock: Lock,
|
lock: Lock,
|
||||||
config: Config,
|
config: Config,
|
||||||
@@ -284,12 +284,12 @@ pub struct DevCfg {
|
|||||||
|
|
||||||
// Included here but not exposed to avoid providing multiple references to the same peripheral.
|
// Included here but not exposed to avoid providing multiple references to the same peripheral.
|
||||||
// Exposed in [crate::xadc].
|
// Exposed in [crate::xadc].
|
||||||
_xadc: crate::xadc::XAdc,
|
_xadc: crate::xadc::Registers,
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<DevCfg>(), 0x11C);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0x11C);
|
||||||
|
|
||||||
impl DevCfg {
|
impl Registers {
|
||||||
/// Create a new DevCfg MMIO instance for for device configuration peripheral at address
|
/// Create a new DevCfg MMIO instance for for device configuration peripheral at address
|
||||||
/// [DEVCFG_BASE_ADDR].
|
/// [DEVCFG_BASE_ADDR].
|
||||||
///
|
///
|
||||||
@@ -298,7 +298,7 @@ impl DevCfg {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub unsafe fn new_mmio_fixed() -> MmioDevCfg<'static> {
|
pub unsafe fn new_mmio_fixed() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(DEVCFG_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(DEVCFG_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -421,7 +421,7 @@ pub struct MatchRegister {
|
|||||||
/// Gigabit Ethernet Controller (GEM) register access.
|
/// Gigabit Ethernet Controller (GEM) register access.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Ethernet {
|
pub struct Registers {
|
||||||
net_ctrl: NetworkControl,
|
net_ctrl: NetworkControl,
|
||||||
net_cfg: NetworkConfig,
|
net_cfg: NetworkConfig,
|
||||||
#[mmio(PureRead)]
|
#[mmio(PureRead)]
|
||||||
@@ -475,7 +475,7 @@ pub struct Ethernet {
|
|||||||
design_cfg_5: u32,
|
design_cfg_5: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<Ethernet>(), 0x294);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0x294);
|
||||||
|
|
||||||
/// Ethernet statistics registers
|
/// Ethernet statistics registers
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
@@ -571,7 +571,7 @@ pub struct Statistics {
|
|||||||
rx_udp_checksum_errors: u32,
|
rx_udp_checksum_errors: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ethernet {
|
impl Registers {
|
||||||
/// Create a new Gigabit Ethernet MMIO instance for GEM 0 at address [GEM_0_BASE_ADDR].
|
/// Create a new Gigabit Ethernet MMIO instance for GEM 0 at address [GEM_0_BASE_ADDR].
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -579,7 +579,7 @@ impl Ethernet {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub const unsafe fn new_mmio_fixed_0() -> MmioEthernet<'static> {
|
pub const unsafe fn new_mmio_fixed_0() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(GEM_0_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(GEM_0_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,7 +590,7 @@ impl Ethernet {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub const unsafe fn new_mmio_fixed_1() -> MmioEthernet<'static> {
|
pub const unsafe fn new_mmio_fixed_1() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(GEM_1_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(GEM_1_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ pub type Typer = TypeRegister;
|
|||||||
/// GIC Distributor registers.
|
/// GIC Distributor registers.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C, align(8))]
|
#[repr(C, align(8))]
|
||||||
pub struct GicDistributor {
|
pub struct GicDistributorRegisters {
|
||||||
/// Distributor Control Register
|
/// Distributor Control Register
|
||||||
pub dcr: DistributorControlRegister,
|
pub dcr: DistributorControlRegister,
|
||||||
/// Interrupt Controller Type Register
|
/// Interrupt Controller Type Register
|
||||||
@@ -109,9 +109,9 @@ pub struct GicDistributor {
|
|||||||
pub cidr: [u32; 4],
|
pub cidr: [u32; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
const_assert_eq!(core::mem::size_of::<GicDistributor>(), 0x1000);
|
const_assert_eq!(core::mem::size_of::<GicDistributorRegisters>(), 0x1000);
|
||||||
|
|
||||||
impl GicDistributor {
|
impl GicDistributorRegisters {
|
||||||
/// Create a new Global Interrupt Controller Distributor MMIO instance at the fixed address of
|
/// Create a new Global Interrupt Controller Distributor MMIO instance at the fixed address of
|
||||||
/// the processing system.
|
/// the processing system.
|
||||||
///
|
///
|
||||||
@@ -121,7 +121,7 @@ impl GicDistributor {
|
|||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const unsafe fn new_mmio_fixed() -> MmioGicDistributor<'static> {
|
pub const unsafe fn new_mmio_fixed() -> MmioGicDistributorRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(GICD_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(GICD_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,7 @@ pub struct InterruptSignalRegister {
|
|||||||
/// GIC CPU interface registers.
|
/// GIC CPU interface registers.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C, align(8))]
|
#[repr(C, align(8))]
|
||||||
pub struct GicCpuInterface {
|
pub struct GicCpuInterfaceRegisters {
|
||||||
/// CPU Interface Control Register (ICR).
|
/// CPU Interface Control Register (ICR).
|
||||||
pub icr: InterfaceControl,
|
pub icr: InterfaceControl,
|
||||||
/// Interrupt Priority Mask Register.
|
/// Interrupt Priority Mask Register.
|
||||||
@@ -183,9 +183,9 @@ pub struct GicCpuInterface {
|
|||||||
pub iidr: u32,
|
pub iidr: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
const_assert_eq!(core::mem::size_of::<GicCpuInterface>(), 0x100);
|
const_assert_eq!(core::mem::size_of::<GicCpuInterfaceRegisters>(), 0x100);
|
||||||
|
|
||||||
impl GicCpuInterface {
|
impl GicCpuInterfaceRegisters {
|
||||||
/// Create a new Global Interrupt Controller CPU MMIO instance at the fixed address of the
|
/// Create a new Global Interrupt Controller CPU MMIO instance at the fixed address of the
|
||||||
/// processing system.
|
/// processing system.
|
||||||
///
|
///
|
||||||
@@ -195,7 +195,7 @@ impl GicCpuInterface {
|
|||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const unsafe fn new_mmio_fixed() -> MmioGicCpuInterface<'static> {
|
pub const unsafe fn new_mmio_fixed() -> MmioGicCpuInterfaceRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(GICC_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(GICC_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pub struct MaskedOutput {
|
|||||||
|
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct BankControl {
|
pub struct BankControlRegisters {
|
||||||
/// Direction mode
|
/// Direction mode
|
||||||
dirm: u32,
|
dirm: u32,
|
||||||
/// Output enable
|
/// Output enable
|
||||||
@@ -38,7 +38,7 @@ pub struct BankControl {
|
|||||||
/// GPIO register access.
|
/// GPIO register access.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Gpio {
|
pub struct Registers {
|
||||||
/// Maskable output data (GPIO bank 0, MIO, lower 16 bits)
|
/// Maskable output data (GPIO bank 0, MIO, lower 16 bits)
|
||||||
masked_out_0_lsw: MaskedOutput,
|
masked_out_0_lsw: MaskedOutput,
|
||||||
/// Maskable output data (GPIO bank 0, MIO, upper 16 bits)
|
/// Maskable output data (GPIO bank 0, MIO, upper 16 bits)
|
||||||
@@ -85,27 +85,27 @@ pub struct Gpio {
|
|||||||
_reserved_2: [u32; 101],
|
_reserved_2: [u32; 101],
|
||||||
|
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
bank_0: BankControl,
|
bank_0: BankControlRegisters,
|
||||||
|
|
||||||
_reserved_3: [u32; 7],
|
_reserved_3: [u32; 7],
|
||||||
|
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
bank_1: BankControl,
|
bank_1: BankControlRegisters,
|
||||||
|
|
||||||
_reserved_4: [u32; 7],
|
_reserved_4: [u32; 7],
|
||||||
|
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
bank_2: BankControl,
|
bank_2: BankControlRegisters,
|
||||||
|
|
||||||
_reserved_5: [u32; 7],
|
_reserved_5: [u32; 7],
|
||||||
|
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
bank_3: BankControl,
|
bank_3: BankControlRegisters,
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<Gpio>(), 0x2E8);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0x2E8);
|
||||||
|
|
||||||
impl Gpio {
|
impl Registers {
|
||||||
/// Create a new XGPIOPS GPIO MMIO instance.
|
/// Create a new XGPIOPS GPIO MMIO instance.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -113,9 +113,9 @@ impl Gpio {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub const unsafe fn new_mmio_fixed() -> MmioGpio<'static> {
|
pub const unsafe fn new_mmio_fixed() -> MmioRegisters<'static> {
|
||||||
MmioGpio {
|
MmioRegisters {
|
||||||
ptr: 0xE000A000 as *mut Gpio,
|
ptr: 0xE000A000 as *mut Registers,
|
||||||
phantom: core::marker::PhantomData,
|
phantom: core::marker::PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ pub struct InterruptStatus {
|
|||||||
/// Global timer counter register access.
|
/// Global timer counter register access.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct GlobalTimerCounter {
|
pub struct Registers {
|
||||||
/// Count register 0, lower 32 bits
|
/// Count register 0, lower 32 bits
|
||||||
count_lower: u32,
|
count_lower: u32,
|
||||||
/// Count register 1, upper 32 bits
|
/// Count register 1, upper 32 bits
|
||||||
@@ -43,9 +43,9 @@ pub struct GlobalTimerCounter {
|
|||||||
auto_increment: u32,
|
auto_increment: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<GlobalTimerCounter>(), 0x1C);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0x1C);
|
||||||
|
|
||||||
impl GlobalTimerCounter {
|
impl Registers {
|
||||||
/// Create a new GTC MMIO instance at the fixed base address.
|
/// Create a new GTC MMIO instance at the fixed base address.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -54,7 +54,7 @@ impl GlobalTimerCounter {
|
|||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const unsafe fn new_mmio_fixed() -> MmioGlobalTimerCounter<'static> {
|
pub const unsafe fn new_mmio_fixed() -> MmioRegisters<'static> {
|
||||||
unsafe { GlobalTimerCounter::new_mmio_at(GTC_BASE_ADDR) }
|
unsafe { Registers::new_mmio_at(GTC_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ pub struct TransferSize {
|
|||||||
/// I2C register access.
|
/// I2C register access.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct I2c {
|
pub struct Registers {
|
||||||
cr: Control,
|
cr: Control,
|
||||||
#[mmio(PureRead)]
|
#[mmio(PureRead)]
|
||||||
sr: Status,
|
sr: Status,
|
||||||
@@ -179,9 +179,9 @@ pub struct I2c {
|
|||||||
idr: InterruptControl,
|
idr: InterruptControl,
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<I2c>(), 0x2C);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0x2C);
|
||||||
|
|
||||||
impl I2c {
|
impl Registers {
|
||||||
/// Create a new I2C MMIO instance for I2C0 at address [I2C_0_BASE_ADDR].
|
/// Create a new I2C MMIO instance for I2C0 at address [I2C_0_BASE_ADDR].
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -189,7 +189,7 @@ impl I2c {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub const unsafe fn new_mmio_fixed_0() -> MmioI2c<'static> {
|
pub const unsafe fn new_mmio_fixed_0() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(I2C_0_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(I2C_0_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ impl I2c {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub const unsafe fn new_mmio_fixed_1() -> MmioI2c<'static> {
|
pub const unsafe fn new_mmio_fixed_1() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(I2C_1_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(I2C_1_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ pub struct InterruptControl {
|
|||||||
/// L2 Cache register access.
|
/// L2 Cache register access.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct L2Cache {
|
pub struct Registers {
|
||||||
#[mmio(PureRead)]
|
#[mmio(PureRead)]
|
||||||
cache_id: CacheId,
|
cache_id: CacheId,
|
||||||
#[mmio(PureRead)]
|
#[mmio(PureRead)]
|
||||||
@@ -273,9 +273,9 @@ pub struct L2Cache {
|
|||||||
power_control: u32,
|
power_control: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<L2Cache>(), 0xF84);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0xF84);
|
||||||
|
|
||||||
impl L2Cache {
|
impl Registers {
|
||||||
/// Create a new L2C MMIO instance for for L2 Cache at address [L2C_BASE_ADDR].
|
/// Create a new L2C MMIO instance for for L2 Cache at address [L2C_BASE_ADDR].
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -283,7 +283,7 @@ impl L2Cache {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub const unsafe fn new_mmio_fixed() -> MmioL2Cache<'static> {
|
pub const unsafe fn new_mmio_fixed() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(L2C_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(L2C_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,26 +43,26 @@ static PERIPHERALS_TAKEN: AtomicBool = AtomicBool::new(false);
|
|||||||
/// The [`svd2rust` documentation](https://docs.rs/svd2rust/latest/svd2rust/#peripheral-api)
|
/// The [`svd2rust` documentation](https://docs.rs/svd2rust/latest/svd2rust/#peripheral-api)
|
||||||
/// provides some more information about this.
|
/// provides some more information about this.
|
||||||
pub struct Peripherals {
|
pub struct Peripherals {
|
||||||
pub gicc: gic::MmioGicCpuInterface<'static>,
|
pub gicc: gic::MmioGicCpuInterfaceRegisters<'static>,
|
||||||
pub gicd: gic::MmioGicDistributor<'static>,
|
pub gicd: gic::MmioGicDistributorRegisters<'static>,
|
||||||
pub l2c: l2_cache::MmioL2Cache<'static>,
|
pub l2c: l2_cache::MmioRegisters<'static>,
|
||||||
pub ddrc: ddrc::MmioDdrController<'static>,
|
pub ddrc: ddrc::MmioRegisters<'static>,
|
||||||
pub uart_0: uart::MmioUart<'static>,
|
pub uart_0: uart::MmioRegisters<'static>,
|
||||||
pub uart_1: uart::MmioUart<'static>,
|
pub uart_1: uart::MmioRegisters<'static>,
|
||||||
pub spi_0: spi::MmioSpi<'static>,
|
pub spi_0: spi::MmioRegisters<'static>,
|
||||||
pub spi_1: spi::MmioSpi<'static>,
|
pub spi_1: spi::MmioRegisters<'static>,
|
||||||
pub i2c_0: i2c::MmioI2c<'static>,
|
pub i2c_0: i2c::MmioRegisters<'static>,
|
||||||
pub i2c_1: i2c::MmioI2c<'static>,
|
pub i2c_1: i2c::MmioRegisters<'static>,
|
||||||
pub gtc: gtc::MmioGlobalTimerCounter<'static>,
|
pub gtc: gtc::MmioRegisters<'static>,
|
||||||
pub gpio: gpio::MmioGpio<'static>,
|
pub gpio: gpio::MmioRegisters<'static>,
|
||||||
pub slcr: slcr::MmioSlcr<'static>,
|
pub slcr: slcr::MmioRegisters<'static>,
|
||||||
pub ttc_0: ttc::MmioTtc<'static>,
|
pub ttc_0: ttc::MmioRegisters<'static>,
|
||||||
pub ttc_1: ttc::MmioTtc<'static>,
|
pub ttc_1: ttc::MmioRegisters<'static>,
|
||||||
pub eth_0: eth::MmioEthernet<'static>,
|
pub eth_0: eth::MmioRegisters<'static>,
|
||||||
pub eth_1: eth::MmioEthernet<'static>,
|
pub eth_1: eth::MmioRegisters<'static>,
|
||||||
pub qspi: qspi::MmioQspi<'static>,
|
pub qspi: qspi::MmioRegisters<'static>,
|
||||||
pub devcfg: devcfg::MmioDevCfg<'static>,
|
pub devcfg: devcfg::MmioRegisters<'static>,
|
||||||
pub xadc: xadc::MmioXAdc<'static>,
|
pub xadc: xadc::MmioRegisters<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Peripherals {
|
impl Peripherals {
|
||||||
@@ -83,26 +83,26 @@ impl Peripherals {
|
|||||||
pub unsafe fn steal() -> Self {
|
pub unsafe fn steal() -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
Self {
|
Self {
|
||||||
gicc: gic::GicCpuInterface::new_mmio_fixed(),
|
gicc: gic::GicCpuInterfaceRegisters::new_mmio_fixed(),
|
||||||
gicd: gic::GicDistributor::new_mmio_fixed(),
|
gicd: gic::GicDistributorRegisters::new_mmio_fixed(),
|
||||||
l2c: l2_cache::L2Cache::new_mmio_fixed(),
|
l2c: l2_cache::Registers::new_mmio_fixed(),
|
||||||
ddrc: ddrc::DdrController::new_mmio_fixed(),
|
ddrc: ddrc::Registers::new_mmio_fixed(),
|
||||||
uart_0: uart::Uart::new_mmio_fixed_0(),
|
uart_0: uart::Registers::new_mmio_fixed_0(),
|
||||||
uart_1: uart::Uart::new_mmio_fixed_1(),
|
uart_1: uart::Registers::new_mmio_fixed_1(),
|
||||||
gtc: gtc::GlobalTimerCounter::new_mmio_fixed(),
|
gtc: gtc::Registers::new_mmio_fixed(),
|
||||||
gpio: gpio::Gpio::new_mmio_fixed(),
|
gpio: gpio::Registers::new_mmio_fixed(),
|
||||||
slcr: slcr::Slcr::new_mmio_fixed(),
|
slcr: slcr::Registers::new_mmio_fixed(),
|
||||||
spi_0: spi::Spi::new_mmio_fixed_0(),
|
spi_0: spi::Registers::new_mmio_fixed_0(),
|
||||||
spi_1: spi::Spi::new_mmio_fixed_1(),
|
spi_1: spi::Registers::new_mmio_fixed_1(),
|
||||||
i2c_0: i2c::I2c::new_mmio_fixed_0(),
|
i2c_0: i2c::Registers::new_mmio_fixed_0(),
|
||||||
i2c_1: i2c::I2c::new_mmio_fixed_1(),
|
i2c_1: i2c::Registers::new_mmio_fixed_1(),
|
||||||
ttc_0: ttc::Ttc::new_mmio_fixed_0(),
|
ttc_0: ttc::Registers::new_mmio_fixed_0(),
|
||||||
ttc_1: ttc::Ttc::new_mmio_fixed_1(),
|
ttc_1: ttc::Registers::new_mmio_fixed_1(),
|
||||||
eth_0: eth::Ethernet::new_mmio_fixed_0(),
|
eth_0: eth::Registers::new_mmio_fixed_0(),
|
||||||
eth_1: eth::Ethernet::new_mmio_fixed_1(),
|
eth_1: eth::Registers::new_mmio_fixed_1(),
|
||||||
qspi: qspi::Qspi::new_mmio_fixed(),
|
qspi: qspi::Registers::new_mmio_fixed(),
|
||||||
devcfg: devcfg::DevCfg::new_mmio_fixed(),
|
devcfg: devcfg::Registers::new_mmio_fixed(),
|
||||||
xadc: xadc::XAdc::new_mmio_fixed(),
|
xadc: xadc::Registers::new_mmio_fixed(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,11 @@
|
|||||||
use static_assertions::const_assert_eq;
|
use static_assertions::const_assert_eq;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
gic::{GicCpuInterface, GicDistributor, MmioGicCpuInterface, MmioGicDistributor},
|
gic::{
|
||||||
gtc::{GlobalTimerCounter, MmioGlobalTimerCounter},
|
GicCpuInterfaceRegisters, GicDistributorRegisters, MmioGicCpuInterfaceRegisters,
|
||||||
|
MmioGicDistributorRegisters,
|
||||||
|
},
|
||||||
|
gtc::{MmioRegisters, Registers},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const MPCORE_BASE_ADDR: usize = 0xF8F0_0000;
|
pub const MPCORE_BASE_ADDR: usize = 0xF8F0_0000;
|
||||||
@@ -54,10 +57,10 @@ pub struct MpCore {
|
|||||||
_reserved_0: [u32; 0x2A],
|
_reserved_0: [u32; 0x2A],
|
||||||
|
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
gicc: GicCpuInterface,
|
gicc: GicCpuInterfaceRegisters,
|
||||||
|
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
gt: GlobalTimerCounter,
|
gt: Registers,
|
||||||
|
|
||||||
_reserved_1: [u32; 0xF9],
|
_reserved_1: [u32; 0xF9],
|
||||||
|
|
||||||
@@ -78,7 +81,7 @@ pub struct MpCore {
|
|||||||
_reserved_3: [u32; 0x272],
|
_reserved_3: [u32; 0x272],
|
||||||
|
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
gicd: GicDistributor,
|
gicd: GicDistributorRegisters,
|
||||||
}
|
}
|
||||||
|
|
||||||
const_assert_eq!(core::mem::size_of::<MpCore>(), 0x2000);
|
const_assert_eq!(core::mem::size_of::<MpCore>(), 0x2000);
|
||||||
|
|||||||
@@ -24,14 +24,14 @@ pub struct InterruptStatus {
|
|||||||
/// CPU private timer register access.
|
/// CPU private timer register access.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct CpuPrivateTimer {
|
pub struct Registers {
|
||||||
reload: u32,
|
reload: u32,
|
||||||
counter: u32,
|
counter: u32,
|
||||||
control: Control,
|
control: Control,
|
||||||
interrupt_status: InterruptStatus,
|
interrupt_status: InterruptStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CpuPrivateTimer {
|
impl Registers {
|
||||||
/// Create a new CPU Private Timer MMIO instance at the fixed base address.
|
/// Create a new CPU Private Timer MMIO instance at the fixed base address.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -43,7 +43,7 @@ impl CpuPrivateTimer {
|
|||||||
/// It should also be noted that the calls to this MMIO structure are private for each CPU
|
/// It should also be noted that the calls to this MMIO structure are private for each CPU
|
||||||
/// core, which might lead to unexpected results when using this in a SMP system.
|
/// core, which might lead to unexpected results when using this in a SMP system.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const unsafe fn new_mmio_fixed() -> MmioCpuPrivateTimer<'static> {
|
pub const unsafe fn new_mmio_fixed() -> MmioRegisters<'static> {
|
||||||
unsafe { CpuPrivateTimer::new_mmio_at(CPU_PRIV_TIM_BASE_ADDR) }
|
unsafe { Registers::new_mmio_at(CPU_PRIV_TIM_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ pub struct LinearQspiStatus {
|
|||||||
/// QSPI register access.
|
/// QSPI register access.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Qspi {
|
pub struct Registers {
|
||||||
config: Config,
|
config: Config,
|
||||||
interrupt_status: InterruptStatus,
|
interrupt_status: InterruptStatus,
|
||||||
#[mmio(Write)]
|
#[mmio(Write)]
|
||||||
@@ -265,9 +265,9 @@ pub struct Qspi {
|
|||||||
module_id: u32,
|
module_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<Qspi>(), 0x100);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0x100);
|
||||||
|
|
||||||
impl Qspi {
|
impl Registers {
|
||||||
/// Create a new QSPI MMIO instance for for QSPI controller at address [QSPI_BASE_ADDR].
|
/// Create a new QSPI MMIO instance for for QSPI controller at address [QSPI_BASE_ADDR].
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -275,7 +275,7 @@ impl Qspi {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub const unsafe fn new_mmio_fixed() -> MmioQspi<'static> {
|
pub const unsafe fn new_mmio_fixed() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(QSPI_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(QSPI_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,14 +110,14 @@ pub struct FpgaClockControl {
|
|||||||
|
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct FpgaClockControlBlock {
|
pub struct FpgaClockControlRegisters {
|
||||||
ctrl: FpgaClockControl,
|
ctrl: FpgaClockControl,
|
||||||
thr_ctrl: u32,
|
thr_ctrl: u32,
|
||||||
thr_cnt: u32,
|
thr_cnt: u32,
|
||||||
thr_status: u32,
|
thr_status: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<FpgaClockControlBlock>(), 0x10);
|
static_assertions::const_assert_eq!(core::mem::size_of::<FpgaClockControlRegisters>(), 0x10);
|
||||||
|
|
||||||
#[bitbybit::bitenum(u2, exhaustive = true)]
|
#[bitbybit::bitenum(u2, exhaustive = true)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -359,7 +359,7 @@ pub struct AperClockControl {
|
|||||||
|
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ClockControl {
|
pub struct ClockControlRegisters {
|
||||||
arm_pll_ctrl: PllControl,
|
arm_pll_ctrl: PllControl,
|
||||||
ddr_pll_ctrl: PllControl,
|
ddr_pll_ctrl: PllControl,
|
||||||
io_pll_ctrl: PllControl,
|
io_pll_ctrl: PllControl,
|
||||||
@@ -391,18 +391,18 @@ pub struct ClockControl {
|
|||||||
pcap_clk_ctrl: SingleCommonPeriphIoClockControl,
|
pcap_clk_ctrl: SingleCommonPeriphIoClockControl,
|
||||||
topsw_clk_ctrl: u32,
|
topsw_clk_ctrl: u32,
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
fpga_0_clk_ctrl: FpgaClockControlBlock,
|
fpga_0_clk_ctrl: FpgaClockControlRegisters,
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
fpga_1_clk_ctrl: FpgaClockControlBlock,
|
fpga_1_clk_ctrl: FpgaClockControlRegisters,
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
fpga_2_clk_ctrl: FpgaClockControlBlock,
|
fpga_2_clk_ctrl: FpgaClockControlRegisters,
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
fpga_3_clk_ctrl: FpgaClockControlBlock,
|
fpga_3_clk_ctrl: FpgaClockControlRegisters,
|
||||||
_gap1: [u32; 5],
|
_gap1: [u32; 5],
|
||||||
clk_621_true: ClockRatioSelectReg,
|
clk_621_true: ClockRatioSelectReg,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClockControl {
|
impl ClockControlRegisters {
|
||||||
/// Create a new handle to this peripheral.
|
/// Create a new handle to this peripheral.
|
||||||
///
|
///
|
||||||
/// Writing to this register requires unlocking the SLCR registers first.
|
/// Writing to this register requires unlocking the SLCR registers first.
|
||||||
@@ -411,9 +411,9 @@ impl ClockControl {
|
|||||||
///
|
///
|
||||||
/// If you create multiple instances of this handle at the same time, you are responsible for
|
/// 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.
|
/// ensuring that there are no read-modify-write races on any of the registers.
|
||||||
pub unsafe fn new_mmio_fixed() -> MmioClockControl<'static> {
|
pub unsafe fn new_mmio_fixed() -> MmioClockControlRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(SLCR_BASE_ADDR + CLOCK_CONTROL_OFFSET) }
|
unsafe { Self::new_mmio_at(SLCR_BASE_ADDR + CLOCK_CONTROL_OFFSET) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<ClockControl>(), 0xC8);
|
static_assertions::const_assert_eq!(core::mem::size_of::<ClockControlRegisters>(), 0xC8);
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ pub struct DdriobConfig {
|
|||||||
|
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct DdrIoB {
|
pub struct DdrIobRegisters {
|
||||||
ddriob_addr0: DdriobConfig,
|
ddriob_addr0: DdriobConfig,
|
||||||
ddriob_addr1: DdriobConfig,
|
ddriob_addr1: DdriobConfig,
|
||||||
ddriob_data0: DdriobConfig,
|
ddriob_data0: DdriobConfig,
|
||||||
@@ -123,7 +123,7 @@ pub struct DdrIoB {
|
|||||||
dci_status: DciStatus,
|
dci_status: DciStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DdrIoB {
|
impl DdrIobRegisters {
|
||||||
/// Create a new handle to this peripheral.
|
/// Create a new handle to this peripheral.
|
||||||
///
|
///
|
||||||
/// Writing to this register requires unlocking the SLCR registers first.
|
/// Writing to this register requires unlocking the SLCR registers first.
|
||||||
@@ -132,9 +132,9 @@ impl DdrIoB {
|
|||||||
///
|
///
|
||||||
/// If you create multiple instances of this handle at the same time, you are responsible for
|
/// 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.
|
/// ensuring that there are no read-modify-write races on any of the registers.
|
||||||
pub unsafe fn new_mmio_fixed() -> MmioDdrIoB<'static> {
|
pub unsafe fn new_mmio_fixed() -> MmioDdrIobRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(super::SLCR_BASE_ADDR + super::DDRIOB_OFFSET) }
|
unsafe { Self::new_mmio_at(super::SLCR_BASE_ADDR + super::DDRIOB_OFFSET) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<DdrIoB>(), 0x38);
|
static_assertions::const_assert_eq!(core::mem::size_of::<DdrIobRegisters>(), 0x38);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Writing any of these registers required unlocking the SLCR first.
|
//! Writing any of these registers required unlocking the SLCR first.
|
||||||
use arbitrary_int::u4;
|
use arbitrary_int::u4;
|
||||||
pub use clocks::{ClockControl, MmioClockControl};
|
pub use clocks::{ClockControlRegisters, MmioClockControlRegisters};
|
||||||
pub use reset::{MmioResetControl, ResetControl};
|
pub use reset::{MmioResetControl, ResetControl};
|
||||||
|
|
||||||
const SLCR_BASE_ADDR: usize = 0xF8000000;
|
const SLCR_BASE_ADDR: usize = 0xF8000000;
|
||||||
@@ -94,7 +94,7 @@ pub struct LevelShifterRegister {
|
|||||||
/// System Level Control Registers access.
|
/// System Level Control Registers access.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Slcr {
|
pub struct Registers {
|
||||||
/// Secure configuration lock.
|
/// Secure configuration lock.
|
||||||
scl: u32,
|
scl: u32,
|
||||||
/// SLCR write protection lock
|
/// SLCR write protection lock
|
||||||
@@ -107,7 +107,7 @@ pub struct Slcr {
|
|||||||
_gap0: [u32; 0x3C],
|
_gap0: [u32; 0x3C],
|
||||||
|
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
clk_ctrl: ClockControl,
|
clk_ctrl: ClockControlRegisters,
|
||||||
|
|
||||||
_gap1: [u32; 0x0E],
|
_gap1: [u32; 0x0E],
|
||||||
|
|
||||||
@@ -180,12 +180,12 @@ pub struct Slcr {
|
|||||||
gpiob: GpiobRegisters,
|
gpiob: GpiobRegisters,
|
||||||
|
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
ddriob: ddriob::DdrIoB,
|
ddriob: ddriob::DdrIobRegisters,
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<Slcr>(), 0xB78);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0xB78);
|
||||||
|
|
||||||
impl Slcr {
|
impl Registers {
|
||||||
/// Create a new handle to this peripheral.
|
/// Create a new handle to this peripheral.
|
||||||
///
|
///
|
||||||
/// Writing to this register requires unlocking the SLCR registers first.
|
/// Writing to this register requires unlocking the SLCR registers first.
|
||||||
@@ -194,7 +194,7 @@ impl Slcr {
|
|||||||
///
|
///
|
||||||
/// If you create multiple instances of this handle at the same time, you are responsible for
|
/// 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.
|
/// ensuring that there are no read-modify-write races on any of the registers.
|
||||||
pub unsafe fn new_mmio_fixed() -> MmioSlcr<'static> {
|
pub unsafe fn new_mmio_fixed() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(SLCR_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(SLCR_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ impl BaudDivSel {
|
|||||||
|
|
||||||
// TODO: Use bitbybit debug support as soon as it was added.
|
// TODO: Use bitbybit debug support as soon as it was added.
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
#[bit(17, rw)]
|
#[bit(17, rw)]
|
||||||
modefail_gen_en: bool,
|
modefail_gen_en: bool,
|
||||||
@@ -181,7 +180,7 @@ pub struct DelayControl {
|
|||||||
/// SPI register access.
|
/// SPI register access.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Spi {
|
pub struct Registers {
|
||||||
cr: Config,
|
cr: Config,
|
||||||
#[mmio(PureRead, Write)]
|
#[mmio(PureRead, Write)]
|
||||||
isr: InterruptStatus,
|
isr: InterruptStatus,
|
||||||
@@ -209,9 +208,9 @@ pub struct Spi {
|
|||||||
mod_id: u32,
|
mod_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<Spi>(), 0x100);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0x100);
|
||||||
|
|
||||||
impl Spi {
|
impl Registers {
|
||||||
/// Create a new SPI MMIO instance for SPI0 at address [SPI_0_BASE_ADDR].
|
/// Create a new SPI MMIO instance for SPI0 at address [SPI_0_BASE_ADDR].
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -219,7 +218,7 @@ impl Spi {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub const unsafe fn new_mmio_fixed_0() -> MmioSpi<'static> {
|
pub const unsafe fn new_mmio_fixed_0() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(SPI_0_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(SPI_0_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +229,7 @@ impl Spi {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub const unsafe fn new_mmio_fixed_1() -> MmioSpi<'static> {
|
pub const unsafe fn new_mmio_fixed_1() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(SPI_1_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(SPI_1_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ pub struct EventCount {
|
|||||||
/// Triple-timer counter register access.
|
/// Triple-timer counter register access.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Ttc {
|
pub struct Registers {
|
||||||
clk_cntr: [ClockControl; 3],
|
clk_cntr: [ClockControl; 3],
|
||||||
cnt_ctrl: [CounterControl; 3],
|
cnt_ctrl: [CounterControl; 3],
|
||||||
#[mmio(PureRead)]
|
#[mmio(PureRead)]
|
||||||
@@ -162,9 +162,9 @@ pub struct Ttc {
|
|||||||
event_reg: [EventCount; 3],
|
event_reg: [EventCount; 3],
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<Ttc>(), 0x84);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0x84);
|
||||||
|
|
||||||
impl Ttc {
|
impl Registers {
|
||||||
/// Create a new TTC MMIO instance for TTC0 at address [TTC_0_BASE_ADDR].
|
/// Create a new TTC MMIO instance for TTC0 at address [TTC_0_BASE_ADDR].
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -172,7 +172,7 @@ impl Ttc {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub const unsafe fn new_mmio_fixed_0() -> MmioTtc<'static> {
|
pub const unsafe fn new_mmio_fixed_0() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(TTC_0_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(TTC_0_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ impl Ttc {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub const unsafe fn new_mmio_fixed_1() -> MmioTtc<'static> {
|
pub const unsafe fn new_mmio_fixed_1() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(TTC_1_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(TTC_1_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ impl InterruptStatus {
|
|||||||
/// UART register access.
|
/// UART register access.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Uart {
|
pub struct Registers {
|
||||||
/// Control Register
|
/// Control Register
|
||||||
cr: Control,
|
cr: Control,
|
||||||
/// Mode register
|
/// Mode register
|
||||||
@@ -325,9 +325,9 @@ pub struct Uart {
|
|||||||
tx_fifo_trigger: FifoTrigger,
|
tx_fifo_trigger: FifoTrigger,
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<Uart>(), 0x48);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0x48);
|
||||||
|
|
||||||
impl Uart {
|
impl Registers {
|
||||||
/// Create a new UART MMIO instance for uart0 at address 0xE000_0000.
|
/// Create a new UART MMIO instance for uart0 at address 0xE000_0000.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -335,7 +335,7 @@ impl Uart {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub const unsafe fn new_mmio_fixed_0() -> MmioUart<'static> {
|
pub const unsafe fn new_mmio_fixed_0() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(UART_0_BASE) }
|
unsafe { Self::new_mmio_at(UART_0_BASE) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,7 +346,7 @@ impl Uart {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub const unsafe fn new_mmio_fixed_1() -> MmioUart<'static> {
|
pub const unsafe fn new_mmio_fixed_1() -> MmioRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(UART_1_BASE) }
|
unsafe { Self::new_mmio_at(UART_1_BASE) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ pub const XADC_BASE_ADDR: usize = 0xF8007100;
|
|||||||
/// XADC register access.
|
/// XADC register access.
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct XAdc {
|
pub struct Registers {
|
||||||
config: u32,
|
config: u32,
|
||||||
interrupt_status: u32,
|
interrupt_status: u32,
|
||||||
interrupt_mask: u32,
|
interrupt_mask: u32,
|
||||||
@@ -13,7 +13,7 @@ pub struct XAdc {
|
|||||||
misc_control: u32,
|
misc_control: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XAdc {
|
impl Registers {
|
||||||
/// Create a new XADC MMIO instance for for device configuration peripheral at address
|
/// Create a new XADC MMIO instance for for device configuration peripheral at address
|
||||||
/// [XADC_BASE_ADDR].
|
/// [XADC_BASE_ADDR].
|
||||||
///
|
///
|
||||||
@@ -22,9 +22,9 @@ impl XAdc {
|
|||||||
/// This API can be used to potentially create a driver to the same peripheral structure
|
/// This API can be used to potentially create a driver to the same peripheral structure
|
||||||
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
|
||||||
/// interfere with each other.
|
/// interfere with each other.
|
||||||
pub unsafe fn new_mmio_fixed() -> MmioXAdc<'static> {
|
pub unsafe fn new_mmio_fixed() -> MmioRegisters<'static> {
|
||||||
unsafe { XAdc::new_mmio_at(XADC_BASE_ADDR) }
|
unsafe { Registers::new_mmio_at(XADC_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<XAdc>(), 0x1C);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Registers>(), 0x1C);
|
||||||
|
|||||||
Reference in New Issue
Block a user