diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-10-24 13:31:53 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2024-11-04 00:47:31 +0100 |
| commit | 51f6b813e1a4311ffb4adf2e66ed3effb990d246 (patch) | |
| tree | 66a175cc893b00dcd56bcaff0e6b90b4d0753732 /embassy-nrf/src/timer.rs | |
| parent | 650f97924ab540d3232b187cbde73d7a0104f734 (diff) | |
nrf: port to chiptool-based `nrf-pac`.
Diffstat (limited to 'embassy-nrf/src/timer.rs')
| -rw-r--r-- | embassy-nrf/src/timer.rs | 80 |
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 | ||
| 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 10 | 10 | ||
| 11 | use crate::pac::timer::vals; | ||
| 11 | use crate::ppi::{Event, Task}; | 12 | use crate::ppi::{Event, Task}; |
| 12 | use crate::{pac, Peripheral}; | 13 | use crate::{pac, Peripheral}; |
| 13 | 14 | ||
| 14 | pub(crate) trait SealedInstance { | 15 | pub(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> { | |||
| 234 | impl<'d, T: Instance> Cc<'d, T> { | 235 | impl<'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 | } |
