aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-09-28 21:03:12 +0200
committerDario Nieuwenhuis <[email protected]>2025-09-28 21:05:37 +0200
commitefe5b18f5d050bf19a5031f683ac24e23aad6746 (patch)
tree2e637ed7b6416e5dc9e8cfdc6599823571a1197a /embassy-nrf
parent37fd0c7bce19d4618669a29bdd01945fb477eea6 (diff)
nrf/rtc: erase instance generic
Diffstat (limited to 'embassy-nrf')
-rw-r--r--embassy-nrf/src/rtc.rs67
1 files changed, 38 insertions, 29 deletions
diff --git a/embassy-nrf/src/rtc.rs b/embassy-nrf/src/rtc.rs
index 1a90d1e24..652de511b 100644
--- a/embassy-nrf/src/rtc.rs
+++ b/embassy-nrf/src/rtc.rs
@@ -2,10 +2,13 @@
2 2
3#![macro_use] 3#![macro_use]
4 4
5use core::marker::PhantomData;
6
7use embassy_hal_internal::interrupt::InterruptExt;
5use embassy_hal_internal::{Peri, PeripheralType}; 8use embassy_hal_internal::{Peri, PeripheralType};
6 9
7use crate::chip::interrupt::typelevel::Interrupt as _; 10use crate::interrupt::typelevel::Interrupt as _;
8use crate::pac; 11use crate::{interrupt, pac};
9 12
10/// Prescaler has an invalid value which exceeds 12 bits. 13/// Prescaler has an invalid value which exceeds 12 bits.
11#[derive(Debug, PartialEq, Eq)] 14#[derive(Debug, PartialEq, Eq)]
@@ -88,23 +91,31 @@ macro_rules! impl_rtc {
88} 91}
89 92
90/// nRF RTC driver. 93/// nRF RTC driver.
91pub struct Rtc<'d, T: Instance>(Peri<'d, T>); 94pub struct Rtc<'d> {
95 r: pac::rtc::Rtc,
96 irq: interrupt::Interrupt,
97 _phantom: PhantomData<&'d ()>,
98}
92 99
93impl<'d, T: Instance> Rtc<'d, T> { 100impl<'d> Rtc<'d> {
94 /// Create a new `Rtc` driver. 101 /// Create a new `Rtc` driver.
95 /// 102 ///
96 /// fRTC \[Hz\] = 32_768 / (`prescaler` + 1 ) 103 /// fRTC \[Hz\] = 32_768 / (`prescaler` + 1 )
97 pub fn new(rtc: Peri<'d, T>, prescaler: u32) -> Result<Self, PrescalerOutOfRangeError> { 104 pub fn new<T: Instance>(_rtc: Peri<'d, T>, prescaler: u32) -> Result<Self, PrescalerOutOfRangeError> {
98 if prescaler >= (1 << 12) { 105 if prescaler >= (1 << 12) {
99 return Err(PrescalerOutOfRangeError(prescaler)); 106 return Err(PrescalerOutOfRangeError(prescaler));
100 } 107 }
101 108
102 T::regs().prescaler().write(|w| w.set_prescaler(prescaler as u16)); 109 T::regs().prescaler().write(|w| w.set_prescaler(prescaler as u16));
103 Ok(Self(rtc)) 110 Ok(Self {
111 r: T::regs(),
112 irq: T::Interrupt::IRQ,
113 _phantom: PhantomData,
114 })
104 } 115 }
105 116
106 /// Create a new `Rtc` driver, configuring it to run at the given frequency. 117 /// Create a new `Rtc` driver, configuring it to run at the given frequency.
107 pub fn new_for_freq(rtc: Peri<'d, T>, freq_hz: u32) -> Result<Self, PrescalerOutOfRangeError> { 118 pub fn new_for_freq<T: Instance>(rtc: Peri<'d, T>, freq_hz: u32) -> Result<Self, PrescalerOutOfRangeError> {
108 let prescaler = (32_768 / freq_hz).saturating_sub(1); 119 let prescaler = (32_768 / freq_hz).saturating_sub(1);
109 Self::new(rtc, prescaler) 120 Self::new(rtc, prescaler)
110 } 121 }
@@ -115,34 +126,38 @@ impl<'d, T: Instance> Rtc<'d, T> {
115 /// 126 ///
116 /// Potentially allows to create multiple instances of the driver for the same peripheral 127 /// Potentially allows to create multiple instances of the driver for the same peripheral
117 /// which can lead to undefined behavior. 128 /// which can lead to undefined behavior.
118 pub unsafe fn steal() -> Self { 129 pub unsafe fn steal<T: Instance>() -> Self {
119 Self(unsafe { T::steal() }) 130 Self {
131 r: T::regs(),
132 irq: T::Interrupt::IRQ,
133 _phantom: PhantomData,
134 }
120 } 135 }
121 136
122 /// Direct access to the RTC registers. 137 /// Direct access to the RTC registers.
123 #[cfg(feature = "unstable-pac")] 138 #[cfg(feature = "unstable-pac")]
124 #[inline] 139 #[inline]
125 pub fn regs(&mut self) -> pac::rtc::Rtc { 140 pub fn regs(&mut self) -> pac::rtc::Rtc {
126 T::regs() 141 self.r
127 } 142 }
128 143
129 /// Enable the RTC. 144 /// Enable the RTC.
130 #[inline] 145 #[inline]
131 pub fn enable(&mut self) { 146 pub fn enable(&mut self) {
132 T::regs().tasks_start().write_value(1); 147 self.r.tasks_start().write_value(1);
133 } 148 }
134 149
135 /// Disable the RTC. 150 /// Disable the RTC.
136 #[inline] 151 #[inline]
137 pub fn disable(&mut self) { 152 pub fn disable(&mut self) {
138 T::regs().tasks_stop().write_value(1); 153 self.r.tasks_stop().write_value(1);
139 } 154 }
140 155
141 /// Enables interrupts for the given [Interrupt] source. 156 /// Enables interrupts for the given [Interrupt] source.
142 /// 157 ///
143 /// Optionally also enables the interrupt in the NVIC. 158 /// Optionally also enables the interrupt in the NVIC.
144 pub fn enable_interrupt(&mut self, int: Interrupt, enable_in_nvic: bool) { 159 pub fn enable_interrupt(&mut self, int: Interrupt, enable_in_nvic: bool) {
145 let regs = T::regs(); 160 let regs = self.r;
146 match int { 161 match int {
147 Interrupt::Tick => regs.intenset().write(|w| w.set_tick(true)), 162 Interrupt::Tick => regs.intenset().write(|w| w.set_tick(true)),
148 Interrupt::Overflow => regs.intenset().write(|w| w.set_ovrflw(true)), 163 Interrupt::Overflow => regs.intenset().write(|w| w.set_ovrflw(true)),
@@ -152,7 +167,7 @@ impl<'d, T: Instance> Rtc<'d, T> {
152 Interrupt::Compare3 => regs.intenset().write(|w| w.set_compare(3, true)), 167 Interrupt::Compare3 => regs.intenset().write(|w| w.set_compare(3, true)),
153 } 168 }
154 if enable_in_nvic { 169 if enable_in_nvic {
155 unsafe { T::Interrupt::enable() }; 170 unsafe { self.irq.enable() };
156 } 171 }
157 } 172 }
158 173
@@ -160,7 +175,7 @@ impl<'d, T: Instance> Rtc<'d, T> {
160 /// 175 ///
161 /// Optionally also disables the interrupt in the NVIC. 176 /// Optionally also disables the interrupt in the NVIC.
162 pub fn disable_interrupt(&mut self, int: Interrupt, disable_in_nvic: bool) { 177 pub fn disable_interrupt(&mut self, int: Interrupt, disable_in_nvic: bool) {
163 let regs = T::regs(); 178 let regs = self.r;
164 match int { 179 match int {
165 Interrupt::Tick => regs.intenclr().write(|w| w.set_tick(true)), 180 Interrupt::Tick => regs.intenclr().write(|w| w.set_tick(true)),
166 Interrupt::Overflow => regs.intenclr().write(|w| w.set_ovrflw(true)), 181 Interrupt::Overflow => regs.intenclr().write(|w| w.set_ovrflw(true)),
@@ -170,13 +185,13 @@ impl<'d, T: Instance> Rtc<'d, T> {
170 Interrupt::Compare3 => regs.intenclr().write(|w| w.set_compare(3, true)), 185 Interrupt::Compare3 => regs.intenclr().write(|w| w.set_compare(3, true)),
171 } 186 }
172 if disable_in_nvic { 187 if disable_in_nvic {
173 T::Interrupt::disable(); 188 self.irq.disable();
174 } 189 }
175 } 190 }
176 191
177 /// Enable the generation of a hardware event from a given stimulus. 192 /// Enable the generation of a hardware event from a given stimulus.
178 pub fn enable_event(&mut self, evt: Interrupt) { 193 pub fn enable_event(&mut self, evt: Interrupt) {
179 let regs = T::regs(); 194 let regs = self.r;
180 match evt { 195 match evt {
181 Interrupt::Tick => regs.evtenset().write(|w| w.set_tick(true)), 196 Interrupt::Tick => regs.evtenset().write(|w| w.set_tick(true)),
182 Interrupt::Overflow => regs.evtenset().write(|w| w.set_ovrflw(true)), 197 Interrupt::Overflow => regs.evtenset().write(|w| w.set_ovrflw(true)),
@@ -189,7 +204,7 @@ impl<'d, T: Instance> Rtc<'d, T> {
189 204
190 /// Disable the generation of a hardware event from a given stimulus. 205 /// Disable the generation of a hardware event from a given stimulus.
191 pub fn disable_event(&mut self, evt: Interrupt) { 206 pub fn disable_event(&mut self, evt: Interrupt) {
192 let regs = T::regs(); 207 let regs = self.r;
193 match evt { 208 match evt {
194 Interrupt::Tick => regs.evtenclr().write(|w| w.set_tick(true)), 209 Interrupt::Tick => regs.evtenclr().write(|w| w.set_tick(true)),
195 Interrupt::Overflow => regs.evtenclr().write(|w| w.set_ovrflw(true)), 210 Interrupt::Overflow => regs.evtenclr().write(|w| w.set_ovrflw(true)),
@@ -202,7 +217,7 @@ impl<'d, T: Instance> Rtc<'d, T> {
202 217
203 /// Resets the given event. 218 /// Resets the given event.
204 pub fn reset_event(&mut self, evt: Interrupt) { 219 pub fn reset_event(&mut self, evt: Interrupt) {
205 let regs = T::regs(); 220 let regs = self.r;
206 match evt { 221 match evt {
207 Interrupt::Tick => regs.events_tick().write_value(0), 222 Interrupt::Tick => regs.events_tick().write_value(0),
208 Interrupt::Overflow => regs.events_ovrflw().write_value(0), 223 Interrupt::Overflow => regs.events_ovrflw().write_value(0),
@@ -215,7 +230,7 @@ impl<'d, T: Instance> Rtc<'d, T> {
215 230
216 /// Checks if the given event has been triggered. 231 /// Checks if the given event has been triggered.
217 pub fn is_event_triggered(&self, evt: Interrupt) -> bool { 232 pub fn is_event_triggered(&self, evt: Interrupt) -> bool {
218 let regs = T::regs(); 233 let regs = self.r;
219 let val = match evt { 234 let val = match evt {
220 Interrupt::Tick => regs.events_tick().read(), 235 Interrupt::Tick => regs.events_tick().read(),
221 Interrupt::Overflow => regs.events_ovrflw().read(), 236 Interrupt::Overflow => regs.events_ovrflw().read(),
@@ -241,25 +256,19 @@ impl<'d, T: Instance> Rtc<'d, T> {
241 CompareChannel::_3 => 3, 256 CompareChannel::_3 => 3,
242 }; 257 };
243 258
244 T::regs().cc(reg).write(|w| w.set_compare(val)); 259 self.r.cc(reg).write(|w| w.set_compare(val));
245 Ok(()) 260 Ok(())
246 } 261 }
247 262
248 /// Clear the Real Time Counter. 263 /// Clear the Real Time Counter.
249 #[inline] 264 #[inline]
250 pub fn clear(&self) { 265 pub fn clear(&self) {
251 T::regs().tasks_clear().write_value(1); 266 self.r.tasks_clear().write_value(1);
252 } 267 }
253 268
254 /// Obtain the current value of the Real Time Counter, 24 bits of range. 269 /// Obtain the current value of the Real Time Counter, 24 bits of range.
255 #[inline] 270 #[inline]
256 pub fn read(&self) -> u32 { 271 pub fn read(&self) -> u32 {
257 T::regs().counter().read().counter() 272 self.r.counter().read().counter()
258 }
259
260 /// Relase the RTC, returning the underlying peripheral instance.
261 #[inline]
262 pub fn release(self) -> Peri<'d, T> {
263 self.0
264 } 273 }
265} 274}