continue eth support
This commit is contained in:
parent
b8fdf1008b
commit
8c9e34f96a
@ -1,5 +1,349 @@
|
|||||||
use arbitrary_int::{u2, u3, u13, u30};
|
use arbitrary_int::{u2, u3, u13, u30};
|
||||||
|
use zynq7000::eth::{GEM_0_BASE_ADDR, GEM_1_BASE_ADDR, MmioEthernet};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
use crate::gpio::mio::{Mio28, Mio29, Mio30, Mio31, Mio32, Mio33};
|
||||||
|
use crate::gpio::{
|
||||||
|
IoPeriphPin,
|
||||||
|
mio::{
|
||||||
|
Mio16, Mio17, Mio18, Mio19, Mio20, Mio21, Mio22, Mio23, Mio24, Mio25, Mio26, Mio27, Mio34,
|
||||||
|
Mio35, Mio36, Mio37, Mio38, Mio39, Mio52, Mio53, MioPinMarker, MuxConf, Pin,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const MUX_CONF_PHY: MuxConf = MuxConf::new_with_l0();
|
||||||
|
pub const MUX_CONF_MDIO: MuxConf = MuxConf::new_with_l3(u3::new(0b100));
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum EthernetId {
|
||||||
|
Eth0 = 0,
|
||||||
|
Eth1 = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PsEthernet {
|
||||||
|
fn reg_block(&self) -> MmioEthernet<'static>;
|
||||||
|
fn id(&self) -> Option<EthernetId>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PsEthernet for MmioEthernet<'static> {
|
||||||
|
#[inline]
|
||||||
|
fn reg_block(&self) -> MmioEthernet<'static> {
|
||||||
|
unsafe { self.clone() }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn id(&self) -> Option<EthernetId> {
|
||||||
|
let base_addr = unsafe { self.ptr() } as usize;
|
||||||
|
if base_addr == GEM_0_BASE_ADDR {
|
||||||
|
return Some(EthernetId::Eth0);
|
||||||
|
} else if base_addr == GEM_1_BASE_ADDR {
|
||||||
|
return Some(EthernetId::Eth1);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait TxClk: MioPinMarker {
|
||||||
|
const ETH_ID: EthernetId;
|
||||||
|
}
|
||||||
|
pub trait TxCtrl: MioPinMarker {
|
||||||
|
const ETH_ID: EthernetId;
|
||||||
|
}
|
||||||
|
pub trait TxData0: MioPinMarker {
|
||||||
|
const ETH_ID: EthernetId;
|
||||||
|
}
|
||||||
|
pub trait TxData1: MioPinMarker {
|
||||||
|
const ETH_ID: EthernetId;
|
||||||
|
}
|
||||||
|
pub trait TxData2: MioPinMarker {
|
||||||
|
const ETH_ID: EthernetId;
|
||||||
|
}
|
||||||
|
pub trait TxData3: MioPinMarker {
|
||||||
|
const ETH_ID: EthernetId;
|
||||||
|
}
|
||||||
|
pub trait RxClk: MioPinMarker {
|
||||||
|
const ETH_ID: EthernetId;
|
||||||
|
}
|
||||||
|
pub trait RxCtrl: MioPinMarker {
|
||||||
|
const ETH_ID: EthernetId;
|
||||||
|
}
|
||||||
|
pub trait RxData0: MioPinMarker {
|
||||||
|
const ETH_ID: EthernetId;
|
||||||
|
}
|
||||||
|
pub trait RxData1: MioPinMarker {
|
||||||
|
const ETH_ID: EthernetId;
|
||||||
|
}
|
||||||
|
pub trait RxData2: MioPinMarker {
|
||||||
|
const ETH_ID: EthernetId;
|
||||||
|
}
|
||||||
|
pub trait RxData3: MioPinMarker {
|
||||||
|
const ETH_ID: EthernetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait MdClk: MioPinMarker {}
|
||||||
|
pub trait MdIo: MioPinMarker {}
|
||||||
|
|
||||||
|
impl MdClk for Pin<Mio52> {}
|
||||||
|
impl MdIo for Pin<Mio53> {}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl TxClk for Pin<Mio16> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth0;
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl TxCtrl for Pin<Mio21> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth0;
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl TxData0 for Pin<Mio17> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth0;
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl TxData1 for Pin<Mio18> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth0;
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl TxData2 for Pin<Mio19> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth0;
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl TxData3 for Pin<Mio20> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth0;
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl RxClk for Pin<Mio22> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth0;
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl RxCtrl for Pin<Mio27> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth0;
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl RxData0 for Pin<Mio23> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth0;
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl RxData1 for Pin<Mio24> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth0;
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl RxData2 for Pin<Mio25> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth0;
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
|
impl RxData3 for Pin<Mio26> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth0;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TxClk for Pin<Mio28> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth1;
|
||||||
|
}
|
||||||
|
impl TxCtrl for Pin<Mio33> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth1;
|
||||||
|
}
|
||||||
|
impl TxData0 for Pin<Mio29> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth1;
|
||||||
|
}
|
||||||
|
impl TxData1 for Pin<Mio30> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth1;
|
||||||
|
}
|
||||||
|
impl TxData2 for Pin<Mio31> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth1;
|
||||||
|
}
|
||||||
|
impl TxData3 for Pin<Mio32> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth1;
|
||||||
|
}
|
||||||
|
impl RxClk for Pin<Mio34> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth1;
|
||||||
|
}
|
||||||
|
impl RxCtrl for Pin<Mio39> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth1;
|
||||||
|
}
|
||||||
|
impl RxData0 for Pin<Mio35> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth1;
|
||||||
|
}
|
||||||
|
impl RxData1 for Pin<Mio36> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth1;
|
||||||
|
}
|
||||||
|
impl RxData2 for Pin<Mio37> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth1;
|
||||||
|
}
|
||||||
|
impl RxData3 for Pin<Mio38> {
|
||||||
|
const ETH_ID: EthernetId = EthernetId::Eth1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct EthernetLowLevel(zynq7000::eth::MmioEthernet<'static>);
|
||||||
|
|
||||||
|
impl EthernetLowLevel {
|
||||||
|
/// Creates a new instance of the Ethernet low-level interface.
|
||||||
|
pub fn new(eth: zynq7000::eth::MmioEthernet<'static>) -> Self {
|
||||||
|
EthernetLowLevel(eth)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to the underlying MMIO Ethernet interface.
|
||||||
|
pub fn regs(&self) -> &zynq7000::eth::MmioEthernet<'static> {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a mutable reference to the underlying MMIO Ethernet interface.
|
||||||
|
pub fn regs_mut(&mut self) -> &mut zynq7000::eth::MmioEthernet<'static> {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Ethernet {
|
||||||
|
ll: EthernetLowLevel,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ethernet {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub fn new_with_mio<
|
||||||
|
TxClkPin: TxClk,
|
||||||
|
TxCtrlPin: TxCtrl,
|
||||||
|
TxData0Pin: TxData0,
|
||||||
|
TxData1Pin: TxData1,
|
||||||
|
TxData2Pin: TxData2,
|
||||||
|
TxData3Pin: TxData3,
|
||||||
|
RxClkPin: RxClk,
|
||||||
|
RxCtrlPin: RxCtrl,
|
||||||
|
RxData0Pin: RxData0,
|
||||||
|
RxData1Pin: RxData1,
|
||||||
|
RxData2Pin: RxData2,
|
||||||
|
RxData3Pin: RxData3,
|
||||||
|
MdClkPin: MdClk,
|
||||||
|
MdIoPin: MdIo,
|
||||||
|
>(
|
||||||
|
ll: EthernetLowLevel,
|
||||||
|
tx_clk: TxClkPin,
|
||||||
|
tx_ctrl: TxCtrlPin,
|
||||||
|
tx_data: (TxData0Pin, TxData1Pin, TxData2Pin, TxData3Pin),
|
||||||
|
rx_clk: RxClkPin,
|
||||||
|
rx_ctrl: RxCtrlPin,
|
||||||
|
rx_data: (RxData0Pin, RxData1Pin, RxData2Pin, RxData3Pin),
|
||||||
|
md_pins: Option<(MdClkPin, MdIoPin)>,
|
||||||
|
) -> Self {
|
||||||
|
let tx_mio_config = zynq7000::slcr::mio::Config::builder()
|
||||||
|
.with_disable_hstl_rcvr(true)
|
||||||
|
.with_pullup(true)
|
||||||
|
.with_io_type(zynq7000::slcr::mio::IoType::Hstl)
|
||||||
|
.with_speed(zynq7000::slcr::mio::Speed::FastCmosEdge)
|
||||||
|
.with_l3_sel(MUX_CONF_PHY.l3_sel())
|
||||||
|
.with_l2_sel(MUX_CONF_PHY.l2_sel())
|
||||||
|
.with_l1_sel(MUX_CONF_PHY.l1_sel())
|
||||||
|
.with_l0_sel(MUX_CONF_PHY.l0_sel())
|
||||||
|
.with_tri_enable(false)
|
||||||
|
.build();
|
||||||
|
let rx_mio_config = zynq7000::slcr::mio::Config::builder()
|
||||||
|
.with_disable_hstl_rcvr(false)
|
||||||
|
.with_pullup(true)
|
||||||
|
.with_io_type(zynq7000::slcr::mio::IoType::Hstl)
|
||||||
|
.with_speed(zynq7000::slcr::mio::Speed::FastCmosEdge)
|
||||||
|
.with_l3_sel(MUX_CONF_PHY.l3_sel())
|
||||||
|
.with_l2_sel(MUX_CONF_PHY.l2_sel())
|
||||||
|
.with_l1_sel(MUX_CONF_PHY.l1_sel())
|
||||||
|
.with_l0_sel(MUX_CONF_PHY.l0_sel())
|
||||||
|
// Disable output driver.
|
||||||
|
.with_tri_enable(true)
|
||||||
|
.build();
|
||||||
|
unsafe {
|
||||||
|
crate::slcr::Slcr::with(|slcr_mut| {
|
||||||
|
IoPeriphPin::new_with_full_config_and_unlocked_slcr(
|
||||||
|
tx_clk,
|
||||||
|
slcr_mut,
|
||||||
|
tx_mio_config,
|
||||||
|
);
|
||||||
|
IoPeriphPin::new_with_full_config_and_unlocked_slcr(
|
||||||
|
tx_ctrl,
|
||||||
|
slcr_mut,
|
||||||
|
tx_mio_config,
|
||||||
|
);
|
||||||
|
IoPeriphPin::new_with_full_config_and_unlocked_slcr(
|
||||||
|
tx_data.0,
|
||||||
|
slcr_mut,
|
||||||
|
tx_mio_config,
|
||||||
|
);
|
||||||
|
IoPeriphPin::new_with_full_config_and_unlocked_slcr(
|
||||||
|
tx_data.1,
|
||||||
|
slcr_mut,
|
||||||
|
tx_mio_config,
|
||||||
|
);
|
||||||
|
IoPeriphPin::new_with_full_config_and_unlocked_slcr(
|
||||||
|
tx_data.2,
|
||||||
|
slcr_mut,
|
||||||
|
tx_mio_config,
|
||||||
|
);
|
||||||
|
IoPeriphPin::new_with_full_config_and_unlocked_slcr(
|
||||||
|
tx_data.3,
|
||||||
|
slcr_mut,
|
||||||
|
tx_mio_config,
|
||||||
|
);
|
||||||
|
IoPeriphPin::new_with_full_config_and_unlocked_slcr(
|
||||||
|
rx_clk,
|
||||||
|
slcr_mut,
|
||||||
|
rx_mio_config,
|
||||||
|
);
|
||||||
|
IoPeriphPin::new_with_full_config_and_unlocked_slcr(
|
||||||
|
rx_ctrl,
|
||||||
|
slcr_mut,
|
||||||
|
rx_mio_config,
|
||||||
|
);
|
||||||
|
IoPeriphPin::new_with_full_config_and_unlocked_slcr(
|
||||||
|
rx_data.0,
|
||||||
|
slcr_mut,
|
||||||
|
rx_mio_config,
|
||||||
|
);
|
||||||
|
IoPeriphPin::new_with_full_config_and_unlocked_slcr(
|
||||||
|
rx_data.1,
|
||||||
|
slcr_mut,
|
||||||
|
rx_mio_config,
|
||||||
|
);
|
||||||
|
IoPeriphPin::new_with_full_config_and_unlocked_slcr(
|
||||||
|
rx_data.2,
|
||||||
|
slcr_mut,
|
||||||
|
rx_mio_config,
|
||||||
|
);
|
||||||
|
IoPeriphPin::new_with_full_config_and_unlocked_slcr(
|
||||||
|
rx_data.3,
|
||||||
|
slcr_mut,
|
||||||
|
rx_mio_config,
|
||||||
|
);
|
||||||
|
if let Some((md_clk, md_io)) = md_pins {
|
||||||
|
let md_mio_config = zynq7000::slcr::mio::Config::builder()
|
||||||
|
.with_disable_hstl_rcvr(false)
|
||||||
|
.with_pullup(true)
|
||||||
|
.with_io_type(zynq7000::slcr::mio::IoType::LvCmos18)
|
||||||
|
.with_speed(zynq7000::slcr::mio::Speed::SlowCmosEdge)
|
||||||
|
.with_l3_sel(MUX_CONF_MDIO.l3_sel())
|
||||||
|
.with_l2_sel(MUX_CONF_MDIO.l2_sel())
|
||||||
|
.with_l1_sel(MUX_CONF_MDIO.l1_sel())
|
||||||
|
.with_l0_sel(MUX_CONF_MDIO.l0_sel())
|
||||||
|
.with_tri_enable(false)
|
||||||
|
.build();
|
||||||
|
IoPeriphPin::new_with_full_config_and_unlocked_slcr(
|
||||||
|
md_clk,
|
||||||
|
slcr_mut,
|
||||||
|
md_mio_config,
|
||||||
|
);
|
||||||
|
IoPeriphPin::new_with_full_config_and_unlocked_slcr(
|
||||||
|
md_io,
|
||||||
|
slcr_mut,
|
||||||
|
md_mio_config,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Enable VREF internal generator, which is required for HSTL pin mode.
|
||||||
|
slcr_mut.gpiob().modify_ctrl(|mut ctrl| {
|
||||||
|
ctrl.set_vref_en(true);
|
||||||
|
ctrl
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ethernet { ll }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(ll: EthernetLowLevel) -> Self {
|
||||||
|
Ethernet { ll }
|
||||||
|
}
|
||||||
|
}
|
||||||
/// RX buffer descriptor.
|
/// RX buffer descriptor.
|
||||||
///
|
///
|
||||||
/// The user should declare an array of this structure inside uncached memory.
|
/// The user should declare an array of this structure inside uncached memory.
|
||||||
|
@ -148,6 +148,23 @@ impl LowLevelGpio {
|
|||||||
self.reconfigure_slcr_mio_cfg(false, pullup, Some(mux_conf));
|
self.reconfigure_slcr_mio_cfg(false, pullup, Some(mux_conf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_mio_pin_config(&mut self, config: zynq7000::slcr::mio::Config) {
|
||||||
|
let raw_offset = self.offset.offset();
|
||||||
|
// Safety: We only modify the MIO config of the pin.
|
||||||
|
let mut slcr_wrapper = unsafe { Slcr::steal() };
|
||||||
|
slcr_wrapper.modify(|mut_slcr| mut_slcr.write_mio_pins(raw_offset, config).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the MIO pin configuration with an unlocked SLCR.
|
||||||
|
pub fn set_mio_pin_config_with_unlocked_slcr(
|
||||||
|
&mut self,
|
||||||
|
slcr: &mut zynq7000::slcr::MmioSlcr<'static>,
|
||||||
|
config: zynq7000::slcr::mio::Config,
|
||||||
|
) {
|
||||||
|
let raw_offset = self.offset.offset();
|
||||||
|
slcr.write_mio_pins(raw_offset, config).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_low(&self) -> bool {
|
pub fn is_low(&self) -> bool {
|
||||||
let (offset, in_reg) = self.get_data_in_reg_and_local_offset();
|
let (offset, in_reg) = self.get_data_in_reg_and_local_offset();
|
||||||
|
@ -31,6 +31,10 @@ impl MuxConf {
|
|||||||
Self { l3, l2, l1, l0 }
|
Self { l3, l2, l1, l0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn new_with_l0() -> Self {
|
||||||
|
Self::new(true, false, u2::new(0b00), u3::new(0b000))
|
||||||
|
}
|
||||||
|
|
||||||
pub const fn new_with_l3(l3: u3) -> Self {
|
pub const fn new_with_l3(l3: u3) -> Self {
|
||||||
Self::new(false, false, u2::new(0b00), l3)
|
Self::new(false, false, u2::new(0b00), l3)
|
||||||
}
|
}
|
||||||
|
@ -384,6 +384,8 @@ pub struct IoPeriphPin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl IoPeriphPin {
|
impl IoPeriphPin {
|
||||||
|
/// Constructor for IO peripheral pins where only the multiplexer and pullup configuration
|
||||||
|
/// need to be changed.
|
||||||
pub fn new(pin: impl MioPinMarker, mux_conf: MuxConf, pullup: Option<bool>) -> Self {
|
pub fn new(pin: impl MioPinMarker, mux_conf: MuxConf, pullup: Option<bool>) -> Self {
|
||||||
let mut low_level = LowLevelGpio::new(PinOffset::Mio(pin.offset()));
|
let mut low_level = LowLevelGpio::new(PinOffset::Mio(pin.offset()));
|
||||||
low_level.configure_as_io_periph_pin(mux_conf, pullup);
|
low_level.configure_as_io_periph_pin(mux_conf, pullup);
|
||||||
@ -392,6 +394,43 @@ impl IoPeriphPin {
|
|||||||
mux_conf,
|
mux_conf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructor to fully configure an IO peripheral pin with a specific MIO pin configuration.
|
||||||
|
pub fn new_with_full_config(
|
||||||
|
pin: impl MioPinMarker,
|
||||||
|
config: zynq7000::slcr::mio::Config,
|
||||||
|
) -> Self {
|
||||||
|
let mut low_level = LowLevelGpio::new(PinOffset::Mio(pin.offset()));
|
||||||
|
low_level.set_mio_pin_config(config);
|
||||||
|
Self {
|
||||||
|
pin: low_level,
|
||||||
|
mux_conf: MuxConf::new(
|
||||||
|
config.l0_sel(),
|
||||||
|
config.l1_sel(),
|
||||||
|
config.l2_sel(),
|
||||||
|
config.l3_sel(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Constructor to fully configure an IO peripheral pin with a specific MIO pin configuration.
|
||||||
|
pub fn new_with_full_config_and_unlocked_slcr(
|
||||||
|
pin: impl MioPinMarker,
|
||||||
|
slcr: &mut zynq7000::slcr::MmioSlcr<'static>,
|
||||||
|
config: zynq7000::slcr::mio::Config,
|
||||||
|
) -> Self {
|
||||||
|
let mut low_level = LowLevelGpio::new(PinOffset::Mio(pin.offset()));
|
||||||
|
low_level.set_mio_pin_config_with_unlocked_slcr(slcr, config);
|
||||||
|
Self {
|
||||||
|
pin: low_level,
|
||||||
|
mux_conf: MuxConf::new(
|
||||||
|
config.l0_sel(),
|
||||||
|
config.l1_sel(),
|
||||||
|
config.l2_sel(),
|
||||||
|
config.l3_sel(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IoPinProvider for IoPeriphPin {
|
impl IoPinProvider for IoPeriphPin {
|
||||||
|
@ -14,7 +14,7 @@ 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: FnMut(&mut MmioSlcr)>(mut f: F) {
|
pub unsafe fn with<F: FnOnce(&mut MmioSlcr<'static>)>(f: F) {
|
||||||
let mut slcr = unsafe { zynq7000::slcr::Slcr::new_mmio_fixed() };
|
let mut slcr = unsafe { zynq7000::slcr::Slcr::new_mmio_fixed() };
|
||||||
slcr.write_unlock(UNLOCK_KEY);
|
slcr.write_unlock(UNLOCK_KEY);
|
||||||
f(&mut slcr);
|
f(&mut slcr);
|
||||||
|
@ -17,7 +17,7 @@ pub enum IoType {
|
|||||||
Hstl = 0b100,
|
Hstl = 0b100,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
#[bit(13, rw)]
|
#[bit(13, rw)]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! System Level Control Registers (slcr)
|
//! System Level Control Registers (slcr)
|
||||||
//!
|
//!
|
||||||
//! 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::{u3, u4};
|
||||||
pub use clocks::{ClockControl, MmioClockControl};
|
pub use clocks::{ClockControl, MmioClockControl};
|
||||||
pub use reset::{MmioResetControl, ResetControl};
|
pub use reset::{MmioResetControl, ResetControl};
|
||||||
|
|
||||||
@ -50,10 +50,27 @@ impl DdrIoB {
|
|||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<DdrIoB>(), 0x38);
|
static_assertions::const_assert_eq!(core::mem::size_of::<DdrIoB>(), 0x38);
|
||||||
|
|
||||||
|
#[bitbybit::bitenum(u3, exhaustive = false)]
|
||||||
|
pub enum VrefSel {
|
||||||
|
Disabled = 0b000,
|
||||||
|
Vref0_9V = 0b001,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bitbybit::bitfield(u32)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GpiobControl {
|
||||||
|
#[bit(11, rw)]
|
||||||
|
vref_sw_en: bool,
|
||||||
|
#[bits(4..=6, rw)]
|
||||||
|
vref_sel: Option<VrefSel>,
|
||||||
|
#[bit(0, rw)]
|
||||||
|
vref_en: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct GpiobCtrl {
|
pub struct GpiobRegisters {
|
||||||
ctrl: u32,
|
ctrl: GpiobControl,
|
||||||
cfg_cmos18: u32,
|
cfg_cmos18: u32,
|
||||||
cfg_cmos25: u32,
|
cfg_cmos25: u32,
|
||||||
cfg_cmos33: u32,
|
cfg_cmos33: u32,
|
||||||
@ -62,7 +79,7 @@ pub struct GpiobCtrl {
|
|||||||
drvr_bias_ctrl: u32,
|
drvr_bias_ctrl: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GpiobCtrl {
|
impl GpiobRegisters {
|
||||||
/// 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.
|
||||||
@ -71,12 +88,13 @@ impl GpiobCtrl {
|
|||||||
///
|
///
|
||||||
/// 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() -> MmioGpiobCtrl<'static> {
|
pub unsafe fn new_mmio_fixed() -> MmioGpiobRegisters<'static> {
|
||||||
unsafe { Self::new_mmio_at(SLCR_BASE_ADDR + GPIOB_OFFSET) }
|
unsafe { Self::new_mmio_at(SLCR_BASE_ADDR + GPIOB_OFFSET) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct BootModeRegister {
|
pub struct BootModeRegister {
|
||||||
#[bit(4, r)]
|
#[bit(4, r)]
|
||||||
pll_bypass: bool,
|
pll_bypass: bool,
|
||||||
@ -183,7 +201,7 @@ pub struct Slcr {
|
|||||||
_gap18: [u32; 0x09],
|
_gap18: [u32; 0x09],
|
||||||
|
|
||||||
#[mmio(inner)]
|
#[mmio(inner)]
|
||||||
gpiob: GpiobCtrl,
|
gpiob: GpiobRegisters,
|
||||||
|
|
||||||
#[mmio(inner)]
|
#[mmio(inner)]
|
||||||
ddriob: DdrIoB,
|
ddriob: DdrIoB,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user