aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/timer.rs
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-10-24 13:31:53 +0200
committerDario Nieuwenhuis <[email protected]>2024-11-04 00:47:31 +0100
commit51f6b813e1a4311ffb4adf2e66ed3effb990d246 (patch)
tree66a175cc893b00dcd56bcaff0e6b90b4d0753732 /embassy-nrf/src/timer.rs
parent650f97924ab540d3232b187cbde73d7a0104f734 (diff)
nrf: port to chiptool-based `nrf-pac`.
Diffstat (limited to 'embassy-nrf/src/timer.rs')
-rw-r--r--embassy-nrf/src/timer.rs80
1 files changed, 32 insertions, 48 deletions
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs
index ac5328ded..a9aeb40fa 100644
--- a/embassy-nrf/src/timer.rs
+++ b/embassy-nrf/src/timer.rs
@@ -8,13 +8,14 @@
8 8
9use embassy_hal_internal::{into_ref, PeripheralRef}; 9use embassy_hal_internal::{into_ref, PeripheralRef};
10 10
11use crate::pac::timer::vals;
11use crate::ppi::{Event, Task}; 12use crate::ppi::{Event, Task};
12use crate::{pac, Peripheral}; 13use crate::{pac, Peripheral};
13 14
14pub(crate) trait SealedInstance { 15pub(crate) trait SealedInstance {
15 /// The number of CC registers this instance has. 16 /// The number of CC registers this instance has.
16 const CCS: usize; 17 const CCS: usize;
17 fn regs() -> &'static pac::timer0::RegisterBlock; 18 fn regs() -> pac::timer::Timer;
18} 19}
19 20
20/// Basic Timer instance. 21/// Basic Timer instance.
@@ -31,8 +32,8 @@ macro_rules! impl_timer {
31 ($type:ident, $pac_type:ident, $irq:ident, $ccs:literal) => { 32 ($type:ident, $pac_type:ident, $irq:ident, $ccs:literal) => {
32 impl crate::timer::SealedInstance for peripherals::$type { 33 impl crate::timer::SealedInstance for peripherals::$type {
33 const CCS: usize = $ccs; 34 const CCS: usize = $ccs;
34 fn regs() -> &'static pac::timer0::RegisterBlock { 35 fn regs() -> pac::timer::Timer {
35 unsafe { &*(pac::$pac_type::ptr() as *const pac::timer0::RegisterBlock) } 36 unsafe { pac::timer::Timer::from_ptr(pac::$pac_type.as_ptr()) }
36 } 37 }
37 } 38 }
38 impl crate::timer::Instance for peripherals::$type { 39 impl crate::timer::Instance for peripherals::$type {
@@ -114,19 +115,19 @@ impl<'d, T: Instance> Timer<'d, T> {
114 // since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification. 115 // since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification.
115 this.stop(); 116 this.stop();
116 117
117 #[cfg(not(feature = "nrf51"))] 118 regs.mode().write(|w| {
118 if _is_counter { 119 w.set_mode(match _is_counter {
119 regs.mode.write(|w| w.mode().low_power_counter()); 120 #[cfg(not(feature = "_nrf51"))]
120 } else { 121 true => vals::Mode::LOW_POWER_COUNTER,
121 regs.mode.write(|w| w.mode().timer()); 122 #[cfg(feature = "_nrf51")]
122 } 123 true => vals::Mode::COUNTER,
123 124 false => vals::Mode::TIMER,
124 #[cfg(feature = "nrf51")] 125 })
125 regs.mode.write(|w| w.mode().timer()); 126 });
126 127
127 // Make the counter's max value as high as possible. 128 // Make the counter's max value as high as possible.
128 // TODO: is there a reason someone would want to set this lower? 129 // TODO: is there a reason someone would want to set this lower?
129 regs.bitmode.write(|w| w.bitmode()._32bit()); 130 regs.bitmode().write(|w| w.set_bitmode(vals::Bitmode::_32BIT));
130 131
131 // Initialize the counter at 0. 132 // Initialize the counter at 0.
132 this.clear(); 133 this.clear();
@@ -148,38 +149,38 @@ impl<'d, T: Instance> Timer<'d, T> {
148 149
149 /// Starts the timer. 150 /// Starts the timer.
150 pub fn start(&self) { 151 pub fn start(&self) {
151 T::regs().tasks_start.write(|w| unsafe { w.bits(1) }) 152 T::regs().tasks_start().write_value(1)
152 } 153 }
153 154
154 /// Stops the timer. 155 /// Stops the timer.
155 pub fn stop(&self) { 156 pub fn stop(&self) {
156 T::regs().tasks_stop.write(|w| unsafe { w.bits(1) }) 157 T::regs().tasks_stop().write_value(1)
157 } 158 }
158 159
159 /// Reset the timer's counter to 0. 160 /// Reset the timer's counter to 0.
160 pub fn clear(&self) { 161 pub fn clear(&self) {
161 T::regs().tasks_clear.write(|w| unsafe { w.bits(1) }) 162 T::regs().tasks_clear().write_value(1)
162 } 163 }
163 164
164 /// Returns the START task, for use with PPI. 165 /// Returns the START task, for use with PPI.
165 /// 166 ///
166 /// When triggered, this task starts the timer. 167 /// When triggered, this task starts the timer.
167 pub fn task_start(&self) -> Task<'d> { 168 pub fn task_start(&self) -> Task<'d> {
168 Task::from_reg(&T::regs().tasks_start) 169 Task::from_reg(T::regs().tasks_start())
169 } 170 }
170 171
171 /// Returns the STOP task, for use with PPI. 172 /// Returns the STOP task, for use with PPI.
172 /// 173 ///
173 /// When triggered, this task stops the timer. 174 /// When triggered, this task stops the timer.
174 pub fn task_stop(&self) -> Task<'d> { 175 pub fn task_stop(&self) -> Task<'d> {
175 Task::from_reg(&T::regs().tasks_stop) 176 Task::from_reg(T::regs().tasks_stop())
176 } 177 }
177 178
178 /// Returns the CLEAR task, for use with PPI. 179 /// Returns the CLEAR task, for use with PPI.
179 /// 180 ///
180 /// When triggered, this task resets the timer's counter to 0. 181 /// When triggered, this task resets the timer's counter to 0.
181 pub fn task_clear(&self) -> Task<'d> { 182 pub fn task_clear(&self) -> Task<'d> {
182 Task::from_reg(&T::regs().tasks_clear) 183 Task::from_reg(T::regs().tasks_clear())
183 } 184 }
184 185
185 /// Returns the COUNT task, for use with PPI. 186 /// Returns the COUNT task, for use with PPI.
@@ -187,7 +188,7 @@ impl<'d, T: Instance> Timer<'d, T> {
187 /// When triggered, this task increments the timer's counter by 1. 188 /// When triggered, this task increments the timer's counter by 1.
188 /// Only works in counter mode. 189 /// Only works in counter mode.
189 pub fn task_count(&self) -> Task<'d> { 190 pub fn task_count(&self) -> Task<'d> {
190 Task::from_reg(&T::regs().tasks_count) 191 Task::from_reg(T::regs().tasks_count())
191 } 192 }
192 193
193 /// Change the timer's frequency. 194 /// Change the timer's frequency.
@@ -198,10 +199,10 @@ impl<'d, T: Instance> Timer<'d, T> {
198 self.stop(); 199 self.stop();
199 200
200 T::regs() 201 T::regs()
201 .prescaler 202 .prescaler()
202 // SAFETY: `frequency` is a variant of `Frequency`, 203 // SAFETY: `frequency` is a variant of `Frequency`,
203 // whose values are all in the range of 0-9 (the valid range of `prescaler`). 204 // whose values are all in the range of 0-9 (the valid range of `prescaler`).
204 .write(|w| unsafe { w.prescaler().bits(frequency as u8) }) 205 .write(|w| w.set_prescaler(frequency as u8))
205 } 206 }
206 207
207 /// Returns this timer's `n`th CC register. 208 /// Returns this timer's `n`th CC register.
@@ -234,28 +235,19 @@ pub struct Cc<'d, T: Instance> {
234impl<'d, T: Instance> Cc<'d, T> { 235impl<'d, T: Instance> Cc<'d, T> {
235 /// Get the current value stored in the register. 236 /// Get the current value stored in the register.
236 pub fn read(&self) -> u32 { 237 pub fn read(&self) -> u32 {
237 #[cfg(not(feature = "nrf51"))] 238 return T::regs().cc(self.n).read();
238 return T::regs().cc[self.n].read().cc().bits();
239
240 #[cfg(feature = "nrf51")]
241 return T::regs().cc[self.n].read().bits();
242 } 239 }
243 240
244 /// Set the value stored in the register. 241 /// Set the value stored in the register.
245 /// 242 ///
246 /// `event_compare` will fire when the timer's counter reaches this value. 243 /// `event_compare` will fire when the timer's counter reaches this value.
247 pub fn write(&self, value: u32) { 244 pub fn write(&self, value: u32) {
248 // SAFETY: there are no invalid values for the CC register. 245 T::regs().cc(self.n).write_value(value);
249 #[cfg(not(feature = "nrf51"))]
250 T::regs().cc[self.n].write(|w| unsafe { w.cc().bits(value) });
251
252 #[cfg(feature = "nrf51")]
253 T::regs().cc[self.n].write(|w| unsafe { w.bits(value) });
254 } 246 }
255 247
256 /// Capture the current value of the timer's counter in this register, and return it. 248 /// Capture the current value of the timer's counter in this register, and return it.
257 pub fn capture(&self) -> u32 { 249 pub fn capture(&self) -> u32 {
258 T::regs().tasks_capture[self.n].write(|w| unsafe { w.bits(1) }); 250 T::regs().tasks_capture(self.n).write_value(1);
259 self.read() 251 self.read()
260 } 252 }
261 253
@@ -263,14 +255,14 @@ impl<'d, T: Instance> Cc<'d, T> {
263 /// 255 ///
264 /// When triggered, this task will capture the current value of the timer's counter in this register. 256 /// When triggered, this task will capture the current value of the timer's counter in this register.
265 pub fn task_capture(&self) -> Task<'d> { 257 pub fn task_capture(&self) -> Task<'d> {
266 Task::from_reg(&T::regs().tasks_capture) 258 Task::from_reg(T::regs().tasks_capture(self.n))
267 } 259 }
268 260
269 /// Returns this CC register's COMPARE event, for use with PPI. 261 /// Returns this CC register's COMPARE event, for use with PPI.
270 /// 262 ///
271 /// This event will fire when the timer's counter reaches the value in this CC register. 263 /// This event will fire when the timer's counter reaches the value in this CC register.
272 pub fn event_compare(&self) -> Event<'d> { 264 pub fn event_compare(&self) -> Event<'d> {
273 Event::from_reg(&T::regs().events_compare[self.n]) 265 Event::from_reg(T::regs().events_compare(self.n))
274 } 266 }
275 267
276 /// Enable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. 268 /// Enable the shortcut between this CC register's COMPARE event and the timer's CLEAR task.
@@ -279,16 +271,12 @@ impl<'d, T: Instance> Cc<'d, T> {
279 /// 271 ///
280 /// So, when the timer's counter reaches the value stored in this register, the timer's counter will be reset to 0. 272 /// So, when the timer's counter reaches the value stored in this register, the timer's counter will be reset to 0.
281 pub fn short_compare_clear(&self) { 273 pub fn short_compare_clear(&self) {
282 T::regs() 274 T::regs().shorts().modify(|w| w.set_compare_clear(self.n, true))
283 .shorts
284 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.n)) })
285 } 275 }
286 276
287 /// Disable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. 277 /// Disable the shortcut between this CC register's COMPARE event and the timer's CLEAR task.
288 pub fn unshort_compare_clear(&self) { 278 pub fn unshort_compare_clear(&self) {
289 T::regs() 279 T::regs().shorts().modify(|w| w.set_compare_clear(self.n, false))
290 .shorts
291 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.n)) })
292 } 280 }
293 281
294 /// Enable the shortcut between this CC register's COMPARE event and the timer's STOP task. 282 /// Enable the shortcut between this CC register's COMPARE event and the timer's STOP task.
@@ -297,15 +285,11 @@ impl<'d, T: Instance> Cc<'d, T> {
297 /// 285 ///
298 /// So, when the timer's counter reaches the value stored in this register, the timer will stop counting up. 286 /// So, when the timer's counter reaches the value stored in this register, the timer will stop counting up.
299 pub fn short_compare_stop(&self) { 287 pub fn short_compare_stop(&self) {
300 T::regs() 288 T::regs().shorts().modify(|w| w.set_compare_stop(self.n, true))
301 .shorts
302 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << (8 + self.n))) })
303 } 289 }
304 290
305 /// Disable the shortcut between this CC register's COMPARE event and the timer's STOP task. 291 /// Disable the shortcut between this CC register's COMPARE event and the timer's STOP task.
306 pub fn unshort_compare_stop(&self) { 292 pub fn unshort_compare_stop(&self) {
307 T::regs() 293 T::regs().shorts().modify(|w| w.set_compare_stop(self.n, false))
308 .shorts
309 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << (8 + self.n))) })
310 } 294 }
311} 295}