@@ -346,25 +346,60 @@ uint32_t rtc_read_lp(void)
346
346
347
347
void rtc_set_wake_up_timer (timestamp_t timestamp )
348
348
{
349
+ /* RTC periodic auto wake up timer is used
350
+ * This WakeUpTimer is loaded to an init value => WakeUpCounter
351
+ * then timer starts counting down (even in low-power modes)
352
+ * When it reaches 0, the WUTF flag is set in the RTC_ISR register
353
+ */
349
354
uint32_t WakeUpCounter ;
350
- uint32_t current_lp_time ;
355
+ uint32_t WakeUpClock = RTC_WAKEUPCLOCK_RTCCLK_DIV4 ;
351
356
352
- current_lp_time = rtc_read_lp ();
357
+ core_util_critical_section_enter ();
353
358
359
+ /* MBED API gives the timestamp value to set
360
+ * WakeUpCounter is then the delta between timestamp and the current tick (LPTICKER_counter)
361
+ * If the current tick preceeds timestamp value, max U32 is added
362
+ */
363
+ uint32_t current_lp_time = rtc_read_lp ();
354
364
if (timestamp < current_lp_time ) {
355
365
WakeUpCounter = 0xFFFFFFFF - current_lp_time + timestamp ;
356
366
} else {
357
367
WakeUpCounter = timestamp - current_lp_time ;
358
368
}
359
369
370
+ /* RTC WakeUpCounter is 16 bits
371
+ * Corresponding time value depends on WakeUpClock
372
+ * - RTC clock divided by 4 : max WakeUpCounter value is 8s (precision around 122 us)
373
+ * - RTC clock divided by 8 : max WakeUpCounter value is 16s (precision around 244 us)
374
+ * - RTC clock divided by 16 : max WakeUpCounter value is 32s (precision around 488 us)
375
+ * - 1 Hz internal clock 16b : max WakeUpCounter value is 18h (precision 1 s)
376
+ * - 1 Hz internal clock 17b : max WakeUpCounter value is 36h (precision 1 s)
377
+ */
360
378
if (WakeUpCounter > 0xFFFF ) {
361
- WakeUpCounter = 0xFFFF ;
379
+ WakeUpClock = RTC_WAKEUPCLOCK_RTCCLK_DIV8 ;
380
+ WakeUpCounter = WakeUpCounter / 2 ;
381
+
382
+ if (WakeUpCounter > 0xFFFF ) {
383
+ WakeUpClock = RTC_WAKEUPCLOCK_RTCCLK_DIV16 ;
384
+ WakeUpCounter = WakeUpCounter / 2 ;
385
+
386
+ if (WakeUpCounter > 0xFFFF ) {
387
+ /* Tick value needs to be translated in seconds : TICK * 16 (previous div16 value) / RTC clock (32768) */
388
+ WakeUpClock = RTC_WAKEUPCLOCK_CK_SPRE_16BITS ;
389
+ WakeUpCounter = WakeUpCounter / 2048 ;
390
+
391
+ if (WakeUpCounter > 0xFFFF ) {
392
+ /* In this case 2^16 is added to the 16-bit counter value */
393
+ WakeUpClock = RTC_WAKEUPCLOCK_CK_SPRE_17BITS ;
394
+ WakeUpCounter = WakeUpCounter - 0x10000 ;
395
+ }
396
+ }
397
+ }
362
398
}
363
399
364
- core_util_critical_section_enter ();
365
400
RtcHandle .Instance = RTC ;
366
401
HAL_RTCEx_DeactivateWakeUpTimer (& RtcHandle );
367
- if (HAL_RTCEx_SetWakeUpTimer_IT (& RtcHandle , WakeUpCounter , RTC_WAKEUPCLOCK_RTCCLK_DIV4 ) != HAL_OK ) {
402
+ if (HAL_RTCEx_SetWakeUpTimer_IT (& RtcHandle , WakeUpCounter , WakeUpClock ) != HAL_OK ) {
368
403
error ("rtc_set_wake_up_timer init error\n" );
369
404
}
370
405
0 commit comments