Fix RTC synchronization after sleep, add many more tests
There were two issues with the tests 1. Incorrect print formats causing incorrect output. 2. The RTC driver was not waiting for the shadow registers to be updated after sleeping, their reset values to be read.
This commit is contained in:
@@ -33,6 +33,9 @@ RtcDriver::RtcSystemTimer RtcDriver::m_sys_timer;
|
||||
|
||||
ReturnCode RtcDriver::init()
|
||||
{
|
||||
m_alarm_count = 0;
|
||||
m_wakeup_count = 0;
|
||||
|
||||
init_hw();
|
||||
|
||||
return ReturnCode::OK;
|
||||
@@ -110,14 +113,16 @@ ReturnCode RtcDriver::init_hw()
|
||||
#elif defined(STM32L4XX)
|
||||
uint32_t temp = RCC->CSR;
|
||||
|
||||
//SET(RCC->CSR, RCC_CSR_RTCRST);
|
||||
// Reset the backup domain (includes the RTC)
|
||||
SET(RCC->BDCR, RCC_BDCR_BDRST);
|
||||
CLR(RCC->BDCR, RCC_BDCR_BDRST);
|
||||
|
||||
SET(RCC->APB1ENR1, RCC_APB1ENR1_PWREN);
|
||||
SET(PWR->CR1, PWR_CR1_DBP);
|
||||
|
||||
SET(temp, RCC_BDCR_LSEON);
|
||||
|
||||
while (!(RCC->BDCR & RCC_BDCR_LSERDY)) {}
|
||||
// while (!(RCC->BDCR & RCC_BDCR_LSERDY)) {}
|
||||
|
||||
SET_TO(temp, RCC_BDCR_RTCSEL, RCC_BDCR_RTCSEL_0);
|
||||
SET(temp, RCC_BDCR_RTCEN);
|
||||
@@ -141,8 +146,8 @@ ReturnCode RtcDriver::init_hw()
|
||||
|
||||
/*<! Load initial date and time */
|
||||
|
||||
// 12-Hour format
|
||||
SET(RTC->CR, RTC_CR_FMT);
|
||||
// 24-Hour format
|
||||
CLR(RTC->CR, RTC_CR_FMT);
|
||||
|
||||
uint32_t time = 0;
|
||||
SET(time, RTC_TR_PM);
|
||||
@@ -163,7 +168,7 @@ ReturnCode RtcDriver::init_hw()
|
||||
// Enable Wakeup irq, we may/will use them later
|
||||
SET(RTC->CR, RTC_CR_WUTIE);
|
||||
NVIC_EnableIRQ(RTC_IRQn);
|
||||
NVIC_SetPriority(RTC_IRQn, 0);
|
||||
NVIC_SetPriority(RTC_IRQn, 1);
|
||||
#elif defined(STM32L4XX)
|
||||
CLR(RTC->ICSR, RTC_ICSR_INIT);
|
||||
|
||||
@@ -173,15 +178,22 @@ ReturnCode RtcDriver::init_hw()
|
||||
// Enable Wakeup irq, we may/will use them later
|
||||
SET(RTC->CR, RTC_CR_WUTIE);
|
||||
NVIC_EnableIRQ(RTC_WKUP_IRQn);
|
||||
NVIC_SetPriority(RTC_WKUP_IRQn, 1);
|
||||
NVIC_SetPriority(RTC_WKUP_IRQn, 0);
|
||||
#else
|
||||
#error "Unsupported device type"
|
||||
#endif
|
||||
enable_periodic_alarm();
|
||||
|
||||
disable_rtc_write();
|
||||
// Disable the wakeup timer. This can be leftover from an old firmware/reset
|
||||
|
||||
//SET(EXTI->SWIER1, EXTI_SWIER1_SWI18);
|
||||
// Clear the interrupt in the RTC
|
||||
SET(RTC->SCR, RTC_SCR_CWUTF);
|
||||
// Disable the Wakeup timer (its periodic, but we use it as a
|
||||
// one-shot timer
|
||||
CLR(RTC->CR, RTC_CR_WUTE);
|
||||
|
||||
|
||||
disable_rtc_write();
|
||||
|
||||
return ReturnCode::OK;
|
||||
}
|
||||
@@ -206,10 +218,6 @@ ReturnCode RtcDriver::get_time(BSP::WallClockTime &wall_time)
|
||||
seconds += 10 * STM32_GET_FIELD(time, RTC_TR_ST);
|
||||
seconds += STM32_GET_FIELD(time, RTC_TR_SU);
|
||||
|
||||
if (STM32_GET_FIELD(time, RTC_TR_PM)) {
|
||||
hours += 12;
|
||||
}
|
||||
|
||||
new (&wall_time) BSP::WallClockTime(hours, minutes, seconds);
|
||||
|
||||
return ReturnCode::OK;
|
||||
@@ -231,14 +239,9 @@ ReturnCode RtcDriver::set_time(const BSP::WallClockTime &wall_time)
|
||||
|
||||
|
||||
/*<! Load initial date and time */
|
||||
|
||||
// 12-Hour format
|
||||
SET(RTC->CR, RTC_CR_FMT);
|
||||
|
||||
uint32_t time = 0;
|
||||
SET_TO(time, RTC_TR_PM, wall_time.get_is_pm() << RTC_TR_PM_Pos);
|
||||
SET_TO(time, RTC_TR_HT, wall_time.get_hours_12_tens() << RTC_TR_HT_Pos);
|
||||
SET_TO(time, RTC_TR_HU, wall_time.get_hours_12_ones() << RTC_TR_HU_Pos);
|
||||
SET_TO(time, RTC_TR_HT, wall_time.get_hours_24_tens() << RTC_TR_HT_Pos);
|
||||
SET_TO(time, RTC_TR_HU, wall_time.get_hours_24_ones() << RTC_TR_HU_Pos);
|
||||
SET_TO(time, RTC_TR_MNT, wall_time.get_minutes_tens() << RTC_TR_MNT_Pos);
|
||||
SET_TO(time, RTC_TR_MNU, wall_time.get_minutes_ones() << RTC_TR_MNU_Pos);
|
||||
SET_TO(time, RTC_TR_ST, wall_time.get_seconds_tens() << RTC_TR_ST_Pos);
|
||||
@@ -247,11 +250,11 @@ ReturnCode RtcDriver::set_time(const BSP::WallClockTime &wall_time)
|
||||
|
||||
#if defined(STM32L0XX)
|
||||
CLR(RTC->ISR, RTC_ISR_INIT);
|
||||
while (!(RTC->ISR & RTC_ISR_INITF)) {}
|
||||
while (!(RTC->ISR & RTC_ISR_INITF)) {} // FIXME: this is probably inverted
|
||||
while (!(RTC->ISR & RTC_ISR_RSF)) {}
|
||||
#elif defined(STM32L4XX)
|
||||
CLR(RTC->ICSR, RTC_ICSR_INIT);
|
||||
while (!(RTC->ICSR & RTC_ICSR_INITF)) {}
|
||||
while ((RTC->ICSR & RTC_ICSR_INITF)) {}
|
||||
while (!(RTC->ICSR & RTC_ICSR_RSF)) {}
|
||||
#else
|
||||
#error "Unsupported device type"
|
||||
@@ -310,6 +313,7 @@ ReturnCode RtcDriver::set_wakeup_in(BSP::time_t wakeup_delay)
|
||||
SET_TO(RTC->WUTR, RTC_WUTR_WUT, delay_cycles - 1);
|
||||
SET_TO(RTC->CR, RTC_CR_WUCKSEL, wucksel << RTC_CR_WUCKSEL_Pos);
|
||||
|
||||
SET(RTC->SCR, RTC_SCR_CWUTF);
|
||||
SET(RTC->CR, RTC_CR_WUTE);
|
||||
|
||||
disable_rtc_write();
|
||||
@@ -322,7 +326,10 @@ BSP::time_t RtcDriver::RtcSystemTimer::get_time()
|
||||
uint32_t new_secs, old_secs, ssr;
|
||||
uint64_t new_timer_ticks, new_millis;
|
||||
|
||||
while (!(RTC->ICSR & RTC_ICSR_WUTWF)) {}
|
||||
enable_rtc_write();
|
||||
RTC->ICSR = ~(RTC_ICSR_INIT | RTC_ICSR_RSF);
|
||||
disable_rtc_write();
|
||||
while (!(RTC->ICSR & RTC_ICSR_RSF)) {}
|
||||
|
||||
do {
|
||||
__disable_irq();
|
||||
@@ -395,9 +402,9 @@ extern "C" void RTC_IRQHandler()
|
||||
|
||||
static void irq_handler() {
|
||||
|
||||
SET(EXTI->PR1, EXTI_PR1_PIF20);
|
||||
if (RTC->SR & RTC_ICSR_WUTWF) {
|
||||
SET(EXTI->PR1, EXTI_PR1_PIF20);
|
||||
|
||||
if (RTC->SR & RTC_SR_WUTF) {
|
||||
RtcDriver::increment_wakeup_count();
|
||||
// Clear the interrupt in the RTC
|
||||
SET(RTC->SCR, RTC_SCR_CWUTF);
|
||||
@@ -423,6 +430,7 @@ extern "C" void RTC_ALARM_IRQHandler()
|
||||
{
|
||||
irq_handler();
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Unsupported device type"
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user