|
1 | | -use super::*; |
2 | | -use fugit::{HertzU32 as Hertz, MicrosDurationU32}; |
| 1 | +use super::{Error, Event, FTimer, GeneralTimer}; |
| 2 | +use core::ops::{Deref, DerefMut}; |
| 3 | +use fugit::{HertzU32 as Hertz, MicrosDurationU32, TimerDurationU32, TimerInstantU32}; |
3 | 4 |
|
4 | 5 | /// Hardware timers |
5 | 6 | pub struct CounterHz<TIM> { |
@@ -95,3 +96,101 @@ impl<TIM: GeneralTimer> CounterHz<TIM> { |
95 | 96 | MicrosDurationU32::from_ticks(u32::try_from(1_000_000 * cnt / freq_divider).unwrap()) |
96 | 97 | } |
97 | 98 | } |
| 99 | + |
| 100 | +// ---------------------------------------------------------------------------- |
| 101 | + |
| 102 | +/// Periodic non-blocking timer that imlements [embedded_hal_02::timer::CountDown] |
| 103 | +pub struct Counter<TIM, const FREQ: u32>(pub(super) FTimer<TIM, FREQ>); |
| 104 | + |
| 105 | +impl<T, const FREQ: u32> Deref for Counter<T, FREQ> { |
| 106 | + type Target = FTimer<T, FREQ>; |
| 107 | + fn deref(&self) -> &Self::Target { |
| 108 | + &self.0 |
| 109 | + } |
| 110 | +} |
| 111 | + |
| 112 | +impl<T, const FREQ: u32> DerefMut for Counter<T, FREQ> { |
| 113 | + fn deref_mut(&mut self) -> &mut Self::Target { |
| 114 | + &mut self.0 |
| 115 | + } |
| 116 | +} |
| 117 | + |
| 118 | +/// `Counter` with precision of 1 μs (1 MHz sampling) |
| 119 | +pub type CounterUs<TIM> = Counter<TIM, 1_000_000>; |
| 120 | + |
| 121 | +/// `Counter` with precision of of 1 ms (1 kHz sampling) |
| 122 | +/// |
| 123 | +/// NOTE: don't use this if your system frequency more than 65 MHz |
| 124 | +pub type CounterMs<TIM> = Counter<TIM, 1_000>; |
| 125 | + |
| 126 | +impl<TIM: GeneralTimer, const FREQ: u32> Counter<TIM, FREQ> { |
| 127 | + /// Releases the TIM peripheral |
| 128 | + pub fn release(mut self) -> FTimer<TIM, FREQ> { |
| 129 | + // stop counter |
| 130 | + self.tim.reset_config(); |
| 131 | + self.0 |
| 132 | + } |
| 133 | + |
| 134 | + pub fn now(&self) -> TimerInstantU32<FREQ> { |
| 135 | + TimerInstantU32::from_ticks(self.tim.read_count().into()) |
| 136 | + } |
| 137 | + |
| 138 | + pub fn start(&mut self, timeout: TimerDurationU32<FREQ>) -> Result<(), Error> { |
| 139 | + // pause |
| 140 | + self.tim.disable_counter(); |
| 141 | + |
| 142 | + self.tim.clear_interrupt_flag(Event::Update); |
| 143 | + |
| 144 | + // reset counter |
| 145 | + self.tim.reset_counter(); |
| 146 | + |
| 147 | + self.tim.set_auto_reload(timeout.ticks() - 1)?; |
| 148 | + |
| 149 | + // Trigger update event to load the registers |
| 150 | + self.tim.trigger_update(); |
| 151 | + |
| 152 | + // start counter |
| 153 | + self.tim.enable_counter(); |
| 154 | + |
| 155 | + Ok(()) |
| 156 | + } |
| 157 | + |
| 158 | + pub fn wait(&mut self) -> nb::Result<(), Error> { |
| 159 | + if self.tim.get_interrupt_flag().contains(Event::Update) { |
| 160 | + self.tim.clear_interrupt_flag(Event::Update); |
| 161 | + Ok(()) |
| 162 | + } else { |
| 163 | + Err(nb::Error::WouldBlock) |
| 164 | + } |
| 165 | + } |
| 166 | + |
| 167 | + pub fn cancel(&mut self) -> Result<(), Error> { |
| 168 | + if !self.tim.is_counter_enabled() { |
| 169 | + return Err(Error::Disabled); |
| 170 | + } |
| 171 | + |
| 172 | + // disable counter |
| 173 | + self.tim.disable_counter(); |
| 174 | + Ok(()) |
| 175 | + } |
| 176 | +} |
| 177 | + |
| 178 | +impl<TIM: GeneralTimer, const FREQ: u32> fugit_timer::Timer<FREQ> for Counter<TIM, FREQ> { |
| 179 | + type Error = Error; |
| 180 | + |
| 181 | + fn now(&mut self) -> TimerInstantU32<FREQ> { |
| 182 | + Self::now(self) |
| 183 | + } |
| 184 | + |
| 185 | + fn start(&mut self, duration: TimerDurationU32<FREQ>) -> Result<(), Self::Error> { |
| 186 | + self.start(duration) |
| 187 | + } |
| 188 | + |
| 189 | + fn cancel(&mut self) -> Result<(), Self::Error> { |
| 190 | + self.cancel() |
| 191 | + } |
| 192 | + |
| 193 | + fn wait(&mut self) -> nb::Result<(), Self::Error> { |
| 194 | + self.wait() |
| 195 | + } |
| 196 | +} |
0 commit comments