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