36
36
37
37
static RTC_HandleTypeDef RtcHandle ;
38
38
39
- #if DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM
40
-
41
- #define GET_TICK_PERIOD (VALUE ) (2048 * 1000000 / VALUE) /* 1s / SynchPrediv value * 2^11 (value to get the maximum precision value with no u32 overflow) */
42
-
43
- static void (* irq_handler )(void );
44
- static void RTC_IRQHandler (void );
45
- static uint32_t lp_TickPeriod_us = GET_TICK_PERIOD (4095 ); /* default SynchPrediv value = 4095 */
46
- #endif /* DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM */
47
-
48
39
void rtc_init (void )
49
40
{
50
41
RCC_OscInitTypeDef RCC_OscInitStruct = {0 };
@@ -119,10 +110,6 @@ void rtc_init(void)
119
110
RtcHandle .Init .OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN ;
120
111
#endif /* TARGET_STM32F1 */
121
112
122
- #if DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM
123
- lp_TickPeriod_us = GET_TICK_PERIOD (RtcHandle .Init .SynchPrediv );
124
- #endif
125
-
126
113
if (HAL_RTC_Init (& RtcHandle ) != HAL_OK ) {
127
114
error ("RTC initialization failed" );
128
115
}
@@ -288,18 +275,41 @@ void rtc_synchronize(void)
288
275
289
276
#if DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM
290
277
278
+ static void RTC_IRQHandler (void );
279
+ static void (* irq_handler )(void );
280
+
281
+ volatile uint8_t lp_Fired = 0 ;
282
+ volatile uint32_t LP_continuous_time = 0 ;
283
+ volatile uint32_t LP_last_RTC_time = 0 ;
284
+
291
285
static void RTC_IRQHandler (void )
292
286
{
293
287
/* Update HAL state */
294
288
RtcHandle .Instance = RTC ;
295
- HAL_RTCEx_WakeUpTimerIRQHandler (& RtcHandle );
296
- /* In case of registered handler, call it. */
297
- if (irq_handler ) {
298
- irq_handler ();
289
+ if (__HAL_RTC_WAKEUPTIMER_GET_IT (& RtcHandle , RTC_IT_WUT )) {
290
+ /* Get the status of the Interrupt */
291
+ if ((uint32_t )(RTC -> CR & RTC_IT_WUT ) != (uint32_t )RESET ) {
292
+ /* Clear the WAKEUPTIMER interrupt pending bit */
293
+ __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG (& RtcHandle , RTC_FLAG_WUTF );
294
+
295
+ lp_Fired = 0 ;
296
+ if (irq_handler ) {
297
+ irq_handler ();
298
+ }
299
+ }
299
300
}
301
+
302
+ if (lp_Fired ) {
303
+ lp_Fired = 0 ;
304
+ if (irq_handler ) {
305
+ irq_handler ();
306
+ }
307
+ }
308
+
309
+ __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG ();
300
310
}
301
311
302
- uint32_t rtc_read_us (void )
312
+ uint32_t rtc_read_lp (void )
303
313
{
304
314
RTC_TimeTypeDef timeStruct = {0 };
305
315
RTC_DateTypeDef dateStruct = {0 };
@@ -316,52 +326,52 @@ uint32_t rtc_read_us(void)
316
326
time/date is one second less than as indicated by RTC_TR/RTC_DR. */
317
327
timeStruct .Seconds -= 1 ;
318
328
}
319
- uint32_t RTCTime = timeStruct .Seconds + timeStruct .Minutes * 60 + timeStruct .Hours * 60 * 60 ;
320
- uint32_t Time_us = ((timeStruct .SecondFraction - timeStruct .SubSeconds ) * lp_TickPeriod_us ) >> 11 ;
329
+ uint32_t RTC_time_s = timeStruct .Seconds + timeStruct .Minutes * 60 + timeStruct .Hours * 60 * 60 ; // Max 0x0001-517F => * 8191 + 8191 = 0x2A2E-AE80
321
330
322
- return (RTCTime * 1000000 ) + Time_us ;
331
+ if (LP_last_RTC_time <= RTC_time_s ) {
332
+ LP_continuous_time += (RTC_time_s - LP_last_RTC_time );
333
+ } else {
334
+ LP_continuous_time += (24 * 60 * 60 + RTC_time_s - LP_last_RTC_time );
335
+ }
336
+ LP_last_RTC_time = RTC_time_s ;
337
+
338
+ return LP_continuous_time * PREDIV_S_VALUE + timeStruct .SecondFraction - timeStruct .SubSeconds ;
323
339
}
324
340
325
- void rtc_set_wake_up_timer (uint32_t delta )
341
+ void rtc_set_wake_up_timer (timestamp_t timestamp )
326
342
{
327
- #define RTC_CLOCK_US (((uint64_t)RTC_CLOCK << 32 ) / 1000000)
328
-
329
343
uint32_t WakeUpCounter ;
330
- uint32_t WakeUpClock ;
331
-
332
- /* Ex for Wakeup period resolution with RTCCLK=32768 Hz :
333
- * RTCCLK_DIV2: ~122us < wakeup period < ~4s
334
- * RTCCLK_DIV4: ~244us < wakeup period < ~8s
335
- * RTCCLK_DIV8: ~488us < wakeup period < ~16s
336
- * RTCCLK_DIV16: ~976us < wakeup period < ~32s
337
- * CK_SPRE_16BITS: 1s < wakeup period < (0xFFFF+ 1) x 1 s = 65536 s (18 hours)
338
- * CK_SPRE_17BITS: 18h+1s < wakeup period < (0x1FFFF+ 1) x 1 s = 131072 s (36 hours)
339
- */
340
- if (delta < (0x10000 * 2 / RTC_CLOCK * 1000000 ) ) { // (0xFFFF + 1) * RTCCLK_DIV2 / RTC_CLOCK * 1s
341
- WakeUpCounter = (((uint64_t )delta * RTC_CLOCK_US ) >> 32 ) >> 1 ;
342
- WakeUpClock = RTC_WAKEUPCLOCK_RTCCLK_DIV2 ;
343
- } else if (delta < (0x10000 * 4 / RTC_CLOCK * 1000000 ) ) {
344
- WakeUpCounter = (((uint64_t )delta * RTC_CLOCK_US ) >> 32 ) >> 2 ;
345
- WakeUpClock = RTC_WAKEUPCLOCK_RTCCLK_DIV4 ;
346
- } else if (delta < (0x10000 * 8 / RTC_CLOCK * 1000000 ) ) {
347
- WakeUpCounter = (((uint64_t )delta * RTC_CLOCK_US ) >> 32 ) >> 3 ;
348
- WakeUpClock = RTC_WAKEUPCLOCK_RTCCLK_DIV8 ;
349
- } else if (delta < (0x10000 * 16 / RTC_CLOCK * 1000000 ) ) {
350
- WakeUpCounter = (((uint64_t )delta * RTC_CLOCK_US ) >> 32 ) >> 4 ;
351
- WakeUpClock = RTC_WAKEUPCLOCK_RTCCLK_DIV16 ;
344
+ uint32_t current_lp_time ;
345
+
346
+ current_lp_time = rtc_read_lp ();
347
+
348
+ if (timestamp < current_lp_time ) {
349
+ WakeUpCounter = 0xFFFFFFFF - current_lp_time + timestamp ;
352
350
} else {
353
- WakeUpCounter = (delta / 1000000 ) ;
354
- WakeUpClock = RTC_WAKEUPCLOCK_CK_SPRE_16BITS ;
351
+ WakeUpCounter = timestamp - current_lp_time ;
355
352
}
356
353
357
- irq_handler = ( void ( * )( void )) lp_ticker_irq_handler ;
358
- NVIC_SetVector ( RTC_WKUP_IRQn , ( uint32_t ) RTC_IRQHandler ) ;
359
- NVIC_EnableIRQ ( RTC_WKUP_IRQn );
354
+ if ( WakeUpCounter > 0xFFFF ) {
355
+ WakeUpCounter = 0xFFFF ;
356
+ }
360
357
361
358
RtcHandle .Instance = RTC ;
362
- if (HAL_RTCEx_SetWakeUpTimer_IT (& RtcHandle , ( uint32_t ) WakeUpCounter , WakeUpClock ) != HAL_OK ) {
359
+ if (HAL_RTCEx_SetWakeUpTimer_IT (& RtcHandle , WakeUpCounter , RTC_WAKEUPCLOCK_RTCCLK_DIV4 ) != HAL_OK ) {
363
360
error ("rtc_set_wake_up_timer init error\n" );
364
361
}
362
+
363
+ NVIC_SetVector (RTC_WKUP_IRQn , (uint32_t )RTC_IRQHandler );
364
+ irq_handler = (void (* )(void ))lp_ticker_irq_handler ;
365
+ NVIC_EnableIRQ (RTC_WKUP_IRQn );
366
+ }
367
+
368
+ void rtc_fire_interrupt (void )
369
+ {
370
+ lp_Fired = 1 ;
371
+ NVIC_SetVector (RTC_WKUP_IRQn , (uint32_t )RTC_IRQHandler );
372
+ irq_handler = (void (* )(void ))lp_ticker_irq_handler ;
373
+ NVIC_SetPendingIRQ (RTC_WKUP_IRQn );
374
+ NVIC_EnableIRQ (RTC_WKUP_IRQn );
365
375
}
366
376
367
377
void rtc_deactivate_wake_up_timer (void )
0 commit comments