11//! RTC peripheral abstraction
22
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+
335use void:: Void ;
436
537use crate :: {
@@ -214,10 +246,9 @@ impl Rtc {
214246
215247 self . write ( false , |rtc| match alarm {
216248 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) { }
221252
222253 rtc. alrmar . modify ( |_, w| unsafe {
223254 w. dt ( )
@@ -241,13 +272,19 @@ impl Rtc {
241272 . wdsel ( )
242273 . clear_bit ( )
243274 } ) ;
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
244281 rtc. cr . modify ( |_, w| w. alrae ( ) . set_bit ( ) ) ;
245282 }
246283 Alarm :: AlarmB => {
247284 rtc. cr . modify ( |_, w| w. alrbe ( ) . clear_bit ( ) ) ;
248285
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 ) { }
251288
252289 rtc. alrmbr . modify ( |_, w| unsafe {
253290 w. dt ( )
@@ -271,10 +308,15 @@ impl Rtc {
271308 . wdsel ( )
272309 . clear_bit ( )
273310 } ) ;
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
274317 rtc. cr . modify ( |_, w| w. alrbe ( ) . set_bit ( ) ) ;
275318 }
276319 } ) ;
277- self . check_interrupt ( alarm. into ( ) , true ) ;
278320 }
279321
280322 /// Starts listening for an interrupt event
@@ -334,27 +376,27 @@ impl Rtc {
334376 /// Checks for an interrupt event
335377 pub fn check_interrupt ( & mut self , event : Event , clear : bool ) -> bool {
336378 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 ) ,
341383 } ;
342384 if clear {
343385 self . write ( false , |rtc| match event {
344386 Event :: WakeupTimer => {
345- rtc . isr . modify ( |_ , w| w . wutf ( ) . clear_bit ( ) ) ;
387+ rtc_registers :: clear_wakeup_timer_flag ( rtc ) ;
346388 unsafe { ( * EXTI :: ptr ( ) ) . pr1 . write ( |w| w. bits ( 1 << 20 ) ) } ;
347389 }
348390 Event :: AlarmA => {
349- rtc . isr . modify ( |_ , w| w . alraf ( ) . clear_bit ( ) ) ;
391+ rtc_registers :: clear_alarm_a_flag ( rtc ) ;
350392 unsafe { ( * EXTI :: ptr ( ) ) . pr1 . write ( |w| w. bits ( 1 << 18 ) ) } ;
351393 }
352394 Event :: AlarmB => {
353- rtc . isr . modify ( |_ , w| w . alrbf ( ) . clear_bit ( ) ) ;
395+ rtc_registers :: clear_alarm_b_flag ( rtc ) ;
354396 unsafe { ( * EXTI :: ptr ( ) ) . pr1 . write ( |w| w. bits ( 1 << 18 ) ) } ;
355397 }
356398 Event :: Timestamp => {
357- rtc . isr . modify ( |_ , w| w . tsf ( ) . clear_bit ( ) ) ;
399+ rtc_registers :: clear_timestamp_flag ( rtc ) ;
358400 unsafe { ( * EXTI :: ptr ( ) ) . pr1 . write ( |w| w. bits ( 1 << 19 ) ) } ;
359401 }
360402 } )
@@ -427,8 +469,7 @@ impl Rtc {
427469 } ) ;
428470
429471 // 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) ;
432473 } ) ;
433474
434475 self . rtc_config = rtc_config;
@@ -448,16 +489,16 @@ impl Rtc {
448489 self . rtc . wpr . write ( |w| unsafe { w. key ( ) . bits ( 0xca ) } ) ;
449490 self . rtc . wpr . write ( |w| unsafe { w. key ( ) . bits ( 0x53 ) } ) ;
450491
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 ) { }
455497 }
456498
457499 let result = f ( & self . rtc ) ;
458-
459500 if init_mode {
460- self . rtc . isr . modify ( |_ , w| w . init ( ) . clear_bit ( ) ) ; // Exits init mode
501+ rtc_registers :: exit_init_mode ( & self . rtc ) ;
461502 }
462503
463504 // Re-enable write protection.
@@ -467,26 +508,22 @@ impl Rtc {
467508 result
468509 }
469510
511+ pub const BACKUP_REGISTER_COUNT : usize = rtc_registers:: BACKUP_REGISTER_COUNT ;
512+
470513 /// Read content of the backup register.
471514 ///
472515 /// The registers retain their values during wakes from standby mode or system resets. They also
473516 /// retain their value when Vdd is switched off as long as V_BAT is powered.
474517 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)
480519 }
481520
482521 /// Set content of the backup register.
483522 ///
484523 /// The registers retain their values during wakes from standby mode or system resets. They also
485524 /// retain their value when Vdd is switched off as long as V_BAT is powered.
486525 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)
490527 }
491528}
492529
@@ -572,7 +609,7 @@ impl timer::CountDown for WakeupTimer<'_> {
572609
573610 // Let's wait for WUTWF to clear. Otherwise we might run into a race
574611 // 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 ) { }
576613 }
577614
578615 fn wait ( & mut self ) -> nb:: Result < ( ) , Void > {
@@ -591,12 +628,8 @@ impl timer::Cancel for WakeupTimer<'_> {
591628 self . rtc . write ( false , |rtc| {
592629 // Disable the wakeup timer
593630 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) ;
600633
601634 // According to the reference manual, section 26.7.4, the WUTF flag
602635 // must be cleared at least 1.5 RTCCLK periods "before WUTF is set
0 commit comments