more cleanup
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:
14
README.md
14
README.md
@@ -8,25 +8,25 @@ family of SoCs.
|
||||
|
||||
This project contains the following crates:
|
||||
|
||||
## Zynq Workspace
|
||||
## [Zynq Workspace](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq)
|
||||
|
||||
This workspace contains libraries and application which can only be run on the target system.
|
||||
|
||||
- The [`zynq7000-rt`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq7000-rt)
|
||||
- The [`zynq7000-rt`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zynq7000-rt)
|
||||
run-time crate containing basic low-level startup code necessary to boot a Rust app on the
|
||||
Zynq7000.
|
||||
- The [`zynq7000`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq7000) PAC
|
||||
- The [`zynq7000`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zynq7000) PAC
|
||||
crate containing basic low-level register definitions.
|
||||
- The [`zynq7000-mmu`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq7000-hal)
|
||||
- The [`zynq7000-mmu`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zynq7000-hal)
|
||||
crate containing common MMU abstractions used by both the HAL and the run-time crate.
|
||||
- The [`zynq7000-hal`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq7000-hal)
|
||||
- The [`zynq7000-hal`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zynq7000-hal)
|
||||
HAL crate containing higher-level abstractions on top of the PAC register crate.
|
||||
- The [`zynq7000-embassy`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq7000-embassy)
|
||||
- The [`zynq7000-embassy`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zynq7000-embassy)
|
||||
crate containing support for running the embassy-rs asynchronous run-time.
|
||||
|
||||
It also contains the following helper crates:
|
||||
|
||||
- The [`examples`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/examples)
|
||||
- The [`examples`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/examples)
|
||||
folder contains various example applications crates using the HAL and the PAC.
|
||||
This folder also contains dedicated example applications using the
|
||||
[`embassy`](https://github.com/embassy-rs/embassy) native Rust RTOS.
|
||||
|
||||
@@ -149,7 +149,7 @@ fn generate_ddrc_config(
|
||||
let ctrl_reg6 = reg_to_values.val_as_token("CTRL Reg 6", 0xF800_607C);
|
||||
let che_t_zq = reg_to_values.val_as_token("CHE T ZQ", 0xF800_60A4);
|
||||
let che_t_zq_short_interval_reg =
|
||||
reg_to_values.val_as_token("CHE T ZQ Short Interval", 0xF800_60A4);
|
||||
reg_to_values.val_as_token("CHE T ZQ Short Interval", 0xF800_60A8);
|
||||
let deep_powerdown = reg_to_values.val_as_token("Deep Powerdown", 0xF800_60AC);
|
||||
let reg_2c = reg_to_values.val_as_token("Reg 2C", 0xF800_60B0);
|
||||
let reg_2d = reg_to_values.val_as_token("Reg 2D", 0xF800_60B4);
|
||||
|
||||
123
zynq/examples/embassy/src/bin/embassy-hello.rs
Normal file
123
zynq/examples/embassy/src/bin/embassy-hello.rs
Normal file
@@ -0,0 +1,123 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
use cortex_ar::asm::nop;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_time::{Duration, Ticker};
|
||||
use embedded_hal::digital::StatefulOutputPin;
|
||||
use embedded_io::Write;
|
||||
use log::{error, info};
|
||||
use zynq7000_hal::{BootMode, InteruptConfig, clocks, gic, gpio, gtc, time::Hertz, uart};
|
||||
|
||||
use zynq7000_rt as _;
|
||||
|
||||
// Define the clock frequency as a constant
|
||||
const PS_CLOCK_FREQUENCY: Hertz = Hertz::from_raw(33_333_300);
|
||||
|
||||
/// 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();
|
||||
}
|
||||
|
||||
#[embassy_executor::main]
|
||||
#[unsafe(export_name = "main")]
|
||||
async fn main(_spawner: Spawner) -> ! {
|
||||
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 = 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 = 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),
|
||||
(mio_pins.mio48, mio_pins.mio49),
|
||||
)
|
||||
.unwrap();
|
||||
uart.write_all(b"-- Zynq 7000 Embassy Hello World --\n\r")
|
||||
.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 mut ticker = Ticker::every(Duration::from_millis(1000));
|
||||
let mut led = gpio::Output::new_for_mio(mio_pins.mio7, gpio::PinState::Low);
|
||||
loop {
|
||||
info!("Hello, world!");
|
||||
led.toggle().unwrap();
|
||||
ticker.next().await;
|
||||
}
|
||||
}
|
||||
|
||||
#[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() {
|
||||
gic::Interrupt::Sgi(_) => (),
|
||||
gic::Interrupt::Ppi(ppi_interrupt) => {
|
||||
if ppi_interrupt == zynq7000_hal::gic::PpiInterrupt::GlobalTimer {
|
||||
unsafe {
|
||||
zynq7000_embassy::on_interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
gic::Interrupt::Spi(_spi_interrupt) => (),
|
||||
gic::Interrupt::Invalid(_) => (),
|
||||
gic::Interrupt::Spurious => (),
|
||||
}
|
||||
gic_helper.end_of_interrupt(irq_info);
|
||||
}
|
||||
|
||||
#[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) -> ! {
|
||||
error!("Panic: {info:?}");
|
||||
loop {}
|
||||
}
|
||||
@@ -6,9 +6,8 @@ use cortex_ar::asm::nop;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_time::{Duration, Ticker};
|
||||
use embedded_hal::digital::StatefulOutputPin;
|
||||
use embedded_io::Write;
|
||||
use log::{error, info};
|
||||
use zynq7000_hal::{BootMode, InteruptConfig, clocks, gic, gpio, gtc, time::Hertz, uart};
|
||||
use log::error;
|
||||
use zynq7000_hal::{InteruptConfig, clocks, gic, gpio, gtc, time::Hertz};
|
||||
|
||||
use zynq7000_rt as _;
|
||||
|
||||
@@ -38,37 +37,10 @@ async fn main(_spawner: Spawner) -> ! {
|
||||
// Set up global timer counter and embassy time driver.
|
||||
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 = 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),
|
||||
(mio_pins.mio48, mio_pins.mio49),
|
||||
)
|
||||
.unwrap();
|
||||
uart.write_all(b"-- Zynq 7000 Embassy Hello World --\n\r")
|
||||
.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 mut ticker = Ticker::every(Duration::from_millis(1000));
|
||||
let mut led = gpio::Output::new_for_mio(mio_pins.mio7, gpio::PinState::Low);
|
||||
loop {
|
||||
info!("Hello, world!");
|
||||
led.toggle().unwrap();
|
||||
ticker.next().await;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "blinky"
|
||||
name = "simple"
|
||||
version = "0.1.0"
|
||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||
edition = "2024"
|
||||
|
||||
103
zynq/examples/simple/src/bin/blinky.rs
Normal file
103
zynq/examples/simple/src/bin/blinky.rs
Normal file
@@ -0,0 +1,103 @@
|
||||
//! Simple blinky app, showing a PAC variant and a HAL variant.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
use cortex_ar::asm::nop;
|
||||
use embedded_hal::{delay::DelayNs, digital::StatefulOutputPin};
|
||||
use zynq7000::Peripherals;
|
||||
use zynq7000_hal::{
|
||||
clocks::Clocks,
|
||||
gpio::{Output, PinState, mio},
|
||||
l2_cache,
|
||||
priv_tim::CpuPrivateTimer,
|
||||
time::Hertz,
|
||||
};
|
||||
use zynq7000_rt as _;
|
||||
|
||||
pub const LIB: Lib = Lib::Hal;
|
||||
|
||||
/// One user LED is MIO7
|
||||
const ZEDBOARD_LED_MASK: u32 = 1 << 7;
|
||||
|
||||
// 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);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Lib {
|
||||
Pac,
|
||||
Hal,
|
||||
}
|
||||
|
||||
/// 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();
|
||||
}
|
||||
|
||||
#[unsafe(export_name = "main")]
|
||||
pub fn main() -> ! {
|
||||
l2_cache::init_with_defaults(&mut unsafe { zynq7000::l2_cache::L2Cache::new_mmio_fixed() });
|
||||
match LIB {
|
||||
Lib::Pac => {
|
||||
let mut gpio = unsafe { zynq7000::gpio::Gpio::new_mmio_fixed() };
|
||||
gpio.bank_0().modify_dirm(|v| v | ZEDBOARD_LED_MASK);
|
||||
gpio.bank_0().modify_out_en(|v| v | ZEDBOARD_LED_MASK);
|
||||
loop {
|
||||
gpio.modify_out_0(|v| v ^ ZEDBOARD_LED_MASK);
|
||||
for _ in 0..5_000_000 {
|
||||
nop();
|
||||
}
|
||||
}
|
||||
}
|
||||
Lib::Hal => {
|
||||
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();
|
||||
let mio_pins = mio::Pins::new(dp.gpio);
|
||||
let mut led = Output::new_for_mio(mio_pins.mio7, PinState::High);
|
||||
loop {
|
||||
led.toggle().unwrap();
|
||||
cpu_tim.delay_ms(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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();
|
||||
}
|
||||
}
|
||||
@@ -4,33 +4,8 @@
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
use cortex_ar::asm::nop;
|
||||
use embedded_hal::{delay::DelayNs, digital::StatefulOutputPin};
|
||||
use zynq7000::Peripherals;
|
||||
use zynq7000_hal::{
|
||||
clocks::Clocks,
|
||||
gpio::{Output, PinState, mio},
|
||||
l2_cache,
|
||||
priv_tim::CpuPrivateTimer,
|
||||
time::Hertz,
|
||||
};
|
||||
use zynq7000_rt as _;
|
||||
|
||||
pub const LIB: Lib = Lib::Hal;
|
||||
|
||||
/// One user LED is MIO7
|
||||
const ZEDBOARD_LED_MASK: u32 = 1 << 7;
|
||||
|
||||
// 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);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Lib {
|
||||
Pac,
|
||||
Hal,
|
||||
}
|
||||
|
||||
/// Entry point (not called like a normal main function)
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
||||
@@ -42,31 +17,8 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
||||
|
||||
#[unsafe(export_name = "main")]
|
||||
pub fn main() -> ! {
|
||||
l2_cache::init_with_defaults(&mut unsafe { zynq7000::l2_cache::L2Cache::new_mmio_fixed() });
|
||||
match LIB {
|
||||
Lib::Pac => {
|
||||
let mut gpio = unsafe { zynq7000::gpio::Gpio::new_mmio_fixed() };
|
||||
gpio.bank_0().modify_dirm(|v| v | ZEDBOARD_LED_MASK);
|
||||
gpio.bank_0().modify_out_en(|v| v | ZEDBOARD_LED_MASK);
|
||||
loop {
|
||||
gpio.modify_out_0(|v| v ^ ZEDBOARD_LED_MASK);
|
||||
for _ in 0..5_000_000 {
|
||||
nop();
|
||||
}
|
||||
}
|
||||
}
|
||||
Lib::Hal => {
|
||||
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();
|
||||
let mio_pins = mio::Pins::new(dp.gpio);
|
||||
let mut led = Output::new_for_mio(mio_pins.mio7, PinState::High);
|
||||
loop {
|
||||
led.toggle().unwrap();
|
||||
cpu_tim.delay_ms(1000);
|
||||
}
|
||||
}
|
||||
loop {
|
||||
cortex_ar::asm::nop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,4 +98,3 @@ pub const DDRC_CONFIG_ZEDBOARD: DdrcConfigSet = DdrcConfigSet {
|
||||
lpddr_ctrl_2: regs::LpddrControl2::new_with_raw_value(0x00005125),
|
||||
lpddr_ctrl_3: regs::LpddrControl3::new_with_raw_value(0x000012a8),
|
||||
};
|
||||
|
||||
|
||||
@@ -13,4 +13,3 @@ pub const DDRIOB_CONFIG_SET_ZEDBOARD: DdriobConfigSet = DdriobConfigSet {
|
||||
diff1: regs::DdriobConfig::new_with_raw_value(0x00000674),
|
||||
clock: regs::DdriobConfig::new_with_raw_value(0x00000600),
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
pub const DDRC_BASE_ADDR: usize = 0xF800_6000;
|
||||
|
||||
pub mod regs {
|
||||
use arbitrary_int::{u2, u3, u4, u5, u6, u7, u9, u10, u11, u12, u20};
|
||||
pub use crate::slcr::ddriob::DdriobConfig;
|
||||
use arbitrary_int::{u2, u3, u4, u5, u6, u7, u9, u10, u11, u12, u20};
|
||||
|
||||
#[bitbybit::bitenum(u2)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
|
||||
Reference in New Issue
Block a user