From 3d00bdf3c069031138889d7cbe975bc1a0899439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Mon, 30 Nov 2020 14:36:33 +0100 Subject: [PATCH] application: add periodis RTC wakeup --- application.c | 50 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/application.c b/application.c index 2d457bc..20222e3 100644 --- a/application.c +++ b/application.c @@ -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 + } +}