forked from M-Labs/zynq-rs
1
0
Fork 0

libasync, libboard_zynq: add block_async glue, make GlobalTimer sharable

This commit is contained in:
Astro 2020-04-25 01:18:49 +02:00
parent 8012573a8f
commit 88a2a2bc71
7 changed files with 72 additions and 20 deletions

3
Cargo.lock generated
View File

@ -38,6 +38,7 @@ dependencies = [
name = "experiments" name = "experiments"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libasync 0.0.0", "libasync 0.0.0",
"libboard_zynq 0.0.0", "libboard_zynq 0.0.0",
"libcortex_a9 0.0.0", "libcortex_a9 0.0.0",
@ -50,8 +51,10 @@ dependencies = [
name = "libasync" name = "libasync"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libboard_zynq 0.0.0", "libboard_zynq 0.0.0",
"libcortex_a9 0.0.0", "libcortex_a9 0.0.0",
"nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
"smoltcp 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "smoltcp 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]

View File

@ -12,6 +12,7 @@ default = ["target_zc706"]
[dependencies] [dependencies]
log = "0.4" log = "0.4"
embedded-hal = "0.2"
libregister = { path = "../libregister" } libregister = { path = "../libregister" }
libcortex_a9 = { path = "../libcortex_a9" } libcortex_a9 = { path = "../libcortex_a9" }
libboard_zynq = { path = "../libboard_zynq" } libboard_zynq = { path = "../libboard_zynq" }

View File

@ -6,6 +6,8 @@ extern crate alloc;
use core::{mem::transmute, task::Poll}; use core::{mem::transmute, task::Poll};
use alloc::{borrow::ToOwned, collections::BTreeMap, format}; use alloc::{borrow::ToOwned, collections::BTreeMap, format};
use log::info; use log::info;
use embedded_hal::timer::CountDown;
use libregister::RegisterR;
use libcortex_a9::{mutex::Mutex, sync_channel::{self, sync_channel}}; use libcortex_a9::{mutex::Mutex, sync_channel::{self, sync_channel}};
use libboard_zynq::{ use libboard_zynq::{
print, println, print, println,
@ -18,12 +20,13 @@ use libboard_zynq::{
socket::SocketSet, socket::SocketSet,
socket::{TcpSocket, TcpSocketBuffer}, socket::{TcpSocket, TcpSocketBuffer},
}, },
time::Milliseconds,
}; };
use libsupport_zynq::{ use libsupport_zynq::{
ram, alloc::{vec, vec::Vec}, ram, alloc::{vec, vec::Vec},
boot, boot,
}; };
use libasync::{smoltcp::{Sockets, TcpStream}, task}; use libasync::{delay, smoltcp::{Sockets, TcpStream}, task};
mod ps7_init; mod ps7_init;
@ -39,10 +42,7 @@ pub fn main_core0() {
libsupport_zynq::logger::init().unwrap(); libsupport_zynq::logger::init().unwrap();
log::set_max_level(log::LevelFilter::Trace); log::set_max_level(log::LevelFilter::Trace);
{
use libregister::RegisterR;
info!("Boot mode: {:?}", zynq::slcr::RegisterBlock::new().boot_mode.read().boot_mode_pins()); info!("Boot mode: {:?}", zynq::slcr::RegisterBlock::new().boot_mode.read().boot_mode_pins());
}
#[cfg(feature = "target_zc706")] #[cfg(feature = "target_zc706")]
const CPU_FREQ: u32 = 800_000_000; const CPU_FREQ: u32 = 800_000_000;
@ -72,6 +72,8 @@ pub fn main_core0() {
} }
let mut flash = flash.stop(); let mut flash = flash.stop();
let timer = libboard_zynq::timer::GlobalTimer::new();
let mut ddr = zynq::ddr::DdrRam::new(); let mut ddr = zynq::ddr::DdrRam::new();
#[cfg(not(feature = "target_zc706"))] #[cfg(not(feature = "target_zc706"))]
ddr.memtest(); ddr.memtest();
@ -262,10 +264,16 @@ pub fn main_core0() {
} }
}); });
let mut time = 0u32; let mut countdown = timer.countdown();
task::spawn(async move {
loop {
delay(&mut countdown, Milliseconds(1000)).await;
println!("time: {} ms", timer.get_time().0);
}
});
Sockets::run(&mut iface, || { Sockets::run(&mut iface, || {
time += 1; Instant::from_millis(timer.get_time().0 as i64)
Instant::from_millis(time)
}) })
} }

