Skip to content

Commit 25e6917

Browse files
committed
STM32 LPTICKER with RTC : optimise sleep duration
1 parent 9da5e48 commit 25e6917

File tree

1 file changed

+40
-5
lines changed

1 file changed

+40
-5
lines changed

targets/TARGET_STM/rtc_api.c

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -346,25 +346,60 @@ uint32_t rtc_read_lp(void)
346346

347347
void rtc_set_wake_up_timer(timestamp_t timestamp)
348348
{
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+
*/
349354
uint32_t WakeUpCounter;
350-
uint32_t current_lp_time;
355+
uint32_t WakeUpClock = RTC_WAKEUPCLOCK_RTCCLK_DIV4;
351356

352-
current_lp_time = rtc_read_lp();
357+
core_util_critical_section_enter();
353358

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();
354364
if (timestamp < current_lp_time) {
355365
WakeUpCounter = 0xFFFFFFFF - current_lp_time + timestamp;
356366
} else {
357367
WakeUpCounter = timestamp - current_lp_time;
358368
}
359369

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+
*/
360378
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+
}
362398
}
363399

364-
core_util_critical_section_enter();
365400
RtcHandle.Instance = RTC;
366401
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) {
368403
error("rtc_set_wake_up_timer init error\n");
369404
}
370405

0 commit comments

Comments
 (0)