diff --git a/examples/stm32/f1/waveshare-open103r/joystick/Makefile b/examples/stm32/f1/waveshare-open103r/joystick/Makefile new file mode 100644 index 0000000..c11fe1a --- /dev/null +++ b/examples/stm32/f1/waveshare-open103r/joystick/Makefile @@ -0,0 +1,26 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2013 Joshua Harlan Lifton +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +BINARY = joystick + +LDSCRIPT = ../waveshare-open103r.ld + +include ../../Makefile.include + diff --git a/examples/stm32/f1/waveshare-open103r/joystick/README b/examples/stm32/f1/waveshare-open103r/joystick/README new file mode 100644 index 0000000..3fffc3c --- /dev/null +++ b/examples/stm32/f1/waveshare-open103r/joystick/README @@ -0,0 +1,11 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This example uses the joystick to control the four LEDs on the +WaveShare Open103R eval board. Joystick directions referenced here are +relative to the text printed on the eval board. Pressing up will +cycle the LED to a lower numbered LED (e.g. LED4 -> LED3 and LED1 -> +LED4), pressing down will cycle the LED the other way, pressing left +will turn on all LEDs, pressing right will turn off all LEDs, and +pressing center will toggle between blinking and solid on. diff --git a/examples/stm32/f1/waveshare-open103r/joystick/joystick.c b/examples/stm32/f1/waveshare-open103r/joystick/joystick.c new file mode 100644 index 0000000..69ce194 --- /dev/null +++ b/examples/stm32/f1/waveshare-open103r/joystick/joystick.c @@ -0,0 +1,148 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Joshua Harlan Lifton + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/* Joystick definitions */ +#define JOY_PORT GPIOA +#define JOY_STATE GPIOA_IDR +#define JOY_LEFT GPIO0 +#define JOY_UP GPIO1 +#define JOY_DOWN GPIO2 +#define JOY_RIGHT GPIO3 +#define JOY_CENTER GPIO4 +#define JOY_ALL (JOY_LEFT | JOY_UP | JOY_DOWN | JOY_RIGHT | JOY_CENTER) +#define JOY_DEBOUNCE_TICKS 20000 + +/* LED array definitions */ +#define LED_PORT GPIOC +#define LED1 GPIO9 +#define LED2 GPIO10 +#define LED3 GPIO11 +#define LED4 GPIO12 +#define LED_ALL (LED1 | LED2 | LED3 | LED4) +#define BLINK_TICK 80000 + +uint16_t joy_state; +uint16_t led_state; +bool led_blinking; + +/* Set STM32 to 24 MHz. */ +static void clock_setup(void) +{ + rcc_clock_setup_in_hse_8mhz_out_24mhz(); +} + +static void led_setup(void) +{ + /* Enable GPIOC clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); + /* Set LEDs to output push-pull. */ + gpio_set_mode(LED_PORT, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, LED_ALL); + /* Turn off all LEDs. */ + gpio_clear(LED_PORT, LED_ALL); +} + +static void joystick_setup(void) +{ + /* Enable GPIOA clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); + /* Set joystick pins to input. */ + gpio_set_mode(JOY_PORT, GPIO_MODE_INPUT, + GPIO_CNF_INPUT_PULL_UPDOWN, + JOY_ALL); + /* Enable all joystick pin pull-up resistors. */ + gpio_set(JOY_PORT, JOY_ALL); +} + +int main(void) +{ + int i = 0; + int debounce = 0; + clock_setup(); + led_setup(); + joystick_setup(); + + joy_state = 0; + led_state = LED1; + led_blinking = false; + + while (1) { + + /* Set LED state according to joystick state. */ + joy_state = (~JOY_STATE) & JOY_ALL; + if (joy_state != 0 && debounce == 0) { + debounce = 1; + gpio_clear(LED_PORT, LED_ALL); + if (joy_state & JOY_UP) { + if (led_state == LED_ALL || led_state == 0) { + led_state = LED4; + } else { + led_state >>= 1; + if (led_state < LED1) { + led_state = LED4; + } + } + } else if (joy_state & JOY_DOWN) { + if (led_state == LED_ALL || led_state == 0) { + led_state = LED1; + } else { + led_state <<= 1; + if (led_state > LED4 || led_state == 0) { + led_state = LED1; + } + } + } else if (joy_state & JOY_LEFT) { + led_state = LED_ALL; + } else if (joy_state & JOY_RIGHT) { + led_state = 0; + } else if (joy_state & JOY_CENTER) { + led_blinking = !led_blinking; + } + } + + /* Debounce joystick press. */ + else if (debounce > 0 && debounce < JOY_DEBOUNCE_TICKS) { + debounce++; + } else if (joy_state == 0 && debounce == JOY_DEBOUNCE_TICKS) { + debounce++; + } + + /* Debounce joystick release. */ + else if (debounce > JOY_DEBOUNCE_TICKS && debounce < 2*JOY_DEBOUNCE_TICKS) { + debounce++; + } else if (joy_state == 0 && debounce == 2*JOY_DEBOUNCE_TICKS) { + debounce = 0; + } + + /* Update LEDs on the fly rather than wait for blink to complete. */ + if (i++ < BLINK_TICK || !led_blinking) { + gpio_set(LED_PORT, led_state); + } else { + gpio_clear(LED_PORT, led_state); + } + if (i > 2*BLINK_TICK) { + i = 0; + } + + } + return 0; +}