fix build ,update examples
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:
2025-09-27 15:12:14 +02:00
parent 38e2109e52
commit e3d9e7dfad
25 changed files with 416 additions and 265 deletions

View File

@@ -11,7 +11,7 @@ members = [
"zynq-mmu",
"zedboard-fsbl",
"zedboard-bsp",
"zynq-boot-image",
"zynq-boot-image", "zedboard-qspi-flasher",
]
exclude = [

View File

@@ -17,10 +17,10 @@ use zynq7000_hal::{
gtc::GlobalTimerCounter,
l2_cache,
time::Hertz,
uart::{ClockConfigRaw, Uart, UartConfig},
uart::{ClockConfig, Config, Uart},
};
use zynq7000::PsPeripherals;
use zynq7000::Peripherals;
use zynq7000_rt as _;
// Define the clock frequency as a constant
@@ -44,7 +44,7 @@ const OPEN_DRAIN_PINS_MIO9_TO_MIO14: bool = false;
#[embassy_executor::main]
#[unsafe(export_name = "main")]
async fn main(_spawner: Spawner) -> ! {
let mut dp = PsPeripherals::take().unwrap();
let mut dp = Peripherals::take().unwrap();
l2_cache::init_with_defaults(&mut dp.l2c);
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
@@ -64,12 +64,12 @@ async fn main(_spawner: Spawner) -> ! {
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
// Set up the UART, we are logging with it.
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
let uart_clk_config = ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut uart = Uart::new_with_mio(
dp.uart_1,
UartConfig::new_with_clk_config(uart_clk_config),
Config::new_with_clk_config(uart_clk_config),
(mio_pins.mio48, mio_pins.mio49),
)
.unwrap();

View File

@@ -9,7 +9,7 @@ use embassy_time::{Duration, Ticker};
use embedded_hal::digital::StatefulOutputPin;
use embedded_io::Write;
use log::{error, info};
use zynq7000::PsPeripherals;
use zynq7000::Peripherals;
use zynq7000_hal::{
BootMode,
clocks::Clocks,
@@ -18,7 +18,7 @@ use zynq7000_hal::{
gtc::GlobalTimerCounter,
l2_cache,
time::Hertz,
uart::{ClockConfigRaw, TxAsync, Uart, UartConfig, on_interrupt_tx},
uart::{ClockConfig, Config, TxAsync, Uart, on_interrupt_tx},
};
use zynq7000_rt as _;
@@ -38,7 +38,7 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
#[unsafe(export_name = "main")]
#[embassy_executor::main]
async fn main(spawner: Spawner) -> ! {
let mut dp = PsPeripherals::take().unwrap();
let mut dp = Peripherals::take().unwrap();
l2_cache::init_with_defaults(&mut dp.l2c);
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
@@ -58,12 +58,12 @@ async fn main(spawner: Spawner) -> ! {
let mio_pins = mio::Pins::new(dp.gpio);
// Set up the UART, we are logging with it.
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
let uart_clk_config = ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut uart = Uart::new_with_mio(
dp.uart_1,
UartConfig::new_with_clk_config(uart_clk_config),
Config::new_with_clk_config(uart_clk_config),
(mio_pins.mio48, mio_pins.mio49),
)
.unwrap();

View File

@@ -23,10 +23,10 @@ use zynq7000_hal::{
gtc::GlobalTimerCounter,
l2_cache,
time::Hertz,
uart::{ClockConfigRaw, Uart, UartConfig},
uart::{ClockConfig, Config, Uart},
};
use zynq7000::PsPeripherals;
use zynq7000::Peripherals;
use zynq7000_rt as _;
// Define the clock frequency as a constant
@@ -44,7 +44,7 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
#[embassy_executor::main]
#[unsafe(export_name = "main")]
async fn main(_spawner: Spawner) -> ! {
let mut dp = PsPeripherals::take().unwrap();
let mut dp = Peripherals::take().unwrap();
l2_cache::init_with_defaults(&mut dp.l2c);
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
@@ -71,12 +71,12 @@ async fn main(_spawner: Spawner) -> ! {
pwm.set_duty_cycle_percent(50).unwrap();
// Set up the UART, we are logging with it.
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
let uart_clk_config = ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut uart = Uart::new_with_mio(
dp.uart_1,
UartConfig::new_with_clk_config(uart_clk_config),
Config::new_with_clk_config(uart_clk_config),
(mio_pins.mio48, mio_pins.mio49),
)
.unwrap();

View File

@@ -8,18 +8,8 @@ use embassy_time::{Duration, Ticker};
use embedded_hal::digital::StatefulOutputPin;
use embedded_io::Write;
use log::{error, info};
use zynq7000_hal::{
BootMode,
clocks::Clocks,
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
gpio::{Output, PinState, mio},
gtc::GlobalTimerCounter,
l2_cache,
time::Hertz,
uart::{ClockConfigRaw, Uart, UartConfig},
};
use zynq7000_hal::{clocks, gic, gpio, gtc, time::Hertz, uart, BootMode, InteruptConfig};
use zynq7000::PsPeripherals;
use zynq7000_rt as _;
// Define the clock frequency as a constant
@@ -37,32 +27,27 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
#[embassy_executor::main]
#[unsafe(export_name = "main")]
async fn main(_spawner: Spawner) -> ! {
let mut dp = PsPeripherals::take().unwrap();
l2_cache::init_with_defaults(&mut dp.l2c);
// 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();
// Set up the global interrupt controller.
let mut gic = GicConfigurator::new_with_init(dp.gicc, dp.gicd);
gic.enable_all_interrupts();
gic.set_all_spi_interrupt_targets_cpu0();
gic.enable();
unsafe {
gic.enable_interrupts();
}
let mio_pins = mio::Pins::new(dp.gpio);
let periphs = zynq7000_hal::init(zynq7000_hal::Config {
init_l2_cache: true,
level_shifter_config: Some(zynq7000_hal::LevelShifterConfig::EnableAll),
interrupt_config: Some(InteruptConfig::AllInterruptsToCpu0),
})
.unwrap();
let clocks = clocks::Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
// Set up global timer counter and embassy time driver.
let gtc = GlobalTimerCounter::new(dp.gtc, clocks.arm_clocks());
let gtc = gtc::GlobalTimerCounter::new(periphs.gtc, clocks.arm_clocks());
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
let mio_pins = gpio::mio::Pins::new(periphs.gpio);
// Set up the UART, we are logging with it.
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
let uart_clk_config = uart::ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut uart = Uart::new_with_mio(
dp.uart_1,
UartConfig::new_with_clk_config(uart_clk_config),
let mut uart = uart::Uart::new_with_mio(
periphs.uart_1,
uart::Config::new_with_clk_config(uart_clk_config),
(mio_pins.mio48, mio_pins.mio49),
)
.unwrap();
@@ -81,7 +66,7 @@ async fn main(_spawner: Spawner) -> ! {
info!("Boot mode: {:?}", boot_mode);
let mut ticker = Ticker::every(Duration::from_millis(1000));
let mut led = Output::new_for_mio(mio_pins.mio7, PinState::Low);
let mut led = gpio::Output::new_for_mio(mio_pins.mio7, gpio::PinState::Low);
loop {
info!("Hello, world!");
led.toggle().unwrap();
@@ -89,42 +74,42 @@ async fn main(_spawner: Spawner) -> ! {
}
}
#[unsafe(no_mangle)]
pub extern "C" fn _irq_handler() {
let mut gic_helper = GicInterruptHelper::new();
#[zynq7000_rt::irq]
pub fn irq_handler() {
let mut gic_helper = gic::GicInterruptHelper::new();
let irq_info = gic_helper.acknowledge_interrupt();
match irq_info.interrupt() {
Interrupt::Sgi(_) => (),
Interrupt::Ppi(ppi_interrupt) => {
gic::Interrupt::Sgi(_) => (),
gic::Interrupt::Ppi(ppi_interrupt) => {
if ppi_interrupt == zynq7000_hal::gic::PpiInterrupt::GlobalTimer {
unsafe {
zynq7000_embassy::on_interrupt();
}
}
}
Interrupt::Spi(_spi_interrupt) => (),
Interrupt::Invalid(_) => (),
Interrupt::Spurious => (),
gic::Interrupt::Spi(_spi_interrupt) => (),
gic::Interrupt::Invalid(_) => (),
gic::Interrupt::Spurious => (),
}
gic_helper.end_of_interrupt(irq_info);
}
#[unsafe(no_mangle)]
pub extern "C" fn _abort_handler() {
#[zynq7000_rt::exception(DataAbort)]
fn data_abort_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}
}
#[unsafe(no_mangle)]
pub extern "C" fn _undefined_handler() {
#[zynq7000_rt::exception(Undefined)]
fn undefined_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}
}
#[unsafe(no_mangle)]
pub extern "C" fn _prefetch_handler() {
#[zynq7000_rt::exception(PrefetchAbort)]
fn prefetch_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}

View File

@@ -15,7 +15,7 @@ use zynq7000_hal::{
l2_cache,
prelude::*,
time::Hertz,
uart::{ClockConfigRaw, Uart, UartConfig},
uart::{ClockConfig, Config, Uart},
};
use zynq7000_rt as _;
@@ -36,7 +36,7 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
#[unsafe(export_name = "main")]
pub fn main() -> ! {
let mut dp = zynq7000::PsPeripherals::take().unwrap();
let mut dp = zynq7000::Peripherals::take().unwrap();
l2_cache::init_with_defaults(&mut dp.l2c);
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
@@ -49,7 +49,7 @@ pub fn main() -> ! {
// Enable interrupt exception.
unsafe { gic.enable_interrupts() };
// Set up the UART, we are logging with it.
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
let uart_clk_config = ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut gtc = GlobalTimerCounter::new(dp.gtc, clocks.arm_clocks());
@@ -64,7 +64,7 @@ pub fn main() -> ! {
let mio_pins = mio::Pins::new(dp.gpio);
let mut uart = Uart::new_with_mio(
dp.uart_1,
UartConfig::new_with_clk_config(uart_clk_config),
Config::new_with_clk_config(uart_clk_config),
(mio_pins.mio48, mio_pins.mio49),
)
.unwrap();

View File

@@ -16,7 +16,7 @@ use zynq7000_hal::{
l2_cache,
prelude::*,
time::Hertz,
uart::{ClockConfigRaw, Uart, UartConfig},
uart::{ClockConfig, Config, Uart},
};
use zynq7000_rt as _;
@@ -37,7 +37,7 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
#[unsafe(export_name = "main")]
pub fn main() -> ! {
let mut dp = zynq7000::PsPeripherals::take().unwrap();
let mut dp = zynq7000::Peripherals::take().unwrap();
l2_cache::init_with_defaults(&mut dp.l2c);
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
@@ -50,7 +50,7 @@ pub fn main() -> ! {
// Enable interrupt exception.
unsafe { gic.enable_interrupts() };
// Set up the UART, we are logging with it.
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
let uart_clk_config = ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut gtc = GlobalTimerCounter::new(dp.gtc, clocks.arm_clocks());
@@ -64,7 +64,7 @@ pub fn main() -> ! {
let mut uart = Uart::new_with_mio(
dp.uart_1,
UartConfig::new_with_clk_config(uart_clk_config),
Config::new_with_clk_config(uart_clk_config),
(mio_pins.mio48, mio_pins.mio49),
)
.unwrap();

View File

@@ -5,7 +5,7 @@
use core::panic::PanicInfo;
use cortex_ar::asm::nop;
use embedded_hal::{delay::DelayNs, digital::StatefulOutputPin};
use zynq7000::PsPeripherals;
use zynq7000::Peripherals;
use zynq7000_hal::{
clocks::Clocks,
gpio::{Output, PinState, mio},
@@ -56,7 +56,7 @@ pub fn main() -> ! {
}
}
Lib::Hal => {
let dp = PsPeripherals::take().unwrap();
let dp = Peripherals::take().unwrap();
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
// Unwrap okay, we only call this once on core 0 here.
let mut cpu_tim = CpuPrivateTimer::take(clocks.arm_clocks()).unwrap();

View File

@@ -46,10 +46,10 @@ use zynq7000_hal::{
gpio::{GpioPins, Output, PinState},
gtc::GlobalTimerCounter,
l2_cache,
uart::{ClockConfigRaw, Uart, UartConfig},
uart::{ClockConfig, Config, Uart},
};
use zynq7000::{PsPeripherals, slcr::LevelShifterConfig};
use zynq7000::{Peripherals, slcr::LevelShifterConfig};
use zynq7000_rt::{self as _, mmu::section_attrs::SHAREABLE_DEVICE, mmu_l1_table_mut};
const USE_DHCP: bool = true;
@@ -206,7 +206,7 @@ async fn tcp_task(mut tcp: TcpSocket<'static>) -> ! {
#[embassy_executor::main]
#[unsafe(export_name = "main")]
async fn main(spawner: Spawner) -> ! {
let mut dp = PsPeripherals::take().unwrap();
let mut dp = Peripherals::take().unwrap();
l2_cache::init_with_defaults(&mut dp.l2c);
// Enable PS-PL level shifters.
@@ -234,12 +234,12 @@ async fn main(spawner: Spawner) -> ! {
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
// Set up the UART, we are logging with it.
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
let uart_clk_config = ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut uart = Uart::new_with_mio(
dp.uart_1,
UartConfig::new_with_clk_config(uart_clk_config),
Config::new_with_clk_config(uart_clk_config),
(gpio_pins.mio.mio48, gpio_pins.mio.mio49),
)
.unwrap();

View File

@@ -29,7 +29,7 @@ use zynq7000_hal::{
uart,
};
use zynq7000::{PsPeripherals, slcr::LevelShifterConfig};
use zynq7000::{Peripherals, slcr::LevelShifterConfig};
use zynq7000_rt as _;
// Define the clock frequency as a constant
@@ -48,7 +48,7 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
#[embassy_executor::main]
#[unsafe(export_name = "main")]
async fn main(_spawner: Spawner) -> ! {
let mut dp = PsPeripherals::take().unwrap();
let mut dp = Peripherals::take().unwrap();
l2_cache::init_with_defaults(&mut dp.l2c);
// Enable PS-PL level shifters.
@@ -73,12 +73,12 @@ async fn main(_spawner: Spawner) -> ! {
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
// Set up the UART, we are logging with it.
let uart_clk_config = uart::ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
let uart_clk_config = uart::ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut uart = uart::Uart::new_with_mio(
dp.uart_1,
uart::UartConfig::new_with_clk_config(uart_clk_config),
uart::Config::new_with_clk_config(uart_clk_config),
(gpio_pins.mio.mio48, gpio_pins.mio.mio49),
)
.unwrap();

View File

@@ -30,7 +30,7 @@ use zynq7000_hal::{
uart::{self, TxAsync, on_interrupt_tx},
};
use zynq7000::{PsPeripherals, slcr::LevelShifterConfig, spi::DelayControl};
use zynq7000::{Peripherals, slcr::LevelShifterConfig, spi::DelayControl};
use zynq7000_rt as _;
// Define the clock frequency as a constant
@@ -51,7 +51,7 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
#[embassy_executor::main]
#[unsafe(export_name = "main")]
async fn main(spawner: Spawner) -> ! {
let mut dp = PsPeripherals::take().unwrap();
let mut dp = Peripherals::take().unwrap();
l2_cache::init_with_defaults(&mut dp.l2c);
// Enable PS-PL level shifters.
@@ -83,12 +83,12 @@ async fn main(spawner: Spawner) -> ! {
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
// Set up the UART, we are logging with it.
let uart_clk_config = uart::ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
let uart_clk_config = uart::ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut uart = uart::Uart::new_with_mio(
dp.uart_1,
uart::UartConfig::new_with_clk_config(uart_clk_config),
uart::Config::new_with_clk_config(uart_clk_config),
(gpio_pins.mio.mio48, gpio_pins.mio.mio49),
)
.unwrap();

View File

@@ -10,23 +10,8 @@ use embedded_io::Write;
use log::{error, info};
use zedboard::PS_CLOCK_FREQUENCY;
use zedboard_bsp::qspi_spansion;
use zynq7000_hal::{
BootMode,
clocks::Clocks,
configure_level_shifter,
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
gpio::{GpioPins, Output, PinState},
gtc::GlobalTimerCounter,
l2_cache,
prelude::*,
qspi,
uart::{ClockConfigRaw, Uart, UartConfig},
};
use zynq7000_hal::{clocks, gic, gpio, gtc, prelude::*, qspi, uart, BootMode};
use zynq7000::{
PsPeripherals,
slcr::{LevelShifterConfig, clocks::SrcSelIo},
};
use zynq7000_rt as _;
const INIT_STRING: &str = "-- Zynq 7000 Zedboard QSPI example --\n\r";
@@ -50,35 +35,28 @@ const ERASE_PROGRAM_READ_TEST: bool = false;
#[embassy_executor::main]
#[unsafe(export_name = "main")]
async fn main(_spawner: Spawner) -> ! {
let mut dp = PsPeripherals::take().unwrap();
l2_cache::init_with_defaults(&mut dp.l2c);
// Enable PS-PL level shifters.
configure_level_shifter(LevelShifterConfig::EnableAll);
let periphs = zynq7000_hal::init(zynq7000_hal::Config {
init_l2_cache: true,
level_shifter_config: Some(zynq7000_hal::LevelShifterConfig::EnableAll),
interrupt_config: Some(zynq7000_hal::InteruptConfig::AllInterruptsToCpu0),
})
.unwrap();
// 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();
// Set up the global interrupt controller.
let mut gic = GicConfigurator::new_with_init(dp.gicc, dp.gicd);
gic.enable_all_interrupts();
gic.set_all_spi_interrupt_targets_cpu0();
gic.enable();
unsafe {
gic.enable_interrupts();
}
let gpio_pins = GpioPins::new(dp.gpio);
let clocks = clocks::Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
let gpio_pins = gpio::GpioPins::new(periphs.gpio);
// Set up global timer counter and embassy time driver.
let gtc = GlobalTimerCounter::new(dp.gtc, clocks.arm_clocks());
let gtc = gtc::GlobalTimerCounter::new(periphs.gtc, clocks.arm_clocks());
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
// Set up the UART, we are logging with it.
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
let uart_clk_config = uart::ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut uart = Uart::new_with_mio(
dp.uart_1,
UartConfig::new_with_clk_config(uart_clk_config),
let mut uart = uart::Uart::new_with_mio(
periphs.uart_1,
uart::Config::new_with_clk_config(uart_clk_config),
(gpio_pins.mio.mio48, gpio_pins.mio.mio49),
)
.unwrap();
@@ -96,10 +74,10 @@ async fn main(_spawner: Spawner) -> ! {
info!("Boot mode: {:?}", boot_mode);
let qspi_clock_config =
qspi::ClockConfig::calculate_with_loopback(SrcSelIo::IoPll, &clocks, 100.MHz())
qspi::ClockConfig::calculate_with_loopback(qspi::SrcSelIo::IoPll, &clocks, 100.MHz())
.expect("QSPI clock calculation failed");
let qspi = qspi::Qspi::new_single_qspi_with_feedback(
dp.qspi,
periphs.qspi,
qspi_clock_config,
embedded_hal::spi::MODE_0,
qspi::IoType::LvCmos33,
@@ -176,7 +154,7 @@ async fn main(_spawner: Spawner) -> ! {
let mut ticker = Ticker::every(Duration::from_millis(200));
let mut mio_led = Output::new_for_mio(gpio_pins.mio.mio7, PinState::Low);
let mut mio_led = gpio::Output::new_for_mio(gpio_pins.mio.mio7, gpio::PinState::Low);
loop {
mio_led.toggle().unwrap();
@@ -184,42 +162,42 @@ async fn main(_spawner: Spawner) -> ! {
}
}
#[unsafe(no_mangle)]
pub extern "C" fn _irq_handler() {
let mut gic_helper = GicInterruptHelper::new();
#[zynq7000_rt::irq]
fn irq_handler() {
let mut gic_helper = gic::GicInterruptHelper::new();
let irq_info = gic_helper.acknowledge_interrupt();
match irq_info.interrupt() {
Interrupt::Sgi(_) => (),
Interrupt::Ppi(ppi_interrupt) => {
if ppi_interrupt == zynq7000_hal::gic::PpiInterrupt::GlobalTimer {
gic::Interrupt::Sgi(_) => (),
gic::Interrupt::Ppi(ppi_interrupt) => {
if ppi_interrupt == gic::PpiInterrupt::GlobalTimer {
unsafe {
zynq7000_embassy::on_interrupt();
}
}
}
Interrupt::Spi(_spi_interrupt) => (),
Interrupt::Invalid(_) => (),
Interrupt::Spurious => (),
gic::Interrupt::Spi(_spi_interrupt) => (),
gic::Interrupt::Invalid(_) => (),
gic::Interrupt::Spurious => (),
}
gic_helper.end_of_interrupt(irq_info);
}
#[unsafe(no_mangle)]
pub extern "C" fn _abort_handler() {
#[zynq7000_rt::exception(DataAbort)]
fn data_abort_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}
}
#[unsafe(no_mangle)]
pub extern "C" fn _undefined_handler() {
#[zynq7000_rt::exception(Undefined)]
fn undefined_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}
}
#[unsafe(no_mangle)]
pub extern "C" fn _prefetch_handler() {
#[zynq7000_rt::exception(PrefetchAbort)]
fn prefetch_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}

View File

@@ -20,10 +20,10 @@ use zynq7000_hal::{
gpio::{GpioPins, Output, PinState},
gtc::GlobalTimerCounter,
l2_cache,
uart::{ClockConfigRaw, Uart, UartConfig},
uart::{ClockConfig, Config, Uart},
};
use zynq7000::{PsPeripherals, slcr::LevelShifterConfig};
use zynq7000::{Peripherals, slcr::LevelShifterConfig};
use zynq7000_rt as _;
const INIT_STRING: &str = "-- Zynq 7000 Zedboard blocking UART example --\n\r";
@@ -101,7 +101,7 @@ impl UartMultiplexer {
#[embassy_executor::main]
#[unsafe(export_name = "main")]
async fn main(_spawner: Spawner) -> ! {
let mut dp = PsPeripherals::take().unwrap();
let mut dp = Peripherals::take().unwrap();
l2_cache::init_with_defaults(&mut dp.l2c);
// Enable PS-PL level shifters.
@@ -123,12 +123,12 @@ async fn main(_spawner: Spawner) -> ! {
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
// Set up the UART, we are logging with it.
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
let uart_clk_config = ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut log_uart = Uart::new_with_mio(
dp.uart_1,
UartConfig::new_with_clk_config(uart_clk_config),
Config::new_with_clk_config(uart_clk_config),
(gpio_pins.mio.mio48, gpio_pins.mio.mio49),
)
.unwrap();
@@ -145,7 +145,7 @@ async fn main(_spawner: Spawner) -> ! {
// UART0 routed through EMIO to PL pins.
let mut uart_0 =
Uart::new_with_emio(dp.uart_0, UartConfig::new_with_clk_config(uart_clk_config)).unwrap();
Uart::new_with_emio(dp.uart_0, Config::new_with_clk_config(uart_clk_config)).unwrap();
// Safety: Valid address of AXI UARTLITE.
let mut uartlite = unsafe { AxiUartlite::new(AXI_UARTLITE_BASE_ADDR) };

View File

@@ -47,7 +47,7 @@ use zynq7000_hal::{
gtc::GlobalTimerCounter,
l2_cache,
time::Hertz,
uart::{ClockConfigRaw, Uart, UartConfig},
uart::{ClockConfig, Config, Uart},
};
pub enum UartMode {
@@ -62,7 +62,7 @@ const INIT_STRING: &str = "-- Zynq 7000 Zedboard non-blocking UART example --\n\
#[global_allocator]
static HEAP: Heap = Heap::empty();
use zynq7000::{PsPeripherals, slcr::LevelShifterConfig};
use zynq7000::{Peripherals, slcr::LevelShifterConfig};
use zynq7000_rt as _;
// Define the clock frequency as a constant
@@ -166,7 +166,7 @@ impl UartMultiplexer {
#[embassy_executor::main]
#[unsafe(export_name = "main")]
async fn main(spawner: Spawner) -> ! {
let mut dp = PsPeripherals::take().unwrap();
let mut dp = Peripherals::take().unwrap();
l2_cache::init_with_defaults(&mut dp.l2c);
// Enable PS-PL level shifters.
@@ -194,12 +194,12 @@ async fn main(spawner: Spawner) -> ! {
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
// Set up the UART, we are logging with it.
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
let uart_clk_config = ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut log_uart = Uart::new_with_mio(
dp.uart_1,
UartConfig::new_with_clk_config(uart_clk_config),
Config::new_with_clk_config(uart_clk_config),
(gpio_pins.mio.mio48, gpio_pins.mio.mio49),
)
.unwrap();
@@ -237,7 +237,7 @@ async fn main(spawner: Spawner) -> ! {
// UART0 routed through EMIO to PL pins.
let uart_0 =
Uart::new_with_emio(dp.uart_0, UartConfig::new_with_clk_config(uart_clk_config)).unwrap();
Uart::new_with_emio(dp.uart_0, Config::new_with_clk_config(uart_clk_config)).unwrap();
// Safety: Valid address of AXI UARTLITE.
let mut uartlite = unsafe { AxiUartlite::new(AXI_UARTLITE_BASE_ADDR) };
// We need to call this before splitting the structure, because the interrupt signal is

View File

@@ -9,18 +9,8 @@ use embedded_hal::digital::StatefulOutputPin;
use embedded_io::Write;
use log::{error, info};
use zedboard::PS_CLOCK_FREQUENCY;
use zynq7000_hal::{
BootMode,
clocks::Clocks,
configure_level_shifter,
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
gpio::{GpioPins, Output, PinState},
gtc::GlobalTimerCounter,
l2_cache,
uart::{ClockConfigRaw, Uart, UartConfig},
};
use zynq7000_hal::{clocks, gic, gpio, gtc, uart, BootMode};
use zynq7000::{PsPeripherals, slcr::LevelShifterConfig};
use zynq7000_rt as _;
const INIT_STRING: &str = "-- Zynq 7000 Zedboard GPIO blinky example --\n\r";
@@ -37,35 +27,28 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
#[embassy_executor::main]
#[unsafe(export_name = "main")]
async fn main(_spawner: Spawner) -> ! {
let mut dp = PsPeripherals::take().unwrap();
l2_cache::init_with_defaults(&mut dp.l2c);
// Enable PS-PL level shifters.
configure_level_shifter(LevelShifterConfig::EnableAll);
let periphs = zynq7000_hal::init(zynq7000_hal::Config {
init_l2_cache: true,
level_shifter_config: Some(zynq7000_hal::LevelShifterConfig::EnableAll),
interrupt_config: Some(zynq7000_hal::InteruptConfig::AllInterruptsToCpu0),
})
.unwrap();
// 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();
// Set up the global interrupt controller.
let mut gic = GicConfigurator::new_with_init(dp.gicc, dp.gicd);
gic.enable_all_interrupts();
gic.set_all_spi_interrupt_targets_cpu0();
gic.enable();
unsafe {
gic.enable_interrupts();
}
let mut gpio_pins = GpioPins::new(dp.gpio);
let clocks = clocks::Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
let mut gpio_pins = gpio::GpioPins::new(periphs.gpio);
// Set up global timer counter and embassy time driver.
let gtc = GlobalTimerCounter::new(dp.gtc, clocks.arm_clocks());
let gtc = gtc::GlobalTimerCounter::new(periphs.gtc, clocks.arm_clocks());
zynq7000_embassy::init(clocks.arm_clocks(), gtc);
// Set up the UART, we are logging with it.
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
let uart_clk_config = uart::ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut uart = Uart::new_with_mio(
dp.uart_1,
UartConfig::new_with_clk_config(uart_clk_config),
let mut uart = uart::Uart::new_with_mio(
periphs.uart_1,
uart::Config::new_with_clk_config(uart_clk_config),
(gpio_pins.mio.mio48, gpio_pins.mio.mio49),
)
.unwrap();
@@ -84,16 +67,16 @@ async fn main(_spawner: Spawner) -> ! {
let mut ticker = Ticker::every(Duration::from_millis(200));
let mut mio_led = Output::new_for_mio(gpio_pins.mio.mio7, PinState::Low);
let mut emio_leds: [Output; 8] = [
Output::new_for_emio(gpio_pins.emio.take(0).unwrap(), PinState::Low),
Output::new_for_emio(gpio_pins.emio.take(1).unwrap(), PinState::Low),
Output::new_for_emio(gpio_pins.emio.take(2).unwrap(), PinState::Low),
Output::new_for_emio(gpio_pins.emio.take(3).unwrap(), PinState::Low),
Output::new_for_emio(gpio_pins.emio.take(4).unwrap(), PinState::Low),
Output::new_for_emio(gpio_pins.emio.take(5).unwrap(), PinState::Low),
Output::new_for_emio(gpio_pins.emio.take(6).unwrap(), PinState::Low),
Output::new_for_emio(gpio_pins.emio.take(7).unwrap(), PinState::Low),
let mut mio_led = gpio::Output::new_for_mio(gpio_pins.mio.mio7, gpio::PinState::Low);
let mut emio_leds: [gpio::Output; 8] = [
gpio::Output::new_for_emio(gpio_pins.emio.take(0).unwrap(), gpio::PinState::Low),
gpio::Output::new_for_emio(gpio_pins.emio.take(1).unwrap(), gpio::PinState::Low),
gpio::Output::new_for_emio(gpio_pins.emio.take(2).unwrap(), gpio::PinState::Low),
gpio::Output::new_for_emio(gpio_pins.emio.take(3).unwrap(), gpio::PinState::Low),
gpio::Output::new_for_emio(gpio_pins.emio.take(4).unwrap(), gpio::PinState::Low),
gpio::Output::new_for_emio(gpio_pins.emio.take(5).unwrap(), gpio::PinState::Low),
gpio::Output::new_for_emio(gpio_pins.emio.take(6).unwrap(), gpio::PinState::Low),
gpio::Output::new_for_emio(gpio_pins.emio.take(7).unwrap(), gpio::PinState::Low),
];
loop {
mio_led.toggle().unwrap();
@@ -108,42 +91,42 @@ async fn main(_spawner: Spawner) -> ! {
}
}
#[unsafe(no_mangle)]
pub extern "C" fn _irq_handler() {
let mut gic_helper = GicInterruptHelper::new();
#[zynq7000_rt::irq]
fn irq_handler() {
let mut gic_helper = gic::GicInterruptHelper::new();
let irq_info = gic_helper.acknowledge_interrupt();
match irq_info.interrupt() {
Interrupt::Sgi(_) => (),
Interrupt::Ppi(ppi_interrupt) => {
if ppi_interrupt == zynq7000_hal::gic::PpiInterrupt::GlobalTimer {
gic::Interrupt::Sgi(_) => (),
gic::Interrupt::Ppi(ppi_interrupt) => {
if ppi_interrupt == gic::PpiInterrupt::GlobalTimer {
unsafe {
zynq7000_embassy::on_interrupt();
}
}
}
Interrupt::Spi(_spi_interrupt) => (),
Interrupt::Invalid(_) => (),
Interrupt::Spurious => (),
gic::Interrupt::Spi(_spi_interrupt) => (),
gic::Interrupt::Invalid(_) => (),
gic::Interrupt::Spurious => (),
}
gic_helper.end_of_interrupt(irq_info);
}
#[unsafe(no_mangle)]
pub extern "C" fn _abort_handler() {
#[zynq7000_rt::exception(DataAbort)]
fn data_abort_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}
}
#[unsafe(no_mangle)]
pub extern "C" fn _undefined_handler() {
#[zynq7000_rt::exception(Undefined)]
fn undefined_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}
}
#[unsafe(no_mangle)]
pub extern "C" fn _prefetch_handler() {
#[zynq7000_rt::exception(PrefetchAbort)]
fn prefetch_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}

View File

@@ -8,21 +8,21 @@ use cortex_ar::asm::nop;
use embedded_io::Write as _;
use log::{error, info};
use zedboard_bsp::qspi_spansion::{self, QspiSpansionS25Fl256SLinearMode};
use zynq_boot_image::DestinationDevice;
use zynq7000_hal::{
BootMode,
clocks::{
pll::{configure_arm_pll, configure_io_pll, PllConfig},
Clocks,
pll::{PllConfig, configure_arm_pll, configure_io_pll},
},
ddr::{configure_ddr_for_ddr3, memtest, DdrClockSetupConfig},
ddr::{DdrClockSetupConfig, configure_ddr_for_ddr3, memtest},
gic, gpio, l2_cache,
prelude::*,
qspi,
time::Hertz,
uart::{ClockConfigRaw, Uart, UartConfig},
BootMode,
uart::{ClockConfig, Config, Uart},
};
use zynq7000_rt as _;
use zynq_boot_image::DestinationDevice;
use crate::ddr_cfg::{DDRC_CONFIG_ZEDBOARD_FULL_BUILDERS, DDRIOB_CONFIG_SET_ZEDBOARD};
@@ -80,7 +80,7 @@ pub fn main() -> ! {
PllConfig::new_from_target_clock(PS_CLK, IO_CLK).unwrap(),
);
let mut dp = zynq7000::PsPeripherals::take().unwrap();
let mut dp = zynq7000::Peripherals::take().unwrap();
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
let clocks = Clocks::new_from_regs(PS_CLK).unwrap();
@@ -88,12 +88,12 @@ pub fn main() -> ! {
let gpio_pins = gpio::GpioPins::new(dp.gpio);
let mio_pins = gpio_pins.mio;
// Set up the UART, we are logging with it.
let uart_clk_config = ClockConfigRaw::new_autocalc_with_error(clocks.io_clocks(), 115200)
let uart_clk_config = ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut uart = Uart::new_with_mio(
dp.uart_1,
UartConfig::new_with_clk_config(uart_clk_config),
Config::new_with_clk_config(uart_clk_config),
(mio_pins.mio48, mio_pins.mio49),
)
.unwrap();

View File

@@ -0,0 +1,14 @@
[package]
name = "zedboard-qspi-flasher"
version = "0.1.0"
edition = "2024"
[dependencies]
cortex-ar = { version = "0.2", git = "https://github.com/rust-embedded/cortex-ar.git", branch = "main" }
zynq7000-rt = { path = "../zynq7000-rt" }
zynq7000 = { path = "../zynq7000" }
zynq7000-hal = { path = "../zynq7000-hal" }
zedboard-bsp = { path = "../zedboard-bsp" }
embedded-io = "0.6"
embedded-hal = "1"
log = "0.4"

View File

@@ -0,0 +1,139 @@
//! QSPI flasher for the Zedboard. Assumes that external scripting took care of transferring
//! a boot binary to RAM.
#![no_std]
#![no_main]
use core::panic::PanicInfo;
use cortex_ar::asm::nop;
use embedded_hal::{delay::DelayNs as _, digital::StatefulOutputPin as _};
use embedded_io::Write as _;
use log::info;
use zedboard_bsp::qspi_spansion;
use zynq7000_hal::{
clocks, gpio, prelude::*, priv_tim, qspi, time::Hertz, uart, BootMode, LevelShifterConfig,
};
use zynq7000_rt as _;
// Define the clock frequency as a constant.
//
// Not required for the PAC mode, is required for clean delays in HAL mode.
const PS_CLOCK_FREQUENCY: Hertz = Hertz::from_raw(33_333_333);
#[allow(dead_code)]
const QSPI_DEV_COMBINATION: qspi::QspiDeviceCombination = qspi::QspiDeviceCombination {
vendor: qspi::QspiVendor::WinbondAndSpansion,
operating_mode: qspi::OperatingMode::FastReadQuadOutput,
two_devices: false,
};
/// Entry point (not called like a normal main function)
#[unsafe(no_mangle)]
pub extern "C" fn boot_core(cpu_id: u32) -> ! {
if cpu_id != 0 {
panic!("unexpected CPU ID {}", cpu_id);
}
main();
}
const INIT_STRING: &str = "-- Zynq 7000 Zedboard QSPI flasher --\n\r";
#[unsafe(export_name = "main")]
pub fn main() -> ! {
let periphs = zynq7000_hal::init(zynq7000_hal::Config {
init_l2_cache: true,
level_shifter_config: Some(LevelShifterConfig::EnableAll),
interrupt_config: Some(zynq7000_hal::InteruptConfig::AllInterruptsToCpu0),
})
.unwrap();
let clocks = clocks::Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
// Unwrap okay, we only call this once on core 0 here.
let mut timer = priv_tim::CpuPrivateTimer::take(clocks.arm_clocks()).unwrap();
let gpio_pins = gpio::GpioPins::new(periphs.gpio);
// Set up the UART, we are logging with it.
let uart_clk_config = uart::ClockConfig::new_autocalc_with_error(clocks.io_clocks(), 115200)
.unwrap()
.0;
let mut uart = uart::Uart::new_with_mio(
periphs.uart_1,
uart::Config::new_with_clk_config(uart_clk_config),
(gpio_pins.mio.mio48, gpio_pins.mio.mio49),
)
.unwrap();
uart.write_all(INIT_STRING.as_bytes()).unwrap();
// Safety: We are not multi-threaded yet.
unsafe {
zynq7000_hal::log::uart_blocking::init_unsafe_single_core(
uart,
log::LevelFilter::Trace,
false,
)
};
let boot_mode = BootMode::new_from_regs();
info!("Boot mode: {:?}", boot_mode);
let qspi_clock_config =
qspi::ClockConfig::calculate_with_loopback(qspi::SrcSelIo::IoPll, &clocks, 100.MHz())
.expect("QSPI clock calculation failed");
let qspi = qspi::Qspi::new_single_qspi_with_feedback(
periphs.qspi,
qspi_clock_config,
qspi::MODE_0,
qspi::IoType::LvCmos33,
gpio_pins.mio.mio1,
(
gpio_pins.mio.mio2,
gpio_pins.mio.mio3,
gpio_pins.mio.mio4,
gpio_pins.mio.mio5,
),
gpio_pins.mio.mio6,
gpio_pins.mio.mio8,
);
let qspi_io_mode = qspi.into_io_mode(false);
let _spansion_qspi = qspi_spansion::QspiSpansionS25Fl256SIoMode::new(qspi_io_mode, true);
let mut mio_led = gpio::Output::new_for_mio(gpio_pins.mio.mio7, gpio::PinState::Low);
loop {
mio_led.toggle().unwrap();
timer.delay_ms(500);
}
}
#[zynq7000_rt::irq]
pub fn irq_handler() {}
#[zynq7000_rt::exception(DataAbort)]
fn data_abort_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}
}
#[zynq7000_rt::exception(Undefined)]
fn undefined_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}
}
#[zynq7000_rt::exception(PrefetchAbort)]
fn prefetch_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}
}
/// Panic handler
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {
nop();
}
}

View File

@@ -226,13 +226,16 @@ pub enum ClockModuleId {
#[derive(Debug)]
pub struct DivisorZero(pub ClockModuleId);
#[derive(Debug)]
#[derive(Debug, thiserror::Error)]
pub enum ClockReadError {
/// The feedback value for the PLL clock output calculation is zero.
#[error("PLL feedback divisor is zero")]
PllFeedbackZero,
/// Detected a divisor of zero.
#[error("divisor is zero")]
DivisorZero(DivisorZero),
/// Detected a divisor that is not even.
/// Detected a divisor that is not even and should be.
#[error("divisor is not even")]
DivisorNotEven,
}

View File

@@ -15,7 +15,7 @@ pub fn configure_bitstream_non_secure(
if bitstream.is_empty() {
return Ok(());
}
let devcfg = unsafe { zynq7000::devcfg::DevCfg::new_mmio_fixed() };
let mut devcfg = unsafe { zynq7000::devcfg::DevCfg::new_mmio_fixed() };
devcfg.modify_control(|mut val| {
val.set_config_access_select(zynq7000::devcfg::PlConfigAccess::ConfigAccessPort);
val.set_access_port_select(zynq7000::devcfg::ConfigAccessPortSelect::Pcap);
@@ -54,10 +54,11 @@ pub fn configure_bitstream_non_secure(
});
devcfg.write_dma_source_addr(bitstream.as_ptr() as u32);
devcfg.write_dma_dest_addr(0xFFFF_FFFF);
devcfg.write_dma_source_len(bitstream.len());
devcfg.write_dma_dest_len(bitstream.len());
devcfg.write_dma_source_len(bitstream.len() as u32);
devcfg.write_dma_dest_len(bitstream.len() as u32);
while !devcfg.read_interrupt_status().dma_done() {}
// TODO: Check for errors.
while !devcfg.read_interrupt_status().pl_programming_done() {}
Ok(())
}

View File

@@ -14,13 +14,14 @@ extern crate alloc;
use slcr::Slcr;
use zynq7000::{
SpiClockPhase, SpiClockPolarity,
slcr::{BootModeRegister, BootPllConfig, LevelShifterRegister},
SpiClockPhase, SpiClockPolarity,
};
pub mod cache;
pub mod clocks;
pub mod ddr;
pub mod devcfg;
pub mod eth;
pub mod gic;
pub mod gpio;
@@ -30,7 +31,6 @@ pub mod l2_cache;
pub mod log;
pub mod prelude;
pub mod priv_tim;
pub mod devcfg;
pub mod qspi;
pub mod slcr;
pub mod spi;
@@ -38,6 +38,57 @@ pub mod time;
pub mod ttc;
pub mod uart;
pub use zynq7000 as pac;
pub use zynq7000::slcr::LevelShifterConfig;
#[derive(Debug, thiserror::Error)]
pub enum InitError {
#[error("peripheral singleton was already taken")]
PeripheralsAlreadyTaken,
}
#[derive(Debug)]
pub enum InteruptConfig {
/// GIC is configured to route all interrupts to CPU0. Suitable if the software handles all
/// the interrupts and only runs on CPU0.
AllInterruptsToCpu0,
}
#[derive(Debug)]
pub struct Config {
pub init_l2_cache: bool,
/// If this has some value, it will configure the level shifter between PS and PL.
pub level_shifter_config: Option<LevelShifterConfig>,
/// If this has some value, it configures the GIC to pre-defined settings.
pub interrupt_config: Option<InteruptConfig>,
}
/// Utility function to perform common initialization steps.
pub fn init(config: Config) -> Result<zynq7000::Peripherals, InitError> {
let mut periphs = zynq7000::Peripherals::take().ok_or(InitError::PeripheralsAlreadyTaken)?;
if config.init_l2_cache {
l2_cache::init_with_defaults(&mut periphs.l2c);
}
if let Some(config) = config.level_shifter_config {
configure_level_shifter(config);
}
if let Some(interrupt_config) = config.interrupt_config {
let mut gic = gic::GicConfigurator::new_with_init(periphs.gicc, periphs.gicd);
match interrupt_config {
InteruptConfig::AllInterruptsToCpu0 => {
gic.enable_all_interrupts();
gic.set_all_spi_interrupt_targets_cpu0();
}
}
gic.enable();
unsafe {
gic.enable_interrupts();
}
}
Ok(unsafe { zynq7000::Peripherals::steal() })
}
/// This enumeration encodes the various boot sources.
#[derive(Debug, Copy, Clone)]
pub enum BootDevice {
@@ -100,7 +151,7 @@ impl BootMode {
/// system (PS).
///
/// 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::LevelShifterConfig) {
pub fn configure_level_shifter(config: LevelShifterConfig) {
// Safety: We only manipulate the level shift registers.
unsafe {
Slcr::with(|slcr_unlocked| {
@@ -222,7 +273,6 @@ const fn spi_mode_const_to_cpol_cpha(
}
}
#[allow(dead_code)]
pub(crate) mod sealed {
pub trait Sealed {}
}

View File

@@ -7,13 +7,11 @@ use zynq7000::{
BaudRateDivisor, Config, InstructionCode, InterruptStatus, LoopbackMasterClockDelay,
SpiEnable,
},
slcr::{
clocks::{SingleCommonPeriphIoClockControl, SrcSelIo},
mio::Speed,
reset::QspiResetControl,
},
slcr::{clocks::SingleCommonPeriphIoClockControl, mio::Speed, reset::QspiResetControl},
};
pub use embedded_hal::spi::{MODE_0, MODE_1, MODE_2, MODE_3, Mode};
pub use zynq7000::slcr::clocks::SrcSelIo;
pub use zynq7000::slcr::mio::IoType;
use crate::{

View File

@@ -187,7 +187,7 @@ pub enum CharLen {
}
#[derive(Debug, Clone, Copy)]
pub struct ClockConfigRaw {
pub struct ClockConfig {
cd: u16,
bdiv: u8,
}
@@ -197,12 +197,12 @@ pub fn calculate_viable_configs(
mut uart_clk: Hertz,
clk_sel: ClockSelect,
target_baud: u32,
) -> alloc::vec::Vec<(ClockConfigRaw, f64)> {
) -> alloc::vec::Vec<(ClockConfig, f64)> {
let mut viable_cfgs = alloc::vec::Vec::new();
if clk_sel == ClockSelect::UartRefClkDiv8 {
uart_clk /= 8;
}
let mut current_clk_config = ClockConfigRaw::default();
let mut current_clk_config = ClockConfig::default();
for bdiv in 4..u8::MAX {
let cd =
round(uart_clk.raw() as f64 / ((bdiv as u32 + 1) as f64 * target_baud as f64)) as u64;
@@ -229,15 +229,15 @@ pub fn calculate_raw_baud_cfg_smallest_error(
mut uart_clk: Hertz,
clk_sel: ClockSelect,
target_baud: u32,
) -> Result<(ClockConfigRaw, f64), DivisorZero> {
) -> Result<(ClockConfig, f64), DivisorZero> {
if target_baud == 0 {
return Err(DivisorZero);
}
if clk_sel == ClockSelect::UartRefClkDiv8 {
uart_clk /= 8;
}
let mut current_clk_config = ClockConfigRaw::default();
let mut best_clk_config = ClockConfigRaw::default();
let mut current_clk_config = ClockConfig::default();
let mut best_clk_config = ClockConfig::default();
let mut smallest_error: f64 = 100.0;
for bdiv in 4..u8::MAX {
let cd =
@@ -258,13 +258,13 @@ pub fn calculate_raw_baud_cfg_smallest_error(
Ok((best_clk_config, smallest_error))
}
impl ClockConfigRaw {
impl ClockConfig {
#[inline]
pub const fn new(cd: u16, bdiv: u8) -> Result<Self, DivisorZero> {
if cd == 0 {
return Err(DivisorZero);
}
Ok(ClockConfigRaw { cd, bdiv })
Ok(ClockConfig { cd, bdiv })
}
/// Auto-calculates the best clock configuration settings for the target baudrate.
@@ -316,16 +316,16 @@ impl ClockConfigRaw {
}
}
impl Default for ClockConfigRaw {
impl Default for ClockConfig {
#[inline]
fn default() -> Self {
ClockConfigRaw::new(1, 0).unwrap()
ClockConfig::new(1, 0).unwrap()
}
}
#[derive(Debug)]
pub struct UartConfig {
clk_config: ClockConfigRaw,
pub struct Config {
clk_config: ClockConfig,
chmode: ChMode,
parity: Parity,
stopbits: Stopbits,
@@ -333,8 +333,8 @@ pub struct UartConfig {
clk_sel: ClockSelect,
}
impl UartConfig {
pub fn new_with_clk_config(clk_config: ClockConfigRaw) -> Self {
impl Config {
pub fn new_with_clk_config(clk_config: ClockConfig) -> Self {
Self::new(
clk_config,
ChMode::default(),
@@ -347,14 +347,14 @@ impl UartConfig {
#[inline]
pub const fn new(
clk_config: ClockConfigRaw,
clk_config: ClockConfig,
chmode: ChMode,
parity: Parity,
stopbits: Stopbits,
chrl: CharLen,
clk_sel: ClockSelect,
) -> Self {
UartConfig {
Config {
clk_config,
chmode,
parity,
@@ -365,7 +365,7 @@ impl UartConfig {
}
#[inline]
pub const fn raw_clk_config(&self) -> ClockConfigRaw {
pub const fn raw_clk_config(&self) -> ClockConfig {
self.clk_config
}
@@ -399,7 +399,7 @@ impl UartConfig {
pub struct Uart {
rx: Rx,
tx: Tx,
cfg: UartConfig,
cfg: Config,
}
#[derive(Debug, thiserror::Error)]
@@ -422,7 +422,7 @@ impl Uart {
///
/// A valid PL design which routes the UART pins through into the PL must be used for this to
/// work.
pub fn new_with_emio(uart: impl PsUart, cfg: UartConfig) -> Result<Uart, InvalidPsUart> {
pub fn new_with_emio(uart: impl PsUart, cfg: Config) -> Result<Uart, InvalidPsUart> {
if uart.uart_id().is_none() {
return Err(InvalidPsUart);
}
@@ -436,7 +436,7 @@ impl Uart {
/// This is the constructor to use the PS UART with MIO pins.
pub fn new_with_mio<TxPinI: TxPin, RxPinI: RxPin>(
uart: impl PsUart,
cfg: UartConfig,
cfg: Config,
pins: (TxPinI, RxPinI),
) -> Result<Self, UartConstructionError>
where
@@ -465,7 +465,7 @@ impl Uart {
pub fn new_generic_unchecked(
mut reg_block: MmioUart<'static>,
uart_id: UartId,
cfg: UartConfig,
cfg: Config,
) -> Uart {
let periph_sel = match uart_id {
UartId::Uart0 => crate::PeriphSelect::Uart0,
@@ -557,7 +557,7 @@ impl Uart {
}
#[inline]
pub const fn cfg(&self) -> &UartConfig {
pub const fn cfg(&self) -> &Config {
&self.cfg
}
@@ -657,7 +657,7 @@ mod tests {
#[test]
fn test_error_calc_0() {
// Baud 600
let cfg_0 = ClockConfigRaw::new(10417, 7).unwrap();
let cfg_0 = ClockConfig::new(10417, 7).unwrap();
let actual_baud_0 = cfg_0.actual_baud(REF_UART_CLK);
assert!(abs_diff_eq!(actual_baud_0, 599.980, epsilon = 0.01));
}
@@ -665,7 +665,7 @@ mod tests {
#[test]
fn test_error_calc_1() {
// Baud 9600
let cfg = ClockConfigRaw::new(81, 7).unwrap();
let cfg = ClockConfig::new(81, 7).unwrap();
let actual_baud = cfg.actual_baud(REF_UART_CLK_DIV_8);
assert!(abs_diff_eq!(actual_baud, 9645.061, epsilon = 0.01));
}
@@ -673,7 +673,7 @@ mod tests {
#[test]
fn test_error_calc_2() {
// Baud 9600
let cfg = ClockConfigRaw::new(651, 7).unwrap();
let cfg = ClockConfig::new(651, 7).unwrap();
let actual_baud = cfg.actual_baud(REF_UART_CLK);
assert!(abs_diff_eq!(actual_baud, 9600.614, epsilon = 0.01));
}
@@ -681,7 +681,7 @@ mod tests {
#[test]
fn test_error_calc_3() {
// Baud 28800
let cfg = ClockConfigRaw::new(347, 4).unwrap();
let cfg = ClockConfig::new(347, 4).unwrap();
let actual_baud = cfg.actual_baud(REF_UART_CLK);
assert!(abs_diff_eq!(actual_baud, 28818.44, epsilon = 0.01));
}
@@ -689,7 +689,7 @@ mod tests {
#[test]
fn test_error_calc_4() {
// Baud 921600
let cfg = ClockConfigRaw::new(9, 5).unwrap();
let cfg = ClockConfig::new(9, 5).unwrap();
let actual_baud = cfg.actual_baud(REF_UART_CLK);
assert!(abs_diff_eq!(actual_baud, 925925.92, epsilon = 0.01));
}
@@ -697,7 +697,7 @@ mod tests {
#[test]
fn test_best_calc_0() {
let result =
ClockConfigRaw::new_autocalc_with_raw_clk(REF_UART_CLK, ClockSelect::UartRefClk, 600);
ClockConfig::new_autocalc_with_raw_clk(REF_UART_CLK, ClockSelect::UartRefClk, 600);
assert!(result.is_ok());
let (cfg, _error) = result.unwrap();
assert_eq!(cfg.cd(), 499);

View File

@@ -254,8 +254,7 @@ pub struct Status {
#[bit(2, rw)]
efuse_sec_enable: bool,
#[bit(1, rw)]
efuse_jtag_disabled: bool
efuse_jtag_disabled: bool,
}
#[derive(derive_mmio::Mmio)]

View File

@@ -18,6 +18,7 @@ extern crate std;
pub const MPCORE_BASE_ADDR: usize = 0xF8F0_0000;
pub mod ddrc;
pub mod devcfg;
pub mod eth;
pub mod gic;
pub mod gpio;
@@ -27,12 +28,11 @@ pub mod l2_cache;
pub mod mpcore;
pub mod priv_tim;
pub mod qspi;
pub mod devcfg;
pub mod xadc;
pub mod slcr;
pub mod spi;
pub mod ttc;
pub mod uart;
pub mod xadc;
static PERIPHERALS_TAKEN: AtomicBool = AtomicBool::new(false);
@@ -41,7 +41,7 @@ static PERIPHERALS_TAKEN: AtomicBool = AtomicBool::new(false);
/// It is a singleton which exposes all peripherals supported by this crate.
/// The [`svd2rust` documentation](https://docs.rs/svd2rust/latest/svd2rust/#peripheral-api)
/// provides some more information about this.
pub struct PsPeripherals {
pub struct Peripherals {
pub gicc: gic::MmioGicCpuInterface<'static>,
pub gicd: gic::MmioGicDistributor<'static>,
pub l2c: l2_cache::MmioL2Cache<'static>,
@@ -64,7 +64,7 @@ pub struct PsPeripherals {
pub xadc: xadc::MmioXAdc<'static>,
}
impl PsPeripherals {
impl Peripherals {
/// Returns all supported processing system peripherals *once*.
pub fn take() -> Option<Self> {
let taken = PERIPHERALS_TAKEN.swap(true, Ordering::Relaxed);
@@ -101,6 +101,7 @@ impl PsPeripherals {
eth_1: eth::Ethernet::new_mmio_fixed_1(),
qspi: qspi::Qspi::new_mmio_fixed(),
devcfg: devcfg::DevCfg::new_mmio_fixed(),
xadc: xadc::XAdc::new_mmio_fixed(),
}
}
}