aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/timer.rs
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-09-27 18:37:33 +0200
committerDario Nieuwenhuis <[email protected]>2025-09-28 21:05:37 +0200
commitb07192079f0fc6ce210104786540aa7be8938d40 (patch)
tree659f336f177367fb82757c5b775c0f6c63894eb9 /embassy-nrf/src/timer.rs
parente5328c78259c7e288bf54c83bc80c2d2311abdf2 (diff)
nrf/uart,timer: erase instance generics.
Diffstat (limited to 'embassy-nrf/src/timer.rs')
-rw-r--r--embassy-nrf/src/timer.rs82
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
9use core::marker::PhantomData;
10
9use embassy_hal_internal::{Peri, PeripheralType}; 11use embassy_hal_internal::{Peri, PeripheralType};
10 12
11use crate::pac; 13use 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.
84pub struct Timer<'d, T: Instance> { 86pub struct Timer<'d> {
85 _p: Peri<'d, T>, 87 r: pac::timer::Timer,
88 ccs: usize,
89 _p: PhantomData<&'d ()>,
86} 90}
87 91
88impl<'d, T: Instance> Timer<'d, T> { 92impl<'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
226impl<T: Instance> Timer<'static, T> { 235impl 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
235impl<'d, T: Instance> Drop for Timer<'d, T> { 244impl<'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
248pub struct Cc<'d, T: Instance> { 257pub 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
253impl<'d, T: Instance> Cc<'d, T> { 263impl<'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}