Skip to content

Commit 99778bd

Browse files
authored
Merge pull request #8777 from jeromecoutant/PR_LP_RTC
STM32 LPTICKER with RTC : better sleep time
2 parents c7a5ef5 + 25e6917 commit 99778bd

File tree

1 file changed

+45
-5
lines changed

1 file changed

+45
-5
lines changed

targets/TARGET_STM/rtc_api.c

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@ void rtc_write(time_t t)
217217
RTC_DateTypeDef dateStruct = {0};
218218
RTC_TimeTypeDef timeStruct = {0};
219219

220+
/* if the requested time is the current time, no need to continue */
221+
if (t == rtc_read()) {
222+
return;
223+
}
224+
220225
core_util_critical_section_enter();
221226
RtcHandle.Instance = RTC;
222227

@@ -353,25 +358,60 @@ uint32_t rtc_read_lp(void)
353358

354359
void rtc_set_wake_up_timer(timestamp_t timestamp)
355360
{
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+
*/
356366
uint32_t WakeUpCounter;
357-
uint32_t current_lp_time;
367+
uint32_t WakeUpClock = RTC_WAKEUPCLOCK_RTCCLK_DIV4;
358368

359-
current_lp_time = rtc_read_lp();
369+
core_util_critical_section_enter();
360370

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();
361376
if (timestamp < current_lp_time) {
362377
WakeUpCounter = 0xFFFFFFFF - current_lp_time + timestamp;
363378
} else {
364379
WakeUpCounter = timestamp - current_lp_time;
365380
}
366381

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+
*/
367390
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+
}
369410
}
370411

371-
core_util_critical_section_enter();
372412
RtcHandle.Instance = RTC;
373413
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) {
375415
error("rtc_set_wake_up_timer init error\n");
376416
}
377417

0 commit comments

Comments
 (0)