diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-09-27 18:37:33 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2025-09-28 21:05:37 +0200 |
| commit | b07192079f0fc6ce210104786540aa7be8938d40 (patch) | |
| tree | 659f336f177367fb82757c5b775c0f6c63894eb9 /embassy-nrf/src/timer.rs | |
| parent | e5328c78259c7e288bf54c83bc80c2d2311abdf2 (diff) | |
nrf/uart,timer: erase instance generics.
Diffstat (limited to 'embassy-nrf/src/timer.rs')
| -rw-r--r-- | embassy-nrf/src/timer.rs | 82 |
1 files changed, 46 insertions, 36 deletions
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index 1d1f77ea8..0b0bb9780 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs | |||
| @@ -6,6 +6,8 @@ | |||
| 6 | 6 | ||
| 7 | #![macro_use] | 7 | #![macro_use] |
| 8 | 8 | ||
| 9 | use core::marker::PhantomData; | ||
| 10 | |||
| 9 | use embassy_hal_internal::{Peri, PeripheralType}; | 11 | use embassy_hal_internal::{Peri, PeripheralType}; |
| 10 | 12 | ||
| 11 | use crate::pac; | 13 | use crate::pac; |
| @@ -81,16 +83,18 @@ pub enum Frequency { | |||
| 81 | /// | 83 | /// |
| 82 | /// It has either 4 or 6 Capture/Compare registers, which can be used to capture the current state of the counter | 84 | /// It has either 4 or 6 Capture/Compare registers, which can be used to capture the current state of the counter |
| 83 | /// or trigger an event when the counter reaches a certain value. | 85 | /// or trigger an event when the counter reaches a certain value. |
| 84 | pub struct Timer<'d, T: Instance> { | 86 | pub struct Timer<'d> { |
| 85 | _p: Peri<'d, T>, | 87 | r: pac::timer::Timer, |
| 88 | ccs: usize, | ||
| 89 | _p: PhantomData<&'d ()>, | ||
| 86 | } | 90 | } |
| 87 | 91 | ||
| 88 | impl<'d, T: Instance> Timer<'d, T> { | 92 | impl<'d> Timer<'d> { |
| 89 | /// Create a new `Timer` driver. | 93 | /// Create a new `Timer` driver. |
| 90 | /// | 94 | /// |
| 91 | /// This can be useful for triggering tasks via PPI. | 95 | /// This can be useful for triggering tasks via PPI. |
| 92 | /// `Uarte` uses this internally. | 96 | /// `Uarte` uses this internally. |
| 93 | pub fn new(timer: Peri<'d, T>) -> Self { | 97 | pub fn new<T: Instance>(timer: Peri<'d, T>) -> Self { |
| 94 | Self::new_inner(timer, false) | 98 | Self::new_inner(timer, false) |
| 95 | } | 99 | } |
| 96 | 100 | ||
| @@ -98,14 +102,18 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 98 | /// | 102 | /// |
| 99 | /// This can be useful for triggering tasks via PPI. | 103 | /// This can be useful for triggering tasks via PPI. |
| 100 | /// `Uarte` uses this internally. | 104 | /// `Uarte` uses this internally. |
| 101 | pub fn new_counter(timer: Peri<'d, T>) -> Self { | 105 | pub fn new_counter<T: Instance>(timer: Peri<'d, T>) -> Self { |
| 102 | Self::new_inner(timer, true) | 106 | Self::new_inner(timer, true) |
| 103 | } | 107 | } |
| 104 | 108 | ||
| 105 | fn new_inner(timer: Peri<'d, T>, is_counter: bool) -> Self { | 109 | fn new_inner<T: Instance>(_timer: Peri<'d, T>, is_counter: bool) -> Self { |
| 106 | let regs = T::regs(); | 110 | let regs = T::regs(); |
| 107 | 111 | ||
| 108 | let this = Self { _p: timer }; | 112 | let this = Self { |
| 113 | r: regs, | ||
| 114 | ccs: T::CCS, | ||
| 115 | _p: PhantomData, | ||
| 116 | }; | ||
| 109 | 117 | ||
| 110 | // Stop the timer before doing anything else, | 118 | // Stop the timer before doing anything else, |
| 111 | // since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification. | 119 | // since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification. |
| @@ -131,7 +139,7 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 131 | // Default to the max frequency of the lower power clock | 139 | // Default to the max frequency of the lower power clock |
| 132 | this.set_frequency(Frequency::F1MHz); | 140 | this.set_frequency(Frequency::F1MHz); |
| 133 | 141 | ||
| 134 | for n in 0..T::CCS { | 142 | for n in 0..this.ccs { |
| 135 | let cc = this.cc(n); | 143 | let cc = this.cc(n); |
| 136 | // Initialize all the shorts as disabled. | 144 | // Initialize all the shorts as disabled. |
| 137 | cc.unshort_compare_clear(); | 145 | cc.unshort_compare_clear(); |
| @@ -147,43 +155,43 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 147 | #[cfg(feature = "unstable-pac")] | 155 | #[cfg(feature = "unstable-pac")] |
| 148 | #[inline] | 156 | #[inline] |
| 149 | pub fn regs(&mut self) -> pac::timer::Timer { | 157 | pub fn regs(&mut self) -> pac::timer::Timer { |
| 150 | T::regs() | 158 | self.r |
| 151 | } | 159 | } |
| 152 | 160 | ||
| 153 | /// Starts the timer. | 161 | /// Starts the timer. |
| 154 | pub fn start(&self) { | 162 | pub fn start(&self) { |
| 155 | T::regs().tasks_start().write_value(1) | 163 | self.r.tasks_start().write_value(1) |
| 156 | } | 164 | } |
| 157 | 165 | ||
| 158 | /// Stops the timer. | 166 | /// Stops the timer. |
| 159 | pub fn stop(&self) { | 167 | pub fn stop(&self) { |
| 160 | T::regs().tasks_stop().write_value(1) | 168 | self.r.tasks_stop().write_value(1) |
| 161 | } | 169 | } |
| 162 | 170 | ||
| 163 | /// Reset the timer's counter to 0. | 171 | /// Reset the timer's counter to 0. |
| 164 | pub fn clear(&self) { | 172 | pub fn clear(&self) { |
| 165 | T::regs().tasks_clear().write_value(1) | 173 | self.r.tasks_clear().write_value(1) |
| 166 | } | 174 | } |
| 167 | 175 | ||
| 168 | /// Returns the START task, for use with PPI. | 176 | /// Returns the START task, for use with PPI. |
| 169 | /// | 177 | /// |
| 170 | /// When triggered, this task starts the timer. | 178 | /// When triggered, this task starts the timer. |
| 171 | pub fn task_start(&self) -> Task<'d> { | 179 | pub fn task_start(&self) -> Task<'d> { |
| 172 | Task::from_reg(T::regs().tasks_start()) | 180 | Task::from_reg(self.r.tasks_start()) |
| 173 | } | 181 | } |
| 174 | 182 | ||
| 175 | /// Returns the STOP task, for use with PPI. | 183 | /// Returns the STOP task, for use with PPI. |
| 176 | /// | 184 | /// |
| 177 | /// When triggered, this task stops the timer. | 185 | /// When triggered, this task stops the timer. |
| 178 | pub fn task_stop(&self) -> Task<'d> { | 186 | pub fn task_stop(&self) -> Task<'d> { |
| 179 | Task::from_reg(T::regs().tasks_stop()) | 187 | Task::from_reg(self.r.tasks_stop()) |
| 180 | } | 188 | } |
| 181 | 189 | ||
| 182 | /// Returns the CLEAR task, for use with PPI. | 190 | /// Returns the CLEAR task, for use with PPI. |
| 183 | /// | 191 | /// |
| 184 | /// When triggered, this task resets the timer's counter to 0. | 192 | /// When triggered, this task resets the timer's counter to 0. |
| 185 | pub fn task_clear(&self) -> Task<'d> { | 193 | pub fn task_clear(&self) -> Task<'d> { |
| 186 | Task::from_reg(T::regs().tasks_clear()) | 194 | Task::from_reg(self.r.tasks_clear()) |
| 187 | } | 195 | } |
| 188 | 196 | ||
| 189 | /// Returns the COUNT task, for use with PPI. | 197 | /// Returns the COUNT task, for use with PPI. |
| @@ -191,7 +199,7 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 191 | /// When triggered, this task increments the timer's counter by 1. | 199 | /// When triggered, this task increments the timer's counter by 1. |
| 192 | /// Only works in counter mode. | 200 | /// Only works in counter mode. |
| 193 | pub fn task_count(&self) -> Task<'d> { | 201 | pub fn task_count(&self) -> Task<'d> { |
| 194 | Task::from_reg(T::regs().tasks_count()) | 202 | Task::from_reg(self.r.tasks_count()) |
| 195 | } | 203 | } |
| 196 | 204 | ||
| 197 | /// Change the timer's frequency. | 205 | /// Change the timer's frequency. |
| @@ -201,7 +209,7 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 201 | pub fn set_frequency(&self, frequency: Frequency) { | 209 | pub fn set_frequency(&self, frequency: Frequency) { |
| 202 | self.stop(); | 210 | self.stop(); |
| 203 | 211 | ||
| 204 | T::regs() | 212 | self.r |
| 205 | .prescaler() | 213 | .prescaler() |
| 206 | // SAFETY: `frequency` is a variant of `Frequency`, | 214 | // SAFETY: `frequency` is a variant of `Frequency`, |
| 207 | // whose values are all in the range of 0-9 (the valid range of `prescaler`). | 215 | // whose values are all in the range of 0-9 (the valid range of `prescaler`). |
| @@ -212,18 +220,19 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 212 | /// | 220 | /// |
| 213 | /// # Panics | 221 | /// # Panics |
| 214 | /// Panics if `n` >= the number of CC registers this timer has (4 for a normal timer, 6 for an extended timer). | 222 | /// Panics if `n` >= the number of CC registers this timer has (4 for a normal timer, 6 for an extended timer). |
| 215 | pub fn cc(&self, n: usize) -> Cc<'d, T> { | 223 | pub fn cc(&self, n: usize) -> Cc<'d> { |
| 216 | if n >= T::CCS { | 224 | if n >= self.ccs { |
| 217 | panic!("Cannot get CC register {} of timer with {} CC registers.", n, T::CCS); | 225 | panic!("Cannot get CC register {} of timer with {} CC registers.", n, self.ccs); |
| 218 | } | 226 | } |
| 219 | Cc { | 227 | Cc { |
| 220 | n, | 228 | n, |
| 221 | _p: unsafe { self._p.clone_unchecked() }, | 229 | r: self.r, |
| 230 | _p: PhantomData, | ||
| 222 | } | 231 | } |
| 223 | } | 232 | } |
| 224 | } | 233 | } |
| 225 | 234 | ||
| 226 | impl<T: Instance> Timer<'static, T> { | 235 | impl Timer<'static> { |
| 227 | /// Persist the timer's configuration for the rest of the program's lifetime. This method | 236 | /// Persist the timer's configuration for the rest of the program's lifetime. This method |
| 228 | /// should be preferred over [`core::mem::forget()`] because the `'static` bound prevents | 237 | /// should be preferred over [`core::mem::forget()`] because the `'static` bound prevents |
| 229 | /// accidental reuse of the underlying peripheral. | 238 | /// accidental reuse of the underlying peripheral. |
| @@ -232,7 +241,7 @@ impl<T: Instance> Timer<'static, T> { | |||
| 232 | } | 241 | } |
| 233 | } | 242 | } |
| 234 | 243 | ||
| 235 | impl<'d, T: Instance> Drop for Timer<'d, T> { | 244 | impl<'d> Drop for Timer<'d> { |
| 236 | fn drop(&mut self) { | 245 | fn drop(&mut self) { |
| 237 | self.stop(); | 246 | self.stop(); |
| 238 | } | 247 | } |
| @@ -245,27 +254,28 @@ impl<'d, T: Instance> Drop for Timer<'d, T> { | |||
| 245 | /// | 254 | /// |
| 246 | /// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register. | 255 | /// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register. |
| 247 | /// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register | 256 | /// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register |
| 248 | pub struct Cc<'d, T: Instance> { | 257 | pub struct Cc<'d> { |
| 249 | n: usize, | 258 | n: usize, |
| 250 | _p: Peri<'d, T>, | 259 | r: pac::timer::Timer, |
| 260 | _p: PhantomData<&'d ()>, | ||
| 251 | } | 261 | } |
| 252 | 262 | ||
| 253 | impl<'d, T: Instance> Cc<'d, T> { | 263 | impl<'d> Cc<'d> { |
| 254 | /// Get the current value stored in the register. | 264 | /// Get the current value stored in the register. |
| 255 | pub fn read(&self) -> u32 { | 265 | pub fn read(&self) -> u32 { |
| 256 | T::regs().cc(self.n).read() | 266 | self.r.cc(self.n).read() |
| 257 | } | 267 | } |
| 258 | 268 | ||
| 259 | /// Set the value stored in the register. | 269 | /// Set the value stored in the register. |
| 260 | /// | 270 | /// |
| 261 | /// `event_compare` will fire when the timer's counter reaches this value. | 271 | /// `event_compare` will fire when the timer's counter reaches this value. |
| 262 | pub fn write(&self, value: u32) { | 272 | pub fn write(&self, value: u32) { |
| 263 | T::regs().cc(self.n).write_value(value); | 273 | self.r.cc(self.n).write_value(value); |
| 264 | } | 274 | } |
| 265 | 275 | ||
| 266 | /// Capture the current value of the timer's counter in this register, and return it. | 276 | /// Capture the current value of the timer's counter in this register, and return it. |
| 267 | pub fn capture(&self) -> u32 { | 277 | pub fn capture(&self) -> u32 { |
| 268 | T::regs().tasks_capture(self.n).write_value(1); | 278 | self.r.tasks_capture(self.n).write_value(1); |
| 269 | self.read() | 279 | self.read() |
| 270 | } | 280 | } |
| 271 | 281 | ||
| @@ -273,20 +283,20 @@ impl<'d, T: Instance> Cc<'d, T> { | |||
| 273 | /// | 283 | /// |
| 274 | /// When triggered, this task will capture the current value of the timer's counter in this register. | 284 | /// When triggered, this task will capture the current value of the timer's counter in this register. |
| 275 | pub fn task_capture(&self) -> Task<'d> { | 285 | pub fn task_capture(&self) -> Task<'d> { |
| 276 | Task::from_reg(T::regs().tasks_capture(self.n)) | 286 | Task::from_reg(self.r.tasks_capture(self.n)) |
| 277 | } | 287 | } |
| 278 | 288 | ||
| 279 | /// Returns this CC register's COMPARE event, for use with PPI. | 289 | /// Returns this CC register's COMPARE event, for use with PPI. |
| 280 | /// | 290 | /// |
| 281 | /// This event will fire when the timer's counter reaches the value in this CC register. | 291 | /// This event will fire when the timer's counter reaches the value in this CC register. |
| 282 | pub fn event_compare(&self) -> Event<'d> { | 292 | pub fn event_compare(&self) -> Event<'d> { |
| 283 | Event::from_reg(T::regs().events_compare(self.n)) | 293 | Event::from_reg(self.r.events_compare(self.n)) |
| 284 | } | 294 | } |
| 285 | 295 | ||
| 286 | /// Clear the COMPARE event for this CC register. | 296 | /// Clear the COMPARE event for this CC register. |
| 287 | #[inline] | 297 | #[inline] |
| 288 | pub fn clear_events(&self) { | 298 | pub fn clear_events(&self) { |
| 289 | T::regs().events_compare(self.n).write_value(0); | 299 | self.r.events_compare(self.n).write_value(0); |
| 290 | } | 300 | } |
| 291 | 301 | ||
| 292 | /// Enable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. | 302 | /// Enable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. |
| @@ -295,12 +305,12 @@ impl<'d, T: Instance> Cc<'d, T> { | |||
| 295 | /// | 305 | /// |
| 296 | /// So, when the timer's counter reaches the value stored in this register, the timer's counter will be reset to 0. | 306 | /// So, when the timer's counter reaches the value stored in this register, the timer's counter will be reset to 0. |
| 297 | pub fn short_compare_clear(&self) { | 307 | pub fn short_compare_clear(&self) { |
| 298 | T::regs().shorts().modify(|w| w.set_compare_clear(self.n, true)) | 308 | self.r.shorts().modify(|w| w.set_compare_clear(self.n, true)) |
| 299 | } | 309 | } |
| 300 | 310 | ||
| 301 | /// Disable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. | 311 | /// Disable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. |
| 302 | pub fn unshort_compare_clear(&self) { | 312 | pub fn unshort_compare_clear(&self) { |
| 303 | T::regs().shorts().modify(|w| w.set_compare_clear(self.n, false)) | 313 | self.r.shorts().modify(|w| w.set_compare_clear(self.n, false)) |
| 304 | } | 314 | } |
| 305 | 315 | ||
| 306 | /// Enable the shortcut between this CC register's COMPARE event and the timer's STOP task. | 316 | /// Enable the shortcut between this CC register's COMPARE event and the timer's STOP task. |
| @@ -309,11 +319,11 @@ impl<'d, T: Instance> Cc<'d, T> { | |||
| 309 | /// | 319 | /// |
| 310 | /// So, when the timer's counter reaches the value stored in this register, the timer will stop counting up. | 320 | /// So, when the timer's counter reaches the value stored in this register, the timer will stop counting up. |
| 311 | pub fn short_compare_stop(&self) { | 321 | pub fn short_compare_stop(&self) { |
| 312 | T::regs().shorts().modify(|w| w.set_compare_stop(self.n, true)) | 322 | self.r.shorts().modify(|w| w.set_compare_stop(self.n, true)) |
| 313 | } | 323 | } |
| 314 | 324 | ||
| 315 | /// Disable the shortcut between this CC register's COMPARE event and the timer's STOP task. | 325 | /// Disable the shortcut between this CC register's COMPARE event and the timer's STOP task. |
| 316 | pub fn unshort_compare_stop(&self) { | 326 | pub fn unshort_compare_stop(&self) { |
| 317 | T::regs().shorts().modify(|w| w.set_compare_stop(self.n, false)) | 327 | self.r.shorts().modify(|w| w.set_compare_stop(self.n, false)) |
| 318 | } | 328 | } |
| 319 | } | 329 | } |
