use super::{Error, Event, FTimer, GeneralTimer};
use crate::common::fugit::{HertzU32, MicrosDurationU32, TimerDurationU32, TimerInstantU32};
use core::ops::{Deref, DerefMut};
pub struct CounterHz<TIM> {
pub(crate) tim: TIM,
pub(crate) clk: HertzU32,
}
impl<TIM: GeneralTimer> CounterHz<TIM> {
pub fn start(&mut self, timeout: HertzU32) -> Result<(), Error> {
self.tim.disable_counter();
self.tim.clear_interrupt_flag(Event::Update);
self.tim.reset_counter();
let clk = self.clk;
self.tim.config_freq(clk, timeout);
self.tim.enable_counter();
Ok(())
}
pub fn wait(&mut self) -> nb::Result<(), Error> {
if self.tim.get_interrupt_flag().contains(Event::Update) {
self.tim.clear_interrupt_flag(Event::Update);
Ok(())
} else {
Err(nb::Error::WouldBlock)
}
}
pub fn cancel(&mut self) -> Result<(), Error> {
if !self.tim.is_counter_enabled() {
return Err(Error::Disabled);
}
self.tim.disable_counter();
Ok(())
}
pub fn start_raw(&mut self, psc: u16, arr: u16) {
self.tim.disable_counter();
self.tim.set_prescaler(psc);
self.tim.set_auto_reload(arr as u32).unwrap();
self.tim.trigger_update();
self.tim.enable_counter();
}
pub fn psc(&self) -> u16 {
self.tim.read_prescaler()
}
pub fn arr(&self) -> u16 {
self.tim.read_auto_reload() as u16
}
pub fn reset(&mut self) {
self.tim.trigger_update();
}
pub fn now(&self) -> MicrosDurationU32 {
let psc = self.tim.read_prescaler() as u32;
let freq_divider = (self.clk.raw() / (psc + 1)) as u64;
let cnt: u32 = self.tim.read_count();
let cnt = cnt as u64;
MicrosDurationU32::from_ticks(u32::try_from(1_000_000 * cnt / freq_divider).unwrap())
}
}
pub struct Counter<TIM, const FREQ: u32>(pub(super) FTimer<TIM, FREQ>);
impl<T, const FREQ: u32> Deref for Counter<T, FREQ> {
type Target = FTimer<T, FREQ>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T, const FREQ: u32> DerefMut for Counter<T, FREQ> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
pub type CounterUs<TIM> = Counter<TIM, 1_000_000>;
pub type CounterMs<TIM> = Counter<TIM, 1_000>;
impl<TIM: GeneralTimer, const FREQ: u32> Counter<TIM, FREQ> {
pub fn release(mut self) -> FTimer<TIM, FREQ> {
self.tim.reset_config();
self.0
}
pub fn now(&self) -> TimerInstantU32<FREQ> {
TimerInstantU32::from_ticks(self.tim.read_count())
}
pub fn start(&mut self, timeout: TimerDurationU32<FREQ>) -> Result<(), Error> {
self.tim.disable_counter();
self.tim.clear_interrupt_flag(Event::Update);
self.tim.reset_counter();
self.tim.set_auto_reload(timeout.ticks() - 1)?;
self.tim.trigger_update();
self.tim.enable_counter();
Ok(())
}
pub fn wait(&mut self) -> nb::Result<(), Error> {
if self.tim.get_interrupt_flag().contains(Event::Update) {
self.tim.clear_interrupt_flag(Event::Update);
Ok(())
} else {
Err(nb::Error::WouldBlock)
}
}
pub fn cancel(&mut self) -> Result<(), Error> {
if !self.tim.is_counter_enabled() {
return Err(Error::Disabled);
}
self.tim.disable_counter();
Ok(())
}
}
impl<TIM: GeneralTimer, const FREQ: u32> fugit_timer::Timer<FREQ> for Counter<TIM, FREQ> {
type Error = Error;
fn now(&mut self) -> TimerInstantU32<FREQ> {
Self::now(self)
}
fn start(&mut self, duration: TimerDurationU32<FREQ>) -> Result<(), Self::Error> {
self.start(duration)
}
fn cancel(&mut self) -> Result<(), Self::Error> {
self.cancel()
}
fn wait(&mut self) -> nb::Result<(), Self::Error> {
self.wait()
}
}