aboutsummaryrefslogtreecommitdiff
path: root/embassy-mcxa
diff options
context:
space:
mode:
authorJames Munns <[email protected]>2025-12-11 16:34:23 +0000
committerGitHub <[email protected]>2025-12-11 16:34:23 +0000
commit802dfbb9f8a3de42f132a3e95682552aefcd50c0 (patch)
treec7e394bac35d5d50524d41a0a19669129ea3242e /embassy-mcxa
parent9a12d8dd5be520f44536106743ba50adafcd2b80 (diff)
parent5eae94057016407c3ed40316bffae9c8efa56247 (diff)
Merge pull request #5038 from jamesmunns/james/retouch-rtc
[MCXA]: Remove instance generic from RTC
Diffstat (limited to 'embassy-mcxa')
-rw-r--r--embassy-mcxa/src/rtc.rs78
1 files changed, 34 insertions, 44 deletions
diff --git a/embassy-mcxa/src/rtc.rs b/embassy-mcxa/src/rtc.rs
index f975d9c9f..c5474d34a 100644
--- a/embassy-mcxa/src/rtc.rs
+++ b/embassy-mcxa/src/rtc.rs
@@ -9,8 +9,6 @@ use crate::interrupt::typelevel::{Handler, Interrupt};
9use crate::pac; 9use crate::pac;
10use crate::pac::rtc0::cr::Um; 10use crate::pac::rtc0::cr::Um;
11 11
12type Regs = pac::rtc0::RegisterBlock;
13
14/// Global wait cell for alarm notifications 12/// Global wait cell for alarm notifications
15static WAKER: WaitCell = WaitCell::new(); 13static WAKER: WaitCell = WaitCell::new();
16 14
@@ -22,7 +20,7 @@ pub struct InterruptHandler<I: Instance> {
22/// Trait for RTC peripheral instances 20/// Trait for RTC peripheral instances
23pub trait Instance: PeripheralType { 21pub trait Instance: PeripheralType {
24 type Interrupt: Interrupt; 22 type Interrupt: Interrupt;
25 fn ptr() -> *const Regs; 23 fn ptr() -> &'static pac::rtc0::RegisterBlock;
26} 24}
27 25
28/// Token for RTC0 26/// Token for RTC0
@@ -30,8 +28,8 @@ pub type Rtc0 = crate::peripherals::RTC0;
30impl Instance for crate::peripherals::RTC0 { 28impl Instance for crate::peripherals::RTC0 {
31 type Interrupt = crate::interrupt::typelevel::RTC; 29 type Interrupt = crate::interrupt::typelevel::RTC;
32 #[inline(always)] 30 #[inline(always)]
33 fn ptr() -> *const Regs { 31 fn ptr() -> &'static pac::rtc0::RegisterBlock {
34 pac::Rtc0::ptr() 32 unsafe { &*pac::Rtc0::ptr() }
35 } 33 }
36} 34}
37 35
@@ -204,18 +202,19 @@ pub fn get_default_config() -> RtcConfig {
204 } 202 }
205} 203}
206/// Minimal RTC handle for a specific instance I (store the zero-sized token like embassy) 204/// Minimal RTC handle for a specific instance I (store the zero-sized token like embassy)
207pub struct Rtc<'a, I: Instance> { 205pub struct Rtc<'a> {
208 _inst: core::marker::PhantomData<&'a mut I>, 206 _inst: core::marker::PhantomData<&'a mut ()>,
207 info: &'static pac::rtc0::RegisterBlock,
209} 208}
210 209
211impl<'a, I: Instance> Rtc<'a, I> { 210impl<'a> Rtc<'a> {
212 /// Create a new instance of the real time clock. 211 /// Create a new instance of the real time clock.
213 pub fn new( 212 pub fn new<I: Instance>(
214 _inst: Peri<'a, I>, 213 _inst: Peri<'a, I>,
215 _irq: impl crate::interrupt::typelevel::Binding<I::Interrupt, InterruptHandler<I>> + 'a, 214 _irq: impl crate::interrupt::typelevel::Binding<I::Interrupt, InterruptHandler<I>> + 'a,
216 config: RtcConfig, 215 config: RtcConfig,
217 ) -> Self { 216 ) -> Self {
218 let rtc = unsafe { &*I::ptr() }; 217 let info = I::ptr();
219 218
220 // The RTC is NOT gated by the MRCC, but we DO need to make sure the 16k clock 219 // The RTC is NOT gated by the MRCC, but we DO need to make sure the 16k clock
221 // on the vsys domain is active 220 // on the vsys domain is active
@@ -227,13 +226,13 @@ impl<'a, I: Instance> Rtc<'a, I> {
227 } 226 }
228 227
229 // RTC reset 228 // RTC reset
230 rtc.cr().modify(|_, w| w.swr().set_bit()); 229 info.cr().modify(|_, w| w.swr().set_bit());
231 rtc.cr().modify(|_, w| w.swr().clear_bit()); 230 info.cr().modify(|_, w| w.swr().clear_bit());
232 rtc.tsr().write(|w| unsafe { w.bits(1) }); 231 info.tsr().write(|w| unsafe { w.bits(1) });
233 232
234 rtc.cr().modify(|_, w| w.um().variant(config.update_mode)); 233 info.cr().modify(|_, w| w.um().variant(config.update_mode));
235 234
236 rtc.tcr().modify(|_, w| unsafe { 235 info.tcr().modify(|_, w| unsafe {
237 w.cir() 236 w.cir()
238 .bits(config.compensation_interval) 237 .bits(config.compensation_interval)
239 .tcr() 238 .tcr()
@@ -246,6 +245,7 @@ impl<'a, I: Instance> Rtc<'a, I> {
246 245
247 Self { 246 Self {
248 _inst: core::marker::PhantomData, 247 _inst: core::marker::PhantomData,
248 info,
249 } 249 }
250 } 250 }
251 251
@@ -259,9 +259,8 @@ impl<'a, I: Instance> Rtc<'a, I> {
259 /// 259 ///
260 /// The datetime is converted to Unix timestamp and written to the time seconds register. 260 /// The datetime is converted to Unix timestamp and written to the time seconds register.
261 pub fn set_datetime(&self, datetime: RtcDateTime) { 261 pub fn set_datetime(&self, datetime: RtcDateTime) {
262 let rtc = unsafe { &*I::ptr() };
263 let seconds = convert_datetime_to_seconds(&datetime); 262 let seconds = convert_datetime_to_seconds(&datetime);
264 rtc.tsr().write(|w| unsafe { w.bits(seconds) }); 263 self.info.tsr().write(|w| unsafe { w.bits(seconds) });
265 } 264 }
266 265
267 /// Get the current date and time 266 /// Get the current date and time
@@ -274,8 +273,7 @@ impl<'a, I: Instance> Rtc<'a, I> {
274 /// 273 ///
275 /// Reads the current Unix timestamp from the time seconds register and converts it. 274 /// Reads the current Unix timestamp from the time seconds register and converts it.
276 pub fn get_datetime(&self) -> RtcDateTime { 275 pub fn get_datetime(&self) -> RtcDateTime {
277 let rtc = unsafe { &*I::ptr() }; 276 let seconds = self.info.tsr().read().bits();
278 let seconds = rtc.tsr().read().bits();
279 convert_seconds_to_datetime(seconds) 277 convert_seconds_to_datetime(seconds)
280 } 278 }
281 279
@@ -295,19 +293,18 @@ impl<'a, I: Instance> Rtc<'a, I> {
295 /// - Uses timeouts to prevent infinite loops 293 /// - Uses timeouts to prevent infinite loops
296 /// - Enables the alarm interrupt after setting 294 /// - Enables the alarm interrupt after setting
297 pub fn set_alarm(&self, alarm: RtcDateTime) { 295 pub fn set_alarm(&self, alarm: RtcDateTime) {
298 let rtc = unsafe { &*I::ptr() };
299 let seconds = convert_datetime_to_seconds(&alarm); 296 let seconds = convert_datetime_to_seconds(&alarm);
300 297
301 rtc.tar().write(|w| unsafe { w.bits(0) }); 298 self.info.tar().write(|w| unsafe { w.bits(0) });
302 let mut timeout = 10000; 299 let mut timeout = 10000;
303 while rtc.tar().read().bits() != 0 && timeout > 0 { 300 while self.info.tar().read().bits() != 0 && timeout > 0 {
304 timeout -= 1; 301 timeout -= 1;
305 } 302 }
306 303
307 rtc.tar().write(|w| unsafe { w.bits(seconds) }); 304 self.info.tar().write(|w| unsafe { w.bits(seconds) });
308 305
309 let mut timeout = 10000; 306 let mut timeout = 10000;
310 while rtc.tar().read().bits() != seconds && timeout > 0 { 307 while self.info.tar().read().bits() != seconds && timeout > 0 {
311 timeout -= 1; 308 timeout -= 1;
312 } 309 }
313 310
@@ -324,8 +321,7 @@ impl<'a, I: Instance> Rtc<'a, I> {
324 /// 321 ///
325 /// Reads the alarm timestamp from the time alarm register and converts it. 322 /// Reads the alarm timestamp from the time alarm register and converts it.
326 pub fn get_alarm(&self) -> RtcDateTime { 323 pub fn get_alarm(&self) -> RtcDateTime {
327 let rtc = unsafe { &*I::ptr() }; 324 let alarm_seconds = self.info.tar().read().bits();
328 let alarm_seconds = rtc.tar().read().bits();
329 convert_seconds_to_datetime(alarm_seconds) 325 convert_seconds_to_datetime(alarm_seconds)
330 } 326 }
331 327
@@ -335,8 +331,7 @@ impl<'a, I: Instance> Rtc<'a, I> {
335 /// 331 ///
336 /// Sets the Time Counter Enable (TCE) bit in the status register. 332 /// Sets the Time Counter Enable (TCE) bit in the status register.
337 pub fn start(&self) { 333 pub fn start(&self) {
338 let rtc = unsafe { &*I::ptr() }; 334 self.info.sr().modify(|_, w| w.tce().set_bit());
339 rtc.sr().modify(|_, w| w.tce().set_bit());
340 } 335 }
341 336
342 /// Stop the RTC time counter 337 /// Stop the RTC time counter
@@ -345,8 +340,7 @@ impl<'a, I: Instance> Rtc<'a, I> {
345 /// 340 ///
346 /// Clears the Time Counter Enable (TCE) bit in the status register. 341 /// Clears the Time Counter Enable (TCE) bit in the status register.
347 pub fn stop(&self) { 342 pub fn stop(&self) {
348 let rtc = unsafe { &*I::ptr() }; 343 self.info.sr().modify(|_, w| w.tce().clear_bit());
349 rtc.sr().modify(|_, w| w.tce().clear_bit());
350 } 344 }
351 345
352 /// Enable specific RTC interrupts 346 /// Enable specific RTC interrupts
@@ -364,19 +358,17 @@ impl<'a, I: Instance> Rtc<'a, I> {
364 /// - Alarm Interrupt 358 /// - Alarm Interrupt
365 /// - Seconds Interrupt 359 /// - Seconds Interrupt
366 pub fn set_interrupt(&self, mask: u32) { 360 pub fn set_interrupt(&self, mask: u32) {
367 let rtc = unsafe { &*I::ptr() };
368
369 if (RtcInterruptEnable::RTC_TIME_INVALID_INTERRUPT_ENABLE & mask) != 0 { 361 if (RtcInterruptEnable::RTC_TIME_INVALID_INTERRUPT_ENABLE & mask) != 0 {
370 rtc.ier().modify(|_, w| w.tiie().tiie_1()); 362 self.info.ier().modify(|_, w| w.tiie().tiie_1());
371 } 363 }
372 if (RtcInterruptEnable::RTC_TIME_OVERFLOW_INTERRUPT_ENABLE & mask) != 0 { 364 if (RtcInterruptEnable::RTC_TIME_OVERFLOW_INTERRUPT_ENABLE & mask) != 0 {
373 rtc.ier().modify(|_, w| w.toie().toie_1()); 365 self.info.ier().modify(|_, w| w.toie().toie_1());
374 } 366 }
375 if (RtcInterruptEnable::RTC_ALARM_INTERRUPT_ENABLE & mask) != 0 { 367 if (RtcInterruptEnable::RTC_ALARM_INTERRUPT_ENABLE & mask) != 0 {
376 rtc.ier().modify(|_, w| w.taie().taie_1()); 368 self.info.ier().modify(|_, w| w.taie().taie_1());
377 } 369 }
378 if (RtcInterruptEnable::RTC_SECONDS_INTERRUPT_ENABLE & mask) != 0 { 370 if (RtcInterruptEnable::RTC_SECONDS_INTERRUPT_ENABLE & mask) != 0 {
379 rtc.ier().modify(|_, w| w.tsie().tsie_1()); 371 self.info.ier().modify(|_, w| w.tsie().tsie_1());
380 } 372 }
381 } 373 }
382 374
@@ -390,19 +382,17 @@ impl<'a, I: Instance> Rtc<'a, I> {
390 /// 382 ///
391 /// This function disables the specified interrupt types. 383 /// This function disables the specified interrupt types.
392 pub fn disable_interrupt(&self, mask: u32) { 384 pub fn disable_interrupt(&self, mask: u32) {
393 let rtc = unsafe { &*I::ptr() };
394
395 if (RtcInterruptEnable::RTC_TIME_INVALID_INTERRUPT_ENABLE & mask) != 0 { 385 if (RtcInterruptEnable::RTC_TIME_INVALID_INTERRUPT_ENABLE & mask) != 0 {
396 rtc.ier().modify(|_, w| w.tiie().tiie_0()); 386 self.info.ier().modify(|_, w| w.tiie().tiie_0());
397 } 387 }
398 if (RtcInterruptEnable::RTC_TIME_OVERFLOW_INTERRUPT_ENABLE & mask) != 0 { 388 if (RtcInterruptEnable::RTC_TIME_OVERFLOW_INTERRUPT_ENABLE & mask) != 0 {
399 rtc.ier().modify(|_, w| w.toie().toie_0()); 389 self.info.ier().modify(|_, w| w.toie().toie_0());
400 } 390 }
401 if (RtcInterruptEnable::RTC_ALARM_INTERRUPT_ENABLE & mask) != 0 { 391 if (RtcInterruptEnable::RTC_ALARM_INTERRUPT_ENABLE & mask) != 0 {
402 rtc.ier().modify(|_, w| w.taie().taie_0()); 392 self.info.ier().modify(|_, w| w.taie().taie_0());
403 } 393 }
404 if (RtcInterruptEnable::RTC_SECONDS_INTERRUPT_ENABLE & mask) != 0 { 394 if (RtcInterruptEnable::RTC_SECONDS_INTERRUPT_ENABLE & mask) != 0 {
405 rtc.ier().modify(|_, w| w.tsie().tsie_0()); 395 self.info.ier().modify(|_, w| w.tsie().tsie_0());
406 } 396 }
407 } 397 }
408 398
@@ -412,8 +402,7 @@ impl<'a, I: Instance> Rtc<'a, I> {
412 /// 402 ///
413 /// This function clears the Time Alarm Interrupt Enable bit. 403 /// This function clears the Time Alarm Interrupt Enable bit.
414 pub fn clear_alarm_flag(&self) { 404 pub fn clear_alarm_flag(&self) {
415 let rtc = unsafe { &*I::ptr() }; 405 self.info.ier().modify(|_, w| w.taie().clear_bit());
416 rtc.ier().modify(|_, w| w.taie().clear_bit());
417 } 406 }
418 407
419 /// Wait for an RTC alarm to trigger. 408 /// Wait for an RTC alarm to trigger.
@@ -421,6 +410,7 @@ impl<'a, I: Instance> Rtc<'a, I> {
421 /// # Arguments 410 /// # Arguments
422 /// 411 ///
423 /// * `alarm` - The date and time when the alarm should trigger 412 /// * `alarm` - The date and time when the alarm should trigger
413 ///
424 /// This function will wait until the RTC alarm is triggered. 414 /// This function will wait until the RTC alarm is triggered.
425 /// If no alarm is scheduled, it will wait indefinitely until one is scheduled and triggered. 415 /// If no alarm is scheduled, it will wait indefinitely until one is scheduled and triggered.
426 pub async fn wait_for_alarm(&mut self, alarm: RtcDateTime) { 416 pub async fn wait_for_alarm(&mut self, alarm: RtcDateTime) {