36
36
#include "mbed_critical.h"
37
37
38
38
#if DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM
39
- volatile uint32_t LP_continuous_time = 0 ;
40
- volatile uint32_t LP_last_RTC_time = 0 ;
39
+ volatile uint32_t LPTICKER_counter = 0 ;
40
+ volatile uint32_t LPTICKER_RTC_time = 0 ;
41
41
#endif
42
42
43
43
static int RTC_inited = 0 ;
@@ -261,14 +261,14 @@ void rtc_write(time_t t)
261
261
#endif /* TARGET_STM32F1 */
262
262
263
263
#if DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM
264
- /* Need to update LP_continuous_time value before new RTC time */
264
+ /* Before setting the new time, we need to update the LPTICKER_counter value */
265
+ /* rtc_read_lp function is then called */
265
266
rtc_read_lp ();
266
267
267
- /* LP_last_RTC_time value is updated with the new RTC time */
268
- LP_last_RTC_time = timeStruct .Seconds + timeStruct .Minutes * 60 + timeStruct .Hours * 60 * 60 ;
269
-
270
- /* Save current SSR */
271
- uint32_t Read_SubSeconds = (uint32_t )(RTC -> SSR );
268
+ /* In rtc_read_lp, LPTICKER_RTC_time value has been updated with the current time */
269
+ /* We need now to overwrite the value with the new RTC time */
270
+ /* Note that when a new RTC time is set by HW, the RTC SubSeconds counter is reset to PREDIV_S_VALUE */
271
+ LPTICKER_RTC_time = (timeStruct .Seconds + timeStruct .Minutes * 60 + timeStruct .Hours * 60 * 60 ) * PREDIV_S_VALUE ;
272
272
#endif /* DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM */
273
273
274
274
// Change the RTC current date/time
@@ -279,11 +279,6 @@ void rtc_write(time_t t)
279
279
error ("HAL_RTC_SetTime error\n" );
280
280
}
281
281
282
- #if DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM
283
- while (Read_SubSeconds != (RTC -> SSR )) {
284
- }
285
- #endif /* DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM */
286
-
287
282
core_util_critical_section_exit ();
288
283
}
289
284
@@ -333,11 +328,18 @@ static void RTC_IRQHandler(void)
333
328
334
329
uint32_t rtc_read_lp (void )
335
330
{
331
+ /* RTC_time_tick is the addition of the RTC time register (in second) and the RTC sub-second register
332
+ * This time value is breaking each 24h (= 86400s = 0x15180)
333
+ * In order to get a U32 continuous time information, we use an internal counter : LPTICKER_counter
334
+ * This counter is the addition of each spent time since last function call
335
+ * Current RTC time is saved into LPTICKER_RTC_time
336
+ * NB: rtc_read_lp() output is not the time in us, but the LPTICKER_counter (frequency LSE/4 = 8kHz => 122us)
337
+ */
338
+ core_util_critical_section_enter ();
336
339
struct tm timeinfo ;
337
340
338
341
/* Since the shadow registers are bypassed we have to read the time twice and compare them until both times are the same */
339
342
/* We don't have to read date as we bypass shadow registers */
340
- uint32_t Read_SecondFraction = (uint32_t )(RTC -> PRER & RTC_PRER_PREDIV_S );
341
343
uint32_t Read_time = (uint32_t )(RTC -> TR & RTC_TR_RESERVED_MASK );
342
344
uint32_t Read_SubSeconds = (uint32_t )(RTC -> SSR );
343
345
@@ -350,17 +352,18 @@ uint32_t rtc_read_lp(void)
350
352
timeinfo .tm_min = RTC_Bcd2ToByte ((uint8_t )((Read_time & (RTC_TR_MNT | RTC_TR_MNU )) >> 8 ));
351
353
timeinfo .tm_sec = RTC_Bcd2ToByte ((uint8_t )((Read_time & (RTC_TR_ST | RTC_TR_SU )) >> 0 ));
352
354
353
- uint32_t RTC_time_s = timeinfo .tm_sec + timeinfo .tm_min * 60 + timeinfo .tm_hour * 60 * 60 ; // Max 0x0001-517F => * 8191 + 8191 = 0x2A2E-AE80
355
+ uint32_t RTC_time_tick = ( timeinfo .tm_sec + timeinfo .tm_min * 60 + timeinfo .tm_hour * 60 * 60 ) * PREDIV_S_VALUE + PREDIV_S_VALUE - Read_SubSeconds ; // Max 0x0001-517F * 8191 + 8191 = 0x2A2E-AE80
354
356
355
- if (LP_last_RTC_time <= RTC_time_s ) {
356
- LP_continuous_time += (RTC_time_s - LP_last_RTC_time );
357
+ if (LPTICKER_RTC_time <= RTC_time_tick ) {
358
+ LPTICKER_counter += (RTC_time_tick - LPTICKER_RTC_time );
357
359
} else {
358
- /* Add 24h */
359
- LP_continuous_time += (24 * 60 * 60 + RTC_time_s - LP_last_RTC_time );
360
+ /* When RTC time is 0h00.01 and was 11H59.59, difference is "current time + 24h - previous time" */
361
+ LPTICKER_counter += (RTC_time_tick + 24 * 60 * 60 * PREDIV_S_VALUE - LPTICKER_RTC_time );
360
362
}
361
- LP_last_RTC_time = RTC_time_s ;
363
+ LPTICKER_RTC_time = RTC_time_tick ;
362
364
363
- return LP_continuous_time * PREDIV_S_VALUE + Read_SecondFraction - Read_SubSeconds ;
365
+ core_util_critical_section_exit ();
366
+ return LPTICKER_counter ;
364
367
}
365
368
366
369
void rtc_set_wake_up_timer (timestamp_t timestamp )
@@ -380,6 +383,7 @@ void rtc_set_wake_up_timer(timestamp_t timestamp)
380
383
WakeUpCounter = 0xFFFF ;
381
384
}
382
385
386
+ core_util_critical_section_enter ();
383
387
RtcHandle .Instance = RTC ;
384
388
HAL_RTCEx_DeactivateWakeUpTimer (& RtcHandle );
385
389
if (HAL_RTCEx_SetWakeUpTimer_IT (& RtcHandle , WakeUpCounter , RTC_WAKEUPCLOCK_RTCCLK_DIV4 ) != HAL_OK ) {
@@ -389,6 +393,7 @@ void rtc_set_wake_up_timer(timestamp_t timestamp)
389
393
NVIC_SetVector (RTC_WKUP_IRQn , (uint32_t )RTC_IRQHandler );
390
394
irq_handler = (void (* )(void ))lp_ticker_irq_handler ;
391
395
NVIC_EnableIRQ (RTC_WKUP_IRQn );
396
+ core_util_critical_section_exit ();
392
397
}
393
398
394
399
void rtc_fire_interrupt (void )
0 commit comments