mirror of https://github.com/ARMmbed/mbed-os.git
Safely initialize RTC on kinetis devices
When initializing the RTC on Kinetis devices, handle the case where the time overflow interrupt is pending and the case where the time alarm flag is pending. These flags persist across reset and if not handled will cause a crash when powering up the low power ticker. This problem manifested as a lp_ticker test failure on the K22F and K64F on CI only when running a nightly. This problem has been present but was made obvious by PR #4094 which configures all tickers to interrupt at least every MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA (~31 minutes). This caused the RTC alarm to fire 31 minutes after the lp_ticker or lp_timeout test and caused the next run of the lp_ticker test to crash on boot.pull/4453/head
parent
8d6bc1d47d
commit
f749a2990b
|
@ -33,16 +33,26 @@ static int lptmr_schedule = 0;
|
||||||
|
|
||||||
static void rtc_isr(void)
|
static void rtc_isr(void)
|
||||||
{
|
{
|
||||||
RTC_DisableInterrupts(RTC, kRTC_AlarmInterruptEnable);
|
uint32_t sr = RTC->SR;
|
||||||
RTC->TAR = 0; /* Write clears the IRQ flag */
|
if (sr & RTC_SR_TOF_MASK) {
|
||||||
|
// Reset RTC to 0 so it keeps counting
|
||||||
|
RTC_StopTimer(RTC);
|
||||||
|
RTC->TSR = 0;
|
||||||
|
RTC_StartTimer(RTC);
|
||||||
|
} else if (sr & RTC_SR_TAF_MASK) {
|
||||||
|
RTC_DisableInterrupts(RTC, kRTC_AlarmInterruptEnable);
|
||||||
|
RTC->TAR = 0; /* Write clears the IRQ flag */
|
||||||
|
|
||||||
/* Wait subsecond remainder if any */
|
/* Wait subsecond remainder if any */
|
||||||
if (lptmr_schedule) {
|
if (lptmr_schedule) {
|
||||||
LPTMR_SetTimerPeriod(LPTMR0, lptmr_schedule);
|
LPTMR_SetTimerPeriod(LPTMR0, lptmr_schedule);
|
||||||
LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
|
LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
|
||||||
LPTMR_StartTimer(LPTMR0);
|
LPTMR_StartTimer(LPTMR0);
|
||||||
} else {
|
} else {
|
||||||
lp_ticker_irq_handler();
|
lp_ticker_irq_handler();
|
||||||
|
}
|
||||||
|
} else if (sr & RTC_SR_TIF_MASK) {
|
||||||
|
RTC_DisableInterrupts(RTC, kRTC_TimeOverflowInterruptEnable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +83,7 @@ void lp_ticker_init(void)
|
||||||
RTC_StartTimer(RTC);
|
RTC_StartTimer(RTC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RTC->TAR = 0; /* Write clears the IRQ flag */
|
||||||
NVIC_ClearPendingIRQ(RTC_IRQn);
|
NVIC_ClearPendingIRQ(RTC_IRQn);
|
||||||
NVIC_SetVector(RTC_IRQn, (uint32_t)rtc_isr);
|
NVIC_SetVector(RTC_IRQn, (uint32_t)rtc_isr);
|
||||||
NVIC_EnableIRQ(RTC_IRQn);
|
NVIC_EnableIRQ(RTC_IRQn);
|
||||||
|
|
Loading…
Reference in New Issue