From 24beb01c250f763a918ca046deafd58c0a99ba00 Mon Sep 17 00:00:00 2001 From: Matthias Urlichs Date: Fri, 1 Nov 2019 22:30:36 +0100 Subject: [PATCH] Fix mainloop to not lose interrupts --- .../button-irq-printf-lowpower/main.c | 33 ++++++++++++++++--- .../button-irq-printf-lowpower/syscfg.h | 1 + 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/main.c b/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/main.c index 2d051499..61246c1a 100644 --- a/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/main.c +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/main.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,8 @@ static void gpio_setup(void) void BUTTON_DISCO_USER_isr(void) { + state.interrupted = true; + exti_reset_request(BUTTON_DISCO_USER_EXTI); state.pressed = true; if (state.falling) { @@ -76,6 +79,8 @@ void BUTTON_DISCO_USER_isr(void) static void setup_buttons(void) { + state.interrupted = true; + /* Enable EXTI0 interrupt. */ nvic_enable_irq(BUTTON_DISCO_USER_NVIC); @@ -227,6 +232,8 @@ static int setup_rtc_wakeup(int period) void rtc_wkup_isr(void) { + state.interrupted = true; + /* clear flag, not write protected */ RTC_ISR &= ~(RTC_ISR_WUTF); exti_reset_request(EXTI20); @@ -235,6 +242,12 @@ void rtc_wkup_isr(void) static int process_state(volatile struct state_t *st) { + st->interrupted = false; + /* + * TODO: protect against another interrupt arriving while we're in + * here, preferably not by disabling all interrupt processing. + */ + if (st->rtc_ticked) { st->rtc_ticked = 0; printf("Tick: %x\n", (unsigned int) RTC_TR); @@ -294,12 +307,22 @@ int main(void) setup_rtc(); setup_rtc_wakeup(1); + /* + * This example demonstrates how to safely handle interrupts in the + * main loop: we want to avoid a deadlock when the interrupt is + * serviced just before the WFI. + */ while (1) { - PWR_CR |= PWR_CR_LPSDSR; - pwr_set_stop_mode(); - __WFI(); - reset_clocks(); - process_state(&state); + cm_disable_interrupts(); + if(state.interrupted) { + cm_enable_interrupts(); + process_state(&state); + } else { + PWR_CR |= PWR_CR_LPSDSR; + pwr_set_stop_mode(); + __WFI(); + reset_clocks(); + } } return 0; diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/syscfg.h b/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/syscfg.h index 86e713b7..3785c938 100644 --- a/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/syscfg.h +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/syscfg.h @@ -47,6 +47,7 @@ extern "C" { #define TIMER_BUTTON_PRESS_RST RST_TIM7 struct state_t { + bool interrupted; bool falling; bool pressed; int rtc_ticked;