123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- /*
- * (c) danielinux 2019
- * GPLv.2
- *
- * See LICENSE for details
- */
- #include <stdio.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #include "system.h"
- #include "button.h"
- #include "systick.h"
- #include "unicore-mx/stm32/gpio.h"
- #include "unicore-mx/stm32/exti.h"
- #include "unicore-mx/stm32/rcc.h"
- #include "unicore-mx/stm32/f4/rcc.h"
- #include "unicore-mx/stm32/adc.h"
- #include "unicore-mx/stm32/f4/adc.h"
- #include "unicore-mx/stm32/f4/nvic.h"
- // Uncomment to enable debug
- //#define BUTTON_DEBUG
- enum button_state {
- IDLE = 0,
- PRESSING,
- PRESSED,
- HOLD,
- RELEASING,
- };
- #ifdef BUTTON_DEBUG
- # define DBG printf
- #else
- # define DBG(...) do {} while (0)
- #endif
- #define BUTTON_DEBOUNCE_TIME 50
- #define BUTTON_HOLD_TIME 200
- static volatile int button_press_pending = 0;
- #define BUTTON_PLUS '+'
- #define BUTTON_MINUS '-'
- static void input_run(uint32_t ev, void *arg);
- static void input_init(void);
- const char button_task_name[] = "Input";
- // PA8 + PA9 // ROTARY encoder
- // PC0 // BUTTON
- //
- // TODO:
- // C4 + C5 rotary
- // B0 + B1 + C3 Buttons (- + RotSW)
- //
- void pin_exti_init(void)
- {
- }
- void pin_exti_start_read(void)
- {
- exti_set_trigger(GPIO0|GPIO1|GPIO3|GPIO4|GPIO5, EXTI_TRIGGER_BOTH);
- exti_enable_request(GPIO0);
- exti_enable_request(GPIO1);
- exti_enable_request(GPIO3);
- exti_enable_request(GPIO4);
- exti_enable_request(GPIO5);
- }
- static void button_setup(void)
- {
- rcc_periph_clock_enable(RCC_SYSCFG);
- rcc_periph_clock_enable(RCC_GPIOB);
- rcc_periph_clock_enable(RCC_GPIOC);
- gpio_mode_setup(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO3 | GPIO4 | GPIO5);
- gpio_mode_setup(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO0 | GPIO1);
- nvic_enable_irq(NVIC_EXTI9_5_IRQ);
- nvic_enable_irq(NVIC_EXTI0_IRQ);
- nvic_enable_irq(NVIC_EXTI1_IRQ);
- nvic_enable_irq(NVIC_EXTI3_IRQ);
- nvic_enable_irq(NVIC_EXTI4_IRQ);
- nvic_set_priority(NVIC_EXTI9_5_IRQ, 1);
- nvic_set_priority(NVIC_EXTI0_IRQ, 1);
- nvic_set_priority(NVIC_EXTI1_IRQ, 1);
- nvic_set_priority(NVIC_EXTI3_IRQ, 1);
- nvic_set_priority(NVIC_EXTI4_IRQ, 1);
- exti_select_source(GPIO0, GPIOB);
- exti_select_source(GPIO1, GPIOB);
- exti_select_source(GPIO3, GPIOC);
- exti_select_source(GPIO4, GPIOC);
- exti_select_source(GPIO5, GPIOC);
- }
- static volatile uint32_t rot_up = 0;
- static volatile uint32_t rot_down = 0;
- static void button_start_read(void)
- {
- exti_set_trigger(GPIO0|GPIO1|GPIO3, EXTI_TRIGGER_RISING);
- exti_set_trigger(GPIO4, EXTI_TRIGGER_FALLING);
- exti_enable_request(GPIO0);
- exti_enable_request(GPIO1);
- exti_enable_request(GPIO3);
- exti_enable_request(GPIO4);
- }
- static volatile uint32_t last_rot_ev = 0;
- void isr_exti_rot0(void)
- {
- uint32_t rot_val = gpio_get(GPIOC, GPIO4 | GPIO5);
- if ((jiffies - last_rot_ev) > 100) {
- if ((rot_val & GPIO4) == 0) {
- if ((rot_val & GPIO5) == 0)
- rot_down++;
- else
- rot_up++;
- }
- }
- exti_reset_request(GPIO4);
- exti_reset_request(GPIO5);
- }
- void isr_exti_button(void)
- {
- uint32_t pending;
- pending = (gpio_get(GPIOB, GPIO0|GPIO1));
- if ((pending & GPIO0) != 0) {
- button_press_pending = '-';
- }
- if ((pending & GPIO1) != 0) {
- button_press_pending = '+';
- }
- if (!pending) {
- pending = (gpio_get(GPIOC, GPIO3));
- if ((pending & GPIO3) != 0) {
- button_press_pending = '*';
- }
- }
- exti_reset_request(GPIO0);
- exti_reset_request(GPIO1);
- exti_reset_request(GPIO3);
- }
- static uint32_t t0s, t0us;
- static uint32_t t1s, t1us;
- static uint32_t time_diff_ms(uint32_t s_a, uint32_t us_a, uint32_t s_b, uint32_t us_b)
- {
- uint32_t res = 0;
- res = (s_a - s_b) * 1000;
- if (us_b > us_a) {
- us_a += 1000000;
- res -= 1000;
- }
- res += (us_a - us_b) / 1000;
- return res;
- }
- /* Button interface */
- struct user_button
- {
- enum button_state state;
- uint32_t transition_start_timestamp;
- };
- static struct user_button Buttons[N_BUTTONS];
- int button_poll(void (*callback)(uint8_t press, int hold))
- {
- int b = 0;
- int st;
- static uint32_t last_event = 0;
- static uint32_t pressed_start = 0;
- while(rot_down > 0) {
- callback('D',0);
- rot_down--;
- }
- while(rot_up > 0) {
- callback('U',0);
- rot_up--;
- }
- if (jiffies - last_event < BUTTON_DEBOUNCE_TIME)
- return;
- last_event = jiffies;
- st = !!(gpio_get(GPIOB, GPIO0 | GPIO1) | gpio_get(GPIOC, GPIO3));
- if (!st) {
- pressed_start = 0;
- }
- if ((button_press_pending) && st) {
- if ((pressed_start == 0) || ((jiffies - pressed_start) > BUTTON_HOLD_TIME)) {
- pressed_start = jiffies;
- callback(button_press_pending, 0);
- return 1;
- }
- }
- button_press_pending = 0;
- return 0;
- }
- void button_init(void)
- {
- memset(Buttons, 0, sizeof(struct user_button) * N_BUTTONS);
- button_setup();
- button_start_read();
- }
|