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"
version = "0.0.0"
dependencies = [
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libasync 0.0.0",
"libboard_zynq 0.0.0",
"libcortex_a9 0.0.0",
@ -50,8 +51,10 @@ dependencies = [
name = "libasync"
version = "0.0.0"
dependencies = [
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libboard_zynq 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)",
"smoltcp 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

View File

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

View File

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

View File

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

View File

@ -4,5 +4,33 @@ extern crate alloc;
pub mod task;
pub mod executor;
mod delay;
pub use delay::delay;
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)]
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"
#[derive(Clone, Copy)]
pub struct GlobalTimer {
regs: &'static mut mpcore::RegisterBlock,
regs: &'static mpcore::RegisterBlock,
}
impl GlobalTimer {
pub fn new() -> GlobalTimer {
let regs = mpcore::RegisterBlock::new();
let mut regs = mpcore::RegisterBlock::new();
Self::reset(&mut regs);
GlobalTimer { regs }
}
pub fn reset(&mut self) {
fn reset(regs: &mut mpcore::RegisterBlock) {
// Disable
self.regs.global_timer_control.write(
regs.global_timer_control.write(
mpcore::GlobalTimerControl::zeroed()
);
// Reset counters
self.regs.global_timer_counter0.write(
regs.global_timer_counter0.write(
mpcore::ValueRegister::zeroed()
);
self.regs.global_timer_counter1.write(
regs.global_timer_counter1.write(
mpcore::ValueRegister::zeroed()
);
// Start
self.regs.global_timer_control.write(
regs.global_timer_control.write(
mpcore::GlobalTimerControl::zeroed()
// maximum prescaler is still enough for millisecond
// precision while overflowing after centuries.
@ -68,23 +70,23 @@ impl GlobalTimer {
/// `embedded_hal::timer::CountDown`
pub fn countdown(&self) -> CountDown {
CountDown {
timer: &self,
timer: self.clone(),
timeout: Milliseconds(0),
}
}
}
#[derive(Clone)]
pub struct CountDown<'a> {
timer: &'a GlobalTimer,
pub struct CountDown {
timer: GlobalTimer,
timeout: Milliseconds,
}
impl embedded_hal::timer::CountDown for CountDown<'_> {
impl embedded_hal::timer::CountDown for CountDown {
type Time = Milliseconds;
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> {