123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- /*
- * (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
- #ifdef BUTTON_DEBUG
- # define DBG printf
- #else
- # define DBG(...) do {} while (0)
- #endif
- #define BUTTON_DEBOUNCE_TIME 50
- #define BUTTON_HOLD_TIME 1500
- static volatile int button_press_pending = 0;
- 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
- void pin_exti_init(void)
- {
- int i;
- uint32_t exti_irq;
- rcc_periph_clock_enable(RCC_SYSCFG);
- rcc_periph_clock_enable(RCC_GPIOA);
- gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO9 | GPIO8 | GPIO7 | GPIO6 | GPIO5);
- nvic_enable_irq(NVIC_EXTI9_5_IRQ);
- nvic_set_priority(NVIC_EXTI9_5_IRQ, 1);
- exti_select_source(GPIO5, GPIOA);
- exti_select_source(GPIO6, GPIOA);
- exti_select_source(GPIO7, GPIOA);
- exti_select_source(GPIO8, GPIOA);
- exti_select_source(GPIO9, GPIOA);
- }
- void pin_exti_start_read(void)
- {
- exti_set_trigger(GPIO5|GPIO6|GPIO7|GPIO8|GPIO9, EXTI_TRIGGER_BOTH);
- exti_enable_request(GPIO5);
- exti_enable_request(GPIO6);
- exti_enable_request(GPIO7);
- exti_enable_request(GPIO8);
- exti_enable_request(GPIO9);
- }
- static void button_setup(void)
- {
- int i;
- uint32_t exti_irq;
- rcc_periph_clock_enable(RCC_SYSCFG);
- rcc_periph_clock_enable(RCC_GPIOA);
- rcc_periph_clock_enable(RCC_GPIOB);
- rcc_periph_clock_enable(RCC_GPIOC);
- gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO10);
- gpio_mode_setup(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO4);
- gpio_mode_setup(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO0);
-
- nvic_enable_irq(NVIC_EXTI4_IRQ);
- nvic_enable_irq(NVIC_EXTI0_IRQ);
- nvic_enable_irq(NVIC_EXTI15_10_IRQ);
- nvic_set_priority(NVIC_EXTI4_IRQ, 1);
- nvic_set_priority(NVIC_EXTI0_IRQ, 1);
- nvic_set_priority(NVIC_EXTI15_10_IRQ, 1);
-
- exti_select_source(GPIO10, GPIOA);
- exti_select_source(GPIO4, GPIOB);
- exti_select_source(GPIO0, GPIOC);
- }
- enum button_state {
- IDLE = 0,
- PRESSING,
- PRESSED,
- HOLD,
- RELEASING,
- };
- static volatile enum button_state button_status = 0;
- static volatile uint32_t rot_up = 0;
- static volatile uint32_t rot_down = 0;
- static void button_start_read(void)
- {
- exti_set_trigger(GPIO0, EXTI_TRIGGER_RISING);
- exti_set_trigger(GPIO10|GPIO4, EXTI_TRIGGER_RISING);
- exti_enable_request(GPIO10);
- exti_enable_request(GPIO4);
- exti_enable_request(GPIO0);
- }
- void isr_exti_rot1(void)
- {
- exti_reset_request(GPIO4);
- if (gpio_get(GPIOA, GPIO10) == 0)
- return;
- rot_down++;
- }
- void isr_exti_rot0(void)
- {
- exti_reset_request(GPIO10);
- if (gpio_get(GPIOB, GPIO4) == 0)
- return;
- rot_up++;
- }
- void isr_exti_button(void)
- {
- button_press_pending = !!(gpio_get(GPIOC, GPIO0));
- exti_reset_request(GPIO0);
- }
- 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;
- }
- typedef void (*exti_trigger_callback_fn)(uint32_t pin, uint8_t front, uint32_t s, uint32_t us);
- static exti_trigger_callback_fn exti_trigger_callback[5];
- void exti_set_callback(uint32_t pin, void (*cb)(uint32_t pin, uint8_t front, uint32_t s, uint32_t us))
- {
- int i;
- for (i = 0; i < 5; i++) {
- if (Channel_Pin[i] == pin) {
- DBG("Setting callback for EXTI on ch %d\r\n", i);
- exti_trigger_callback[i] = cb;
- return;
- }
- }
- }
- void exti_clear_callback(uint32_t pin)
- {
- int i;
- for (i = 0; i < 5; i++) {
- if (Channel_Pin[i] == pin) {
- DBG("Clearing callback for EXTI on ch %d\r\n", i);
- exti_trigger_callback[i] = NULL;
- return;
- }
- }
- }
- struct trig_timeval {
- int channel;
- uint32_t pin;
- int front;
- uint32_t tv_sec;
- uint32_t tv_usec;
- };
- static struct trig_timeval trig_tv[32] = {};
- static volatile uint8_t trig_pending = 0;
- void isr_exti_channel(void)
- {
- uint32_t ts, tus;
- gettime(&ts, &tus);
- DBG("EXTI\r\n");
- if (exti_get_flag_status(GPIO9)) {
- DBG("c1\r\n");
- if (exti_trigger_callback[1]) {
- gettime(&ts, &tus);
- trig_tv[trig_pending].channel = 1;
- trig_tv[trig_pending].pin = GPIO9;
- trig_tv[trig_pending].front = !!gpio_get(GPIOA,GPIO9);
- trig_tv[trig_pending].tv_sec = ts;
- trig_tv[trig_pending].tv_usec = tus;
- trig_pending++;
- }
- exti_reset_request(GPIO9);
- }
- if (exti_get_flag_status(GPIO8)) {
- DBG("c0\r\n");
- if (exti_trigger_callback[0]) {
- gettime(&ts, &tus);
- trig_tv[trig_pending].channel = 0;
- trig_tv[trig_pending].pin = GPIO8;
- trig_tv[trig_pending].front = !!gpio_get(GPIOA,GPIO8);
- trig_tv[trig_pending].tv_sec = ts;
- trig_tv[trig_pending].tv_usec = tus;
- trig_pending++;
- }
- exti_reset_request(GPIO8);
- }
- if (exti_get_flag_status(GPIO7)) {
- if (exti_trigger_callback[2]) {
- gettime(&ts, &tus);
- trig_tv[trig_pending].channel = 2;
- trig_tv[trig_pending].pin = GPIO7;
- trig_tv[trig_pending].front = !!gpio_get(GPIOA,GPIO7);
- trig_tv[trig_pending].tv_sec = ts;
- trig_tv[trig_pending].tv_usec = tus;
- trig_pending++;
- }
- exti_reset_request(GPIO7);
- }
- if (exti_get_flag_status(GPIO6)) {
- if (exti_trigger_callback[3]) {
- gettime(&ts, &tus);
- trig_tv[trig_pending].channel = 3;
- trig_tv[trig_pending].pin = GPIO6;
- trig_tv[trig_pending].front = !!gpio_get(GPIOA,GPIO6);
- trig_tv[trig_pending].tv_sec = ts;
- trig_tv[trig_pending].tv_usec = tus;
- trig_pending++;
- }
- exti_reset_request(GPIO6);
- }
- if (exti_get_flag_status(GPIO5)) {
- if (exti_trigger_callback[4]) {
- gettime(&ts, &tus);
- trig_tv[trig_pending].channel = 4;
- trig_tv[trig_pending].pin = GPIO5;
- trig_tv[trig_pending].front = !!gpio_get(GPIOA,GPIO5);
- trig_tv[trig_pending].tv_sec = ts;
- trig_tv[trig_pending].tv_usec = tus;
- trig_pending++;
- }
- exti_reset_request(GPIO5);
- }
- }
- void exti_poll(void)
- {
- int i;
- uint32_t pin;
- for (i = 0; i < trig_pending; i++) {
- if (exti_trigger_callback[trig_tv[i].channel]) {
- DBG("EXTI cb!\r\n");
- exti_trigger_callback[trig_tv[i].channel](trig_tv[i].pin, trig_tv[i].front, trig_tv[i].tv_sec, trig_tv[i].tv_usec);
- }
- }
- trig_pending = 0;
- }
- /* 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('-',0);
- rot_down--;
- }
- while(rot_up > 0) {
- callback('+',0);
- rot_up--;
- }
- if (jiffies - last_event < BUTTON_DEBOUNCE_TIME)
- return;
- last_event = jiffies;
- st = !!gpio_get(GPIOC, GPIO0);
- if (!st) {
- pressed_start = 0;
- }
- if ((button_press_pending) && st) {
- if ((pressed_start == 0) || ((jiffies - pressed_start) > BUTTON_HOLD_TIME)) {
- pressed_start = jiffies;
- callback('*', 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();
- }
|