From dc0ff5562c15cc2ef1637681df99abfbb1ec6620 Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Mon, 13 Apr 2020 02:43:47 +0200 Subject: [PATCH] Implement IRQ handling of the button --- main.c | 56 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/main.c b/main.c index 00aa67a..122b650 100644 --- a/main.c +++ b/main.c @@ -11,12 +11,17 @@ #include #include +#include +#include #include //#define DELAY 8000000 // Should be a second, or maybe not (second iff 8MHz clk, 1/3second if 24MHz clk) // Too long!! -#define DELAY 400000 // This is bad -- it's a value that was found to be OK +#define DELAY 4000000 // This is bad -- it's a value that was found to be OK #define STM32F1 1 // Needed for libopencm3 +enum {FORWARD, BACKWARD} direction; +bool running = false; + void setup (void) { // All the blackbox code // Set up clock @@ -26,44 +31,59 @@ void setup (void) { // All the blackbox code rcc_periph_clock_enable(RCC_GPIOC); rcc_periph_clock_enable(RCC_GPIOA); + // Enable AFIO (we need that to map GPIO to EXTI) + rcc_periph_clock_enable(RCC_AFIO); + + // Enable EXTI0 interrupt. + // The interrupts are a bit magic, as the Internet says (the datasheet for F100RBT6B does not mention the EXTI/NVIC interface) + // This one is for EXTI0 ~~ GPIOx0 pins + nvic_enable_irq(NVIC_EXTI0_IRQ); + // GPIO C8 amd C9 are the two LEDs gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO8 | GPIO9); // GPIO A0 is the push button + // And we set it as a regular button and enable its interrupts in the next block gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO0); + + // Configure the EXTI0 interrupts + // 1. Which pin + exti_select_source(EXTI0, GPIOA); + // 2. Which edge + exti_set_trigger(EXTI0, EXTI_TRIGGER_RISING); + // 3. Enable the interrupts + exti_enable_request(EXTI0); } -void initial_wait (void) { - gpio_clear(GPIOC, GPIO8 | GPIO9); - while (gpio_get(GPIOA, GPIO0) == 0); - return; +// libopencm3 has a pre-declared interrupt handlers, so it needs to have this name +void exti0_isr (void) { + // Clear the interrupt + exti_reset_request(EXTI0); + // NB: For some reason it is at the begining in the examples + // It needs to be here (possibly because of reordering, when this was at the end, I usually got the interrupt twice). + + if (!running) { + direction = FORWARD; + } else { + direction = direction == FORWARD ? BACKWARD : FORWARD; + } + running = true; } + int main (void) { setup(); - initial_wait(); - // Array of what leds should be on uint16_t states[4] = {0, GPIO9, GPIO8, GPIO9 | GPIO8}; - enum {FORWARD, BACKWARD} direction = FORWARD; - bool pressed = true; - bool change = false; char state = 0; int i; while (true) { - change = false; for (i=0 ; i