@@ -202,23 +202,54 @@ impl Rtc {
202
202
} )
203
203
}
204
204
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 {
207
211
let sync_p = self . rtc_config . sync_prescaler as u32 ;
208
212
let ssr = self . rtc . ssr . read ( ) ;
209
213
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 ) {
210
224
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 ( ) ) ) ;
213
225
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 ) {
216
237
let dr = self . rtc . dr . read ( ) ;
217
238
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 ;
220
240
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 ;
222
253
223
254
let time = Time :: from_hms_micro ( hour, minute, second, micro) . unwrap ( ) ;
224
255
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 {
809
840
810
841
tmp + ( value & 0x0F )
811
842
}
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