View File

@ -8,6 +8,8 @@ edition = "2018"
[dependencies] [dependencies]
#futures = { version = "0.3", default-features = false } #futures = { version = "0.3", default-features = false }
pin-utils = "0.1.0-alpha.4" pin-utils = "0.1.0-alpha.4"
embedded-hal = "0.2"
nb = "0.1"
libcortex_a9 = { path = "../libcortex_a9" } libcortex_a9 = { path = "../libcortex_a9" }
[dependencies.smoltcp] [dependencies.smoltcp]

View File

@ -4,5 +4,33 @@ extern crate alloc;
pub mod task; pub mod task;
pub mod executor; pub mod executor;
mod delay;
pub use delay::delay;
pub mod smoltcp; pub mod smoltcp;
/// Reexport for macro use
pub use nb;
/// The `nb` crate's `block!` macro adapted for async fns
///
/// Call `.await` on the result!
#[macro_export]
macro_rules! block_async {
($e:expr) => {
async {
loop {
#[allow(unreachable_patterns)]
match $e {
Err($crate::nb::Error::Other(e)) => {
#[allow(unreachable_code)]
break Err(e)
},
Err($crate::nb::Error::WouldBlock) =>
$crate::task::r#yield().await,
Ok(x) => break Ok(x),
}
}
}
}
}

View File

@ -1,2 +1,10 @@
#[derive(Debug, Clone, PartialEq, PartialOrd)] #[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct Milliseconds(pub u64); pub struct Milliseconds(pub u64);
impl core::ops::Add for Milliseconds {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Milliseconds(self.0 + rhs.0)
}
}

View File

@ -7,32 +7,34 @@ use crate::{
}; };
/// "uptime" /// "uptime"
#[derive(Clone, Copy)]
pub struct GlobalTimer { pub struct GlobalTimer {
regs: &'static mut mpcore::RegisterBlock, regs: &'static mpcore::RegisterBlock,
} }
impl GlobalTimer { impl GlobalTimer {
pub fn new() -> GlobalTimer { pub fn new() -> GlobalTimer {
let regs = mpcore::RegisterBlock::new(); let mut regs = mpcore::RegisterBlock::new();
Self::reset(&mut regs);
GlobalTimer { regs } GlobalTimer { regs }
} }
pub fn reset(&mut self) { fn reset(regs: &mut mpcore::RegisterBlock) {
// Disable // Disable
self.regs.global_timer_control.write( regs.global_timer_control.write(
mpcore::GlobalTimerControl::zeroed() mpcore::GlobalTimerControl::zeroed()
); );
// Reset counters // Reset counters
self.regs.global_timer_counter0.write( regs.global_timer_counter0.write(
mpcore::ValueRegister::zeroed() mpcore::ValueRegister::zeroed()
); );
self.regs.global_timer_counter1.write( regs.global_timer_counter1.write(
mpcore::ValueRegister::zeroed() mpcore::ValueRegister::zeroed()
); );
// Start // Start
self.regs.global_timer_control.write( regs.global_timer_control.write(
mpcore::GlobalTimerControl::zeroed() mpcore::GlobalTimerControl::zeroed()
// maximum prescaler is still enough for millisecond // maximum prescaler is still enough for millisecond
// precision while overflowing after centuries. // precision while overflowing after centuries.
@ -68,23 +70,23 @@ impl GlobalTimer {
/// `embedded_hal::timer::CountDown` /// `embedded_hal::timer::CountDown`
pub fn countdown(&self) -> CountDown { pub fn countdown(&self) -> CountDown {
CountDown { CountDown {
timer: &self, timer: self.clone(),
timeout: Milliseconds(0), timeout: Milliseconds(0),
} }
} }
} }
#[derive(Clone)] #[derive(Clone)]
pub struct CountDown<'a> { pub struct CountDown {
timer: &'a GlobalTimer, timer: GlobalTimer,
timeout: Milliseconds, timeout: Milliseconds,
} }
impl embedded_hal::timer::CountDown for CountDown<'_> { impl embedded_hal::timer::CountDown for CountDown {
type Time = Milliseconds; type Time = Milliseconds;
fn start<T: Into<Self::Time>>(&mut self, count: T) { fn start<T: Into<Self::Time>>(&mut self, count: T) {
self.timeout = count.into(); self.timeout = self.timer.get_time() + count.into();
} }
fn wait(&mut self) -> nb::Result<(), Void> { fn wait(&mut self) -> nb::Result<(), Void> {