1
1
//! RTC peripheral abstraction
2
2
3
+ /// refer to AN4759 to compare features of RTC2 and RTC3
4
+ #[ cfg( not( any(
5
+ feature = "stm32l412" ,
6
+ feature = "stm32l422" ,
7
+ feature = "stm32l4p5" ,
8
+ feature = "stm32l4q5"
9
+ ) ) ) ]
10
+ pub mod rtc2;
11
+ #[ cfg( not( any(
12
+ feature = "stm32l412" ,
13
+ feature = "stm32l422" ,
14
+ feature = "stm32l4p5" ,
15
+ feature = "stm32l4q5"
16
+ ) ) ) ]
17
+ pub use rtc2 as rtc_registers;
18
+
19
+ /// refer to AN4759 to compare features of RTC2 and RTC3
20
+ #[ cfg( any(
21
+ feature = "stm32l412" ,
22
+ feature = "stm32l422" ,
23
+ feature = "stm32l4p5" ,
24
+ feature = "stm32l4q5"
25
+ ) ) ]
26
+ pub mod rtc3;
27
+ #[ cfg( any(
28
+ feature = "stm32l412" ,
29
+ feature = "stm32l422" ,
30
+ feature = "stm32l4p5" ,
31
+ feature = "stm32l4q5"
32
+ ) ) ]
33
+ pub use rtc3 as rtc_registers;
34
+
3
35
use void:: Void ;
4
36
5
37
use crate :: {
@@ -214,10 +246,9 @@ impl Rtc {
214
246
215
247
self . write ( false , |rtc| match alarm {
216
248
Alarm :: AlarmA => {
217
- rtc. cr . modify ( |_, w| w. alrae ( ) . clear_bit ( ) ) ;
218
-
219
- // Wait until we're allowed to update the alarm b configuration
220
- while rtc. isr . read ( ) . alrawf ( ) . bit_is_clear ( ) { }
249
+ rtc. cr . modify ( |_, w| w. alrae ( ) . clear_bit ( ) ) ; // Disable Alarm A
250
+ rtc_registers:: clear_alarm_a_flag ( rtc) ;
251
+ while !rtc_registers:: is_alarm_a_accessible ( rtc) { }
221
252
222
253
rtc. alrmar . modify ( |_, w| unsafe {
223
254
w. dt ( )
@@ -241,13 +272,19 @@ impl Rtc {
241
272
. wdsel ( )
242
273
. clear_bit ( )
243
274
} ) ;
275
+ // binary mode alarm not implemented (RTC3 only)
276
+ // subsecond alarm not implemented
277
+ // would need a conversion method between `time.micros` and RTC ticks
278
+ // write the SS value and mask to `rtc.alrmassr`
279
+
280
+ // enable alarm and reenable interrupt if it was enabled
244
281
rtc. cr . modify ( |_, w| w. alrae ( ) . set_bit ( ) ) ;
245
282
}
246
283
Alarm :: AlarmB => {
247
284
rtc. cr . modify ( |_, w| w. alrbe ( ) . clear_bit ( ) ) ;
248
285
249
- // Wait until we're allowed to update the alarm b configuration
250
- while rtc . isr . read ( ) . alrbwf ( ) . bit_is_clear ( ) { }
286
+ rtc_registers :: clear_alarm_b_flag ( rtc ) ;
287
+ while !rtc_registers :: is_alarm_b_accessible ( rtc ) { }
251
288
252
289
rtc. alrmbr . modify ( |_, w| unsafe {
253
290
w. dt ( )
@@ -271,10 +308,15 @@ impl Rtc {
271
308
. wdsel ( )
272
309
. clear_bit ( )
273
310
} ) ;
311
+ // binary mode alarm not implemented (RTC3 only)
312
+ // subsecond alarm not implemented
313
+ // would need a conversion method between `time.micros` and RTC ticks
314
+ // write the SS value and mask to `rtc.alrmbssr`
315
+
316
+ // enable alarm and reenable interrupt if it was enabled
274
317
rtc. cr . modify ( |_, w| w. alrbe ( ) . set_bit ( ) ) ;
275
318
}
276
319
} ) ;
277
- self . check_interrupt ( alarm. into ( ) , true ) ;
278
320
}
279
321
280
322
/// Starts listening for an interrupt event
@@ -334,27 +376,27 @@ impl Rtc {
334
376
/// Checks for an interrupt event
335
377
pub fn check_interrupt ( & mut self , event : Event , clear : bool ) -> bool {
336
378
let result = match event {
337
- Event :: WakeupTimer => self . rtc . isr . read ( ) . wutf ( ) . bit_is_set ( ) ,
338
- Event :: AlarmA => self . rtc . isr . read ( ) . alraf ( ) . bit_is_set ( ) ,
339
- Event :: AlarmB => self . rtc . isr . read ( ) . alrbf ( ) . bit_is_set ( ) ,
340
- Event :: Timestamp => self . rtc . isr . read ( ) . tsf ( ) . bit_is_set ( ) ,
379
+ Event :: WakeupTimer => rtc_registers :: is_wakeup_timer_flag_set ( & self . rtc ) ,
380
+ Event :: AlarmA => rtc_registers :: is_alarm_a_flag_set ( & self . rtc ) ,
381
+ Event :: AlarmB => rtc_registers :: is_alarm_b_flag_set ( & self . rtc ) ,
382
+ Event :: Timestamp => rtc_registers :: is_timestamp_flag_set ( & self . rtc ) ,
341
383
} ;
342
384
if clear {
343
385
self . write ( false , |rtc| match event {
344
386
Event :: WakeupTimer => {
345
- rtc . isr . modify ( |_ , w| w . wutf ( ) . clear_bit ( ) ) ;
387
+ rtc_registers :: clear_wakeup_timer_flag ( rtc ) ;
346
388
unsafe { ( * EXTI :: ptr ( ) ) . pr1 . write ( |w| w. bits ( 1 << 20 ) ) } ;
347
389
}
348
390
Event :: AlarmA => {
349
- rtc . isr . modify ( |_ , w| w . alraf ( ) . clear_bit ( ) ) ;
391
+ rtc_registers :: clear_alarm_a_flag ( rtc ) ;
350
392
unsafe { ( * EXTI :: ptr ( ) ) . pr1 . write ( |w| w. bits ( 1 << 18 ) ) } ;
351
393
}
352
394
Event :: AlarmB => {
353
- rtc . isr . modify ( |_ , w| w . alrbf ( ) . clear_bit ( ) ) ;
395
+ rtc_registers :: clear_alarm_b_flag ( rtc ) ;
354
396
unsafe { ( * EXTI :: ptr ( ) ) . pr1 . write ( |w| w. bits ( 1 << 18 ) ) } ;
355
397
}
356
398
Event :: Timestamp => {
357
- rtc . isr . modify ( |_ , w| w . tsf ( ) . clear_bit ( ) ) ;
399
+ rtc_registers :: clear_timestamp_flag ( rtc ) ;
358
400
unsafe { ( * EXTI :: ptr ( ) ) . pr1 . write ( |w| w. bits ( 1 << 19 ) ) } ;
359
401
}
360
402
} )
@@ -427,8 +469,7 @@ impl Rtc {
427
469
} ) ;
428
470
429
471
// TODO configuration for output pins
430
- rtc. or
431
- . modify ( |_, w| w. rtc_alarm_type ( ) . clear_bit ( ) . rtc_out_rmp ( ) . clear_bit ( ) ) ;
472
+ rtc_registers:: reset_gpio ( rtc) ;
432
473
} ) ;
433
474
434
475
self . rtc_config = rtc_config;
@@ -448,16 +489,16 @@ impl Rtc {
448
489
self . rtc . wpr . write ( |w| unsafe { w. key ( ) . bits ( 0xca ) } ) ;
449
490
self . rtc . wpr . write ( |w| unsafe { w. key ( ) . bits ( 0x53 ) } ) ;
450
491
451
- if init_mode && self . rtc . isr . read ( ) . initf ( ) . bit_is_clear ( ) {
452
- // are we already in init mode?
453
- self . rtc . isr . modify ( |_, w| w. init ( ) . set_bit ( ) ) ;
454
- while self . rtc . isr . read ( ) . initf ( ) . bit_is_clear ( ) { } // wait to return to init state
492
+ if init_mode && !rtc_registers:: is_init_mode ( & self . rtc ) {
493
+ rtc_registers:: enter_init_mode ( & self . rtc ) ;
494
+ // wait till init state entered
495
+ // ~2 RTCCLK cycles
496
+ while !rtc_registers:: is_init_mode ( & self . rtc ) { }
455
497
}
456
498
457
499
let result = f ( & self . rtc ) ;
458
-
459
500
if init_mode {
460
- self . rtc . isr . modify ( |_ , w| w . init ( ) . clear_bit ( ) ) ; // Exits init mode
501
+ rtc_registers :: exit_init_mode ( & self . rtc ) ;
461
502
}
462
503
463
504
// Re-enable write protection.
@@ -467,26 +508,22 @@ impl Rtc {
467
508
result
468
509
}
469
510
511
+ pub const BACKUP_REGISTER_COUNT : usize = rtc_registers:: BACKUP_REGISTER_COUNT ;
512
+
470
513
/// Read content of the backup register.
471
514
///
472
515
/// The registers retain their values during wakes from standby mode or system resets. They also
473
516
/// retain their value when Vdd is switched off as long as V_BAT is powered.
474
517
pub fn read_backup_register ( & self , register : usize ) -> Option < u32 > {
475
- if register < 32 {
476
- Some ( self . rtc . bkpr [ register] . read ( ) . bits ( ) )
477
- } else {
478
- None
479
- }
518
+ rtc_registers:: read_backup_register ( & self . rtc , register)
480
519
}
481
520
482
521
/// Set content of the backup register.
483
522
///
484
523
/// The registers retain their values during wakes from standby mode or system resets. They also
485
524
/// retain their value when Vdd is switched off as long as V_BAT is powered.
486
525
pub fn write_backup_register ( & self , register : usize , value : u32 ) {
487
- if register < 32 {
488
- unsafe { self . rtc . bkpr [ register] . write ( |w| w. bits ( value) ) }
489
- }
526
+ rtc_registers:: write_backup_register ( & self . rtc , register, value)
490
527
}
491
528
}
492
529
@@ -572,7 +609,7 @@ impl timer::CountDown for WakeupTimer<'_> {
572
609
573
610
// Let's wait for WUTWF to clear. Otherwise we might run into a race
574
611
// condition, if the user calls this method again really quickly.
575
- while self . rtc . rtc . isr . read ( ) . wutwf ( ) . bit_is_set ( ) { }
612
+ while rtc_registers :: is_wakeup_timer_write_flag_set ( & self . rtc . rtc ) { }
576
613
}
577
614
578
615
fn wait ( & mut self ) -> nb:: Result < ( ) , Void > {
@@ -591,12 +628,8 @@ impl timer::Cancel for WakeupTimer<'_> {
591
628
self . rtc . write ( false , |rtc| {
592
629
// Disable the wakeup timer
593
630
rtc. cr . modify ( |_, w| w. wute ( ) . clear_bit ( ) ) ;
594
-
595
- // Wait until we're allowed to update the wakeup timer configuration
596
- while rtc. isr . read ( ) . wutwf ( ) . bit_is_clear ( ) { }
597
-
598
- // Clear wakeup timer flag
599
- rtc. isr . modify ( |_, w| w. wutf ( ) . clear_bit ( ) ) ;
631
+ while rtc_registers:: is_wakeup_timer_write_flag_set ( & rtc) { }
632
+ rtc_registers:: clear_wakeup_timer_flag ( rtc) ;
600
633
601
634
// According to the reference manual, section 26.7.4, the WUTF flag
602
635
// must be cleared at least 1.5 RTCCLK periods "before WUTF is set
0 commit comments