From f36b1a610e7886be185cb6f1c059da7cbd9a46ca Mon Sep 17 00:00:00 2001 From: Astro Date: Wed, 22 Jul 2020 23:41:15 +0200 Subject: [PATCH] timer::global: wrap us in Microseconds, impl embedded_hal blocking delay traits --- libboard_zynq/src/devc/mod.rs | 2 +- libboard_zynq/src/logger.rs | 2 +- libboard_zynq/src/sdio/mod.rs | 2 +- libboard_zynq/src/time.rs | 15 +++++++ libboard_zynq/src/timer/global.rs | 68 +++++++++++++++++++++++++------ 5 files changed, 73 insertions(+), 16 deletions(-) diff --git a/libboard_zynq/src/devc/mod.rs b/libboard_zynq/src/devc/mod.rs index d56755f..27eca30 100644 --- a/libboard_zynq/src/devc/mod.rs +++ b/libboard_zynq/src/devc/mod.rs @@ -10,7 +10,7 @@ mod regs; pub struct DevC { regs: &'static mut regs::RegisterBlock, enabled: bool, - count_down: super::timer::global::CountDown, + count_down: super::timer::global::CountDown, timeout_ms: Milliseconds, } diff --git a/libboard_zynq/src/logger.rs b/libboard_zynq/src/logger.rs index 8d633df..28bbcf8 100644 --- a/libboard_zynq/src/logger.rs +++ b/libboard_zynq/src/logger.rs @@ -19,7 +19,7 @@ impl log::Log for Logger { if self.enabled(record.metadata()) { let timestamp = unsafe { GlobalTimer::get() - }.get_us(); + }.get_us().0; let seconds = timestamp / 1_000_000; let micros = timestamp % 1_000_000; diff --git a/libboard_zynq/src/sdio/mod.rs b/libboard_zynq/src/sdio/mod.rs index 85b412d..cc69d1c 100644 --- a/libboard_zynq/src/sdio/mod.rs +++ b/libboard_zynq/src/sdio/mod.rs @@ -14,7 +14,7 @@ use nb; /// Basic SDIO Struct with common low-level functions. pub struct SDIO { regs: &'static mut regs::RegisterBlock, - count_down: super::timer::global::CountDown, + count_down: super::timer::global::CountDown, input_clk_hz: u32, card_type: CardType, card_detect: bool, diff --git a/libboard_zynq/src/time.rs b/libboard_zynq/src/time.rs index b9fc6f3..1dde7fe 100644 --- a/libboard_zynq/src/time.rs +++ b/libboard_zynq/src/time.rs @@ -8,3 +8,18 @@ impl core::ops::Add for Milliseconds { 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 { + fn now(&self) -> U; +} diff --git a/libboard_zynq/src/timer/global.rs b/libboard_zynq/src/timer/global.rs index 71069f6..9b46c79 100644 --- a/libboard_zynq/src/timer/global.rs +++ b/libboard_zynq/src/timer/global.rs @@ -1,9 +1,10 @@ +use core::ops::Add; use void::Void; use libregister::{RegisterR, RegisterW}; use crate::{ clocks::Clocks, mpcore, - time::Milliseconds, + time::{Milliseconds, Microseconds, TimeSource}, }; /// "uptime" @@ -79,41 +80,82 @@ impl GlobalTimer { } /// 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 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 /// `embedded_hal::timer::CountDown` - pub fn countdown(&self) -> CountDown { + pub fn countdown(&self) -> CountDown + where + Self: TimeSource, + { CountDown { timer: self.clone(), - timeout: Milliseconds(0), + timeout: self.now(), } } } -#[derive(Clone)] -pub struct CountDown { - timer: GlobalTimer, - timeout: Milliseconds, +impl TimeSource for GlobalTimer { + fn now(&self) -> Milliseconds { + self.get_time() + } } -impl embedded_hal::timer::CountDown for CountDown { - type Time = Milliseconds; +impl TimeSource for GlobalTimer { + fn now(&self) -> Microseconds { + self.get_us() + } +} + +#[derive(Clone)] +pub struct CountDown { + timer: GlobalTimer, + timeout: U, +} + +/// embedded-hal async API +impl + PartialOrd> embedded_hal::timer::CountDown for CountDown +where + GlobalTimer: TimeSource, +{ + type Time = U; fn start>(&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> { - if self.timer.get_time() <= self.timeout { + if self.timer.now() <= self.timeout { Err(nb::Error::WouldBlock) } else { Ok(()) } } } + +/// embedded-hal sync API +impl embedded_hal::blocking::delay::DelayMs for GlobalTimer { + fn delay_ms(&mut self, ms: u64) { + use embedded_hal::timer::CountDown; + + let mut countdown = self.countdown::(); + countdown.start(Milliseconds(ms)); + nb::block!(countdown.wait()).unwrap(); + } +} + +/// embedded-hal sync API +impl embedded_hal::blocking::delay::DelayUs for GlobalTimer { + fn delay_us(&mut self, us: u64) { + use embedded_hal::timer::CountDown; + + let mut countdown = self.countdown::(); + countdown.start(Microseconds(us)); + nb::block!(countdown.wait()).unwrap(); + } +}