|
1 |
| -use super::{compute_arr_presc, Error, Event, FTimer, Instance, Timer}; |
| 1 | +use super::{compute_arr_presc, Error, Event, FTimer, Instance, SysEvent, Timer}; |
| 2 | +use crate::pac::SYST; |
2 | 3 | use core::ops::{Deref, DerefMut};
|
3 |
| -use fugit::HertzU32 as Hertz; |
| 4 | +use fugit::{HertzU32 as Hertz, TimerDurationU32, TimerInstantU32}; |
4 | 5 |
|
5 | 6 | /// Hardware timers
|
6 | 7 | pub struct CounterHz<TIM>(pub(super) Timer<TIM>);
|
@@ -66,7 +67,6 @@ impl<TIM: Instance> CounterHz<TIM> {
|
66 | 67 | Ok(())
|
67 | 68 | }
|
68 | 69 | }
|
69 |
| -use fugit::{TimerDurationU32, TimerInstantU32}; |
70 | 70 |
|
71 | 71 | /// Periodic non-blocking timer that imlements [embedded_hal::timer::CountDown]
|
72 | 72 | pub struct Counter<TIM, const FREQ: u32>(pub(super) FTimer<TIM, FREQ>);
|
@@ -160,3 +160,158 @@ impl<TIM: Instance, const FREQ: u32> fugit_timer::Timer<FREQ> for Counter<TIM, F
|
160 | 160 | self.wait()
|
161 | 161 | }
|
162 | 162 | }
|
| 163 | + |
| 164 | +impl Timer<SYST> { |
| 165 | + /// Creates [SysCounterHz] which takes [Hertz] as Duration |
| 166 | + pub fn counter_hz(self) -> SysCounterHz { |
| 167 | + SysCounterHz(self) |
| 168 | + } |
| 169 | + |
| 170 | + /// Creates [SysCounter] with custom precision (core frequency recommended is known) |
| 171 | + pub fn counter<const FREQ: u32>(self) -> SysCounter<FREQ> { |
| 172 | + SysCounter(self) |
| 173 | + } |
| 174 | + |
| 175 | + /// Creates [SysCounter] 1 microsecond precision |
| 176 | + pub fn counter_us(self) -> SysCounterUs { |
| 177 | + SysCounter(self) |
| 178 | + } |
| 179 | +} |
| 180 | + |
| 181 | +/// Hardware timers |
| 182 | +pub struct SysCounterHz(Timer<SYST>); |
| 183 | + |
| 184 | +impl Deref for SysCounterHz { |
| 185 | + type Target = Timer<SYST>; |
| 186 | + fn deref(&self) -> &Self::Target { |
| 187 | + &self.0 |
| 188 | + } |
| 189 | +} |
| 190 | + |
| 191 | +impl DerefMut for SysCounterHz { |
| 192 | + fn deref_mut(&mut self) -> &mut Self::Target { |
| 193 | + &mut self.0 |
| 194 | + } |
| 195 | +} |
| 196 | + |
| 197 | +impl SysCounterHz { |
| 198 | + pub fn start(&mut self, timeout: Hertz) -> Result<(), Error> { |
| 199 | + let rvr = self.clk.raw() / timeout.raw() - 1; |
| 200 | + |
| 201 | + if rvr >= (1 << 24) { |
| 202 | + return Err(Error::WrongAutoReload); |
| 203 | + } |
| 204 | + |
| 205 | + self.tim.set_reload(rvr); |
| 206 | + self.tim.clear_current(); |
| 207 | + self.tim.enable_counter(); |
| 208 | + |
| 209 | + Ok(()) |
| 210 | + } |
| 211 | + |
| 212 | + pub fn wait(&mut self) -> nb::Result<(), Error> { |
| 213 | + if self.tim.has_wrapped() { |
| 214 | + Ok(()) |
| 215 | + } else { |
| 216 | + Err(nb::Error::WouldBlock) |
| 217 | + } |
| 218 | + } |
| 219 | + |
| 220 | + pub fn cancel(&mut self) -> Result<(), Error> { |
| 221 | + if !self.tim.is_counter_enabled() { |
| 222 | + return Err(Error::Disabled); |
| 223 | + } |
| 224 | + |
| 225 | + self.tim.disable_counter(); |
| 226 | + Ok(()) |
| 227 | + } |
| 228 | +} |
| 229 | + |
| 230 | +pub type SysCounterUs = SysCounter<1_000_000>; |
| 231 | + |
| 232 | +/// SysTick timer with precision of 1 μs (1 MHz sampling) |
| 233 | +pub struct SysCounter<const FREQ: u32>(Timer<SYST>); |
| 234 | + |
| 235 | +impl<const FREQ: u32> Deref for SysCounter<FREQ> { |
| 236 | + type Target = Timer<SYST>; |
| 237 | + fn deref(&self) -> &Self::Target { |
| 238 | + &self.0 |
| 239 | + } |
| 240 | +} |
| 241 | + |
| 242 | +impl<const FREQ: u32> DerefMut for SysCounter<FREQ> { |
| 243 | + fn deref_mut(&mut self) -> &mut Self::Target { |
| 244 | + &mut self.0 |
| 245 | + } |
| 246 | +} |
| 247 | + |
| 248 | +impl<const FREQ: u32> SysCounter<FREQ> { |
| 249 | + /// Starts listening for an `event` |
| 250 | + pub fn listen(&mut self, event: SysEvent) { |
| 251 | + match event { |
| 252 | + SysEvent::Update => self.tim.enable_interrupt(), |
| 253 | + } |
| 254 | + } |
| 255 | + |
| 256 | + /// Stops listening for an `event` |
| 257 | + pub fn unlisten(&mut self, event: SysEvent) { |
| 258 | + match event { |
| 259 | + SysEvent::Update => self.tim.disable_interrupt(), |
| 260 | + } |
| 261 | + } |
| 262 | + |
| 263 | + pub fn now(&self) -> TimerInstantU32<FREQ> { |
| 264 | + TimerInstantU32::from_ticks(SYST::get_current() / (self.clk.raw() / FREQ)) |
| 265 | + } |
| 266 | + |
| 267 | + pub fn start(&mut self, timeout: TimerDurationU32<FREQ>) -> Result<(), Error> { |
| 268 | + let rvr = timeout.ticks() * (self.clk.raw() / FREQ) - 1; |
| 269 | + |
| 270 | + if rvr >= (1 << 24) { |
| 271 | + return Err(Error::WrongAutoReload); |
| 272 | + } |
| 273 | + |
| 274 | + self.tim.set_reload(rvr); |
| 275 | + self.tim.clear_current(); |
| 276 | + self.tim.enable_counter(); |
| 277 | + |
| 278 | + Ok(()) |
| 279 | + } |
| 280 | + |
| 281 | + pub fn wait(&mut self) -> nb::Result<(), Error> { |
| 282 | + if self.tim.has_wrapped() { |
| 283 | + Ok(()) |
| 284 | + } else { |
| 285 | + Err(nb::Error::WouldBlock) |
| 286 | + } |
| 287 | + } |
| 288 | + |
| 289 | + pub fn cancel(&mut self) -> Result<(), Error> { |
| 290 | + if !self.tim.is_counter_enabled() { |
| 291 | + return Err(Error::Disabled); |
| 292 | + } |
| 293 | + |
| 294 | + self.tim.disable_counter(); |
| 295 | + Ok(()) |
| 296 | + } |
| 297 | +} |
| 298 | + |
| 299 | +impl<const FREQ: u32> fugit_timer::Timer<FREQ> for SysCounter<FREQ> { |
| 300 | + type Error = Error; |
| 301 | + |
| 302 | + fn now(&mut self) -> TimerInstantU32<FREQ> { |
| 303 | + Self::now(self) |
| 304 | + } |
| 305 | + |
| 306 | + fn start(&mut self, duration: TimerDurationU32<FREQ>) -> Result<(), Self::Error> { |
| 307 | + self.start(duration) |
| 308 | + } |
| 309 | + |
| 310 | + fn wait(&mut self) -> nb::Result<(), Self::Error> { |
| 311 | + self.wait() |
| 312 | + } |
| 313 | + |
| 314 | + fn cancel(&mut self) -> Result<(), Self::Error> { |
| 315 | + self.cancel() |
| 316 | + } |
| 317 | +} |
0 commit comments