/* * My first project * * It blinks LEDs like counting in binary, when the button is pressed, it reverses the order * * Build on top of libopenocm3, blackbox parts of code (setup()) copied from * libopencm3-examples/examples/stm32/f1/stm32vl-discovery/button project * * Open source licence, let's say Artistic Licence, although it doesn't matter, as it is local only */ #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 4000000 // This is bad -- it's a value that was found to be OK #define STM32F1 1 // Needed for libopencm3 volatile enum {FORWARD, BACKWARD} direction; volatile bool running = false; void setup (void) { // All the blackbox code // Set up clock rcc_clock_setup_in_hse_8mhz_out_24mhz(); // Enable the two GPIOs 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); } // 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(); // Array of what leds should be on uint16_t states[4] = {0, GPIO9, GPIO8, GPIO9 | GPIO8}; char state = 0; int i; // Initial wait while (!running) ; while (true) { for (i=0 ; i