@@ -202,23 +202,54 @@ impl Rtc {
202202 } )
203203 }
204204
205- /// Get date and time.
206- pub fn get_datetime ( & self ) -> PrimitiveDateTime {
205+ /// Get raw microsecond.
206+ ///
207+ /// Reading `RTC_SSR` locks the values in the higher-order calendar shadow registers
208+ /// until `RTC_DR` is read, so this must be called before `date_raw`.
209+ #[ inline]
210+ fn microsecond_raw ( & self ) -> u32 {
207211 let sync_p = self . rtc_config . sync_prescaler as u32 ;
208212 let ssr = self . rtc . ssr . read ( ) ;
209213 let micro = 1_000_000u32 / ( sync_p + 1 ) * ( sync_p - ssr. ss ( ) . bits ( ) as u32 ) ;
214+
215+ micro
216+ }
217+
218+ /// Get raw hour, minute and second.
219+ ///
220+ /// Reading `RTC_TR` locks the values in the higher-order calendar shadow registers
221+ /// until `RTC_DR` is read, so this must be called before `date_raw`.
222+ #[ inline]
223+ fn time_raw ( & self ) -> ( u8 , u8 , u8 ) {
210224 let tr = self . rtc . tr . read ( ) ;
211- let second = bcd2_to_byte ( ( tr. st ( ) . bits ( ) , tr. su ( ) . bits ( ) ) ) ;
212- let minute = bcd2_to_byte ( ( tr. mnt ( ) . bits ( ) , tr. mnu ( ) . bits ( ) ) ) ;
213225 let hour = bcd2_to_byte ( ( tr. ht ( ) . bits ( ) , tr. hu ( ) . bits ( ) ) ) ;
214- // Reading either RTC_SSR or RTC_TR locks the values in the higher-order
215- // calendar shadow registers until RTC_DR is read.
226+ let minute = bcd2_to_byte ( ( tr. mnt ( ) . bits ( ) , tr. mnu ( ) . bits ( ) ) ) ;
227+ let second = bcd2_to_byte ( ( tr. st ( ) . bits ( ) , tr. su ( ) . bits ( ) ) ) ;
228+
229+ ( hour, minute, second)
230+ }
231+
232+ /// Get raw year (since 1970), month and day.
233+ ///
234+ /// Must be called after `time_raw` and/or `microsecond_raw`.
235+ #[ inline]
236+ fn date_raw ( & self ) -> ( u16 , u8 , u8 ) {
216237 let dr = self . rtc . dr . read ( ) ;
217238
218- // let weekday = dr.wdu().bits();
219- let day = bcd2_to_byte ( ( dr. dt ( ) . bits ( ) , dr. du ( ) . bits ( ) ) ) ;
239+ let year = bcd2_to_byte ( ( dr. yt ( ) . bits ( ) , dr. yu ( ) . bits ( ) ) ) as u16 ;
220240 let month = bcd2_to_byte ( ( dr. mt ( ) . bit ( ) as u8 , dr. mu ( ) . bits ( ) ) ) ;
221- let year = bcd2_to_byte ( ( dr. yt ( ) . bits ( ) , dr. yu ( ) . bits ( ) ) ) as u16 + 1970_u16 ;
241+ let day = bcd2_to_byte ( ( dr. dt ( ) . bits ( ) , dr. du ( ) . bits ( ) ) ) ;
242+ // let weekday = dr.wdu().bits();
243+
244+ ( year, month, day)
245+ }
246+
247+ /// Get date and time.
248+ pub fn get_datetime ( & self ) -> PrimitiveDateTime {
249+ let ( hour, minute, second) = self . time_raw ( ) ;
250+ let micro = self . microsecond_raw ( ) ;
251+ let ( year, month, day) = self . date_raw ( ) ;
252+ let year = year + 1970 ;
222253
223254 let time = Time :: from_hms_micro ( hour, minute, second, micro) . unwrap ( ) ;
224255 let date = Date :: from_calendar_date ( year. into ( ) , month. try_into ( ) . unwrap ( ) , day) . unwrap ( ) ;
@@ -809,3 +840,21 @@ fn bcd2_to_byte(bcd: (u8, u8)) -> u8 {
809840
810841 tmp + ( value & 0x0F )
811842}
843+
844+ #[ cfg( feature = "embedded-sdmmc" ) ]
845+ impl embedded_sdmmc:: TimeSource for Rtc {
846+ #[ inline]
847+ fn get_timestamp ( & self ) -> embedded_sdmmc:: Timestamp {
848+ let ( hour, minute, second) = self . time_raw ( ) ;
849+ let ( year, month, day) = self . date_raw ( ) ;
850+
851+ embedded_sdmmc:: Timestamp {
852+ year_since_1970 : year. try_into ( ) . unwrap ( ) ,
853+ zero_indexed_month : month - 1 ,
854+ zero_indexed_day : day - 1 ,
855+ hours : hour,
856+ minutes : minute,
857+ seconds : second,
858+ }
859+ }
860+ }
0 commit comments