STM32 LPTICKER with RTC : Fix tickless and lp wrapper

When both tickless and LPTICKER_DELAY_TICKS are enabled some ST
devices randomly get stuck sleeping forever. This is because the
wake up time passed to the rtc is ignored if the previous match is
about to occur. This causes the device to get stuck in sleep.

This patch prevents matches from getting dropped by the rtc by
deactivating the rtc wake up timer before setting a new value.

Events leading up to this failure for the RTC:

-1st call to lp_ticker_set_interrupt
-delay until ticker interrupt is about to fire
-2nd call to lp_ticker_set_interrupt
-interrupt for 1st call fires and match time for 2nd call is dropped
-LowPowerTickerWrapper gets ticker interrupt but treats it as a
 spurious interrupt and drops it since it comes in too early
-device enters sleep without a wakeup source and locks up
pull/8242/head
jeromecoutant 2018-09-21 17:11:29 +02:00
parent b1d23e5ec5
commit 9bc2e5a5ad
2 changed files with 2 additions and 5 deletions

View File

@ -258,7 +258,6 @@ uint32_t lp_ticker_read(void)
void lp_ticker_set_interrupt(timestamp_t timestamp)
{
lp_ticker_disable_interrupt();
rtc_set_wake_up_timer(timestamp);
}

View File

@ -389,6 +389,7 @@ void rtc_set_wake_up_timer(timestamp_t timestamp)
}
RtcHandle.Instance = RTC;
HAL_RTCEx_DeactivateWakeUpTimer(&RtcHandle);
if (HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, WakeUpCounter, RTC_WAKEUPCLOCK_RTCCLK_DIV4) != HAL_OK) {
error("rtc_set_wake_up_timer init error\n");
}
@ -410,10 +411,7 @@ void rtc_fire_interrupt(void)
void rtc_deactivate_wake_up_timer(void)
{
RtcHandle.Instance = RTC;
__HAL_RTC_WRITEPROTECTION_DISABLE(&RtcHandle);
__HAL_RTC_WAKEUPTIMER_DISABLE(&RtcHandle);
__HAL_RTC_WAKEUPTIMER_DISABLE_IT(&RtcHandle, RTC_IT_WUT);
__HAL_RTC_WRITEPROTECTION_ENABLE(&RtcHandle);
HAL_RTCEx_DeactivateWakeUpTimer(&RtcHandle);
NVIC_DisableIRQ(RTC_WKUP_IRQn);
}