forked from M-Labs/zynq-rs
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"
|
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)",
|
||||||
]
|
]
|
||||||
|
|
|
@ -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" }
|
||||||
|
|
|
@ -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)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
Loading…
Reference in New Issue