continue eth support
This commit is contained in:
parent
b8fdf1008b
commit
8c9e34f96a
@ -1,5 +1,349 @@
|
||||
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.
|
||||
///
|
||||
/// 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));
|
||||
}
|
||||
|
||||
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]
|
||||
pub fn is_low(&self) -> bool {
|
||||
let (offset, in_reg) = self.get_data_in_reg_and_local_offset();
|
||||
|
@ -31,6 +31,10 @@ impl MuxConf {
|
||||
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 {
|
||||
Self::new(false, false, u2::new(0b00), l3)
|
||||
}
|
||||
|
@ -384,6 +384,8 @@ pub struct 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 {
|
||||
let mut low_level = LowLevelGpio::new(PinOffset::Mio(pin.offset()));
|
||||
low_level.configure_as_io_periph_pin(mux_conf, pullup);
|
||||
@ -392,6 +394,43 @@ impl IoPeriphPin {
|
||||
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 {
|
||||
|
@ -14,7 +14,7 @@ impl Slcr {
|
||||
/// 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
|
||||
/// 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() };
|
||||
slcr.write_unlock(UNLOCK_KEY);
|
||||
f(&mut slcr);
|
||||
|
@ -17,7 +17,7 @@ pub enum IoType {
|
||||
Hstl = 0b100,
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32)]
|
||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||
#[derive(Debug)]
|
||||
pub struct Config {
|
||||
#[bit(13, rw)]
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! System Level Control Registers (slcr)
|
||||
//!
|
||||
//! 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 reset::{MmioResetControl, ResetControl};
|
||||
|
||||
@ -50,10 +50,27 @@ impl DdrIoB {
|
||||
|
||||
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)]
|
||||
#[repr(C)]
|
||||
pub struct GpiobCtrl {
|
||||
ctrl: u32,
|
||||
pub struct GpiobRegisters {
|
||||
ctrl: GpiobControl,
|
||||
cfg_cmos18: u32,
|
||||
cfg_cmos25: u32,
|
||||
cfg_cmos33: u32,
|
||||
@ -62,7 +79,7 @@ pub struct GpiobCtrl {
|
||||
drvr_bias_ctrl: u32,
|
||||
}
|
||||
|
||||
impl GpiobCtrl {
|
||||
impl GpiobRegisters {
|
||||
/// Create a new handle to this peripheral.
|
||||
///
|
||||
/// 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
|
||||
/// 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) }
|
||||
}
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32)]
|
||||
#[derive(Debug)]
|
||||
pub struct BootModeRegister {
|
||||
#[bit(4, r)]
|
||||
pll_bypass: bool,
|
||||
@ -183,7 +201,7 @@ pub struct Slcr {
|
||||
_gap18: [u32; 0x09],
|
||||
|
||||
#[mmio(inner)]
|
||||
gpiob: GpiobCtrl,
|
||||
gpiob: GpiobRegisters,
|
||||
|
||||
#[mmio(inner)]
|
||||
ddriob: DdrIoB,
|
||||
|
Loading…
x
Reference in New Issue
Block a user