after some further deliberation, readability is more important
Some checks failed
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled
Some checks failed
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled
This commit is contained in:
@@ -17,7 +17,7 @@ use zynq7000_hal::{
|
|||||||
gtc::GlobalTimerCounter,
|
gtc::GlobalTimerCounter,
|
||||||
l2_cache,
|
l2_cache,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClockConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
use zynq7000::PsPeripherals;
|
use zynq7000::PsPeripherals;
|
||||||
@@ -64,7 +64,7 @@ async fn main(_spawner: Spawner) -> ! {
|
|||||||
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
||||||
|
|
||||||
// Set up the UART, we are logging with it.
|
// Set up the UART, we are logging with it.
|
||||||
let uart_clk_config = ClkConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let mut uart = Uart::new_with_mio(
|
let mut uart = Uart::new_with_mio(
|
||||||
|
@@ -18,7 +18,7 @@ use zynq7000_hal::{
|
|||||||
gtc::GlobalTimerCounter,
|
gtc::GlobalTimerCounter,
|
||||||
l2_cache,
|
l2_cache,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{ClkConfigRaw, TxAsync, Uart, UartConfig, on_interrupt_tx},
|
uart::{ClockConfigRaw, TxAsync, Uart, UartConfig, on_interrupt_tx},
|
||||||
};
|
};
|
||||||
|
|
||||||
use zynq7000_rt as _;
|
use zynq7000_rt as _;
|
||||||
@@ -58,7 +58,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
let mio_pins = mio::Pins::new(dp.gpio);
|
let mio_pins = mio::Pins::new(dp.gpio);
|
||||||
|
|
||||||
// Set up the UART, we are logging with it.
|
// Set up the UART, we are logging with it.
|
||||||
let uart_clk_config = ClkConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let mut uart = Uart::new_with_mio(
|
let mut uart = Uart::new_with_mio(
|
||||||
|
@@ -23,7 +23,7 @@ use zynq7000_hal::{
|
|||||||
gtc::GlobalTimerCounter,
|
gtc::GlobalTimerCounter,
|
||||||
l2_cache,
|
l2_cache,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClockConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
use zynq7000::PsPeripherals;
|
use zynq7000::PsPeripherals;
|
||||||
@@ -71,7 +71,7 @@ async fn main(_spawner: Spawner) -> ! {
|
|||||||
pwm.set_duty_cycle_percent(50).unwrap();
|
pwm.set_duty_cycle_percent(50).unwrap();
|
||||||
|
|
||||||
// Set up the UART, we are logging with it.
|
// Set up the UART, we are logging with it.
|
||||||
let uart_clk_config = ClkConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let mut uart = Uart::new_with_mio(
|
let mut uart = Uart::new_with_mio(
|
||||||
|
@@ -16,7 +16,7 @@ use zynq7000_hal::{
|
|||||||
gtc::GlobalTimerCounter,
|
gtc::GlobalTimerCounter,
|
||||||
l2_cache,
|
l2_cache,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClockConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
use zynq7000::PsPeripherals;
|
use zynq7000::PsPeripherals;
|
||||||
@@ -57,7 +57,7 @@ async fn main(_spawner: Spawner) -> ! {
|
|||||||
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
||||||
|
|
||||||
// Set up the UART, we are logging with it.
|
// Set up the UART, we are logging with it.
|
||||||
let uart_clk_config = ClkConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let mut uart = Uart::new_with_mio(
|
let mut uart = Uart::new_with_mio(
|
||||||
|
@@ -15,7 +15,7 @@ use zynq7000_hal::{
|
|||||||
l2_cache,
|
l2_cache,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClockConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
use zynq7000_rt as _;
|
use zynq7000_rt as _;
|
||||||
@@ -49,7 +49,7 @@ pub fn main() -> ! {
|
|||||||
// Enable interrupt exception.
|
// Enable interrupt exception.
|
||||||
unsafe { gic.enable_interrupts() };
|
unsafe { gic.enable_interrupts() };
|
||||||
// Set up the UART, we are logging with it.
|
// Set up the UART, we are logging with it.
|
||||||
let uart_clk_config = ClkConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let mut gtc = GlobalTimerCounter::new(dp.gtc, clocks.arm_clocks());
|
let mut gtc = GlobalTimerCounter::new(dp.gtc, clocks.arm_clocks());
|
||||||
|
@@ -16,7 +16,7 @@ use zynq7000_hal::{
|
|||||||
l2_cache,
|
l2_cache,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClockConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
use zynq7000_rt as _;
|
use zynq7000_rt as _;
|
||||||
@@ -50,7 +50,7 @@ pub fn main() -> ! {
|
|||||||
// Enable interrupt exception.
|
// Enable interrupt exception.
|
||||||
unsafe { gic.enable_interrupts() };
|
unsafe { gic.enable_interrupts() };
|
||||||
// Set up the UART, we are logging with it.
|
// Set up the UART, we are logging with it.
|
||||||
let uart_clk_config = ClkConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let mut gtc = GlobalTimerCounter::new(dp.gtc, clocks.arm_clocks());
|
let mut gtc = GlobalTimerCounter::new(dp.gtc, clocks.arm_clocks());
|
||||||
|
@@ -42,17 +42,16 @@ use zynq7000_hal::{
|
|||||||
clocks::Clocks,
|
clocks::Clocks,
|
||||||
configure_level_shifter,
|
configure_level_shifter,
|
||||||
eth::{
|
eth::{
|
||||||
AlignedBuffer, ClkDivCollection, EthernetConfig, EthernetLowLevel,
|
AlignedBuffer, ClockDivSet, EthernetConfig, EthernetLowLevel, embassy_net::InterruptResult,
|
||||||
embassy_net::InterruptResult,
|
|
||||||
},
|
},
|
||||||
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
||||||
gpio::{GpioPins, Output, PinState},
|
gpio::{GpioPins, Output, PinState},
|
||||||
gtc::GlobalTimerCounter,
|
gtc::GlobalTimerCounter,
|
||||||
l2_cache,
|
l2_cache,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClockConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
use zynq7000::{PsPeripherals, slcr::LevelShifterCfg};
|
use zynq7000::{PsPeripherals, slcr::LevelShifterConfig};
|
||||||
use zynq7000_rt::{self as _, mmu::section_attrs::SHAREABLE_DEVICE, mmu_l1_table_mut};
|
use zynq7000_rt::{self as _, mmu::section_attrs::SHAREABLE_DEVICE, mmu_l1_table_mut};
|
||||||
|
|
||||||
const USE_DHCP: bool = true;
|
const USE_DHCP: bool = true;
|
||||||
@@ -213,7 +212,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
l2_cache::init_with_defaults(&mut dp.l2c);
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Enable PS-PL level shifters.
|
// Enable PS-PL level shifters.
|
||||||
configure_level_shifter(LevelShifterCfg::EnableAll);
|
configure_level_shifter(LevelShifterConfig::EnableAll);
|
||||||
|
|
||||||
// Configure the uncached memory region using the MMU.
|
// Configure the uncached memory region using the MMU.
|
||||||
mmu_l1_table_mut()
|
mmu_l1_table_mut()
|
||||||
@@ -237,7 +236,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
||||||
|
|
||||||
// Set up the UART, we are logging with it.
|
// Set up the UART, we are logging with it.
|
||||||
let uart_clk_config = ClkConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let mut uart = Uart::new_with_mio(
|
let mut uart = Uart::new_with_mio(
|
||||||
@@ -280,15 +279,14 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
info!("Ethernet Module ID: {mod_id:?}");
|
info!("Ethernet Module ID: {mod_id:?}");
|
||||||
assert_eq!(mod_id, 0x20118);
|
assert_eq!(mod_id, 0x20118);
|
||||||
|
|
||||||
let (clk_divs, clk_errors) =
|
let (clk_divs, clk_errors) = ClockDivSet::calculate_for_rgmii_and_io_clock(clocks.io_clocks());
|
||||||
ClkDivCollection::calculate_for_rgmii_and_io_clock(clocks.io_clocks());
|
|
||||||
debug!(
|
debug!(
|
||||||
"Calculated RGMII clock configuration: {:?}, errors (missmatch from ideal rate in hertz): {:?}",
|
"Calculated RGMII clock configuration: {:?}, errors (missmatch from ideal rate in hertz): {:?}",
|
||||||
clk_divs, clk_errors
|
clk_divs, clk_errors
|
||||||
);
|
);
|
||||||
// Unwrap okay, we use a standard clock config, and the clock config should never fail.
|
// Unwrap okay, we use a standard clock config, and the clock config should never fail.
|
||||||
let eth_cfg = EthernetConfig::new(
|
let eth_cfg = EthernetConfig::new(
|
||||||
zynq7000_hal::eth::ClkConfig::new(clk_divs.cfg_1000_mbps),
|
zynq7000_hal::eth::ClockConfig::new(clk_divs.cfg_1000_mbps),
|
||||||
zynq7000_hal::eth::calculate_mdc_clk_div(clocks.arm_clocks()).unwrap(),
|
zynq7000_hal::eth::calculate_mdc_clk_div(clocks.arm_clocks()).unwrap(),
|
||||||
MAC_ADDRESS,
|
MAC_ADDRESS,
|
||||||
);
|
);
|
||||||
|
@@ -29,7 +29,7 @@ use zynq7000_hal::{
|
|||||||
uart,
|
uart,
|
||||||
};
|
};
|
||||||
|
|
||||||
use zynq7000::{PsPeripherals, slcr::LevelShifterCfg};
|
use zynq7000::{PsPeripherals, slcr::LevelShifterConfig};
|
||||||
use zynq7000_rt as _;
|
use zynq7000_rt as _;
|
||||||
|
|
||||||
// Define the clock frequency as a constant
|
// Define the clock frequency as a constant
|
||||||
@@ -52,7 +52,7 @@ async fn main(_spawner: Spawner) -> ! {
|
|||||||
l2_cache::init_with_defaults(&mut dp.l2c);
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Enable PS-PL level shifters.
|
// Enable PS-PL level shifters.
|
||||||
configure_level_shifter(LevelShifterCfg::EnableAll);
|
configure_level_shifter(LevelShifterConfig::EnableAll);
|
||||||
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
@@ -73,7 +73,7 @@ async fn main(_spawner: Spawner) -> ! {
|
|||||||
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
||||||
|
|
||||||
// Set up the UART, we are logging with it.
|
// Set up the UART, we are logging with it.
|
||||||
let uart_clk_config = uart::ClkConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
let uart_clk_config = uart::ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let mut uart = uart::Uart::new_with_mio(
|
let mut uart = uart::Uart::new_with_mio(
|
||||||
|
@@ -30,7 +30,7 @@ use zynq7000_hal::{
|
|||||||
uart::{self, TxAsync, on_interrupt_tx},
|
uart::{self, TxAsync, on_interrupt_tx},
|
||||||
};
|
};
|
||||||
|
|
||||||
use zynq7000::{PsPeripherals, slcr::LevelShifterCfg, spi::DelayControl};
|
use zynq7000::{PsPeripherals, slcr::LevelShifterConfig, spi::DelayControl};
|
||||||
use zynq7000_rt as _;
|
use zynq7000_rt as _;
|
||||||
|
|
||||||
// Define the clock frequency as a constant
|
// Define the clock frequency as a constant
|
||||||
@@ -55,7 +55,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
l2_cache::init_with_defaults(&mut dp.l2c);
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Enable PS-PL level shifters.
|
// Enable PS-PL level shifters.
|
||||||
configure_level_shifter(LevelShifterCfg::EnableAll);
|
configure_level_shifter(LevelShifterConfig::EnableAll);
|
||||||
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let mut clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let mut clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
@@ -83,7 +83,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
||||||
|
|
||||||
// Set up the UART, we are logging with it.
|
// Set up the UART, we are logging with it.
|
||||||
let uart_clk_config = uart::ClkConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
let uart_clk_config = uart::ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let mut uart = uart::Uart::new_with_mio(
|
let mut uart = uart::Uart::new_with_mio(
|
||||||
|
@@ -20,10 +20,10 @@ use zynq7000_hal::{
|
|||||||
gpio::{GpioPins, Output, PinState},
|
gpio::{GpioPins, Output, PinState},
|
||||||
gtc::GlobalTimerCounter,
|
gtc::GlobalTimerCounter,
|
||||||
l2_cache,
|
l2_cache,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClockConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
use zynq7000::{PsPeripherals, slcr::LevelShifterCfg};
|
use zynq7000::{PsPeripherals, slcr::LevelShifterConfig};
|
||||||
use zynq7000_rt as _;
|
use zynq7000_rt as _;
|
||||||
|
|
||||||
const INIT_STRING: &str = "-- Zynq 7000 Zedboard blocking UART example --\n\r";
|
const INIT_STRING: &str = "-- Zynq 7000 Zedboard blocking UART example --\n\r";
|
||||||
@@ -105,7 +105,7 @@ async fn main(_spawner: Spawner) -> ! {
|
|||||||
l2_cache::init_with_defaults(&mut dp.l2c);
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Enable PS-PL level shifters.
|
// Enable PS-PL level shifters.
|
||||||
configure_level_shifter(LevelShifterCfg::EnableAll);
|
configure_level_shifter(LevelShifterConfig::EnableAll);
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
// Set up the global interrupt controller.
|
// Set up the global interrupt controller.
|
||||||
@@ -123,7 +123,7 @@ async fn main(_spawner: Spawner) -> ! {
|
|||||||
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
||||||
|
|
||||||
// Set up the UART, we are logging with it.
|
// Set up the UART, we are logging with it.
|
||||||
let uart_clk_config = ClkConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let mut log_uart = Uart::new_with_mio(
|
let mut log_uart = Uart::new_with_mio(
|
||||||
|
@@ -47,7 +47,7 @@ use zynq7000_hal::{
|
|||||||
gtc::GlobalTimerCounter,
|
gtc::GlobalTimerCounter,
|
||||||
l2_cache,
|
l2_cache,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClockConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub enum UartMode {
|
pub enum UartMode {
|
||||||
@@ -62,7 +62,7 @@ const INIT_STRING: &str = "-- Zynq 7000 Zedboard non-blocking UART example --\n\
|
|||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static HEAP: Heap = Heap::empty();
|
static HEAP: Heap = Heap::empty();
|
||||||
|
|
||||||
use zynq7000::{PsPeripherals, slcr::LevelShifterCfg};
|
use zynq7000::{PsPeripherals, slcr::LevelShifterConfig};
|
||||||
use zynq7000_rt as _;
|
use zynq7000_rt as _;
|
||||||
|
|
||||||
// Define the clock frequency as a constant
|
// Define the clock frequency as a constant
|
||||||
@@ -170,7 +170,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
l2_cache::init_with_defaults(&mut dp.l2c);
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Enable PS-PL level shifters.
|
// Enable PS-PL level shifters.
|
||||||
configure_level_shifter(LevelShifterCfg::EnableAll);
|
configure_level_shifter(LevelShifterConfig::EnableAll);
|
||||||
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
@@ -194,7 +194,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
||||||
|
|
||||||
// Set up the UART, we are logging with it.
|
// Set up the UART, we are logging with it.
|
||||||
let uart_clk_config = ClkConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let mut log_uart = Uart::new_with_mio(
|
let mut log_uart = Uart::new_with_mio(
|
||||||
|
@@ -17,10 +17,10 @@ use zynq7000_hal::{
|
|||||||
gpio::{GpioPins, Output, PinState},
|
gpio::{GpioPins, Output, PinState},
|
||||||
gtc::GlobalTimerCounter,
|
gtc::GlobalTimerCounter,
|
||||||
l2_cache,
|
l2_cache,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClockConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
use zynq7000::{PsPeripherals, slcr::LevelShifterCfg};
|
use zynq7000::{PsPeripherals, slcr::LevelShifterConfig};
|
||||||
use zynq7000_rt as _;
|
use zynq7000_rt as _;
|
||||||
|
|
||||||
const INIT_STRING: &str = "-- Zynq 7000 Zedboard GPIO blinky example --\n\r";
|
const INIT_STRING: &str = "-- Zynq 7000 Zedboard GPIO blinky example --\n\r";
|
||||||
@@ -41,7 +41,7 @@ async fn main(_spawner: Spawner) -> ! {
|
|||||||
l2_cache::init_with_defaults(&mut dp.l2c);
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Enable PS-PL level shifters.
|
// Enable PS-PL level shifters.
|
||||||
configure_level_shifter(LevelShifterCfg::EnableAll);
|
configure_level_shifter(LevelShifterConfig::EnableAll);
|
||||||
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
@@ -60,7 +60,7 @@ async fn main(_spawner: Spawner) -> ! {
|
|||||||
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
|
||||||
|
|
||||||
// Set up the UART, we are logging with it.
|
// Set up the UART, we are logging with it.
|
||||||
let uart_clk_config = ClkConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let mut uart = Uart::new_with_mio(
|
let mut uart = Uart::new_with_mio(
|
||||||
|
@@ -35,7 +35,7 @@ libm = "0.2"
|
|||||||
log = "0.4"
|
log = "0.4"
|
||||||
embassy-sync = "0.7"
|
embassy-sync = "0.7"
|
||||||
embassy-net-driver = "0.2"
|
embassy-net-driver = "0.2"
|
||||||
smoltcp = { version = "0.12", default-features = false }
|
smoltcp = { version = "0.12", default-features = false, features = ["proto-ipv4", "medium-ethernet", "socket-raw"] }
|
||||||
vcell = "0.1"
|
vcell = "0.1"
|
||||||
raw-slicee = "0.1"
|
raw-slicee = "0.1"
|
||||||
embedded-io-async = "0.6"
|
embedded-io-async = "0.6"
|
||||||
|
3
zynq7000-hal/docs.sh
Executable file
3
zynq7000-hal/docs.sh
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
export RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options"
|
||||||
|
cargo +nightly doc --features alloc --open
|
@@ -4,8 +4,8 @@ use arbitrary_int::Number;
|
|||||||
use zynq7000::slcr::{
|
use zynq7000::slcr::{
|
||||||
ClockControl,
|
ClockControl,
|
||||||
clocks::{
|
clocks::{
|
||||||
ClkRatioSelect, DualCommonPeriphIoClkCtrl, FpgaClkCtrl, GigEthClkCtrl,
|
ClockkRatioSelect, DualCommonPeriphIoClockControl, FpgaClockControl, GigEthClockControl,
|
||||||
SingleCommonPeriphIoClkCtrl,
|
SingleCommonPeriphIoClockControl,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -228,14 +228,14 @@ impl Clocks {
|
|||||||
}
|
}
|
||||||
let arm_clk_divided = arm_base_clk / arm_clk_ctrl.divisor().as_u32();
|
let arm_clk_divided = arm_base_clk / arm_clk_ctrl.divisor().as_u32();
|
||||||
let arm_clks = match clk_sel.sel() {
|
let arm_clks = match clk_sel.sel() {
|
||||||
ClkRatioSelect::FourToTwoToOne => ArmClocks {
|
ClockkRatioSelect::FourToTwoToOne => ArmClocks {
|
||||||
ref_clk: arm_pll_out,
|
ref_clk: arm_pll_out,
|
||||||
cpu_1x_clk: arm_clk_divided / 4,
|
cpu_1x_clk: arm_clk_divided / 4,
|
||||||
cpu_2x_clk: arm_clk_divided / 2,
|
cpu_2x_clk: arm_clk_divided / 2,
|
||||||
cpu_3x2x_clk: arm_clk_divided / 2,
|
cpu_3x2x_clk: arm_clk_divided / 2,
|
||||||
cpu_6x4x_clk: arm_clk_divided,
|
cpu_6x4x_clk: arm_clk_divided,
|
||||||
},
|
},
|
||||||
ClkRatioSelect::SixToTwoToOne => ArmClocks {
|
ClockkRatioSelect::SixToTwoToOne => ArmClocks {
|
||||||
ref_clk: arm_pll_out,
|
ref_clk: arm_pll_out,
|
||||||
cpu_1x_clk: arm_clk_divided / 6,
|
cpu_1x_clk: arm_clk_divided / 6,
|
||||||
cpu_2x_clk: arm_clk_divided / 3,
|
cpu_2x_clk: arm_clk_divided / 3,
|
||||||
@@ -254,7 +254,7 @@ impl Clocks {
|
|||||||
ddr_2x_clk: ddr_pll_out / ddr_clk_ctrl.div_2x_clk().as_u32(),
|
ddr_2x_clk: ddr_pll_out / ddr_clk_ctrl.div_2x_clk().as_u32(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let handle_common_single_clock_config = |single_block: SingleCommonPeriphIoClkCtrl,
|
let handle_common_single_clock_config = |single_block: SingleCommonPeriphIoClockControl,
|
||||||
id: ClockModuleId|
|
id: ClockModuleId|
|
||||||
-> Result<Hertz, ClockReadError> {
|
-> Result<Hertz, ClockReadError> {
|
||||||
if single_block.divisor().as_u32() == 0 {
|
if single_block.divisor().as_u32() == 0 {
|
||||||
@@ -273,7 +273,7 @@ impl Clocks {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
let handle_common_dual_clock_config = |dual_block: DualCommonPeriphIoClkCtrl,
|
let handle_common_dual_clock_config = |dual_block: DualCommonPeriphIoClockControl,
|
||||||
id: ClockModuleId|
|
id: ClockModuleId|
|
||||||
-> Result<Hertz, ClockReadError> {
|
-> Result<Hertz, ClockReadError> {
|
||||||
if dual_block.divisor().as_u32() == 0 {
|
if dual_block.divisor().as_u32() == 0 {
|
||||||
@@ -340,31 +340,34 @@ impl Clocks {
|
|||||||
| zynq7000::slcr::clocks::SrcSelTpiu::EmioTraceClkAlt1
|
| zynq7000::slcr::clocks::SrcSelTpiu::EmioTraceClkAlt1
|
||||||
| zynq7000::slcr::clocks::SrcSelTpiu::EmioTraceClkAlt2 => None,
|
| zynq7000::slcr::clocks::SrcSelTpiu::EmioTraceClkAlt2 => None,
|
||||||
};
|
};
|
||||||
let calculate_fpga_clk = |fpga_clk_ctrl: FpgaClkCtrl| -> Result<Hertz, ClockReadError> {
|
let calculate_fpga_clk =
|
||||||
if fpga_clk_ctrl.divisor_0().as_u32() == 0 || fpga_clk_ctrl.divisor_1().as_u32() == 0 {
|
|fpga_clk_ctrl: FpgaClockControl| -> Result<Hertz, ClockReadError> {
|
||||||
return Err(ClockReadError::DivisorZero(DivisorZero(
|
if fpga_clk_ctrl.divisor_0().as_u32() == 0
|
||||||
ClockModuleId::Fpga,
|
|| fpga_clk_ctrl.divisor_1().as_u32() == 0
|
||||||
)));
|
{
|
||||||
}
|
return Err(ClockReadError::DivisorZero(DivisorZero(
|
||||||
Ok(match fpga_clk_ctrl.srcsel() {
|
ClockModuleId::Fpga,
|
||||||
zynq7000::slcr::clocks::SrcSelIo::IoPll
|
)));
|
||||||
| zynq7000::slcr::clocks::SrcSelIo::IoPllAlt => {
|
|
||||||
io_pll_out
|
|
||||||
/ fpga_clk_ctrl.divisor_0().as_u32()
|
|
||||||
/ fpga_clk_ctrl.divisor_1().as_u32()
|
|
||||||
}
|
}
|
||||||
zynq7000::slcr::clocks::SrcSelIo::ArmPll => {
|
Ok(match fpga_clk_ctrl.srcsel() {
|
||||||
arm_pll_out
|
zynq7000::slcr::clocks::SrcSelIo::IoPll
|
||||||
/ fpga_clk_ctrl.divisor_0().as_u32()
|
| zynq7000::slcr::clocks::SrcSelIo::IoPllAlt => {
|
||||||
/ fpga_clk_ctrl.divisor_1().as_u32()
|
io_pll_out
|
||||||
}
|
/ fpga_clk_ctrl.divisor_0().as_u32()
|
||||||
zynq7000::slcr::clocks::SrcSelIo::DdrPll => {
|
/ fpga_clk_ctrl.divisor_1().as_u32()
|
||||||
ddr_pll_out
|
}
|
||||||
/ fpga_clk_ctrl.divisor_0().as_u32()
|
zynq7000::slcr::clocks::SrcSelIo::ArmPll => {
|
||||||
/ fpga_clk_ctrl.divisor_1().as_u32()
|
arm_pll_out
|
||||||
}
|
/ fpga_clk_ctrl.divisor_0().as_u32()
|
||||||
})
|
/ fpga_clk_ctrl.divisor_1().as_u32()
|
||||||
};
|
}
|
||||||
|
zynq7000::slcr::clocks::SrcSelIo::DdrPll => {
|
||||||
|
ddr_pll_out
|
||||||
|
/ fpga_clk_ctrl.divisor_0().as_u32()
|
||||||
|
/ fpga_clk_ctrl.divisor_1().as_u32()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
ps_clk: ps_clk_freq,
|
ps_clk: ps_clk_freq,
|
||||||
@@ -418,7 +421,7 @@ impl Clocks {
|
|||||||
|
|
||||||
fn calculate_gem_ref_clock(
|
fn calculate_gem_ref_clock(
|
||||||
&self,
|
&self,
|
||||||
reg: GigEthClkCtrl,
|
reg: GigEthClockControl,
|
||||||
module: ClockModuleId,
|
module: ClockModuleId,
|
||||||
) -> Result<Hertz, DivisorZero> {
|
) -> Result<Hertz, DivisorZero> {
|
||||||
let source_clk = match reg.srcsel() {
|
let source_clk = match reg.srcsel() {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
use arbitrary_int::{Number, u6};
|
use arbitrary_int::{Number, u6};
|
||||||
use zynq7000::{
|
use zynq7000::{
|
||||||
eth::{InterruptCtrl, NetworkCtrl, RxStatus, TxStatus},
|
eth::{InterruptControl, NetworkControl, RxStatus, TxStatus},
|
||||||
slcr::reset::EthernetRst,
|
slcr::reset::EthernetReset,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{clocks::IoClocks, enable_amba_periph_clk, slcr::Slcr, time::Hertz};
|
use crate::{clocks::IoClocks, enable_amba_periph_clk, slcr::Slcr, time::Hertz};
|
||||||
@@ -37,12 +37,12 @@ pub enum Duplex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct ClkDivisors {
|
pub struct ClockDivisors {
|
||||||
pub divisor_0: u6,
|
pub divisor_0: u6,
|
||||||
pub divisor_1: u6,
|
pub divisor_1: u6,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClkDivisors {
|
impl ClockDivisors {
|
||||||
pub const fn new(divisor_0: u6, divisor_1: u6) -> Self {
|
pub const fn new(divisor_0: u6, divisor_1: u6) -> Self {
|
||||||
Self {
|
Self {
|
||||||
divisor_0,
|
divisor_0,
|
||||||
@@ -90,16 +90,16 @@ impl ClkDivisors {
|
|||||||
|
|
||||||
/// Full clock configuration for the ethernet peripheral.
|
/// Full clock configuration for the ethernet peripheral.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct ClkConfig {
|
pub struct ClockConfig {
|
||||||
pub src_sel: zynq7000::slcr::clocks::SrcSelIo,
|
pub src_sel: zynq7000::slcr::clocks::SrcSelIo,
|
||||||
pub use_emio_tx_clk: bool,
|
pub use_emio_tx_clk: bool,
|
||||||
pub divs: ClkDivisors,
|
pub divs: ClockDivisors,
|
||||||
/// Enable the clock.
|
/// Enable the clock.
|
||||||
pub enable: bool,
|
pub enable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClkConfig {
|
impl ClockConfig {
|
||||||
pub const fn new(divs: ClkDivisors) -> Self {
|
pub const fn new(divs: ClockDivisors) -> Self {
|
||||||
Self {
|
Self {
|
||||||
src_sel: zynq7000::slcr::clocks::SrcSelIo::IoPll,
|
src_sel: zynq7000::slcr::clocks::SrcSelIo::IoPll,
|
||||||
use_emio_tx_clk: false,
|
use_emio_tx_clk: false,
|
||||||
@@ -109,23 +109,23 @@ impl ClkConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is a collection of clock configuration for all relevant speed settings.
|
/// This is a set of clock configuration for all relevant speed settings.
|
||||||
///
|
///
|
||||||
/// Generally, the clock need to be re-configured each time the speed settings change, for example
|
/// Generally, the clock need to be re-configured each time the speed settings change, for example
|
||||||
/// after a completed auto-negotiation process. The necessary clock configurations for each speed
|
/// after a completed auto-negotiation process. The necessary clock configurations for each speed
|
||||||
/// setting can be pre-calculated and stored using this data structure.
|
/// setting can be pre-calculated and stored using this data structure.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct ClkDivCollection {
|
pub struct ClockDivSet {
|
||||||
pub cfg_10_mbps: ClkDivisors,
|
pub cfg_10_mbps: ClockDivisors,
|
||||||
pub cfg_100_mbps: ClkDivisors,
|
pub cfg_100_mbps: ClockDivisors,
|
||||||
pub cfg_1000_mbps: ClkDivisors,
|
pub cfg_1000_mbps: ClockDivisors,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClkDivCollection {
|
impl ClockDivSet {
|
||||||
pub const fn new(
|
pub const fn new(
|
||||||
cfg_10_mbps: ClkDivisors,
|
cfg_10_mbps: ClockDivisors,
|
||||||
cfg_100_mbps: ClkDivisors,
|
cfg_100_mbps: ClockDivisors,
|
||||||
cfg_1000_mbps: ClkDivisors,
|
cfg_1000_mbps: ClockDivisors,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
cfg_10_mbps,
|
cfg_10_mbps,
|
||||||
@@ -135,7 +135,7 @@ impl ClkDivCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn clk_divs_for_speed(&self, speed: Speed) -> &ClkDivisors {
|
pub fn clk_divs_for_speed(&self, speed: Speed) -> &ClockDivisors {
|
||||||
match speed {
|
match speed {
|
||||||
Speed::Mbps10 => &self.cfg_10_mbps,
|
Speed::Mbps10 => &self.cfg_10_mbps,
|
||||||
Speed::Mbps100 => &self.cfg_100_mbps,
|
Speed::Mbps100 => &self.cfg_100_mbps,
|
||||||
@@ -158,11 +158,12 @@ impl ClkDivCollection {
|
|||||||
/// and the second entry is the difference between calculated clock speed for the divisors
|
/// and the second entry is the difference between calculated clock speed for the divisors
|
||||||
/// and the target speed. Ideally, this difference should be 0.
|
/// and the target speed. Ideally, this difference should be 0.
|
||||||
pub fn calculate_for_rgmii(ref_clk: Hertz) -> (Self, [u32; 3]) {
|
pub fn calculate_for_rgmii(ref_clk: Hertz) -> (Self, [u32; 3]) {
|
||||||
let (cfg_10_mbps, error_10_mbps) = ClkDivisors::calculate_for_rgmii(ref_clk, Speed::Mbps10);
|
let (cfg_10_mbps, error_10_mbps) =
|
||||||
|
ClockDivisors::calculate_for_rgmii(ref_clk, Speed::Mbps10);
|
||||||
let (cfg_100_mbps, error_100_mbps) =
|
let (cfg_100_mbps, error_100_mbps) =
|
||||||
ClkDivisors::calculate_for_rgmii(ref_clk, Speed::Mbps100);
|
ClockDivisors::calculate_for_rgmii(ref_clk, Speed::Mbps100);
|
||||||
let (cfg_1000_mbps, error_1000_mbps) =
|
let (cfg_1000_mbps, error_1000_mbps) =
|
||||||
ClkDivisors::calculate_for_rgmii(ref_clk, Speed::Mbps1000);
|
ClockDivisors::calculate_for_rgmii(ref_clk, Speed::Mbps1000);
|
||||||
(
|
(
|
||||||
Self::new(cfg_10_mbps, cfg_100_mbps, cfg_1000_mbps),
|
Self::new(cfg_10_mbps, cfg_100_mbps, cfg_1000_mbps),
|
||||||
[error_10_mbps, error_100_mbps, error_1000_mbps],
|
[error_10_mbps, error_100_mbps, error_1000_mbps],
|
||||||
@@ -204,7 +205,7 @@ impl EthernetLowLevel {
|
|||||||
|
|
||||||
pub fn reset(&mut self, cycles: usize) {
|
pub fn reset(&mut self, cycles: usize) {
|
||||||
let assert_reset = match self.id {
|
let assert_reset = match self.id {
|
||||||
EthernetId::Eth0 => EthernetRst::builder()
|
EthernetId::Eth0 => EthernetReset::builder()
|
||||||
.with_gem1_ref_rst(false)
|
.with_gem1_ref_rst(false)
|
||||||
.with_gem0_ref_rst(true)
|
.with_gem0_ref_rst(true)
|
||||||
.with_gem1_rx_rst(false)
|
.with_gem1_rx_rst(false)
|
||||||
@@ -212,7 +213,7 @@ impl EthernetLowLevel {
|
|||||||
.with_gem1_cpu1x_rst(false)
|
.with_gem1_cpu1x_rst(false)
|
||||||
.with_gem0_cpu1x_rst(true)
|
.with_gem0_cpu1x_rst(true)
|
||||||
.build(),
|
.build(),
|
||||||
EthernetId::Eth1 => EthernetRst::builder()
|
EthernetId::Eth1 => EthernetReset::builder()
|
||||||
.with_gem1_ref_rst(true)
|
.with_gem1_ref_rst(true)
|
||||||
.with_gem0_ref_rst(false)
|
.with_gem0_ref_rst(false)
|
||||||
.with_gem1_rx_rst(true)
|
.with_gem1_rx_rst(true)
|
||||||
@@ -227,7 +228,7 @@ impl EthernetLowLevel {
|
|||||||
for _ in 0..cycles {
|
for _ in 0..cycles {
|
||||||
cortex_ar::asm::nop();
|
cortex_ar::asm::nop();
|
||||||
}
|
}
|
||||||
regs.reset_ctrl().write_eth(EthernetRst::DEFAULT);
|
regs.reset_ctrl().write_eth(EthernetReset::DEFAULT);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,10 +242,10 @@ impl EthernetLowLevel {
|
|||||||
enable_amba_periph_clk(periph_sel);
|
enable_amba_periph_clk(periph_sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Completely configures the clock based on the provided [ClkConfig].
|
/// Completely configures the clock based on the provided [ClockConfig].
|
||||||
///
|
///
|
||||||
/// This should be called once when initializing the peripheral.
|
/// This should be called once when initializing the peripheral.
|
||||||
pub fn configure_clock(&mut self, cfg: ClkConfig, enable_rx_clock: bool) {
|
pub fn configure_clock(&mut self, cfg: ClockConfig, enable_rx_clock: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
Slcr::with(|regs| {
|
Slcr::with(|regs| {
|
||||||
let (ptr_gig_eth_clk_ctrl, ptr_gig_eth_rclk_ctrl) = self.id().clk_config_regs(regs);
|
let (ptr_gig_eth_clk_ctrl, ptr_gig_eth_rclk_ctrl) = self.id().clk_config_regs(regs);
|
||||||
@@ -268,7 +269,7 @@ impl EthernetLowLevel {
|
|||||||
/// Re-configures the clock divisors for the Ethernet peripheral.
|
/// Re-configures the clock divisors for the Ethernet peripheral.
|
||||||
///
|
///
|
||||||
/// This might be necessary after auto-negotiation of speed settings.
|
/// This might be necessary after auto-negotiation of speed settings.
|
||||||
pub fn configure_clock_divs(&mut self, cfg: ClkDivisors) {
|
pub fn configure_clock_divs(&mut self, cfg: ClockDivisors) {
|
||||||
unsafe {
|
unsafe {
|
||||||
Slcr::with(|regs| {
|
Slcr::with(|regs| {
|
||||||
let (ptr_gig_eth_clk_ctrl, _ptr_gig_eth_rclk_ctrl) =
|
let (ptr_gig_eth_clk_ctrl, _ptr_gig_eth_rclk_ctrl) =
|
||||||
@@ -290,13 +291,13 @@ impl EthernetLowLevel {
|
|||||||
&mut self,
|
&mut self,
|
||||||
speed: Speed,
|
speed: Speed,
|
||||||
duplex: Duplex,
|
duplex: Duplex,
|
||||||
clk_collection: &ClkDivCollection,
|
clk_collection: &ClockDivSet,
|
||||||
) {
|
) {
|
||||||
self.configure_clock_for_speed(speed, clk_collection);
|
self.configure_clock_for_speed(speed, clk_collection);
|
||||||
self.set_speed_and_duplex(speed, duplex);
|
self.set_speed_and_duplex(speed, duplex);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn configure_clock_for_speed(&mut self, speed: Speed, clk_collection: &ClkDivCollection) {
|
pub fn configure_clock_for_speed(&mut self, speed: Speed, clk_collection: &ClockDivSet) {
|
||||||
match speed {
|
match speed {
|
||||||
Speed::Mbps10 => self.configure_clock_divs(clk_collection.cfg_10_mbps),
|
Speed::Mbps10 => self.configure_clock_divs(clk_collection.cfg_10_mbps),
|
||||||
Speed::Mbps100 => self.configure_clock_divs(clk_collection.cfg_100_mbps),
|
Speed::Mbps100 => self.configure_clock_divs(clk_collection.cfg_100_mbps),
|
||||||
@@ -362,7 +363,7 @@ impl EthernetLowLevel {
|
|||||||
///
|
///
|
||||||
/// These steps do not include any resets or clock configuration.
|
/// These steps do not include any resets or clock configuration.
|
||||||
pub fn initialize(&mut self, reset_rx_tx_queue_base_addr: bool) {
|
pub fn initialize(&mut self, reset_rx_tx_queue_base_addr: bool) {
|
||||||
let mut ctrl_val = NetworkCtrl::new_with_raw_value(0);
|
let mut ctrl_val = NetworkControl::new_with_raw_value(0);
|
||||||
self.regs.write_net_ctrl(ctrl_val);
|
self.regs.write_net_ctrl(ctrl_val);
|
||||||
// Now clear statistics.
|
// Now clear statistics.
|
||||||
ctrl_val.set_clear_statistics(true);
|
ctrl_val.set_clear_statistics(true);
|
||||||
@@ -370,7 +371,7 @@ impl EthernetLowLevel {
|
|||||||
self.regs.write_tx_status(TxStatus::new_clear_all());
|
self.regs.write_tx_status(TxStatus::new_clear_all());
|
||||||
self.regs.write_rx_status(RxStatus::new_clear_all());
|
self.regs.write_rx_status(RxStatus::new_clear_all());
|
||||||
self.regs
|
self.regs
|
||||||
.write_interrupt_disable(InterruptCtrl::new_clear_all());
|
.write_interrupt_disable(InterruptControl::new_clear_all());
|
||||||
if reset_rx_tx_queue_base_addr {
|
if reset_rx_tx_queue_base_addr {
|
||||||
self.regs.write_rx_buf_queue_base_addr(0);
|
self.regs.write_rx_buf_queue_base_addr(0);
|
||||||
self.regs.write_tx_buf_queue_base_addr(0);
|
self.regs.write_tx_buf_queue_base_addr(0);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
use arbitrary_int::{u2, u5};
|
use arbitrary_int::{u2, u5};
|
||||||
use zynq7000::eth::{MdcClkDiv, PhyMaintenance};
|
use zynq7000::eth::{MdcClockDivisor, PhyMaintenance};
|
||||||
|
|
||||||
use super::{EthernetId, ll::EthernetLowLevel};
|
use super::{EthernetId, ll::EthernetLowLevel};
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ impl Mdio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn configure_clock_div(&mut self, clk_div: MdcClkDiv) {
|
pub fn configure_clock_div(&mut self, clk_div: MdcClockDivisor) {
|
||||||
self.regs.modify_net_cfg(|mut val| {
|
self.regs.modify_net_cfg(|mut val| {
|
||||||
val.set_mdc_clk_div(clk_div);
|
val.set_mdc_clk_div(clk_div);
|
||||||
val
|
val
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
use arbitrary_int::{u2, u3};
|
use arbitrary_int::{u2, u3};
|
||||||
pub use zynq7000::eth::MdcClkDiv;
|
pub use zynq7000::eth::MdcClockDivisor;
|
||||||
use zynq7000::eth::{
|
use zynq7000::eth::{
|
||||||
BurstLength, DmaRxBufSize, GEM_0_BASE_ADDR, GEM_1_BASE_ADDR, InterruptCtrl, InterruptStatus,
|
BurstLength, DmaRxBufSize, GEM_0_BASE_ADDR, GEM_1_BASE_ADDR, InterruptControl, InterruptStatus,
|
||||||
MmioEthernet, RxStatus, TxStatus,
|
MmioEthernet, RxStatus, TxStatus,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use ll::{ClkConfig, ClkDivCollection, Duplex, EthernetLowLevel, Speed};
|
pub use ll::{ClockConfig, ClockDivSet, Duplex, EthernetLowLevel, Speed};
|
||||||
|
|
||||||
pub mod embassy_net;
|
pub mod embassy_net;
|
||||||
pub mod ll;
|
pub mod ll;
|
||||||
@@ -27,19 +27,19 @@ use crate::gpio::mio::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
clocks::ArmClocks,
|
clocks::ArmClocks,
|
||||||
eth::ll::ClkDivisors,
|
eth::ll::ClockDivisors,
|
||||||
gpio::{
|
gpio::{
|
||||||
IoPeriphPin,
|
IoPeriphPin,
|
||||||
mio::{
|
mio::{
|
||||||
Mio28, Mio29, Mio30, Mio31, Mio32, Mio33, Mio34, Mio35, Mio36, Mio37, Mio38, Mio39,
|
Mio28, Mio29, Mio30, Mio31, Mio32, Mio33, Mio34, Mio35, Mio36, Mio37, Mio38, Mio39,
|
||||||
Mio52, Mio53, MioPinMarker, MuxCfg, Pin,
|
Mio52, Mio53, MioPinMarker, MuxConfig, Pin,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const MUX_CONF_PHY: MuxCfg = MuxCfg::new_with_l0();
|
pub const MUX_CONF_PHY: MuxConfig = MuxConfig::new_with_l0();
|
||||||
pub const MUX_CONF_MDIO: MuxCfg = MuxCfg::new_with_l3(u3::new(0b100));
|
pub const MUX_CONF_MDIO: MuxConfig = MuxConfig::new_with_l3(u3::new(0b100));
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum EthernetId {
|
pub enum EthernetId {
|
||||||
@@ -66,8 +66,8 @@ impl EthernetId {
|
|||||||
&self,
|
&self,
|
||||||
slcr: &mut zynq7000::slcr::MmioSlcr<'static>,
|
slcr: &mut zynq7000::slcr::MmioSlcr<'static>,
|
||||||
) -> (
|
) -> (
|
||||||
*mut zynq7000::slcr::clocks::GigEthClkCtrl,
|
*mut zynq7000::slcr::clocks::GigEthClockControl,
|
||||||
*mut zynq7000::slcr::clocks::GigEthRclkCtrl,
|
*mut zynq7000::slcr::clocks::GigEthRclkControl,
|
||||||
) {
|
) {
|
||||||
match self {
|
match self {
|
||||||
EthernetId::Eth0 => (
|
EthernetId::Eth0 => (
|
||||||
@@ -236,17 +236,17 @@ impl RxData3 for Pin<Mio38> {
|
|||||||
|
|
||||||
/// Calculate the CPU 1x clock divisor required to achieve a clock speed which is below
|
/// Calculate the CPU 1x clock divisor required to achieve a clock speed which is below
|
||||||
/// 2.5 MHz, as specified by the 802.3 standard.
|
/// 2.5 MHz, as specified by the 802.3 standard.
|
||||||
pub fn calculate_mdc_clk_div(arm_clks: &ArmClocks) -> Option<MdcClkDiv> {
|
pub fn calculate_mdc_clk_div(arm_clks: &ArmClocks) -> Option<MdcClockDivisor> {
|
||||||
let div = arm_clks.cpu_1x_clk().raw().div_ceil(MAX_MDC_SPEED.raw());
|
let div = arm_clks.cpu_1x_clk().raw().div_ceil(MAX_MDC_SPEED.raw());
|
||||||
match div {
|
match div {
|
||||||
0..8 => Some(MdcClkDiv::Div8),
|
0..8 => Some(MdcClockDivisor::Div8),
|
||||||
8..16 => Some(MdcClkDiv::Div16),
|
8..16 => Some(MdcClockDivisor::Div16),
|
||||||
16..32 => Some(MdcClkDiv::Div32),
|
16..32 => Some(MdcClockDivisor::Div32),
|
||||||
32..48 => Some(MdcClkDiv::Div48),
|
32..48 => Some(MdcClockDivisor::Div48),
|
||||||
48..64 => Some(MdcClkDiv::Div64),
|
48..64 => Some(MdcClockDivisor::Div64),
|
||||||
64..96 => Some(MdcClkDiv::Div96),
|
64..96 => Some(MdcClockDivisor::Div96),
|
||||||
96..128 => Some(MdcClkDiv::Div128),
|
96..128 => Some(MdcClockDivisor::Div128),
|
||||||
128..224 => Some(MdcClkDiv::Div224),
|
128..224 => Some(MdcClockDivisor::Div224),
|
||||||
// MDC clock divisor is too high for the maximum speed.
|
// MDC clock divisor is too high for the maximum speed.
|
||||||
// This is not a valid configuration.
|
// This is not a valid configuration.
|
||||||
_ => None,
|
_ => None,
|
||||||
@@ -255,16 +255,16 @@ pub fn calculate_mdc_clk_div(arm_clks: &ArmClocks) -> Option<MdcClkDiv> {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct EthernetConfig {
|
pub struct EthernetConfig {
|
||||||
pub clk_config_1000_mbps: ClkConfig,
|
pub clk_config_1000_mbps: ClockConfig,
|
||||||
pub mdc_clk_div: MdcClkDiv,
|
pub mdc_clk_div: MdcClockDivisor,
|
||||||
pub mac_address: [u8; 6],
|
pub mac_address: [u8; 6],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EthernetConfig {
|
impl EthernetConfig {
|
||||||
/// Creates a new Ethernet configuration.
|
/// Creates a new Ethernet configuration.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
clk_config_1000_mbps: ClkConfig,
|
clk_config_1000_mbps: ClockConfig,
|
||||||
mdc_clk_div: MdcClkDiv,
|
mdc_clk_div: MdcClockDivisor,
|
||||||
mac_address: [u8; 6],
|
mac_address: [u8; 6],
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -281,10 +281,10 @@ pub struct Ethernet {
|
|||||||
mdio: mdio::Mdio,
|
mdio: mdio::Mdio,
|
||||||
current_speed: Speed,
|
current_speed: Speed,
|
||||||
current_duplex: Duplex,
|
current_duplex: Duplex,
|
||||||
current_clk_divs: ClkDivisors,
|
current_clk_divs: ClockDivisors,
|
||||||
}
|
}
|
||||||
|
|
||||||
const IRQ_CONTROL: InterruptCtrl = InterruptCtrl::builder()
|
const IRQ_CONTROL: InterruptControl = InterruptControl::builder()
|
||||||
.with_tsu_sec_incr(false)
|
.with_tsu_sec_incr(false)
|
||||||
.with_partner_pg_rx(false)
|
.with_partner_pg_rx(false)
|
||||||
.with_auto_negotiation_complete(false)
|
.with_auto_negotiation_complete(false)
|
||||||
@@ -618,7 +618,7 @@ impl Ethernet {
|
|||||||
&mut self,
|
&mut self,
|
||||||
speed: Speed,
|
speed: Speed,
|
||||||
duplex: Duplex,
|
duplex: Duplex,
|
||||||
clk_collection: &ClkDivCollection,
|
clk_collection: &ClockDivSet,
|
||||||
) {
|
) {
|
||||||
if speed == self.current_speed
|
if speed == self.current_speed
|
||||||
&& duplex == self.current_duplex
|
&& duplex == self.current_duplex
|
||||||
@@ -721,7 +721,7 @@ pub(crate) fn on_interrupt(
|
|||||||
let mut clear = InterruptStatus::new_with_raw_value(0);
|
let mut clear = InterruptStatus::new_with_raw_value(0);
|
||||||
let mut tx_status_clear = TxStatus::new_with_raw_value(0);
|
let mut tx_status_clear = TxStatus::new_with_raw_value(0);
|
||||||
let mut rx_status_clear = RxStatus::new_with_raw_value(0);
|
let mut rx_status_clear = RxStatus::new_with_raw_value(0);
|
||||||
let mut disable = InterruptCtrl::new_with_raw_value(0);
|
let mut disable = InterruptControl::new_with_raw_value(0);
|
||||||
let mut result = InterruptResult::default();
|
let mut result = InterruptResult::default();
|
||||||
|
|
||||||
if status.frame_sent() {
|
if status.frame_sent() {
|
||||||
|
@@ -10,7 +10,8 @@ use arbitrary_int::Number;
|
|||||||
|
|
||||||
use cortex_ar::interrupt;
|
use cortex_ar::interrupt;
|
||||||
use zynq7000::gic::{
|
use zynq7000::gic::{
|
||||||
Dcr, GicCpuInterface, GicDistributor, InterfaceCtrl, InterruptSignalRegister, MmioGicCpuInterface, MmioGicDistributor, PriorityReg,
|
DistributorControlRegister, GicCpuInterface, GicDistributor, InterfaceControl,
|
||||||
|
InterruptSignalRegister, MmioGicCpuInterface, MmioGicDistributor, PriorityRegister,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SPURIOUS_INTERRUPT_ID: u32 = 1023;
|
const SPURIOUS_INTERRUPT_ID: u32 = 1023;
|
||||||
@@ -191,7 +192,7 @@ pub struct InvalidSgiInterruptId(pub usize);
|
|||||||
/// The flow of using this controller is as follows:
|
/// The flow of using this controller is as follows:
|
||||||
///
|
///
|
||||||
/// 1. Create the controller using [Self::new_with_init]. You can use the [zynq7000::PsPeripherals]
|
/// 1. Create the controller using [Self::new_with_init]. You can use the [zynq7000::PsPeripherals]
|
||||||
/// structure or the [zynq7000::gic::Gicc::new_mmio] and [zynq7000::gic::Gicd::new_mmio]
|
/// structure or the [zynq7000::gic::GicCpuInterface::new_mmio] and [zynq7000::gic::GicDistributor::new_mmio]
|
||||||
/// functions to create the MMIO instances. The constructor configures all PL interrupts
|
/// functions to create the MMIO instances. The constructor configures all PL interrupts
|
||||||
/// sensivities to high-level sensitivity and configures all sensitivities which are expected
|
/// sensivities to high-level sensitivity and configures all sensitivities which are expected
|
||||||
/// to have a certain value. It also sets the priority mask to 0xff by calling
|
/// to have a certain value. It also sets the priority mask to 0xff by calling
|
||||||
@@ -231,7 +232,10 @@ impl GicConfigurator {
|
|||||||
/// Create a new GIC controller instance and calls [Self::initialize] to perform
|
/// Create a new GIC controller instance and calls [Self::initialize] to perform
|
||||||
/// strongly recommended initialization routines for the GIC.
|
/// strongly recommended initialization routines for the GIC.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_with_init(gicc: MmioGicCpuInterface<'static>, gicd: MmioGicDistributor<'static>) -> Self {
|
pub fn new_with_init(
|
||||||
|
gicc: MmioGicCpuInterface<'static>,
|
||||||
|
gicd: MmioGicDistributor<'static>,
|
||||||
|
) -> Self {
|
||||||
let mut gic = GicConfigurator { gicc, gicd };
|
let mut gic = GicConfigurator { gicc, gicd };
|
||||||
gic.initialize();
|
gic.initialize();
|
||||||
gic
|
gic
|
||||||
@@ -280,7 +284,7 @@ impl GicConfigurator {
|
|||||||
/// 8-bit bitfield. See p.83 of the ARM GICv1 architecture specification.
|
/// 8-bit bitfield. See p.83 of the ARM GICv1 architecture specification.
|
||||||
pub fn set_priority_mask(&mut self, mask: u8) {
|
pub fn set_priority_mask(&mut self, mask: u8) {
|
||||||
self.gicc
|
self.gicc
|
||||||
.write_pmr(PriorityReg::new_with_raw_value(mask as u32));
|
.write_pmr(PriorityRegister::new_with_raw_value(mask as u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the sensitivity of a the Programmable Logic SPI interrupts.
|
/// Set the sensitivity of a the Programmable Logic SPI interrupts.
|
||||||
@@ -442,14 +446,14 @@ impl GicConfigurator {
|
|||||||
/// to call [Self::enable_interrupts] for interrupts to work.
|
/// to call [Self::enable_interrupts] for interrupts to work.
|
||||||
pub fn enable(&mut self) {
|
pub fn enable(&mut self) {
|
||||||
self.update_ctrl_regs(
|
self.update_ctrl_regs(
|
||||||
InterfaceCtrl::builder()
|
InterfaceControl::builder()
|
||||||
.with_sbpr(false)
|
.with_sbpr(false)
|
||||||
.with_fiq_en(false)
|
.with_fiq_en(false)
|
||||||
.with_ack_ctrl(false)
|
.with_ack_ctrl(false)
|
||||||
.with_enable_non_secure(true)
|
.with_enable_non_secure(true)
|
||||||
.with_enable_secure(true)
|
.with_enable_secure(true)
|
||||||
.build(),
|
.build(),
|
||||||
Dcr::builder()
|
DistributorControlRegister::builder()
|
||||||
.with_enable_non_secure(true)
|
.with_enable_non_secure(true)
|
||||||
.with_enable_secure(true)
|
.with_enable_secure(true)
|
||||||
.build(),
|
.build(),
|
||||||
@@ -476,7 +480,7 @@ impl GicConfigurator {
|
|||||||
|
|
||||||
/// Update the control registers which control the safety configuration and which also enable
|
/// Update the control registers which control the safety configuration and which also enable
|
||||||
/// the GIC.
|
/// the GIC.
|
||||||
pub fn update_ctrl_regs(&mut self, icr: InterfaceCtrl, dcr: Dcr) {
|
pub fn update_ctrl_regs(&mut self, icr: InterfaceControl, dcr: DistributorControlRegister) {
|
||||||
self.gicc.write_icr(icr);
|
self.gicc.write_icr(icr);
|
||||||
self.gicd.write_dcr(dcr);
|
self.gicd.write_dcr(dcr);
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,19 @@ pub struct EmioPin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EmioPin {
|
impl EmioPin {
|
||||||
|
/// Steal an EMIO peripheral instance pin.
|
||||||
|
///
|
||||||
|
/// It is recommended to retrieve EMIO pins safely by using the [Pins::new] and [Pins::take]
|
||||||
|
/// API instead
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This allows to create multiple instances of the same pin, which can lead to
|
||||||
|
/// data races on concurrent access.
|
||||||
|
pub unsafe fn steal(offset: usize) -> Self {
|
||||||
|
Self { offset }
|
||||||
|
}
|
||||||
|
|
||||||
/// This offset ranges from 0 to 64.
|
/// This offset ranges from 0 to 64.
|
||||||
pub fn offset(&self) -> usize {
|
pub fn offset(&self) -> usize {
|
||||||
self.offset
|
self.offset
|
||||||
|
@@ -4,7 +4,7 @@ use zynq7000::gpio::{Gpio, MaskedOutput, MmioGpio};
|
|||||||
|
|
||||||
use crate::slcr::Slcr;
|
use crate::slcr::Slcr;
|
||||||
|
|
||||||
use super::{PinIsOutputOnly, mio::MuxCfg};
|
use super::{PinIsOutputOnly, mio::MuxConfig};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum PinOffset {
|
pub enum PinOffset {
|
||||||
@@ -68,7 +68,7 @@ impl LowLevelGpio {
|
|||||||
let (offset, dirm, outen) = self.get_dirm_outen_regs_and_local_offset();
|
let (offset, dirm, outen) = self.get_dirm_outen_regs_and_local_offset();
|
||||||
if self.offset.is_mio() {
|
if self.offset.is_mio() {
|
||||||
// Tri-state bit must be 0 for the output driver to work.
|
// Tri-state bit must be 0 for the output driver to work.
|
||||||
self.reconfigure_slcr_mio_cfg(false, None, Some(MuxCfg::new_for_gpio()));
|
self.reconfigure_slcr_mio_cfg(false, None, Some(MuxConfig::new_for_gpio()));
|
||||||
}
|
}
|
||||||
let mut curr_dirm = unsafe { core::ptr::read_volatile(dirm) };
|
let mut curr_dirm = unsafe { core::ptr::read_volatile(dirm) };
|
||||||
curr_dirm |= 1 << offset;
|
curr_dirm |= 1 << offset;
|
||||||
@@ -100,7 +100,7 @@ impl LowLevelGpio {
|
|||||||
self.reconfigure_slcr_mio_cfg(
|
self.reconfigure_slcr_mio_cfg(
|
||||||
false,
|
false,
|
||||||
Some(with_internal_pullup),
|
Some(with_internal_pullup),
|
||||||
Some(MuxCfg::new_for_gpio()),
|
Some(MuxConfig::new_for_gpio()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let mut curr_dirm = unsafe { core::ptr::read_volatile(dirm) };
|
let mut curr_dirm = unsafe { core::ptr::read_volatile(dirm) };
|
||||||
@@ -124,7 +124,7 @@ impl LowLevelGpio {
|
|||||||
if offset_raw == 7 || offset_raw == 8 {
|
if offset_raw == 7 || offset_raw == 8 {
|
||||||
return Err(PinIsOutputOnly);
|
return Err(PinIsOutputOnly);
|
||||||
}
|
}
|
||||||
self.reconfigure_slcr_mio_cfg(true, Some(false), Some(MuxCfg::new_for_gpio()));
|
self.reconfigure_slcr_mio_cfg(true, Some(false), Some(MuxConfig::new_for_gpio()));
|
||||||
}
|
}
|
||||||
self.configure_input_pin();
|
self.configure_input_pin();
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -137,14 +137,14 @@ impl LowLevelGpio {
|
|||||||
if offset_raw == 7 || offset_raw == 8 {
|
if offset_raw == 7 || offset_raw == 8 {
|
||||||
return Err(PinIsOutputOnly);
|
return Err(PinIsOutputOnly);
|
||||||
}
|
}
|
||||||
self.reconfigure_slcr_mio_cfg(true, Some(true), Some(MuxCfg::new_for_gpio()));
|
self.reconfigure_slcr_mio_cfg(true, Some(true), Some(MuxConfig::new_for_gpio()));
|
||||||
}
|
}
|
||||||
self.configure_input_pin();
|
self.configure_input_pin();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the pin into an IO peripheral pin.
|
/// Convert the pin into an IO peripheral pin.
|
||||||
pub fn configure_as_io_periph_pin(&mut self, mux_conf: MuxCfg, pullup: Option<bool>) {
|
pub fn configure_as_io_periph_pin(&mut self, mux_conf: MuxConfig, pullup: Option<bool>) {
|
||||||
self.reconfigure_slcr_mio_cfg(false, pullup, Some(mux_conf));
|
self.reconfigure_slcr_mio_cfg(false, pullup, Some(mux_conf));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ impl LowLevelGpio {
|
|||||||
&mut self,
|
&mut self,
|
||||||
tristate: bool,
|
tristate: bool,
|
||||||
pullup: Option<bool>,
|
pullup: Option<bool>,
|
||||||
mux_conf: Option<MuxCfg>,
|
mux_conf: Option<MuxConfig>,
|
||||||
) {
|
) {
|
||||||
let raw_offset = self.offset.offset();
|
let raw_offset = self.offset.offset();
|
||||||
// Safety: We only modify the MIO config of the pin.
|
// Safety: We only modify the MIO config of the pin.
|
||||||
@@ -243,7 +243,7 @@ impl LowLevelGpio {
|
|||||||
// re-configuration which might also be potentially unsafe at run-time.
|
// re-configuration which might also be potentially unsafe at run-time.
|
||||||
let mio_cfg = slcr_wrapper.regs().read_mio_pins(raw_offset).unwrap();
|
let mio_cfg = slcr_wrapper.regs().read_mio_pins(raw_offset).unwrap();
|
||||||
if (pullup.is_some() && mio_cfg.pullup() != pullup.unwrap())
|
if (pullup.is_some() && mio_cfg.pullup() != pullup.unwrap())
|
||||||
|| (mux_conf.is_some() && MuxCfg::from(mio_cfg) != mux_conf.unwrap())
|
|| (mux_conf.is_some() && MuxConfig::from(mio_cfg) != mux_conf.unwrap())
|
||||||
|| tristate != mio_cfg.tri_enable()
|
|| tristate != mio_cfg.tri_enable()
|
||||||
{
|
{
|
||||||
slcr_wrapper.modify(|mut_slcr| {
|
slcr_wrapper.modify(|mut_slcr| {
|
||||||
|
@@ -7,14 +7,14 @@ use arbitrary_int::{u2, u3};
|
|||||||
use zynq7000::gpio::MmioGpio;
|
use zynq7000::gpio::MmioGpio;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct MuxCfg {
|
pub struct MuxConfig {
|
||||||
l3: u3,
|
l3: u3,
|
||||||
l2: u2,
|
l2: u2,
|
||||||
l1: bool,
|
l1: bool,
|
||||||
l0: bool,
|
l0: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<zynq7000::slcr::mio::Config> for MuxCfg {
|
impl From<zynq7000::slcr::mio::Config> for MuxConfig {
|
||||||
fn from(value: zynq7000::slcr::mio::Config) -> Self {
|
fn from(value: zynq7000::slcr::mio::Config) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
value.l0_sel(),
|
value.l0_sel(),
|
||||||
@@ -25,7 +25,7 @@ impl From<zynq7000::slcr::mio::Config> for MuxCfg {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MuxCfg {
|
impl MuxConfig {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn new(l0: bool, l1: bool, l2: u2, l3: u3) -> Self {
|
pub const fn new(l0: bool, l1: bool, l2: u2, l3: u3) -> Self {
|
||||||
Self { l3, l2, l1, l0 }
|
Self { l3, l2, l1, l0 }
|
||||||
@@ -193,7 +193,7 @@ impl<I: PinId> Pin<I> {
|
|||||||
|
|
||||||
/// Steal a typed MIO pin.
|
/// Steal a typed MIO pin.
|
||||||
///
|
///
|
||||||
/// Usually, you can just use the MIO pin members of the [MioPins] structure.
|
/// Usually, you can just use the MIO pin members of the [Pins] structure.
|
||||||
/// However, if you pass the pins into a consuming peripheral driver which performs
|
/// However, if you pass the pins into a consuming peripheral driver which performs
|
||||||
/// immediate type erasure, and you require the pins for/after a re-configuration
|
/// immediate type erasure, and you require the pins for/after a re-configuration
|
||||||
/// of the system, you can unsafely steal the pin. This function will NOT perform any
|
/// of the system, you can unsafely steal the pin. This function will NOT perform any
|
||||||
|
@@ -14,12 +14,12 @@ pub mod mio;
|
|||||||
|
|
||||||
use core::convert::Infallible;
|
use core::convert::Infallible;
|
||||||
use ll::PinOffset;
|
use ll::PinOffset;
|
||||||
use mio::{MioPinMarker, MuxCfg};
|
use mio::{MioPinMarker, MuxConfig};
|
||||||
|
|
||||||
use crate::gpio::ll::LowLevelGpio;
|
use crate::gpio::ll::LowLevelGpio;
|
||||||
use crate::{enable_amba_periph_clk, slcr::Slcr};
|
use crate::{enable_amba_periph_clk, slcr::Slcr};
|
||||||
pub use embedded_hal::digital::PinState;
|
pub use embedded_hal::digital::PinState;
|
||||||
use zynq7000::{gpio::MmioGpio, slcr::reset::GpioClkRst};
|
use zynq7000::{gpio::MmioGpio, 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")]
|
||||||
@@ -47,11 +47,11 @@ pub fn reset() {
|
|||||||
unsafe {
|
unsafe {
|
||||||
Slcr::with(|regs| {
|
Slcr::with(|regs| {
|
||||||
regs.reset_ctrl()
|
regs.reset_ctrl()
|
||||||
.write_gpio(GpioClkRst::builder().with_gpio_cpu1x_rst(true).build());
|
.write_gpio(GpioClockReset::builder().with_gpio_cpu1x_rst(true).build());
|
||||||
// Keep it in reset for one cycle.. not sure if this is necessary.
|
// Keep it in reset for one cycle.. not sure if this is necessary.
|
||||||
cortex_ar::asm::nop();
|
cortex_ar::asm::nop();
|
||||||
regs.reset_ctrl()
|
regs.reset_ctrl()
|
||||||
.write_gpio(GpioClkRst::builder().with_gpio_cpu1x_rst(false).build());
|
.write_gpio(GpioClockReset::builder().with_gpio_cpu1x_rst(false).build());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ pub enum PinMode {
|
|||||||
InputFloating,
|
InputFloating,
|
||||||
InputPullUp,
|
InputPullUp,
|
||||||
/// MIO-only peripheral pin configuration
|
/// MIO-only peripheral pin configuration
|
||||||
MioIoPeriph(MuxCfg),
|
MioIoPeriph(MuxConfig),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
@@ -380,13 +380,13 @@ impl embedded_hal::digital::InputPin for Input {
|
|||||||
/// IO peripheral pin.
|
/// IO peripheral pin.
|
||||||
pub struct IoPeriphPin {
|
pub struct IoPeriphPin {
|
||||||
pin: LowLevelGpio,
|
pin: LowLevelGpio,
|
||||||
mux_conf: MuxCfg,
|
mux_conf: MuxConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IoPeriphPin {
|
impl IoPeriphPin {
|
||||||
/// Constructor for IO peripheral pins where only the multiplexer and pullup configuration
|
/// Constructor for IO peripheral pins where only the multiplexer and pullup configuration
|
||||||
/// need to be changed.
|
/// need to be changed.
|
||||||
pub fn new(pin: impl MioPinMarker, mux_conf: MuxCfg, pullup: Option<bool>) -> Self {
|
pub fn new(pin: impl MioPinMarker, mux_conf: MuxConfig, 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);
|
||||||
Self {
|
Self {
|
||||||
@@ -404,7 +404,7 @@ impl IoPeriphPin {
|
|||||||
low_level.set_mio_pin_config(config);
|
low_level.set_mio_pin_config(config);
|
||||||
Self {
|
Self {
|
||||||
pin: low_level,
|
pin: low_level,
|
||||||
mux_conf: MuxCfg::new(
|
mux_conf: MuxConfig::new(
|
||||||
config.l0_sel(),
|
config.l0_sel(),
|
||||||
config.l1_sel(),
|
config.l1_sel(),
|
||||||
config.l2_sel(),
|
config.l2_sel(),
|
||||||
@@ -423,7 +423,7 @@ impl IoPeriphPin {
|
|||||||
low_level.set_mio_pin_config_with_unlocked_slcr(slcr, config);
|
low_level.set_mio_pin_config_with_unlocked_slcr(slcr, config);
|
||||||
Self {
|
Self {
|
||||||
pin: low_level,
|
pin: low_level,
|
||||||
mux_conf: MuxCfg::new(
|
mux_conf: MuxConfig::new(
|
||||||
config.l0_sel(),
|
config.l0_sel(),
|
||||||
config.l1_sel(),
|
config.l1_sel(),
|
||||||
config.l2_sel(),
|
config.l2_sel(),
|
||||||
|
@@ -38,7 +38,7 @@ impl GlobalTimerCounter {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// This function allows creating an arbitrary amount of memory-mapped peripheral drivers.
|
/// This function allows creating an arbitrary amount of memory-mapped peripheral drivers.
|
||||||
/// See the [zynq7000::gtc::Gtc::new_mmio] docs for more safety information.
|
/// See the [zynq7000::gtc::GlobalTimerCounter::new_mmio] docs for more safety information.
|
||||||
#[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 {
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
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::{Ctrl, I2C_0_BASE_ADDR, I2C_1_BASE_ADDR, InterruptStatus, MmioI2c, TransferSize},
|
i2c::{Control, I2C_0_BASE_ADDR, I2C_1_BASE_ADDR, InterruptStatus, MmioI2c, TransferSize},
|
||||||
slcr::reset::DualClkRst,
|
slcr::reset::DualClockReset,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
@@ -17,14 +17,14 @@ use crate::{
|
|||||||
mio::{
|
mio::{
|
||||||
Mio10, Mio11, Mio12, Mio13, Mio14, Mio15, Mio28, Mio29, Mio30, Mio31, Mio32, Mio33,
|
Mio10, Mio11, Mio12, Mio13, Mio14, Mio15, Mio28, Mio29, Mio30, Mio31, Mio32, Mio33,
|
||||||
Mio34, Mio35, Mio36, Mio37, Mio38, Mio39, Mio48, Mio49, Mio52, Mio53, MioPinMarker,
|
Mio34, Mio35, Mio36, Mio37, Mio38, Mio39, Mio48, Mio49, Mio52, Mio53, MioPinMarker,
|
||||||
MuxCfg, Pin,
|
MuxConfig, Pin,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
slcr::Slcr,
|
slcr::Slcr,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const I2C_MUX_CONF: MuxCfg = MuxCfg::new_with_l3(u3::new(0b010));
|
pub const I2C_MUX_CONF: MuxConfig = MuxConfig::new_with_l3(u3::new(0b010));
|
||||||
pub const FIFO_DEPTH: usize = 16;
|
pub const FIFO_DEPTH: usize = 16;
|
||||||
/// Maximum read size in one read operation.
|
/// Maximum read size in one read operation.
|
||||||
pub const MAX_READ_SIZE: usize = 255;
|
pub const MAX_READ_SIZE: usize = 255;
|
||||||
@@ -351,7 +351,7 @@ impl I2c {
|
|||||||
enable_amba_periph_clk(periph_sel);
|
enable_amba_periph_clk(periph_sel);
|
||||||
//reset(id);
|
//reset(id);
|
||||||
regs.write_cr(
|
regs.write_cr(
|
||||||
Ctrl::builder()
|
Control::builder()
|
||||||
.with_div_a(u2::new(clk_cfg.div_a()))
|
.with_div_a(u2::new(clk_cfg.div_a()))
|
||||||
.with_div_b(u6::new(clk_cfg.div_b()))
|
.with_div_b(u6::new(clk_cfg.div_b()))
|
||||||
.with_clear_fifo(true)
|
.with_clear_fifo(true)
|
||||||
@@ -360,7 +360,7 @@ impl I2c {
|
|||||||
.with_acken(false)
|
.with_acken(false)
|
||||||
.with_addressing(true)
|
.with_addressing(true)
|
||||||
.with_mode(zynq7000::i2c::Mode::Master)
|
.with_mode(zynq7000::i2c::Mode::Master)
|
||||||
.with_dir(zynq7000::i2c::Dir::Transmitter)
|
.with_dir(zynq7000::i2c::Direction::Transmitter)
|
||||||
.build(),
|
.build(),
|
||||||
);
|
);
|
||||||
Self { regs }
|
Self { regs }
|
||||||
@@ -370,7 +370,7 @@ impl I2c {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn start_transfer(&mut self, address: u8) {
|
fn start_transfer(&mut self, address: u8) {
|
||||||
self.regs
|
self.regs
|
||||||
.write_addr(zynq7000::i2c::Addr::new_with_raw_value(address as u32));
|
.write_addr(zynq7000::i2c::Address::new_with_raw_value(address as u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -399,7 +399,7 @@ impl I2c {
|
|||||||
cr.set_acken(true);
|
cr.set_acken(true);
|
||||||
cr.set_mode(zynq7000::i2c::Mode::Master);
|
cr.set_mode(zynq7000::i2c::Mode::Master);
|
||||||
cr.set_clear_fifo(true);
|
cr.set_clear_fifo(true);
|
||||||
cr.set_dir(zynq7000::i2c::Dir::Transmitter);
|
cr.set_dir(zynq7000::i2c::Direction::Transmitter);
|
||||||
if !generate_stop {
|
if !generate_stop {
|
||||||
cr.set_hold_bus(true);
|
cr.set_hold_bus(true);
|
||||||
}
|
}
|
||||||
@@ -498,7 +498,7 @@ impl I2c {
|
|||||||
cr.set_acken(true);
|
cr.set_acken(true);
|
||||||
cr.set_mode(zynq7000::i2c::Mode::Master);
|
cr.set_mode(zynq7000::i2c::Mode::Master);
|
||||||
cr.set_clear_fifo(true);
|
cr.set_clear_fifo(true);
|
||||||
cr.set_dir(zynq7000::i2c::Dir::Receiver);
|
cr.set_dir(zynq7000::i2c::Direction::Receiver);
|
||||||
if data.len() > FIFO_DEPTH {
|
if data.len() > FIFO_DEPTH {
|
||||||
cr.set_hold_bus(true);
|
cr.set_hold_bus(true);
|
||||||
}
|
}
|
||||||
@@ -640,11 +640,11 @@ impl embedded_hal::i2c::I2c for I2c {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn reset(id: I2cId) {
|
pub fn reset(id: I2cId) {
|
||||||
let assert_reset = match id {
|
let assert_reset = match id {
|
||||||
I2cId::I2c0 => DualClkRst::builder()
|
I2cId::I2c0 => DualClockReset::builder()
|
||||||
.with_periph1_cpu1x_rst(false)
|
.with_periph1_cpu1x_rst(false)
|
||||||
.with_periph0_cpu1x_rst(true)
|
.with_periph0_cpu1x_rst(true)
|
||||||
.build(),
|
.build(),
|
||||||
I2cId::I2c1 => DualClkRst::builder()
|
I2cId::I2c1 => DualClockReset::builder()
|
||||||
.with_periph1_cpu1x_rst(true)
|
.with_periph1_cpu1x_rst(true)
|
||||||
.with_periph0_cpu1x_rst(false)
|
.with_periph0_cpu1x_rst(false)
|
||||||
.build(),
|
.build(),
|
||||||
@@ -657,7 +657,7 @@ pub fn reset(id: I2cId) {
|
|||||||
for _ in 0..3 {
|
for _ in 0..3 {
|
||||||
cortex_ar::asm::nop();
|
cortex_ar::asm::nop();
|
||||||
}
|
}
|
||||||
regs.reset_ctrl().write_i2c(DualClkRst::DEFAULT);
|
regs.reset_ctrl().write_i2c(DualClockReset::DEFAULT);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,15 @@
|
|||||||
use core::sync::atomic::compiler_fence;
|
use core::sync::atomic::compiler_fence;
|
||||||
|
|
||||||
use arbitrary_int::{u2, u3};
|
use arbitrary_int::{u2, u3};
|
||||||
pub use zynq7000::l2_cache::LatencyCfg;
|
pub use zynq7000::l2_cache::LatencyConfig;
|
||||||
use zynq7000::l2_cache::{
|
use zynq7000::l2_cache::{
|
||||||
Associativity, AuxCtrl, Ctrl, InterruptCtrl, MmioL2Cache, ReplacementPolicy, WaySize,
|
Associativity, AuxControl, Control, InterruptControl, MmioL2Cache, ReplacementPolicy, WaySize,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::slcr::Slcr;
|
use crate::slcr::Slcr;
|
||||||
|
|
||||||
/// This is the default configuration used by Xilinx/AMD.
|
/// This is the default configuration used by Xilinx/AMD.
|
||||||
pub const AUX_CTRL_DEFAULT: AuxCtrl = AuxCtrl::builder()
|
pub const AUX_CTRL_DEFAULT: AuxControl = AuxControl::builder()
|
||||||
.with_early_bresp_enable(true)
|
.with_early_bresp_enable(true)
|
||||||
.with_isntruction_prefetch_enable(true)
|
.with_isntruction_prefetch_enable(true)
|
||||||
.with_data_prefetch_enable(true)
|
.with_data_prefetch_enable(true)
|
||||||
@@ -30,14 +30,14 @@ pub const AUX_CTRL_DEFAULT: AuxCtrl = AuxCtrl::builder()
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
/// Xilinx/AMD default configuration. 2 cycles for setup, write and read.
|
/// Xilinx/AMD default configuration. 2 cycles for setup, write and read.
|
||||||
pub const DEFAULT_TAG_RAM_LATENCY: LatencyCfg = LatencyCfg::builder()
|
pub const DEFAULT_TAG_RAM_LATENCY: LatencyConfig = LatencyConfig::builder()
|
||||||
.with_write_access_latency(u3::new(0b001))
|
.with_write_access_latency(u3::new(0b001))
|
||||||
.with_read_access_latency(u3::new(0b001))
|
.with_read_access_latency(u3::new(0b001))
|
||||||
.with_setup_latency(u3::new(0b001))
|
.with_setup_latency(u3::new(0b001))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
/// Xilinx/AMD default configuration. 2 cycles for setup and write, 3 cycles for read.
|
/// Xilinx/AMD default configuration. 2 cycles for setup and write, 3 cycles for read.
|
||||||
pub const DEFAULT_DATA_RAM_LATENCY: LatencyCfg = LatencyCfg::builder()
|
pub const DEFAULT_DATA_RAM_LATENCY: LatencyConfig = LatencyConfig::builder()
|
||||||
.with_write_access_latency(u3::new(0b001))
|
.with_write_access_latency(u3::new(0b001))
|
||||||
.with_read_access_latency(u3::new(0b010))
|
.with_read_access_latency(u3::new(0b010))
|
||||||
.with_setup_latency(u3::new(0b001))
|
.with_setup_latency(u3::new(0b001))
|
||||||
@@ -57,10 +57,10 @@ pub fn init_with_defaults(l2c_mmio: &mut MmioL2Cache<'static>) {
|
|||||||
/// 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 MmioL2Cache<'static>,
|
||||||
tag_ram_latency: LatencyCfg,
|
tag_ram_latency: LatencyConfig,
|
||||||
data_ram_latency: LatencyCfg,
|
data_ram_latency: LatencyConfig,
|
||||||
) {
|
) {
|
||||||
l2c_mmio.write_control(Ctrl::new_disabled());
|
l2c_mmio.write_control(Control::new_disabled());
|
||||||
l2c_mmio.write_aux_control(AUX_CTRL_DEFAULT);
|
l2c_mmio.write_aux_control(AUX_CTRL_DEFAULT);
|
||||||
l2c_mmio.write_tag_ram_latency(tag_ram_latency);
|
l2c_mmio.write_tag_ram_latency(tag_ram_latency);
|
||||||
l2c_mmio.write_data_ram_latency(data_ram_latency);
|
l2c_mmio.write_data_ram_latency(data_ram_latency);
|
||||||
@@ -71,11 +71,11 @@ pub fn init(
|
|||||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
|
|
||||||
let pending = l2c_mmio.read_interrupt_raw_status();
|
let pending = l2c_mmio.read_interrupt_raw_status();
|
||||||
l2c_mmio.write_interrupt_clear(InterruptCtrl::new_with_raw_value(pending.raw_value()));
|
l2c_mmio.write_interrupt_clear(InterruptControl::new_with_raw_value(pending.raw_value()));
|
||||||
unsafe {
|
unsafe {
|
||||||
Slcr::with(|slcr| {
|
Slcr::with(|slcr| {
|
||||||
slcr.write_magic_l2c_register(SLCR_L2C_CONFIG_MAGIC_VALUE);
|
slcr.write_magic_l2c_register(SLCR_L2C_CONFIG_MAGIC_VALUE);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
l2c_mmio.write_control(Ctrl::new_enabled());
|
l2c_mmio.write_control(Control::new_enabled());
|
||||||
}
|
}
|
||||||
|
@@ -9,8 +9,11 @@
|
|||||||
//! various drivers in the embedded rust ecosystem.
|
//! various drivers in the embedded rust ecosystem.
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
use slcr::Slcr;
|
use slcr::Slcr;
|
||||||
use zynq7000::slcr::LevelShifterReg;
|
use zynq7000::slcr::LevelShifterRegister;
|
||||||
|
|
||||||
pub mod cache;
|
pub mod cache;
|
||||||
pub mod clocks;
|
pub mod clocks;
|
||||||
@@ -40,7 +43,7 @@ pub enum BootDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub enum BootPllCfg {
|
pub enum BootPllConfig {
|
||||||
Enabled,
|
Enabled,
|
||||||
Bypassed,
|
Bypassed,
|
||||||
}
|
}
|
||||||
@@ -48,7 +51,7 @@ pub enum BootPllCfg {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BootMode {
|
pub struct BootMode {
|
||||||
boot_mode: Option<BootDevice>,
|
boot_mode: Option<BootDevice>,
|
||||||
pll_config: BootPllCfg,
|
pll_config: BootPllConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BootMode {
|
impl BootMode {
|
||||||
@@ -82,9 +85,9 @@ impl BootMode {
|
|||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let pll_config = if (raw_register >> 4) & 0b1 == 0 {
|
let pll_config = if (raw_register >> 4) & 0b1 == 0 {
|
||||||
BootPllCfg::Enabled
|
BootPllConfig::Enabled
|
||||||
} else {
|
} else {
|
||||||
BootPllCfg::Bypassed
|
BootPllConfig::Bypassed
|
||||||
};
|
};
|
||||||
Self {
|
Self {
|
||||||
boot_mode,
|
boot_mode,
|
||||||
@@ -95,7 +98,7 @@ impl BootMode {
|
|||||||
self.boot_mode
|
self.boot_mode
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn pll_enable(&self) -> BootPllCfg {
|
pub const fn pll_enable(&self) -> BootPllConfig {
|
||||||
self.pll_config
|
self.pll_config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,11 +107,12 @@ impl BootMode {
|
|||||||
/// system (PS).
|
/// system (PS).
|
||||||
///
|
///
|
||||||
/// The Zynq-7000 TRM p.32 specifies more information about this register and how to use it.
|
/// The Zynq-7000 TRM p.32 specifies more information about this register and how to use it.
|
||||||
pub fn configure_level_shifter(config: zynq7000::slcr::LevelShifterCfg) {
|
pub fn configure_level_shifter(config: zynq7000::slcr::LevelShifterConfig) {
|
||||||
// Safety: We only manipulate the level shift registers.
|
// Safety: We only manipulate the level shift registers.
|
||||||
unsafe {
|
unsafe {
|
||||||
Slcr::with(|slcr_unlocked| {
|
Slcr::with(|slcr_unlocked| {
|
||||||
slcr_unlocked.write_lvl_shftr_en(LevelShifterReg::new_with_raw_value(config as u32));
|
slcr_unlocked
|
||||||
|
.write_lvl_shftr_en(LevelShifterRegister::new_with_raw_value(config as u32));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,7 @@ use crate::enable_amba_periph_clk;
|
|||||||
use crate::gpio::IoPeriphPin;
|
use crate::gpio::IoPeriphPin;
|
||||||
use crate::gpio::mio::{
|
use crate::gpio::mio::{
|
||||||
Mio10, Mio11, Mio12, Mio13, Mio14, Mio15, Mio28, Mio29, Mio30, Mio31, Mio32, Mio33, Mio34,
|
Mio10, Mio11, Mio12, Mio13, Mio14, Mio15, Mio28, Mio29, Mio30, Mio31, Mio32, Mio33, Mio34,
|
||||||
Mio35, Mio36, Mio37, Mio38, Mio39, MioPinMarker, MuxCfg, Pin,
|
Mio35, Mio36, Mio37, Mio38, Mio39, MioPinMarker, MuxConfig, Pin,
|
||||||
};
|
};
|
||||||
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
use crate::gpio::mio::{
|
use crate::gpio::mio::{
|
||||||
@@ -19,10 +19,10 @@ use arbitrary_int::{Number, u3, u4, u6};
|
|||||||
use embedded_hal::delay::DelayNs;
|
use embedded_hal::delay::DelayNs;
|
||||||
pub use embedded_hal::spi::Mode;
|
pub use embedded_hal::spi::Mode;
|
||||||
use embedded_hal::spi::{MODE_0, MODE_1, MODE_2, MODE_3, SpiBus as _};
|
use embedded_hal::spi::{MODE_0, MODE_1, MODE_2, MODE_3, SpiBus as _};
|
||||||
use zynq7000::slcr::reset::DualRefAndClkRst;
|
use zynq7000::slcr::reset::DualRefAndClockReset;
|
||||||
use zynq7000::spi::{
|
use zynq7000::spi::{
|
||||||
BaudDivSel, DelayControl, FifoWrite, InterruptControl, InterruptMask, InterruptStatus,
|
BaudDivSel, DelayControl, FifoWrite, InterruptControl, InterruptMask, InterruptStatus, MmioSpi,
|
||||||
MmioSpi, SPI_0_BASE_ADDR, SPI_1_BASE_ADDR,
|
SPI_0_BASE_ADDR, SPI_1_BASE_ADDR,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const FIFO_DEPTH: usize = 128;
|
pub const FIFO_DEPTH: usize = 128;
|
||||||
@@ -81,7 +81,7 @@ pub trait SsPin: MioPinMarker {
|
|||||||
const GROUP: usize;
|
const GROUP: usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const SPI_MUX_CONF: MuxCfg = MuxCfg::new_with_l3(u3::new(0b101));
|
pub const SPI_MUX_CONF: MuxConfig = MuxConfig::new_with_l3(u3::new(0b101));
|
||||||
|
|
||||||
// SPI0, choice 1
|
// SPI0, choice 1
|
||||||
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||||
@@ -493,7 +493,7 @@ impl SpiLowLevel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.regs.write_cr(
|
self.regs.write_cr(
|
||||||
zynq7000::spi::Cfg::builder()
|
zynq7000::spi::Config::builder()
|
||||||
.with_modefail_gen_en(false)
|
.with_modefail_gen_en(false)
|
||||||
.with_manual_start(false)
|
.with_manual_start(false)
|
||||||
.with_manual_start_enable(man_start)
|
.with_manual_start_enable(man_start)
|
||||||
@@ -1106,13 +1106,13 @@ impl<Delay: DelayNs> embedded_hal::spi::SpiDevice for SpiWithHwCs<Delay> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn reset(id: SpiId) {
|
pub fn reset(id: SpiId) {
|
||||||
let assert_reset = match id {
|
let assert_reset = match id {
|
||||||
SpiId::Spi0 => DualRefAndClkRst::builder()
|
SpiId::Spi0 => DualRefAndClockReset::builder()
|
||||||
.with_periph1_ref_rst(false)
|
.with_periph1_ref_rst(false)
|
||||||
.with_periph0_ref_rst(true)
|
.with_periph0_ref_rst(true)
|
||||||
.with_periph1_cpu1x_rst(false)
|
.with_periph1_cpu1x_rst(false)
|
||||||
.with_periph0_cpu1x_rst(true)
|
.with_periph0_cpu1x_rst(true)
|
||||||
.build(),
|
.build(),
|
||||||
SpiId::Spi1 => DualRefAndClkRst::builder()
|
SpiId::Spi1 => DualRefAndClockReset::builder()
|
||||||
.with_periph1_ref_rst(true)
|
.with_periph1_ref_rst(true)
|
||||||
.with_periph0_ref_rst(false)
|
.with_periph0_ref_rst(false)
|
||||||
.with_periph1_cpu1x_rst(true)
|
.with_periph1_cpu1x_rst(true)
|
||||||
@@ -1127,7 +1127,7 @@ pub fn reset(id: SpiId) {
|
|||||||
for _ in 0..3 {
|
for _ in 0..3 {
|
||||||
cortex_ar::asm::nop();
|
cortex_ar::asm::nop();
|
||||||
}
|
}
|
||||||
regs.reset_ctrl().write_spi(DualRefAndClkRst::DEFAULT);
|
regs.reset_ctrl().write_spi(DualRefAndClockReset::DEFAULT);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,7 @@ use crate::{
|
|||||||
clocks::ArmClocks,
|
clocks::ArmClocks,
|
||||||
gpio::{
|
gpio::{
|
||||||
IoPeriphPin,
|
IoPeriphPin,
|
||||||
mio::{Mio28, Mio29, Mio30, Mio31, MioPinMarker, MuxCfg, Pin},
|
mio::{Mio28, Mio29, Mio30, Mio31, MioPinMarker, MuxConfig, Pin},
|
||||||
},
|
},
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
};
|
};
|
||||||
@@ -55,7 +55,7 @@ impl PsTtc for MmioTtc<'static> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const TTC_MUX_CONF: MuxCfg = MuxCfg::new_with_l3(u3::new(0b110));
|
pub const TTC_MUX_CONF: MuxConfig = MuxConfig::new_with_l3(u3::new(0b110));
|
||||||
|
|
||||||
pub trait ClockInPin: MioPinMarker {
|
pub trait ClockInPin: MioPinMarker {
|
||||||
const ID: TtcId;
|
const ID: TtcId;
|
||||||
@@ -172,7 +172,7 @@ impl TtcChannel {
|
|||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
#[error("invalid TTC pin configuration")]
|
#[error("invalid TTC pin configuration")]
|
||||||
pub struct InvalidTtcPinConfigError(pub MuxCfg);
|
pub struct InvalidTtcPinConfigError(pub MuxConfig);
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
#[error("frequency is zero")]
|
#[error("frequency is zero")]
|
||||||
@@ -186,10 +186,7 @@ pub enum TtcConstructionError {
|
|||||||
FrequencyIsZero(#[from] FrequencyIsZeroError),
|
FrequencyIsZero(#[from] FrequencyIsZeroError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn calc_prescaler_reg_and_interval_ticks(
|
pub fn calc_prescaler_reg_and_interval_ticks(mut ref_clk: Hertz, freq: Hertz) -> (Option<u4>, u16) {
|
||||||
mut ref_clk: Hertz,
|
|
||||||
freq: Hertz,
|
|
||||||
) -> (Option<u4>, u16) {
|
|
||||||
// TODO: Can this be optimized?
|
// TODO: Can this be optimized?
|
||||||
let mut prescaler_reg: Option<u4> = None;
|
let mut prescaler_reg: Option<u4> = None;
|
||||||
let mut tick_val = ref_clk / freq;
|
let mut tick_val = ref_clk / freq;
|
||||||
@@ -261,8 +258,7 @@ impl Pwm {
|
|||||||
return Err(FrequencyIsZeroError);
|
return Err(FrequencyIsZeroError);
|
||||||
}
|
}
|
||||||
let id = self.channel.id() as usize;
|
let id = self.channel.id() as usize;
|
||||||
let (prescaler_reg, tick_val) =
|
let (prescaler_reg, tick_val) = calc_prescaler_reg_and_interval_ticks(self.ref_clk, freq);
|
||||||
calc_prescaler_reg_and_interval_ticks(self.ref_clk, freq);
|
|
||||||
self.set_up_and_configure_pwm(id, prescaler_reg, tick_val);
|
self.set_up_and_configure_pwm(id, prescaler_reg, tick_val);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -320,7 +316,7 @@ impl Pwm {
|
|||||||
.regs
|
.regs
|
||||||
.write_clk_cntr(
|
.write_clk_cntr(
|
||||||
id,
|
id,
|
||||||
zynq7000::ttc::ClkCtrl::builder()
|
zynq7000::ttc::ClockControl::builder()
|
||||||
.with_ext_clk_edge(false)
|
.with_ext_clk_edge(false)
|
||||||
.with_clk_src(zynq7000::ttc::ClockSource::Pclk)
|
.with_clk_src(zynq7000::ttc::ClockSource::Pclk)
|
||||||
.with_prescaler(prescaler_reg.unwrap_or(u4::new(0)))
|
.with_prescaler(prescaler_reg.unwrap_or(u4::new(0)))
|
||||||
|
@@ -6,9 +6,9 @@ use core::convert::Infallible;
|
|||||||
use arbitrary_int::u3;
|
use arbitrary_int::u3;
|
||||||
use libm::round;
|
use libm::round;
|
||||||
use zynq7000::{
|
use zynq7000::{
|
||||||
slcr::reset::DualRefAndClkRst,
|
slcr::reset::DualRefAndClockReset,
|
||||||
uart::{
|
uart::{
|
||||||
BaudRateDiv, Baudgen, ChMode, ClkSel, FifoTrigger, InterruptControl, MmioUart, Mode,
|
BaudRateDiv, Baudgen, ChMode, ClockSelect, FifoTrigger, InterruptControl, MmioUart, Mode,
|
||||||
UART_0_BASE, UART_1_BASE,
|
UART_0_BASE, UART_1_BASE,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -20,7 +20,7 @@ use crate::{
|
|||||||
mio::{
|
mio::{
|
||||||
Mio8, Mio9, Mio10, Mio11, Mio12, Mio13, Mio14, Mio15, Mio28, Mio29, Mio30, Mio31,
|
Mio8, Mio9, Mio10, Mio11, Mio12, Mio13, Mio14, Mio15, Mio28, Mio29, Mio30, Mio31,
|
||||||
Mio32, Mio33, Mio34, Mio35, Mio36, Mio37, Mio38, Mio39, Mio48, Mio49, Mio52, Mio53,
|
Mio32, Mio33, Mio34, Mio35, Mio36, Mio37, Mio38, Mio39, Mio48, Mio49, Mio52, Mio53,
|
||||||
MioPinMarker, MuxCfg, Pin,
|
MioPinMarker, MuxConfig, Pin,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
slcr::Slcr,
|
slcr::Slcr,
|
||||||
@@ -45,7 +45,7 @@ pub use rx::*;
|
|||||||
|
|
||||||
pub const FIFO_DEPTH: usize = 64;
|
pub const FIFO_DEPTH: usize = 64;
|
||||||
pub const DEFAULT_RX_TRIGGER_LEVEL: u8 = 32;
|
pub const DEFAULT_RX_TRIGGER_LEVEL: u8 = 32;
|
||||||
pub const UART_MUX_CONF: MuxCfg = MuxCfg::new_with_l3(u3::new(0b111));
|
pub const UART_MUX_CONF: MuxConfig = MuxConfig::new_with_l3(u3::new(0b111));
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum UartId {
|
pub enum UartId {
|
||||||
@@ -120,31 +120,6 @@ macro_rules! pin_pairs {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
macro_rules! impl_into_uart {
|
|
||||||
(($($Mio:ident),+)) => {
|
|
||||||
$(
|
|
||||||
impl From<Pin<$Mio>> for IoPeriphPin {
|
|
||||||
fn from(pin: Pin<$Mio>) -> Self {
|
|
||||||
IoPeriphPin::new(pin, UART_MUX_CONF, None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_into_uart!((
|
|
||||||
Mio10, Mio11, Mio15, Mio14, Mio31, Mio30, Mio35, Mio34, Mio39, Mio38, Mio8, Mio9, Mio12, Mio13,
|
|
||||||
Mio28, Mio29, Mio32, Mio33, Mio36, Mio37, Mio48, Mio49, Mio52, Mio53
|
|
||||||
));
|
|
||||||
|
|
||||||
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
|
||||||
impl_into_uart!((
|
|
||||||
Mio19, Mio18, Mio23, Mio22, Mio43, Mio42, Mio47, Mio46, Mio51, Mio50, Mio16, Mio17, Mio20,
|
|
||||||
Mio21, Mio24, Mio25, Mio40, Mio41, Mio44, Mio45
|
|
||||||
));
|
|
||||||
*/
|
|
||||||
|
|
||||||
pin_pairs!(
|
pin_pairs!(
|
||||||
UartId::Uart0,
|
UartId::Uart0,
|
||||||
(
|
(
|
||||||
@@ -185,6 +160,8 @@ pub const MAX_BAUD_RATE: u32 = 6240000;
|
|||||||
/// Based on values provided by the vendor library.
|
/// Based on values provided by the vendor library.
|
||||||
pub const MIN_BAUD_RATE: u32 = 110;
|
pub const MIN_BAUD_RATE: u32 = 110;
|
||||||
|
|
||||||
|
pub const MAX_BAUDERROR_RATE: f32 = 0.005;
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy)]
|
#[derive(Debug, Default, Clone, Copy)]
|
||||||
pub enum Parity {
|
pub enum Parity {
|
||||||
Even,
|
Even,
|
||||||
@@ -210,7 +187,7 @@ pub enum CharLen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct ClkConfigRaw {
|
pub struct ClockConfigRaw {
|
||||||
cd: u16,
|
cd: u16,
|
||||||
bdiv: u8,
|
bdiv: u8,
|
||||||
}
|
}
|
||||||
@@ -218,14 +195,14 @@ pub struct ClkConfigRaw {
|
|||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub fn calculate_viable_configs(
|
pub fn calculate_viable_configs(
|
||||||
mut uart_clk: Hertz,
|
mut uart_clk: Hertz,
|
||||||
clk_sel: ClkSel,
|
clk_sel: ClockSelect,
|
||||||
target_baud: u32,
|
target_baud: u32,
|
||||||
) -> alloc::vec::Vec<(ClkConfigRaw, f64)> {
|
) -> alloc::vec::Vec<(ClockConfigRaw, f64)> {
|
||||||
let mut viable_cfgs = alloc::vec::Vec::new();
|
let mut viable_cfgs = alloc::vec::Vec::new();
|
||||||
if clk_sel == ClkSel::UartRefClkDiv8 {
|
if clk_sel == ClockSelect::UartRefClkDiv8 {
|
||||||
uart_clk /= 8;
|
uart_clk /= 8;
|
||||||
}
|
}
|
||||||
let mut current_clk_config = ClkConfigRaw::new(0, 0);
|
let mut current_clk_config = ClockConfigRaw::default();
|
||||||
for bdiv in 4..u8::MAX {
|
for bdiv in 4..u8::MAX {
|
||||||
let cd =
|
let cd =
|
||||||
round(uart_clk.raw() as f64 / ((bdiv as u32 + 1) as f64 * target_baud as f64)) as u64;
|
round(uart_clk.raw() as f64 / ((bdiv as u32 + 1) as f64 * target_baud as f64)) as u64;
|
||||||
@@ -250,17 +227,17 @@ pub fn calculate_viable_configs(
|
|||||||
/// You can also use [calculate_viable_configs] to get a list of all viable configurations.
|
/// You can also use [calculate_viable_configs] to get a list of all viable configurations.
|
||||||
pub fn calculate_raw_baud_cfg_smallest_error(
|
pub fn calculate_raw_baud_cfg_smallest_error(
|
||||||
mut uart_clk: Hertz,
|
mut uart_clk: Hertz,
|
||||||
clk_sel: ClkSel,
|
clk_sel: ClockSelect,
|
||||||
target_baud: u32,
|
target_baud: u32,
|
||||||
) -> Result<(ClkConfigRaw, f64), DivisorZero> {
|
) -> Result<(ClockConfigRaw, f64), DivisorZero> {
|
||||||
if target_baud == 0 {
|
if target_baud == 0 {
|
||||||
return Err(DivisorZero);
|
return Err(DivisorZero);
|
||||||
}
|
}
|
||||||
if clk_sel == ClkSel::UartRefClkDiv8 {
|
if clk_sel == ClockSelect::UartRefClkDiv8 {
|
||||||
uart_clk /= 8;
|
uart_clk /= 8;
|
||||||
}
|
}
|
||||||
let mut current_clk_config = ClkConfigRaw::default();
|
let mut current_clk_config = ClockConfigRaw::default();
|
||||||
let mut best_clk_config = ClkConfigRaw::default();
|
let mut best_clk_config = ClockConfigRaw::default();
|
||||||
let mut smallest_error: f64 = 100.0;
|
let mut smallest_error: f64 = 100.0;
|
||||||
for bdiv in 4..u8::MAX {
|
for bdiv in 4..u8::MAX {
|
||||||
let cd =
|
let cd =
|
||||||
@@ -281,30 +258,30 @@ pub fn calculate_raw_baud_cfg_smallest_error(
|
|||||||
Ok((best_clk_config, smallest_error))
|
Ok((best_clk_config, smallest_error))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClkConfigRaw {
|
impl ClockConfigRaw {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn new(cd: u16, bdiv: u8) -> Result<Self, DivisorZero> {
|
pub const fn new(cd: u16, bdiv: u8) -> Result<Self, DivisorZero> {
|
||||||
if cd == 0 {
|
if cd == 0 {
|
||||||
return Err(DivisorZero);
|
return Err(DivisorZero);
|
||||||
}
|
}
|
||||||
Ok(ClkConfigRaw { cd, bdiv })
|
Ok(ClockConfigRaw { cd, bdiv })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Auto-calculates the best clock configuration settings for the target baudrate.
|
/// Auto-calculates the best clock configuration settings for the target baudrate.
|
||||||
///
|
///
|
||||||
/// This function assumes [ClkSel::UartRefClk] as the clock source. It returns a tuple
|
/// This function assumes [ClockSelect::UartRefClk] as the clock source. It returns a tuple
|
||||||
/// where the first entry is the clock configuration while the second entry is the associated
|
/// where the first entry is the clock configuration while the second entry is the associated
|
||||||
/// baud error from 0.0 to 1.0. It is recommended to keep this error below 2-3 %.
|
/// baud error from 0.0 to 1.0. It is recommended to keep this error below 2-3 %.
|
||||||
pub fn new_autocalc_with_error(
|
pub fn new_autocalc_with_error(
|
||||||
io_clks: &IoClocks,
|
io_clks: &IoClocks,
|
||||||
target_baud: u32,
|
target_baud: u32,
|
||||||
) -> Result<(Self, f64), DivisorZero> {
|
) -> Result<(Self, f64), DivisorZero> {
|
||||||
Self::new_autocalc_generic(io_clks, ClkSel::UartRefClk, target_baud)
|
Self::new_autocalc_generic(io_clks, ClockSelect::UartRefClk, target_baud)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_autocalc_generic(
|
pub fn new_autocalc_generic(
|
||||||
io_clks: &IoClocks,
|
io_clks: &IoClocks,
|
||||||
clk_sel: ClkSel,
|
clk_sel: ClockSelect,
|
||||||
target_baud: u32,
|
target_baud: u32,
|
||||||
) -> Result<(Self, f64), DivisorZero> {
|
) -> Result<(Self, f64), DivisorZero> {
|
||||||
Self::new_autocalc_with_raw_clk(io_clks.uart_clk(), clk_sel, target_baud)
|
Self::new_autocalc_with_raw_clk(io_clks.uart_clk(), clk_sel, target_baud)
|
||||||
@@ -312,7 +289,7 @@ impl ClkConfigRaw {
|
|||||||
|
|
||||||
pub fn new_autocalc_with_raw_clk(
|
pub fn new_autocalc_with_raw_clk(
|
||||||
uart_clk: Hertz,
|
uart_clk: Hertz,
|
||||||
clk_sel: ClkSel,
|
clk_sel: ClockSelect,
|
||||||
target_baud: u32,
|
target_baud: u32,
|
||||||
) -> Result<(Self, f64), DivisorZero> {
|
) -> Result<(Self, f64), DivisorZero> {
|
||||||
calculate_raw_baud_cfg_smallest_error(uart_clk, clk_sel, target_baud)
|
calculate_raw_baud_cfg_smallest_error(uart_clk, clk_sel, target_baud)
|
||||||
@@ -339,43 +316,43 @@ impl ClkConfigRaw {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ClkConfigRaw {
|
impl Default for ClockConfigRaw {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
ClkConfigRaw::new(1, 0).unwrap()
|
ClockConfigRaw::new(1, 0).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UartConfig {
|
pub struct UartConfig {
|
||||||
clk_config: ClkConfigRaw,
|
clk_config: ClockConfigRaw,
|
||||||
chmode: ChMode,
|
chmode: ChMode,
|
||||||
parity: Parity,
|
parity: Parity,
|
||||||
stopbits: Stopbits,
|
stopbits: Stopbits,
|
||||||
chrl: CharLen,
|
chrl: CharLen,
|
||||||
clk_sel: ClkSel,
|
clk_sel: ClockSelect,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UartConfig {
|
impl UartConfig {
|
||||||
pub fn new_with_clk_config(clk_config: ClkConfigRaw) -> Self {
|
pub fn new_with_clk_config(clk_config: ClockConfigRaw) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
clk_config,
|
clk_config,
|
||||||
ChMode::default(),
|
ChMode::default(),
|
||||||
Parity::default(),
|
Parity::default(),
|
||||||
Stopbits::default(),
|
Stopbits::default(),
|
||||||
CharLen::default(),
|
CharLen::default(),
|
||||||
ClkSel::default(),
|
ClockSelect::default(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn new(
|
pub const fn new(
|
||||||
clk_config: ClkConfigRaw,
|
clk_config: ClockConfigRaw,
|
||||||
chmode: ChMode,
|
chmode: ChMode,
|
||||||
parity: Parity,
|
parity: Parity,
|
||||||
stopbits: Stopbits,
|
stopbits: Stopbits,
|
||||||
chrl: CharLen,
|
chrl: CharLen,
|
||||||
clk_sel: ClkSel,
|
clk_sel: ClockSelect,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
UartConfig {
|
UartConfig {
|
||||||
clk_config,
|
clk_config,
|
||||||
@@ -388,7 +365,7 @@ impl UartConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn raw_clk_config(&self) -> ClkConfigRaw {
|
pub const fn raw_clk_config(&self) -> ClockConfigRaw {
|
||||||
self.clk_config
|
self.clk_config
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,7 +390,7 @@ impl UartConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn clksel(&self) -> ClkSel {
|
pub const fn clksel(&self) -> ClockSelect {
|
||||||
self.clk_sel
|
self.clk_sel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -436,7 +413,7 @@ pub enum UartConstructionError {
|
|||||||
#[error("missmatch between pins index and passed index")]
|
#[error("missmatch between pins index and passed index")]
|
||||||
IdxMissmatch,
|
IdxMissmatch,
|
||||||
#[error("invalid pin mux conf for UART")]
|
#[error("invalid pin mux conf for UART")]
|
||||||
InvalidMuxConf(MuxCfg),
|
InvalidMuxConf(MuxConfig),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Uart {
|
impl Uart {
|
||||||
@@ -516,9 +493,9 @@ impl Uart {
|
|||||||
Parity::None => zynq7000::uart::Parity::NoParity,
|
Parity::None => zynq7000::uart::Parity::NoParity,
|
||||||
})
|
})
|
||||||
.with_chrl(match cfg.chrl {
|
.with_chrl(match cfg.chrl {
|
||||||
CharLen::SixBits => zynq7000::uart::Chrl::SixBits,
|
CharLen::SixBits => zynq7000::uart::CharLen::SixBits,
|
||||||
CharLen::SevenBits => zynq7000::uart::Chrl::SevenBits,
|
CharLen::SevenBits => zynq7000::uart::CharLen::SevenBits,
|
||||||
CharLen::EightBits => zynq7000::uart::Chrl::EightBits,
|
CharLen::EightBits => zynq7000::uart::CharLen::EightBits,
|
||||||
})
|
})
|
||||||
.with_clksel(cfg.clk_sel)
|
.with_clksel(cfg.clk_sel)
|
||||||
.build();
|
.build();
|
||||||
@@ -644,13 +621,13 @@ impl embedded_io::Read for Uart {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn reset(id: UartId) {
|
pub fn reset(id: UartId) {
|
||||||
let assert_reset = match id {
|
let assert_reset = match id {
|
||||||
UartId::Uart0 => DualRefAndClkRst::builder()
|
UartId::Uart0 => DualRefAndClockReset::builder()
|
||||||
.with_periph1_ref_rst(false)
|
.with_periph1_ref_rst(false)
|
||||||
.with_periph0_ref_rst(true)
|
.with_periph0_ref_rst(true)
|
||||||
.with_periph1_cpu1x_rst(false)
|
.with_periph1_cpu1x_rst(false)
|
||||||
.with_periph0_cpu1x_rst(true)
|
.with_periph0_cpu1x_rst(true)
|
||||||
.build(),
|
.build(),
|
||||||
UartId::Uart1 => DualRefAndClkRst::builder()
|
UartId::Uart1 => DualRefAndClockReset::builder()
|
||||||
.with_periph1_ref_rst(true)
|
.with_periph1_ref_rst(true)
|
||||||
.with_periph0_ref_rst(false)
|
.with_periph0_ref_rst(false)
|
||||||
.with_periph1_cpu1x_rst(true)
|
.with_periph1_cpu1x_rst(true)
|
||||||
@@ -662,7 +639,7 @@ pub fn reset(id: UartId) {
|
|||||||
regs.reset_ctrl().write_uart(assert_reset);
|
regs.reset_ctrl().write_uart(assert_reset);
|
||||||
// Keep it in reset for one cycle.. not sure if this is necessary.
|
// Keep it in reset for one cycle.. not sure if this is necessary.
|
||||||
cortex_ar::asm::nop();
|
cortex_ar::asm::nop();
|
||||||
regs.reset_ctrl().write_uart(DualRefAndClkRst::DEFAULT);
|
regs.reset_ctrl().write_uart(DualRefAndClockReset::DEFAULT);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -672,7 +649,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use approx::abs_diff_eq;
|
use approx::abs_diff_eq;
|
||||||
use fugit::HertzU32;
|
use fugit::HertzU32;
|
||||||
use zynq7000::uart::ClkSel;
|
use zynq7000::uart::ClockSelect;
|
||||||
|
|
||||||
const REF_UART_CLK: HertzU32 = HertzU32::from_raw(50_000_000);
|
const REF_UART_CLK: HertzU32 = HertzU32::from_raw(50_000_000);
|
||||||
const REF_UART_CLK_DIV_8: HertzU32 = HertzU32::from_raw(6_250_000);
|
const REF_UART_CLK_DIV_8: HertzU32 = HertzU32::from_raw(6_250_000);
|
||||||
@@ -680,7 +657,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_error_calc_0() {
|
fn test_error_calc_0() {
|
||||||
// Baud 600
|
// Baud 600
|
||||||
let cfg_0 = ClkConfigRaw::new(10417, 7).unwrap();
|
let cfg_0 = ClockConfigRaw::new(10417, 7).unwrap();
|
||||||
let actual_baud_0 = cfg_0.actual_baud(REF_UART_CLK);
|
let actual_baud_0 = cfg_0.actual_baud(REF_UART_CLK);
|
||||||
assert!(abs_diff_eq!(actual_baud_0, 599.980, epsilon = 0.01));
|
assert!(abs_diff_eq!(actual_baud_0, 599.980, epsilon = 0.01));
|
||||||
}
|
}
|
||||||
@@ -688,7 +665,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_error_calc_1() {
|
fn test_error_calc_1() {
|
||||||
// Baud 9600
|
// Baud 9600
|
||||||
let cfg = ClkConfigRaw::new(81, 7).unwrap();
|
let cfg = ClockConfigRaw::new(81, 7).unwrap();
|
||||||
let actual_baud = cfg.actual_baud(REF_UART_CLK_DIV_8);
|
let actual_baud = cfg.actual_baud(REF_UART_CLK_DIV_8);
|
||||||
assert!(abs_diff_eq!(actual_baud, 9645.061, epsilon = 0.01));
|
assert!(abs_diff_eq!(actual_baud, 9645.061, epsilon = 0.01));
|
||||||
}
|
}
|
||||||
@@ -696,7 +673,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_error_calc_2() {
|
fn test_error_calc_2() {
|
||||||
// Baud 9600
|
// Baud 9600
|
||||||
let cfg = ClkConfigRaw::new(651, 7).unwrap();
|
let cfg = ClockConfigRaw::new(651, 7).unwrap();
|
||||||
let actual_baud = cfg.actual_baud(REF_UART_CLK);
|
let actual_baud = cfg.actual_baud(REF_UART_CLK);
|
||||||
assert!(abs_diff_eq!(actual_baud, 9600.614, epsilon = 0.01));
|
assert!(abs_diff_eq!(actual_baud, 9600.614, epsilon = 0.01));
|
||||||
}
|
}
|
||||||
@@ -704,7 +681,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_error_calc_3() {
|
fn test_error_calc_3() {
|
||||||
// Baud 28800
|
// Baud 28800
|
||||||
let cfg = ClkConfigRaw::new(347, 4).unwrap();
|
let cfg = ClockConfigRaw::new(347, 4).unwrap();
|
||||||
let actual_baud = cfg.actual_baud(REF_UART_CLK);
|
let actual_baud = cfg.actual_baud(REF_UART_CLK);
|
||||||
assert!(abs_diff_eq!(actual_baud, 28818.44, epsilon = 0.01));
|
assert!(abs_diff_eq!(actual_baud, 28818.44, epsilon = 0.01));
|
||||||
}
|
}
|
||||||
@@ -712,14 +689,15 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_error_calc_4() {
|
fn test_error_calc_4() {
|
||||||
// Baud 921600
|
// Baud 921600
|
||||||
let cfg = ClkConfigRaw::new(9, 5).unwrap();
|
let cfg = ClockConfigRaw::new(9, 5).unwrap();
|
||||||
let actual_baud = cfg.actual_baud(REF_UART_CLK);
|
let actual_baud = cfg.actual_baud(REF_UART_CLK);
|
||||||
assert!(abs_diff_eq!(actual_baud, 925925.92, epsilon = 0.01));
|
assert!(abs_diff_eq!(actual_baud, 925925.92, epsilon = 0.01));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_best_calc_0() {
|
fn test_best_calc_0() {
|
||||||
let result = ClkConfigRaw::new_autocalc_with_raw_clk(REF_UART_CLK, ClkSel::UartRefClk, 600);
|
let result =
|
||||||
|
ClockConfigRaw::new_autocalc_with_raw_clk(REF_UART_CLK, ClockSelect::UartRefClk, 600);
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
let (cfg, _error) = result.unwrap();
|
let (cfg, _error) = result.unwrap();
|
||||||
assert_eq!(cfg.cd(), 499);
|
assert_eq!(cfg.cd(), 499);
|
||||||
@@ -729,7 +707,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
fn test_viable_config_calculation() {
|
fn test_viable_config_calculation() {
|
||||||
let cfgs = calculate_viable_configs(REF_UART_CLK, ClkSel::UartRefClk, 115200);
|
let cfgs = calculate_viable_configs(REF_UART_CLK, ClockSelect::UartRefClk, 115200);
|
||||||
assert!(
|
assert!(
|
||||||
cfgs.iter()
|
cfgs.iter()
|
||||||
.find(|(cfg, _error)| { cfg.cd() == 62 && cfg.bdiv() == 6 })
|
.find(|(cfg, _error)| { cfg.cd() == 62 && cfg.bdiv() == 6 })
|
||||||
|
@@ -6,7 +6,7 @@ pub const GEM_1_BASE_ADDR: usize = 0xE000_C000;
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct NetworkCtrl {
|
pub struct NetworkControl {
|
||||||
#[bit(18, w)]
|
#[bit(18, w)]
|
||||||
flush_next_rx_dpram_pkt: bool,
|
flush_next_rx_dpram_pkt: bool,
|
||||||
#[bit(17, w)]
|
#[bit(17, w)]
|
||||||
@@ -56,7 +56,7 @@ pub enum PcsSelect {
|
|||||||
|
|
||||||
#[bitbybit::bitenum(u3, exhaustive = true)]
|
#[bitbybit::bitenum(u3, exhaustive = true)]
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum MdcClkDiv {
|
pub enum MdcClockDivisor {
|
||||||
Div8 = 0,
|
Div8 = 0,
|
||||||
Div16 = 1,
|
Div16 = 1,
|
||||||
Div32 = 2,
|
Div32 = 2,
|
||||||
@@ -67,24 +67,24 @@ pub enum MdcClkDiv {
|
|||||||
Div224 = 7,
|
Div224 = 7,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MdcClkDiv {
|
impl MdcClockDivisor {
|
||||||
pub fn divisor(&self) -> usize {
|
pub fn divisor(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
MdcClkDiv::Div8 => 8,
|
MdcClockDivisor::Div8 => 8,
|
||||||
MdcClkDiv::Div16 => 16,
|
MdcClockDivisor::Div16 => 16,
|
||||||
MdcClkDiv::Div32 => 32,
|
MdcClockDivisor::Div32 => 32,
|
||||||
MdcClkDiv::Div48 => 48,
|
MdcClockDivisor::Div48 => 48,
|
||||||
MdcClkDiv::Div64 => 64,
|
MdcClockDivisor::Div64 => 64,
|
||||||
MdcClkDiv::Div96 => 96,
|
MdcClockDivisor::Div96 => 96,
|
||||||
MdcClkDiv::Div128 => 128,
|
MdcClockDivisor::Div128 => 128,
|
||||||
MdcClkDiv::Div224 => 224,
|
MdcClockDivisor::Div224 => 224,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct NetworkCfg {
|
pub struct NetworkConfig {
|
||||||
#[bit(30, rw)]
|
#[bit(30, rw)]
|
||||||
ignore_ipg_rx_error: bool,
|
ignore_ipg_rx_error: bool,
|
||||||
#[bit(29, rw)]
|
#[bit(29, rw)]
|
||||||
@@ -105,7 +105,7 @@ pub struct NetworkCfg {
|
|||||||
#[bits(21..=22, r)]
|
#[bits(21..=22, r)]
|
||||||
dbus_width: u2,
|
dbus_width: u2,
|
||||||
#[bits(18..=20, rw)]
|
#[bits(18..=20, rw)]
|
||||||
mdc_clk_div: MdcClkDiv,
|
mdc_clk_div: MdcClockDivisor,
|
||||||
#[bit(17, rw)]
|
#[bit(17, rw)]
|
||||||
fcs_removal: bool,
|
fcs_removal: bool,
|
||||||
#[bit(16, rw)]
|
#[bit(16, rw)]
|
||||||
@@ -217,7 +217,7 @@ impl DmaRxBufSize {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DmaCfg {
|
pub struct DmaConfig {
|
||||||
#[bit(24, rw)]
|
#[bit(24, rw)]
|
||||||
discard_when_ahb_full: bool,
|
discard_when_ahb_full: bool,
|
||||||
/// DMA receive buffer size in AHB system memory.
|
/// DMA receive buffer size in AHB system memory.
|
||||||
@@ -340,7 +340,7 @@ pub struct InterruptStatus {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32, default = 0x00)]
|
#[bitbybit::bitfield(u32, default = 0x00)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InterruptCtrl {
|
pub struct InterruptControl {
|
||||||
#[bit(26, w)]
|
#[bit(26, w)]
|
||||||
tsu_sec_incr: bool,
|
tsu_sec_incr: bool,
|
||||||
/// Marked N/A in datasheet. Probably because external PHYs are used.
|
/// Marked N/A in datasheet. Probably because external PHYs are used.
|
||||||
@@ -380,7 +380,7 @@ pub struct InterruptCtrl {
|
|||||||
mgmt_frame_sent: bool,
|
mgmt_frame_sent: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InterruptCtrl {
|
impl InterruptControl {
|
||||||
pub fn new_clear_all() -> Self {
|
pub fn new_clear_all() -> Self {
|
||||||
Self::new_with_raw_value(0xFFFF_FFFF)
|
Self::new_with_raw_value(0xFFFF_FFFF)
|
||||||
}
|
}
|
||||||
@@ -430,19 +430,19 @@ pub struct MatchRegister {
|
|||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Ethernet {
|
pub struct Ethernet {
|
||||||
net_ctrl: NetworkCtrl,
|
net_ctrl: NetworkControl,
|
||||||
net_cfg: NetworkCfg,
|
net_cfg: NetworkConfig,
|
||||||
#[mmio(PureRead)]
|
#[mmio(PureRead)]
|
||||||
net_status: NetworkStatus,
|
net_status: NetworkStatus,
|
||||||
_reserved0: u32,
|
_reserved0: u32,
|
||||||
dma_cfg: DmaCfg,
|
dma_cfg: DmaConfig,
|
||||||
tx_status: TxStatus,
|
tx_status: TxStatus,
|
||||||
rx_buf_queue_base_addr: u32,
|
rx_buf_queue_base_addr: u32,
|
||||||
tx_buf_queue_base_addr: u32,
|
tx_buf_queue_base_addr: u32,
|
||||||
rx_status: RxStatus,
|
rx_status: RxStatus,
|
||||||
interrupt_status: InterruptStatus,
|
interrupt_status: InterruptStatus,
|
||||||
interrupt_enable: InterruptCtrl,
|
interrupt_enable: InterruptControl,
|
||||||
interrupt_disable: InterruptCtrl,
|
interrupt_disable: InterruptControl,
|
||||||
interrupt_mask: InterruptStatus,
|
interrupt_mask: InterruptStatus,
|
||||||
phy_maintenance: PhyMaintenance,
|
phy_maintenance: PhyMaintenance,
|
||||||
#[mmio(PureRead)]
|
#[mmio(PureRead)]
|
||||||
|
@@ -5,7 +5,7 @@ use static_assertions::const_assert_eq;
|
|||||||
|
|
||||||
/// Distributor Control Register
|
/// Distributor Control Register
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
pub struct Dcr {
|
pub struct DistributorControlRegister {
|
||||||
#[bit(1, rw)]
|
#[bit(1, rw)]
|
||||||
enable_non_secure: bool,
|
enable_non_secure: bool,
|
||||||
#[bit(0, rw)]
|
#[bit(0, rw)]
|
||||||
@@ -14,7 +14,7 @@ pub struct Dcr {
|
|||||||
|
|
||||||
/// Read only bit. This register only returns fixed constants.
|
/// Read only bit. This register only returns fixed constants.
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
pub struct TypeReg {
|
pub struct TypeRegister {
|
||||||
#[bits(11..=15, r)]
|
#[bits(11..=15, r)]
|
||||||
lspi: u5,
|
lspi: u5,
|
||||||
#[bit(10, r)]
|
#[bit(10, r)]
|
||||||
@@ -25,7 +25,7 @@ pub struct TypeReg {
|
|||||||
it_lines_number: u5,
|
it_lines_number: u5,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeReg {
|
impl TypeRegister {
|
||||||
pub const SECURITY_EXTNS_BIT: bool = true;
|
pub const SECURITY_EXTNS_BIT: bool = true;
|
||||||
/// 31 LSPIs.
|
/// 31 LSPIs.
|
||||||
pub const NUM_LSPI: usize = 0x1f;
|
pub const NUM_LSPI: usize = 0x1f;
|
||||||
@@ -38,14 +38,14 @@ impl TypeReg {
|
|||||||
pub const NUM_OF_INTERRUPTS: usize = 96;
|
pub const NUM_OF_INTERRUPTS: usize = 96;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Typer = TypeReg;
|
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 GicDistributor {
|
||||||
/// Distributor Control Register
|
/// Distributor Control Register
|
||||||
pub dcr: Dcr,
|
pub dcr: DistributorControlRegister,
|
||||||
/// Interrupt Controller Type Register
|
/// Interrupt Controller Type Register
|
||||||
#[mmio(PureRead)]
|
#[mmio(PureRead)]
|
||||||
pub ictr: Typer,
|
pub ictr: Typer,
|
||||||
@@ -128,7 +128,7 @@ impl GicDistributor {
|
|||||||
|
|
||||||
/// CPU interface control register.
|
/// CPU interface control register.
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
pub struct InterfaceCtrl {
|
pub struct InterfaceControl {
|
||||||
#[bit(4, rw)]
|
#[bit(4, rw)]
|
||||||
sbpr: bool,
|
sbpr: bool,
|
||||||
#[bit(3, rw)]
|
#[bit(3, rw)]
|
||||||
@@ -143,7 +143,7 @@ pub struct InterfaceCtrl {
|
|||||||
|
|
||||||
/// Priority Mask Register
|
/// Priority Mask Register
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
pub struct PriorityReg {
|
pub struct PriorityRegister {
|
||||||
#[bits(0..=7, rw)]
|
#[bits(0..=7, rw)]
|
||||||
priority: u8,
|
priority: u8,
|
||||||
}
|
}
|
||||||
@@ -163,9 +163,9 @@ pub struct InterruptSignalRegister {
|
|||||||
#[repr(C, align(8))]
|
#[repr(C, align(8))]
|
||||||
pub struct GicCpuInterface {
|
pub struct GicCpuInterface {
|
||||||
/// CPU Interface Control Register (ICR).
|
/// CPU Interface Control Register (ICR).
|
||||||
pub icr: InterfaceCtrl,
|
pub icr: InterfaceControl,
|
||||||
/// Interrupt Priority Mask Register.
|
/// Interrupt Priority Mask Register.
|
||||||
pub pmr: PriorityReg,
|
pub pmr: PriorityRegister,
|
||||||
/// Binary Point Register.
|
/// Binary Point Register.
|
||||||
pub bpr: u32,
|
pub bpr: u32,
|
||||||
/// Interrupt Acknowledge Register.
|
/// Interrupt Acknowledge Register.
|
||||||
@@ -173,7 +173,7 @@ pub struct GicCpuInterface {
|
|||||||
/// End of Interrupt Register.
|
/// End of Interrupt Register.
|
||||||
pub eoir: InterruptSignalRegister,
|
pub eoir: InterruptSignalRegister,
|
||||||
/// Running Priority Register.
|
/// Running Priority Register.
|
||||||
pub rpr: PriorityReg,
|
pub rpr: PriorityRegister,
|
||||||
/// Highest Pending Interrupt Register.
|
/// Highest Pending Interrupt Register.
|
||||||
pub hpir: InterruptSignalRegister,
|
pub hpir: InterruptSignalRegister,
|
||||||
/// Aliased Binary Point Register
|
/// Aliased Binary Point Register
|
||||||
|
@@ -10,7 +10,7 @@ pub struct MaskedOutput {
|
|||||||
|
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct BankCtrl {
|
pub struct BankControl {
|
||||||
/// Direction mode
|
/// Direction mode
|
||||||
dirm: u32,
|
dirm: u32,
|
||||||
/// Output enable
|
/// Output enable
|
||||||
@@ -84,22 +84,22 @@ pub struct Gpio {
|
|||||||
_reserved_2: [u32; 101],
|
_reserved_2: [u32; 101],
|
||||||
|
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
bank_0: BankCtrl,
|
bank_0: BankControl,
|
||||||
|
|
||||||
_reserved_3: [u32; 7],
|
_reserved_3: [u32; 7],
|
||||||
|
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
bank_1: BankCtrl,
|
bank_1: BankControl,
|
||||||
|
|
||||||
_reserved_4: [u32; 7],
|
_reserved_4: [u32; 7],
|
||||||
|
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
bank_2: BankCtrl,
|
bank_2: BankControl,
|
||||||
|
|
||||||
_reserved_5: [u32; 7],
|
_reserved_5: [u32; 7],
|
||||||
|
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
bank_3: BankCtrl,
|
bank_3: BankControl,
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assertions::const_assert_eq!(core::mem::size_of::<Gpio>(), 0x2E8);
|
static_assertions::const_assert_eq!(core::mem::size_of::<Gpio>(), 0x2E8);
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
pub const GTC_BASE_ADDR: usize = super::mpcore::MPCORE_BASE_ADDR + 0x0000_0200;
|
pub const GTC_BASE_ADDR: usize = super::mpcore::MPCORE_BASE_ADDR + 0x0000_0200;
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
pub struct GtcCtrl {
|
pub struct GtcControl {
|
||||||
#[bits(8..=15, rw)]
|
#[bits(8..=15, rw)]
|
||||||
prescaler: u8,
|
prescaler: u8,
|
||||||
#[bit(3, rw)]
|
#[bit(3, rw)]
|
||||||
@@ -31,7 +31,7 @@ pub struct GlobalTimerCounter {
|
|||||||
/// Count register 1, upper 32 bits
|
/// Count register 1, upper 32 bits
|
||||||
count_upper: u32,
|
count_upper: u32,
|
||||||
/// Control register
|
/// Control register
|
||||||
ctrl: GtcCtrl,
|
ctrl: GtcControl,
|
||||||
/// Interrupt status register
|
/// Interrupt status register
|
||||||
#[mmio(PureRead, Write)]
|
#[mmio(PureRead, Write)]
|
||||||
isr: InterruptStatus,
|
isr: InterruptStatus,
|
||||||
|
@@ -6,7 +6,7 @@ pub const I2C_1_BASE_ADDR: usize = 0xE000_5000;
|
|||||||
|
|
||||||
#[bitbybit::bitenum(u1, exhaustive = true)]
|
#[bitbybit::bitenum(u1, exhaustive = true)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Dir {
|
pub enum Direction {
|
||||||
Receiver = 0b1,
|
Receiver = 0b1,
|
||||||
Transmitter = 0b0,
|
Transmitter = 0b0,
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ pub enum Mode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
pub struct Ctrl {
|
pub struct Control {
|
||||||
/// Divides the input PCLK frequency by this value + 1
|
/// Divides the input PCLK frequency by this value + 1
|
||||||
#[bits(14..=15, rw)]
|
#[bits(14..=15, rw)]
|
||||||
div_a: u2,
|
div_a: u2,
|
||||||
@@ -44,7 +44,7 @@ pub struct Ctrl {
|
|||||||
#[bit(1, rw)]
|
#[bit(1, rw)]
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
#[bit(0, rw)]
|
#[bit(0, rw)]
|
||||||
dir: Dir,
|
dir: Direction,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
@@ -66,7 +66,7 @@ pub struct Status {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
pub struct Addr {
|
pub struct Address {
|
||||||
#[bits(0..=9, rw)]
|
#[bits(0..=9, rw)]
|
||||||
addr: u10,
|
addr: u10,
|
||||||
}
|
}
|
||||||
@@ -159,10 +159,10 @@ pub struct TransferSize {
|
|||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct I2c {
|
pub struct I2c {
|
||||||
cr: Ctrl,
|
cr: Control,
|
||||||
#[mmio(PureRead)]
|
#[mmio(PureRead)]
|
||||||
sr: Status,
|
sr: Status,
|
||||||
addr: Addr,
|
addr: Address,
|
||||||
#[mmio(Read, Write)]
|
#[mmio(Read, Write)]
|
||||||
data: Fifo,
|
data: Fifo,
|
||||||
#[mmio(PureRead, Write, Modify)]
|
#[mmio(PureRead, Write, Modify)]
|
||||||
|
@@ -18,7 +18,7 @@ pub struct CacheSync {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DebugCtrl {
|
pub struct DebugControl {
|
||||||
#[bit(2, rw)]
|
#[bit(2, rw)]
|
||||||
spniden: bool,
|
spniden: bool,
|
||||||
#[bit(1, rw)]
|
#[bit(1, rw)]
|
||||||
@@ -41,9 +41,9 @@ pub struct CacheId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Ctrl(u32);
|
pub struct Control(u32);
|
||||||
|
|
||||||
impl Ctrl {
|
impl Control {
|
||||||
pub fn new_enabled() -> Self {
|
pub fn new_enabled() -> Self {
|
||||||
Self(0x1)
|
Self(0x1)
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ pub enum Associativity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
pub struct AuxCtrl {
|
pub struct AuxControl {
|
||||||
#[bit(30, rw)]
|
#[bit(30, rw)]
|
||||||
early_bresp_enable: bool,
|
early_bresp_enable: bool,
|
||||||
#[bit(29, rw)]
|
#[bit(29, rw)]
|
||||||
@@ -127,7 +127,7 @@ pub struct AuxCtrl {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct LatencyCfg {
|
pub struct LatencyConfig {
|
||||||
/// Latency is the numerical value + 1 cycles.
|
/// Latency is the numerical value + 1 cycles.
|
||||||
#[bits(8..=10, rw)]
|
#[bits(8..=10, rw)]
|
||||||
write_access_latency: u3,
|
write_access_latency: u3,
|
||||||
@@ -165,7 +165,7 @@ pub struct InterruptStatus {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InterruptCtrl {
|
pub struct InterruptControl {
|
||||||
#[bit(8, w)]
|
#[bit(8, w)]
|
||||||
dec_error_l3: bool,
|
dec_error_l3: bool,
|
||||||
#[bit(7, w)]
|
#[bit(7, w)]
|
||||||
@@ -197,10 +197,10 @@ pub struct L2Cache {
|
|||||||
|
|
||||||
_reserved: [u32; 0x3E],
|
_reserved: [u32; 0x3E],
|
||||||
|
|
||||||
control: Ctrl,
|
control: Control,
|
||||||
aux_control: AuxCtrl,
|
aux_control: AuxControl,
|
||||||
tag_ram_latency: LatencyCfg,
|
tag_ram_latency: LatencyConfig,
|
||||||
data_ram_latency: LatencyCfg,
|
data_ram_latency: LatencyConfig,
|
||||||
|
|
||||||
_reserved2: [u32; 0x3C],
|
_reserved2: [u32; 0x3C],
|
||||||
|
|
||||||
@@ -215,7 +215,7 @@ pub struct L2Cache {
|
|||||||
#[mmio(PureRead)]
|
#[mmio(PureRead)]
|
||||||
interrupt_raw_status: InterruptStatus,
|
interrupt_raw_status: InterruptStatus,
|
||||||
#[mmio(Write)]
|
#[mmio(Write)]
|
||||||
interrupt_clear: InterruptCtrl,
|
interrupt_clear: InterruptControl,
|
||||||
|
|
||||||
_reserved3: [u32; 0x143],
|
_reserved3: [u32; 0x143],
|
||||||
|
|
||||||
@@ -264,7 +264,7 @@ pub struct L2Cache {
|
|||||||
|
|
||||||
_reserved13: [u32; 0xCE],
|
_reserved13: [u32; 0xCE],
|
||||||
|
|
||||||
debug_control: DebugCtrl,
|
debug_control: DebugControl,
|
||||||
|
|
||||||
_reserved14: [u32; 0x7],
|
_reserved14: [u32; 0x7],
|
||||||
|
|
||||||
@@ -278,7 +278,7 @@ pub struct L2Cache {
|
|||||||
static_assertions::const_assert_eq!(core::mem::size_of::<L2Cache>(), 0xF84);
|
static_assertions::const_assert_eq!(core::mem::size_of::<L2Cache>(), 0xF84);
|
||||||
|
|
||||||
impl L2Cache {
|
impl L2Cache {
|
||||||
/// Create a new L2C MMIO instance for for L2 Cache at address [I2C_0_BASE_ADDR].
|
/// Create a new L2C MMIO instance for for L2 Cache at address [L2C_BASE_ADDR].
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
|
@@ -15,7 +15,7 @@ pub const GICD_BASE_ADDR: usize = MPCORE_BASE_ADDR + 0x1000;
|
|||||||
|
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Scu {
|
pub struct SnoopControlUnit {
|
||||||
ctrl: u32,
|
ctrl: u32,
|
||||||
config: u32,
|
config: u32,
|
||||||
cpu_power_status: u32,
|
cpu_power_status: u32,
|
||||||
@@ -28,7 +28,7 @@ pub struct Scu {
|
|||||||
non_secure_access_ctrl: u32,
|
non_secure_access_ctrl: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scu {
|
impl SnoopControlUnit {
|
||||||
/// Create a new Snoop Control Unit interface at the fixed base address.
|
/// Create a new Snoop Control Unit interface at the fixed base address.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -37,18 +37,18 @@ impl Scu {
|
|||||||
/// 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() -> MmioScu<'static> {
|
pub const unsafe fn new_mmio_fixed() -> MmioSnoopControlUnit<'static> {
|
||||||
unsafe { Self::new_mmio_at(SCU_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(SCU_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const_assert_eq!(core::mem::size_of::<Scu>(), 0x58);
|
const_assert_eq!(core::mem::size_of::<SnoopControlUnit>(), 0x58);
|
||||||
|
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Mpcore {
|
pub struct MpCore {
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
scu: Scu,
|
scu: SnoopControlUnit,
|
||||||
|
|
||||||
_reserved_0: [u32; 0x2A],
|
_reserved_0: [u32; 0x2A],
|
||||||
|
|
||||||
@@ -80,9 +80,9 @@ pub struct Mpcore {
|
|||||||
gicd: GicDistributor,
|
gicd: GicDistributor,
|
||||||
}
|
}
|
||||||
|
|
||||||
const_assert_eq!(core::mem::size_of::<Mpcore>(), 0x2000);
|
const_assert_eq!(core::mem::size_of::<MpCore>(), 0x2000);
|
||||||
|
|
||||||
impl Mpcore {
|
impl MpCore {
|
||||||
/// Create a MP core peripheral interface at the fixed base address.
|
/// Create a MP core peripheral interface at the fixed base address.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -91,7 +91,7 @@ impl Mpcore {
|
|||||||
/// 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() -> MmioMpcore<'static> {
|
pub const unsafe fn new_mmio_fixed() -> MmioMpCore<'static> {
|
||||||
unsafe { Self::new_mmio_at(MPCORE_BASE_ADDR) }
|
unsafe { Self::new_mmio_at(MPCORE_BASE_ADDR) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -20,7 +20,7 @@ pub enum BypassQual {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PllCtrl {
|
pub struct PllControl {
|
||||||
/// Feedback divisor for the PLL.
|
/// Feedback divisor for the PLL.
|
||||||
///
|
///
|
||||||
/// NOTE: Before changing this value, the PLL must first be bypassed and then put into
|
/// NOTE: Before changing this value, the PLL must first be bypassed and then put into
|
||||||
@@ -43,7 +43,7 @@ pub struct PllCtrl {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PllCfg {
|
pub struct PllConfig {
|
||||||
#[bits(12..=21, rw)]
|
#[bits(12..=21, rw)]
|
||||||
lock_count: u10,
|
lock_count: u10,
|
||||||
/// Charge Pump control
|
/// Charge Pump control
|
||||||
@@ -73,7 +73,7 @@ pub struct PllStatus {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FpgaClkCtrl {
|
pub struct FpgaClockControl {
|
||||||
// Reset value 0x1
|
// Reset value 0x1
|
||||||
#[bits(20..=25, rw)]
|
#[bits(20..=25, rw)]
|
||||||
divisor_1: u6,
|
divisor_1: u6,
|
||||||
@@ -86,14 +86,14 @@ pub struct FpgaClkCtrl {
|
|||||||
|
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct FpgaClkCtrlBlock {
|
pub struct FpgaClockControlBlock {
|
||||||
ctrl: FpgaClkCtrl,
|
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::<FpgaClkCtrlBlock>(), 0x10);
|
static_assertions::const_assert_eq!(core::mem::size_of::<FpgaClockControlBlock>(), 0x10);
|
||||||
|
|
||||||
#[bitbybit::bitenum(u2, exhaustive = true)]
|
#[bitbybit::bitenum(u2, exhaustive = true)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -105,7 +105,7 @@ pub enum SrcSelArm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
pub struct ArmClkCtrl {
|
pub struct ArmClockControl {
|
||||||
#[bit(28, rw)]
|
#[bit(28, rw)]
|
||||||
cpu_peri_clk_act: bool,
|
cpu_peri_clk_act: bool,
|
||||||
#[bit(27, rw)]
|
#[bit(27, rw)]
|
||||||
@@ -126,7 +126,7 @@ pub struct ArmClkCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
pub struct DdrClkCtrl {
|
pub struct DdrClockControl {
|
||||||
/// Divisor for DDR 2x clock. Reset value: 0x6
|
/// Divisor for DDR 2x clock. Reset value: 0x6
|
||||||
#[bits(26..=31, rw)]
|
#[bits(26..=31, rw)]
|
||||||
div_2x_clk: u6,
|
div_2x_clk: u6,
|
||||||
@@ -142,7 +142,7 @@ pub struct DdrClkCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
pub struct DciClkCtrl {
|
pub struct DciClockControl {
|
||||||
/// Second cascade divider. Reset value: 0x1E
|
/// Second cascade divider. Reset value: 0x1E
|
||||||
#[bits(20..=25, rw)]
|
#[bits(20..=25, rw)]
|
||||||
divisor_1: u6,
|
divisor_1: u6,
|
||||||
@@ -156,15 +156,15 @@ pub struct DciClkCtrl {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ClkRatioSelectReg {
|
pub struct ClockRatioSelectReg {
|
||||||
/// Reset value: 0x1 (6:2:1 clock)
|
/// Reset value: 0x1 (6:2:1 clock)
|
||||||
#[bit(0, rw)]
|
#[bit(0, rw)]
|
||||||
sel: ClkRatioSelect,
|
sel: ClockkRatioSelect,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitenum(u1, exhaustive = true)]
|
#[bitbybit::bitenum(u1, exhaustive = true)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ClkRatioSelect {
|
pub enum ClockkRatioSelect {
|
||||||
/// 4:2:1 clock ratio, which is an abbreviation for 4:2:2:1.
|
/// 4:2:1 clock ratio, which is an abbreviation for 4:2:2:1.
|
||||||
FourToTwoToOne = 0b0,
|
FourToTwoToOne = 0b0,
|
||||||
/// 6:2:1 clock ratio, which is an abbreviation for 6:3:2:1.
|
/// 6:2:1 clock ratio, which is an abbreviation for 6:3:2:1.
|
||||||
@@ -201,7 +201,7 @@ impl PartialEq for SrcSelIo {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GigEthClkCtrl {
|
pub struct GigEthClockControl {
|
||||||
#[bits(20..=25, rw)]
|
#[bits(20..=25, rw)]
|
||||||
divisor_1: u6,
|
divisor_1: u6,
|
||||||
#[bits(8..=13, rw)]
|
#[bits(8..=13, rw)]
|
||||||
@@ -223,7 +223,7 @@ pub enum SrcSelGigEthRclk {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GigEthRclkCtrl {
|
pub struct GigEthRclkControl {
|
||||||
#[bit(4, rw)]
|
#[bit(4, rw)]
|
||||||
srcsel: SrcSelGigEthRclk,
|
srcsel: SrcSelGigEthRclk,
|
||||||
// Enable the ethernet controller RX clock.
|
// Enable the ethernet controller RX clock.
|
||||||
@@ -233,7 +233,7 @@ pub struct GigEthRclkCtrl {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CanClkCtrl {
|
pub struct CanClockControl {
|
||||||
#[bits(20..=25, rw)]
|
#[bits(20..=25, rw)]
|
||||||
divisor_1: u6,
|
divisor_1: u6,
|
||||||
#[bits(8..=13, rw)]
|
#[bits(8..=13, rw)]
|
||||||
@@ -247,7 +247,7 @@ pub struct CanClkCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
pub struct SingleCommonPeriphIoClkCtrl {
|
pub struct SingleCommonPeriphIoClockControl {
|
||||||
#[bits(8..=13, rw)]
|
#[bits(8..=13, rw)]
|
||||||
divisor: u6,
|
divisor: u6,
|
||||||
#[bits(4..=5, rw)]
|
#[bits(4..=5, rw)]
|
||||||
@@ -258,7 +258,7 @@ pub struct SingleCommonPeriphIoClkCtrl {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DualCommonPeriphIoClkCtrl {
|
pub struct DualCommonPeriphIoClockControl {
|
||||||
#[bits(8..=13, rw)]
|
#[bits(8..=13, rw)]
|
||||||
divisor: u6,
|
divisor: u6,
|
||||||
#[bits(4..=5, rw)]
|
#[bits(4..=5, rw)]
|
||||||
@@ -283,7 +283,7 @@ pub enum SrcSelTpiu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
pub struct TracePortClkCtrl {
|
pub struct TracePortClockControl {
|
||||||
#[bits(8..=13, rw)]
|
#[bits(8..=13, rw)]
|
||||||
divisor: u6,
|
divisor: u6,
|
||||||
#[bits(4..=6, rw)]
|
#[bits(4..=6, rw)]
|
||||||
@@ -299,7 +299,7 @@ pub struct TracePortClkCtrl {
|
|||||||
/// These clocks must be enabled if you want to read from the peripheral register space.
|
/// These clocks must be enabled if you want to read from the peripheral register space.
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AperClkCtrl {
|
pub struct AperClockControl {
|
||||||
#[bit(24, rw)]
|
#[bit(24, rw)]
|
||||||
smc_1x_clk_act: bool,
|
smc_1x_clk_act: bool,
|
||||||
#[bit(23, rw)]
|
#[bit(23, rw)]
|
||||||
@@ -341,46 +341,46 @@ pub struct AperClkCtrl {
|
|||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ClockControl {
|
pub struct ClockControl {
|
||||||
arm_pll: PllCtrl,
|
arm_pll: PllControl,
|
||||||
ddr_pll: PllCtrl,
|
ddr_pll: PllControl,
|
||||||
io_pll: PllCtrl,
|
io_pll: PllControl,
|
||||||
pll_status: PllStatus,
|
pll_status: PllStatus,
|
||||||
arm_pll_cfg: PllCfg,
|
arm_pll_cfg: PllConfig,
|
||||||
ddr_pll_cfg: PllCfg,
|
ddr_pll_cfg: PllConfig,
|
||||||
io_pll_cfg: PllCfg,
|
io_pll_cfg: PllConfig,
|
||||||
_gap0: u32,
|
_gap0: u32,
|
||||||
arm_clk_ctrl: ArmClkCtrl,
|
arm_clk_ctrl: ArmClockControl,
|
||||||
ddr_clk_ctrl: DdrClkCtrl,
|
ddr_clk_ctrl: DdrClockControl,
|
||||||
dci_clk_ctrl: DciClkCtrl,
|
dci_clk_ctrl: DciClockControl,
|
||||||
/// AMBA peripheral clock control
|
/// AMBA peripheral clock control
|
||||||
aper_clk_ctrl: AperClkCtrl,
|
aper_clk_ctrl: AperClockControl,
|
||||||
usb_0_clk_ctrl: u32,
|
usb_0_clk_ctrl: u32,
|
||||||
usb_1_clk_ctrl: u32,
|
usb_1_clk_ctrl: u32,
|
||||||
gem_0_rclk_ctrl: GigEthRclkCtrl,
|
gem_0_rclk_ctrl: GigEthRclkControl,
|
||||||
gem_1_rclk_ctrl: GigEthRclkCtrl,
|
gem_1_rclk_ctrl: GigEthRclkControl,
|
||||||
gem_0_clk_ctrl: GigEthClkCtrl,
|
gem_0_clk_ctrl: GigEthClockControl,
|
||||||
gem_1_clk_ctrl: GigEthClkCtrl,
|
gem_1_clk_ctrl: GigEthClockControl,
|
||||||
smc_clk_ctrl: SingleCommonPeriphIoClkCtrl,
|
smc_clk_ctrl: SingleCommonPeriphIoClockControl,
|
||||||
lqspi_clk_ctrl: SingleCommonPeriphIoClkCtrl,
|
lqspi_clk_ctrl: SingleCommonPeriphIoClockControl,
|
||||||
sdio_clk_ctrl: DualCommonPeriphIoClkCtrl,
|
sdio_clk_ctrl: DualCommonPeriphIoClockControl,
|
||||||
uart_clk_ctrl: DualCommonPeriphIoClkCtrl,
|
uart_clk_ctrl: DualCommonPeriphIoClockControl,
|
||||||
spi_clk_ctrl: DualCommonPeriphIoClkCtrl,
|
spi_clk_ctrl: DualCommonPeriphIoClockControl,
|
||||||
can_clk_ctrl: CanClkCtrl,
|
can_clk_ctrl: CanClockControl,
|
||||||
can_mioclk_ctrl: u32,
|
can_mioclk_ctrl: u32,
|
||||||
/// Debug or Trace Port clock control.
|
/// Debug or Trace Port clock control.
|
||||||
dbg_clk_ctrl: TracePortClkCtrl,
|
dbg_clk_ctrl: TracePortClockControl,
|
||||||
pcap_clk_ctrl: SingleCommonPeriphIoClkCtrl,
|
pcap_clk_ctrl: SingleCommonPeriphIoClockControl,
|
||||||
topsw_clk_ctrl: u32,
|
topsw_clk_ctrl: u32,
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
fpga_0_clk_ctrl: FpgaClkCtrlBlock,
|
fpga_0_clk_ctrl: FpgaClockControlBlock,
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
fpga_1_clk_ctrl: FpgaClkCtrlBlock,
|
fpga_1_clk_ctrl: FpgaClockControlBlock,
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
fpga_2_clk_ctrl: FpgaClkCtrlBlock,
|
fpga_2_clk_ctrl: FpgaClockControlBlock,
|
||||||
#[mmio(Inner)]
|
#[mmio(Inner)]
|
||||||
fpga_3_clk_ctrl: FpgaClkCtrlBlock,
|
fpga_3_clk_ctrl: FpgaClockControlBlock,
|
||||||
_gap1: [u32; 5],
|
_gap1: [u32; 5],
|
||||||
clk_621_true: ClkRatioSelectReg,
|
clk_621_true: ClockRatioSelectReg,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClockControl {
|
impl ClockControl {
|
||||||
|
@@ -58,7 +58,7 @@ pub enum VrefSel {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GpiobCtrl {
|
pub struct GpiobControl {
|
||||||
#[bit(11, rw)]
|
#[bit(11, rw)]
|
||||||
vref_sw_en: bool,
|
vref_sw_en: bool,
|
||||||
#[bits(4..=6, rw)]
|
#[bits(4..=6, rw)]
|
||||||
@@ -70,7 +70,7 @@ pub struct GpiobCtrl {
|
|||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct GpiobRegisters {
|
pub struct GpiobRegisters {
|
||||||
ctrl: GpiobCtrl,
|
ctrl: GpiobControl,
|
||||||
cfg_cmos18: u32,
|
cfg_cmos18: u32,
|
||||||
cfg_cmos25: u32,
|
cfg_cmos25: u32,
|
||||||
cfg_cmos33: u32,
|
cfg_cmos33: u32,
|
||||||
@@ -95,7 +95,7 @@ impl GpiobRegisters {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BootModeReg {
|
pub struct BootModeRegister {
|
||||||
#[bit(4, r)]
|
#[bit(4, r)]
|
||||||
pll_bypass: bool,
|
pll_bypass: bool,
|
||||||
#[bits(0..=3, r)]
|
#[bits(0..=3, r)]
|
||||||
@@ -104,16 +104,16 @@ pub struct BootModeReg {
|
|||||||
|
|
||||||
#[bitbybit::bitenum(u4)]
|
#[bitbybit::bitenum(u4)]
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum LevelShifterCfg {
|
pub enum LevelShifterConfig {
|
||||||
DisableAll = 0x00,
|
DisableAll = 0x00,
|
||||||
EnablePsToPl = 0xA,
|
EnablePsToPl = 0xA,
|
||||||
EnableAll = 0xF,
|
EnableAll = 0xF,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
pub struct LevelShifterReg {
|
pub struct LevelShifterRegister {
|
||||||
#[bits(0..=3, rw)]
|
#[bits(0..=3, rw)]
|
||||||
user_lvl_shftr_en: Option<LevelShifterCfg>,
|
user_lvl_shftr_en: Option<LevelShifterConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// System Level Control Registers
|
/// System Level Control Registers
|
||||||
@@ -142,7 +142,7 @@ pub struct Slcr {
|
|||||||
_gap2: [u32; 0x02],
|
_gap2: [u32; 0x02],
|
||||||
|
|
||||||
reboot_status: u32,
|
reboot_status: u32,
|
||||||
boot_mode: BootModeReg,
|
boot_mode: BootModeRegister,
|
||||||
|
|
||||||
_gap3: [u32; 0x28],
|
_gap3: [u32; 0x28],
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ pub struct Slcr {
|
|||||||
|
|
||||||
_gap13: [u32; 0x32],
|
_gap13: [u32; 0x32],
|
||||||
|
|
||||||
lvl_shftr_en: LevelShifterReg,
|
lvl_shftr_en: LevelShifterRegister,
|
||||||
|
|
||||||
_gap14: [u32; 0x03],
|
_gap14: [u32; 0x03],
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@ use super::{RESET_BLOCK_OFFSET, SLCR_BASE_ADDR};
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DualClkRst {
|
pub struct DualClockReset {
|
||||||
/// Peripheral 1 AMBA software reset.
|
/// Peripheral 1 AMBA software reset.
|
||||||
#[bit(1, rw)]
|
#[bit(1, rw)]
|
||||||
periph1_cpu1x_rst: bool,
|
periph1_cpu1x_rst: bool,
|
||||||
@@ -13,7 +13,7 @@ pub struct DualClkRst {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DualRefAndClkRst {
|
pub struct DualRefAndClockReset {
|
||||||
/// Periperal 1 Reference software reset.
|
/// Periperal 1 Reference software reset.
|
||||||
#[bit(3, rw)]
|
#[bit(3, rw)]
|
||||||
periph1_ref_rst: bool,
|
periph1_ref_rst: bool,
|
||||||
@@ -30,14 +30,14 @@ pub struct DualRefAndClkRst {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GpioClkRst {
|
pub struct GpioClockReset {
|
||||||
#[bit(0, rw)]
|
#[bit(0, rw)]
|
||||||
gpio_cpu1x_rst: bool,
|
gpio_cpu1x_rst: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EthernetRst {
|
pub struct EthernetReset {
|
||||||
#[bit(5, rw)]
|
#[bit(5, rw)]
|
||||||
gem1_ref_rst: bool,
|
gem1_ref_rst: bool,
|
||||||
#[bit(4, rw)]
|
#[bit(4, rw)]
|
||||||
@@ -62,13 +62,13 @@ pub struct ResetControl {
|
|||||||
topsw: u32,
|
topsw: u32,
|
||||||
dmac: u32,
|
dmac: u32,
|
||||||
usb: u32,
|
usb: u32,
|
||||||
eth: EthernetRst,
|
eth: EthernetReset,
|
||||||
sdio: DualRefAndClkRst,
|
sdio: DualRefAndClockReset,
|
||||||
spi: DualRefAndClkRst,
|
spi: DualRefAndClockReset,
|
||||||
can: DualClkRst,
|
can: DualClockReset,
|
||||||
i2c: DualClkRst,
|
i2c: DualClockReset,
|
||||||
uart: DualRefAndClkRst,
|
uart: DualRefAndClockReset,
|
||||||
gpio: GpioClkRst,
|
gpio: GpioClockReset,
|
||||||
lqspi: u32,
|
lqspi: u32,
|
||||||
smc: u32,
|
smc: u32,
|
||||||
ocm: u32,
|
ocm: u32,
|
||||||
|
@@ -33,7 +33,7 @@ impl BaudDivSel {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Cfg {
|
pub struct Config {
|
||||||
#[bit(17, rw)]
|
#[bit(17, rw)]
|
||||||
modefail_gen_en: bool,
|
modefail_gen_en: bool,
|
||||||
#[bit(16, w)]
|
#[bit(16, w)]
|
||||||
@@ -182,7 +182,7 @@ pub struct DelayControl {
|
|||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Spi {
|
pub struct Spi {
|
||||||
cr: Cfg,
|
cr: Config,
|
||||||
#[mmio(PureRead, Write)]
|
#[mmio(PureRead, Write)]
|
||||||
isr: InterruptStatus,
|
isr: InterruptStatus,
|
||||||
/// Interrupt Enable Register.
|
/// Interrupt Enable Register.
|
||||||
|
@@ -14,7 +14,7 @@ pub enum ClockSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
pub struct ClkCtrl {
|
pub struct ClockControl {
|
||||||
/// When this bit is set and the external clock is selected, the counter clocks on the
|
/// When this bit is set and the external clock is selected, the counter clocks on the
|
||||||
/// negative edge of the external clock input.
|
/// negative edge of the external clock input.
|
||||||
#[bit(6, rw)]
|
#[bit(6, rw)]
|
||||||
@@ -146,7 +146,7 @@ pub struct EventCount {
|
|||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Ttc {
|
pub struct Ttc {
|
||||||
clk_cntr: [ClkCtrl; 3],
|
clk_cntr: [ClockControl; 3],
|
||||||
cnt_ctrl: [CounterControl; 3],
|
cnt_ctrl: [CounterControl; 3],
|
||||||
#[mmio(PureRead)]
|
#[mmio(PureRead)]
|
||||||
current_counter: [Counter; 3],
|
current_counter: [Counter; 3],
|
||||||
|
@@ -20,7 +20,7 @@ pub enum Parity {
|
|||||||
|
|
||||||
#[bitbybit::bitenum(u2, exhaustive = true)]
|
#[bitbybit::bitenum(u2, exhaustive = true)]
|
||||||
#[derive(Default, Debug, PartialEq, Eq)]
|
#[derive(Default, Debug, PartialEq, Eq)]
|
||||||
pub enum Chrl {
|
pub enum CharLen {
|
||||||
SixBits = 0b11,
|
SixBits = 0b11,
|
||||||
SevenBits = 0b10,
|
SevenBits = 0b10,
|
||||||
#[default]
|
#[default]
|
||||||
@@ -30,7 +30,7 @@ pub enum Chrl {
|
|||||||
|
|
||||||
#[bitbybit::bitenum(u1, exhaustive = true)]
|
#[bitbybit::bitenum(u1, exhaustive = true)]
|
||||||
#[derive(Default, Debug, PartialEq, Eq)]
|
#[derive(Default, Debug, PartialEq, Eq)]
|
||||||
pub enum ClkSel {
|
pub enum ClockSelect {
|
||||||
#[default]
|
#[default]
|
||||||
UartRefClk = 0b0,
|
UartRefClk = 0b0,
|
||||||
UartRefClkDiv8 = 0b1,
|
UartRefClkDiv8 = 0b1,
|
||||||
@@ -57,7 +57,7 @@ pub enum ChMode {
|
|||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Ctrl {
|
pub struct Control {
|
||||||
/// Stop transmitter break.
|
/// Stop transmitter break.
|
||||||
#[bit(8, rw)]
|
#[bit(8, rw)]
|
||||||
stopbrk: bool,
|
stopbrk: bool,
|
||||||
@@ -98,9 +98,9 @@ pub struct Mode {
|
|||||||
par: Parity,
|
par: Parity,
|
||||||
/// Char length.
|
/// Char length.
|
||||||
#[bits(1..=2, rw)]
|
#[bits(1..=2, rw)]
|
||||||
chrl: Chrl,
|
chrl: CharLen,
|
||||||
#[bit(0, rw)]
|
#[bit(0, rw)]
|
||||||
clksel: ClkSel,
|
clksel: ClockSelect,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
@@ -287,7 +287,7 @@ impl InterruptStatus {
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Uart {
|
pub struct Uart {
|
||||||
/// Control Register
|
/// Control Register
|
||||||
cr: Ctrl,
|
cr: Control,
|
||||||
/// Mode register
|
/// Mode register
|
||||||
mr: Mode,
|
mr: Mode,
|
||||||
/// Interrupt enable register
|
/// Interrupt enable register
|
||||||
|
Reference in New Issue
Block a user