forked from M-Labs/zynq-rs
timer::global: wrap us in Microseconds, impl embedded_hal blocking delay traits
This commit is contained in:
parent
7f45d10af3
commit
f36b1a610e
@ -10,7 +10,7 @@ mod regs;
|
|||||||
pub struct DevC {
|
pub struct DevC {
|
||||||
regs: &'static mut regs::RegisterBlock,
|
regs: &'static mut regs::RegisterBlock,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
count_down: super::timer::global::CountDown,
|
count_down: super::timer::global::CountDown<Milliseconds>,
|
||||||
timeout_ms: Milliseconds,
|
timeout_ms: Milliseconds,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ impl log::Log for Logger {
|
|||||||
if self.enabled(record.metadata()) {
|
if self.enabled(record.metadata()) {
|
||||||
let timestamp = unsafe {
|
let timestamp = unsafe {
|
||||||
GlobalTimer::get()
|
GlobalTimer::get()
|
||||||
}.get_us();
|
}.get_us().0;
|
||||||
let seconds = timestamp / 1_000_000;
|
let seconds = timestamp / 1_000_000;
|
||||||
let micros = timestamp % 1_000_000;
|
let micros = timestamp % 1_000_000;
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ use nb;
|
|||||||
/// Basic SDIO Struct with common low-level functions.
|
/// Basic SDIO Struct with common low-level functions.
|
||||||
pub struct SDIO {
|
pub struct SDIO {
|
||||||
regs: &'static mut regs::RegisterBlock,
|
regs: &'static mut regs::RegisterBlock,
|
||||||
count_down: super::timer::global::CountDown,
|
count_down: super::timer::global::CountDown<Milliseconds>,
|
||||||
input_clk_hz: u32,
|
input_clk_hz: u32,
|
||||||
card_type: CardType,
|
card_type: CardType,
|
||||||
card_detect: bool,
|
card_detect: bool,
|
||||||
|
@ -8,3 +8,18 @@ impl core::ops::Add for Milliseconds {
|
|||||||
Milliseconds(self.0 + rhs.0)
|
Milliseconds(self.0 + rhs.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
||||||
|
pub struct Microseconds(pub u64);
|
||||||
|
|
||||||
|
impl core::ops::Add for Microseconds {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, rhs: Self) -> Self::Output {
|
||||||
|
Microseconds(self.0 + rhs.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait TimeSource<U> {
|
||||||
|
fn now(&self) -> U;
|
||||||
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
|
use core::ops::Add;
|
||||||
use void::Void;
|
use void::Void;
|
||||||
use libregister::{RegisterR, RegisterW};
|
use libregister::{RegisterR, RegisterW};
|
||||||
use crate::{
|
use crate::{
|
||||||
clocks::Clocks,
|
clocks::Clocks,
|
||||||
mpcore,
|
mpcore,
|
||||||
time::Milliseconds,
|
time::{Milliseconds, Microseconds, TimeSource},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// "uptime"
|
/// "uptime"
|
||||||
@ -79,41 +80,82 @@ impl GlobalTimer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// read with high precision
|
/// read with high precision
|
||||||
pub fn get_us(&self) -> u64 {
|
pub fn get_us(&self) -> Microseconds {
|
||||||
let prescaler = self.regs.global_timer_control.read().prescaler() as u64;
|
let prescaler = self.regs.global_timer_control.read().prescaler() as u64;
|
||||||
let clocks = Clocks::get();
|
let clocks = Clocks::get();
|
||||||
|
|
||||||
1_000_000 * self.get_counter() * (prescaler + 1) / clocks.cpu_3x2x() as u64
|
Microseconds(1_000_000 * self.get_counter() * (prescaler + 1) / clocks.cpu_3x2x() as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return a handle that has implements
|
/// return a handle that has implements
|
||||||
/// `embedded_hal::timer::CountDown`
|
/// `embedded_hal::timer::CountDown`
|
||||||
pub fn countdown(&self) -> CountDown {
|
pub fn countdown<U>(&self) -> CountDown<U>
|
||||||
|
where
|
||||||
|
Self: TimeSource<U>,
|
||||||
|
{
|
||||||
CountDown {
|
CountDown {
|
||||||
timer: self.clone(),
|
timer: self.clone(),
|
||||||
timeout: Milliseconds(0),
|
timeout: self.now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
impl TimeSource<Milliseconds> for GlobalTimer {
|
||||||
pub struct CountDown {
|
fn now(&self) -> Milliseconds {
|
||||||
timer: GlobalTimer,
|
self.get_time()
|
||||||
timeout: Milliseconds,
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl embedded_hal::timer::CountDown for CountDown {
|
impl TimeSource<Microseconds> for GlobalTimer {
|
||||||
type Time = Milliseconds;
|
fn now(&self) -> Microseconds {
|
||||||
|
self.get_us()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct CountDown<U> {
|
||||||
|
timer: GlobalTimer,
|
||||||
|
timeout: U,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// embedded-hal async API
|
||||||
|
impl<U: Add<Output=U> + PartialOrd> embedded_hal::timer::CountDown for CountDown<U>
|
||||||
|
where
|
||||||
|
GlobalTimer: TimeSource<U>,
|
||||||
|
{
|
||||||
|
type Time = U;
|
||||||
|
|
||||||
fn start<T: Into<Self::Time>>(&mut self, count: T) {
|
fn start<T: Into<Self::Time>>(&mut self, count: T) {
|
||||||
self.timeout = self.timer.get_time() + count.into();
|
self.timeout = self.timer.now() + count.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wait(&mut self) -> nb::Result<(), Void> {
|
fn wait(&mut self) -> nb::Result<(), Void> {
|
||||||
if self.timer.get_time() <= self.timeout {
|
if self.timer.now() <= self.timeout {
|
||||||
Err(nb::Error::WouldBlock)
|
Err(nb::Error::WouldBlock)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// embedded-hal sync API
|
||||||
|
impl embedded_hal::blocking::delay::DelayMs<u64> for GlobalTimer {
|
||||||
|
fn delay_ms(&mut self, ms: u64) {
|
||||||
|
use embedded_hal::timer::CountDown;
|
||||||
|
|
||||||
|
let mut countdown = self.countdown::<Milliseconds>();
|
||||||
|
countdown.start(Milliseconds(ms));
|
||||||
|
nb::block!(countdown.wait()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// embedded-hal sync API
|
||||||
|
impl embedded_hal::blocking::delay::DelayUs<u64> for GlobalTimer {
|
||||||
|
fn delay_us(&mut self, us: u64) {
|
||||||
|
use embedded_hal::timer::CountDown;
|
||||||
|
|
||||||
|
let mut countdown = self.countdown::<Microseconds>();
|
||||||
|
countdown.start(Microseconds(us));
|
||||||
|
nb::block!(countdown.wait()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user