Compare commits
No commits in common. "88a2a2bc7155722b6f69a1d4ca3fb09c6fb00adf" and "04c47b9bdb065eceb111b60f064f165882360771" have entirely different histories.
88a2a2bc71
...
04c47b9bdb
|
@ -38,7 +38,6 @@ 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",
|
||||||
|
@ -51,10 +50,8 @@ 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)",
|
||||||
]
|
]
|
||||||
|
@ -69,7 +66,6 @@ dependencies = [
|
||||||
"libregister 0.0.0",
|
"libregister 0.0.0",
|
||||||
"nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nb 0.1.2 (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)",
|
||||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ 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,8 +6,6 @@ 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,
|
||||||
|
@ -20,13 +18,12 @@ 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::{delay, smoltcp::{Sockets, TcpStream}, task};
|
use libasync::{smoltcp::{Sockets, TcpStream}, task};
|
||||||
|
|
||||||
mod ps7_init;
|
mod ps7_init;
|
||||||
|
|
||||||
|
@ -42,7 +39,10 @@ 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,8 +72,6 @@ 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();
|
||||||
|
@ -264,16 +262,10 @@ pub fn main_core0() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut countdown = timer.countdown();
|
let mut time = 0u32;
|
||||||
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, || {
|
||||||
Instant::from_millis(timer.get_time().0 as i64)
|
time += 1;
|
||||||
|
Instant::from_millis(time)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,6 @@ 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,33 +4,5 @@ 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),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ volatile-register = "0.2"
|
||||||
bit_field = "0.10"
|
bit_field = "0.10"
|
||||||
embedded-hal = "0.2"
|
embedded-hal = "0.2"
|
||||||
nb = "0.1"
|
nb = "0.1"
|
||||||
void = { version = "1", default-features = false }
|
|
||||||
libregister = { path = "../libregister" }
|
libregister = { path = "../libregister" }
|
||||||
libcortex_a9 = { path = "../libcortex_a9" }
|
libcortex_a9 = { path = "../libcortex_a9" }
|
||||||
|
|
||||||
|
|
|
@ -15,5 +15,3 @@ pub mod ddr;
|
||||||
pub mod mpcore;
|
pub mod mpcore;
|
||||||
pub mod flash;
|
pub mod flash;
|
||||||
pub mod dmac;
|
pub mod dmac;
|
||||||
pub mod time;
|
|
||||||
pub mod timer;
|
|
||||||
|
|
|
@ -18,34 +18,6 @@ pub struct RegisterBlock {
|
||||||
reserved1: [u32; 2],
|
reserved1: [u32; 2],
|
||||||
pub scu_access_control: RW<u32>,
|
pub scu_access_control: RW<u32>,
|
||||||
pub scu_non_secure_access_control: RW<u32>,
|
pub scu_non_secure_access_control: RW<u32>,
|
||||||
reserved2: [u32; 42],
|
|
||||||
pub iccicr: RW<u32>,
|
|
||||||
pub iccpmw: RW<u32>,
|
|
||||||
pub iccbpr: RW<u32>,
|
|
||||||
pub icciar: RW<u32>,
|
|
||||||
pub icceoir: RW<u32>,
|
|
||||||
pub iccrpr: RW<u32>,
|
|
||||||
pub icchpir: RW<u32>,
|
|
||||||
pub iccabpr: RW<u32>,
|
|
||||||
reserved3: [u32; 55],
|
|
||||||
pub iccidr: RW<u32>,
|
|
||||||
pub global_timer_counter0: ValueRegister,
|
|
||||||
pub global_timer_counter1: ValueRegister,
|
|
||||||
pub global_timer_control: GlobalTimerControl,
|
|
||||||
pub global_timer_interrupt_status: RW<u32>,
|
|
||||||
pub comparator_value0: ValueRegister,
|
|
||||||
pub comparator_value1: ValueRegister,
|
|
||||||
pub auto_increment: ValueRegister,
|
|
||||||
reserved4: [u32; 249],
|
|
||||||
pub private_timer_load: ValueRegister,
|
|
||||||
pub private_timer_counter: ValueRegister,
|
|
||||||
pub private_timer_control: RW<u32>,
|
|
||||||
pub private_timer_interrupt_status: RW<u32>,
|
|
||||||
reserved5: [u32; 4],
|
|
||||||
pub watchdog_load: ValueRegister,
|
|
||||||
pub watchdog_counter: ValueRegister,
|
|
||||||
pub watchdog_control: RW<u32>,
|
|
||||||
pub watchdog_interrupt_status: RW<u32>,
|
|
||||||
// there is plenty more (unimplemented)
|
// there is plenty more (unimplemented)
|
||||||
}
|
}
|
||||||
register_at!(RegisterBlock, 0xF8F00000, new);
|
register_at!(RegisterBlock, 0xF8F00000, new);
|
||||||
|
@ -87,13 +59,3 @@ impl ScuInvalidate {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
register!(value_register, ValueRegister, RW, u32);
|
|
||||||
register_bits!(value_register, value, u32, 0, 31);
|
|
||||||
|
|
||||||
register!(global_timer_control, GlobalTimerControl, RW, u32);
|
|
||||||
register_bits!(global_timer_control, prescaler, u16, 8, 15);
|
|
||||||
register_bit!(global_timer_control, auto_increment_mode, 3);
|
|
||||||
register_bit!(global_timer_control, irq_enable, 2);
|
|
||||||
register_bit!(global_timer_control, comp_enablea, 1);
|
|
||||||
register_bit!(global_timer_control, timer_enable, 0);
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
#[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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,99 +0,0 @@
|
||||||
use void::Void;
|
|
||||||
use libregister::{RegisterR, RegisterW};
|
|
||||||
use crate::{
|
|
||||||
clocks::Clocks,
|
|
||||||
mpcore,
|
|
||||||
time::Milliseconds,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// "uptime"
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub struct GlobalTimer {
|
|
||||||
regs: &'static mpcore::RegisterBlock,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GlobalTimer {
|
|
||||||
pub fn new() -> GlobalTimer {
|
|
||||||
let mut regs = mpcore::RegisterBlock::new();
|
|
||||||
Self::reset(&mut regs);
|
|
||||||
GlobalTimer { regs }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reset(regs: &mut mpcore::RegisterBlock) {
|
|
||||||
// Disable
|
|
||||||
regs.global_timer_control.write(
|
|
||||||
mpcore::GlobalTimerControl::zeroed()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Reset counters
|
|
||||||
regs.global_timer_counter0.write(
|
|
||||||
mpcore::ValueRegister::zeroed()
|
|
||||||
);
|
|
||||||
regs.global_timer_counter1.write(
|
|
||||||
mpcore::ValueRegister::zeroed()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Start
|
|
||||||
regs.global_timer_control.write(
|
|
||||||
mpcore::GlobalTimerControl::zeroed()
|
|
||||||
// maximum prescaler is still enough for millisecond
|
|
||||||
// precision while overflowing after centuries.
|
|
||||||
.prescaler(255)
|
|
||||||
.auto_increment_mode(true)
|
|
||||||
.timer_enable(true)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// read the raw counter value
|
|
||||||
pub fn get_counter(&self) -> u64 {
|
|
||||||
loop {
|
|
||||||
let c1_pre = self.regs.global_timer_counter1.read().value();
|
|
||||||
let c0 = self.regs.global_timer_counter0.read().value();
|
|
||||||
let c1_post = self.regs.global_timer_counter1.read().value();
|
|
||||||
|
|
||||||
if c1_pre == c1_post {
|
|
||||||
return ((c1_pre as u64) << 32) | (c0 as u64);
|
|
||||||
}
|
|
||||||
// retry if c0 has wrapped while reading.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// read and convert to time
|
|
||||||
pub fn get_time(&self) -> Milliseconds {
|
|
||||||
let prescaler = self.regs.global_timer_control.read().prescaler() as u64;
|
|
||||||
let clocks = Clocks::get();
|
|
||||||
|
|
||||||
Milliseconds(self.get_counter() * (prescaler + 1) / (clocks.cpu_3x2x() as u64 / 1000))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return a handle that has implements
|
|
||||||
/// `embedded_hal::timer::CountDown`
|
|
||||||
pub fn countdown(&self) -> CountDown {
|
|
||||||
CountDown {
|
|
||||||
timer: self.clone(),
|
|
||||||
timeout: Milliseconds(0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct CountDown {
|
|
||||||
timer: GlobalTimer,
|
|
||||||
timeout: Milliseconds,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl embedded_hal::timer::CountDown for CountDown {
|
|
||||||
type Time = Milliseconds;
|
|
||||||
|
|
||||||
fn start<T: Into<Self::Time>>(&mut self, count: T) {
|
|
||||||
self.timeout = self.timer.get_time() + count.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn wait(&mut self) -> nb::Result<(), Void> {
|
|
||||||
if self.timer.get_time() < self.timeout {
|
|
||||||
Err(nb::Error::WouldBlock)
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
pub mod global;
|
|
||||||
pub use global::GlobalTimer;
|
|
|
@ -1,5 +1,4 @@
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use void::Void;
|
|
||||||
|
|
||||||
use libregister::*;
|
use libregister::*;
|
||||||
use super::slcr;
|
use super::slcr;
|
||||||
|
@ -210,9 +209,9 @@ impl fmt::Write for Uart {
|
||||||
|
|
||||||
/// embedded_hal async API
|
/// embedded_hal async API
|
||||||
impl embedded_hal::serial::Write<u8> for Uart {
|
impl embedded_hal::serial::Write<u8> for Uart {
|
||||||
type Error = Void;
|
type Error = ();
|
||||||
|
|
||||||
fn write(&mut self, b: u8) -> nb::Result<(), Void> {
|
fn write(&mut self, b: u8) -> nb::Result<(), ()> {
|
||||||
if self.tx_fifo_full() {
|
if self.tx_fifo_full() {
|
||||||
Err(nb::Error::WouldBlock)
|
Err(nb::Error::WouldBlock)
|
||||||
} else {
|
} else {
|
||||||
|
@ -221,7 +220,7 @@ impl embedded_hal::serial::Write<u8> for Uart {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> nb::Result<(), Void> {
|
fn flush(&mut self) -> nb::Result<(), ()> {
|
||||||
if self.tx_fifo_empty() {
|
if self.tx_fifo_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue