libasync, libboard_zynq: add block_async glue, make GlobalTimer sharable
This commit is contained in:
parent
8012573a8f
commit
88a2a2bc71
|
@ -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)",
|
||||
]
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
Loading…
Reference in New Issue