application: add periodis RTC wakeup

This commit is contained in:
King Kévin 2020-11-30 14:36:33 +01:00
parent 319a02d2b4
commit 3d00bdf3c0
1 changed files with 41 additions and 9 deletions

View File

@ -36,10 +36,14 @@
/** watchdog period in ms */
#define WATCHDOG_PERIOD 10000
/** wakeup frequency (i.e. least number of times per second to perform the main loop) */
#define WAKEUP_FREQ 16
/** @defgroup main_flags flag set in interrupts to be processed in main task
* @{
*/
static volatile bool rtc_internal_tick_flag = false; /**< flag set when internal RTC ticked */
static volatile bool wakeup_flag = false; /**< flag set when wakeup timer triggered */
static volatile bool second_flag = false; /**< flag set when a second passed */
/** @} */
size_t putc(char c)
@ -408,6 +412,22 @@ void main(void)
}
puts("OK\n");
// setup wakeup timer for periodic checks
puts("setup wakeup: ");
// RTC needs to be configured beforehand
pwr_disable_backup_domain_write_protect(); // disable backup protection so we can write to the RTC registers
rtc_unlock(); // enable writing RTC registers
rtc_clear_wakeup_flag(); // clear flag for fresh start
#if defined(MINIF401)
rtc_set_wakeup_time((32768 / 2) / WAKEUP_FREQ - 1, RTC_CR_WUCLKSEL_RTC_DIV2); // set wakeup time based on LSE (keep highest precision, also enables the wakeup timer)
#else
rtc_set_wakeup_time((32000 / 2) / WAKEUP_FREQ - 1, RTC_CR_WUCLKSEL_RTC_DIV2); // set wakeup time based on LSI (keep highest precision, also enables the wakeup timer)
#endif
rtc_enable_wakeup_timer_interrupt(); // enable interrupt
rtc_lock(); // disable writing RTC registers
// important: do not re-enable backup_domain_write_protect, since this will prevent clearing flags (but RTC registers do not need to be unlocked)
puts("OK\n");
// setup terminal
terminal_prefix = ""; // set default prefix
terminal_process = &process_command; // set central function to process commands
@ -432,15 +452,13 @@ void main(void)
sleep_ms(100); // wait a bit to remove noise and double trigger
button_flag = false; // reset flag
}
/*
if (rtc_internal_tick_flag) { // the internal RTC ticked
rtc_internal_tick_flag = false; // reset flag
action = true; // action has been performed
if (0 == (rtc_get_counter_val() % RTC_TICKS_SECOND)) { // one second has passed
led_toggle(); // toggle LED (good to indicate if main function is stuck)
}
if (wakeup_flag) { // time to do periodic checks
wakeup_flag = false; // clear flag
}
if (second_flag) { // one second passed
second_flag = false; // clear flag
led_toggle(); // toggle LED to indicate if main function is stuck
}
*/
if (action) { // go to sleep if nothing had to be done, else recheck for activity
action = false;
} else {
@ -448,3 +466,17 @@ void main(void)
}
} // main loop
}
/** interrupt service routine when the wakeup timer triggered */
void rtc_wkup_isr(void)
{
static uint16_t tick = WAKEUP_FREQ; // how many wakeup have occurred
exti_reset_request(EXTI22); // clear EXTI flag used by wakeup
rtc_clear_wakeup_flag(); // clear flag
wakeup_flag = true; // notify main loop
tick--; // count the number of ticks down (do it in the ISR to no miss any tick)
if (0 == tick) { // count down completed
second_flag = true; // notify main loop a second has passed
tick = WAKEUP_FREQ; // restart count down
}
}