button.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * (c) danielinux 2019
  3. * GPLv.2
  4. *
  5. * See LICENSE for details
  6. */
  7. #include <stdio.h>
  8. #include <stdint.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include "system.h"
  12. #include "button.h"
  13. #include "systick.h"
  14. #include "unicore-mx/stm32/gpio.h"
  15. #include "unicore-mx/stm32/exti.h"
  16. #include "unicore-mx/stm32/rcc.h"
  17. #include "unicore-mx/stm32/f4/rcc.h"
  18. #include "unicore-mx/stm32/adc.h"
  19. #include "unicore-mx/stm32/f4/adc.h"
  20. #include "unicore-mx/stm32/f4/nvic.h"
  21. // Uncomment to enable debug
  22. //#define BUTTON_DEBUG
  23. enum button_state {
  24. IDLE = 0,
  25. PRESSING,
  26. PRESSED,
  27. HOLD,
  28. RELEASING,
  29. };
  30. #ifdef BUTTON_DEBUG
  31. # define DBG printf
  32. #else
  33. # define DBG(...) do {} while (0)
  34. #endif
  35. #define BUTTON_DEBOUNCE_TIME 50
  36. #define BUTTON_HOLD_TIME 200
  37. static volatile int button_press_pending = 0;
  38. #define BUTTON_PLUS '+'
  39. #define BUTTON_MINUS '-'
  40. static void input_run(uint32_t ev, void *arg);
  41. static void input_init(void);
  42. const char button_task_name[] = "Input";
  43. // PA8 + PA9 // ROTARY encoder
  44. // PC0 // BUTTON
  45. //
  46. // TODO:
  47. // C4 + C5 rotary
  48. // B0 + B1 + C3 Buttons (- + RotSW)
  49. //
  50. void pin_exti_init(void)
  51. {
  52. }
  53. void pin_exti_start_read(void)
  54. {
  55. exti_set_trigger(GPIO0|GPIO1|GPIO3|GPIO4|GPIO5, EXTI_TRIGGER_BOTH);
  56. exti_enable_request(GPIO0);
  57. exti_enable_request(GPIO1);
  58. exti_enable_request(GPIO3);
  59. exti_enable_request(GPIO4);
  60. exti_enable_request(GPIO5);
  61. }
  62. static void button_setup(void)
  63. {
  64. rcc_periph_clock_enable(RCC_SYSCFG);
  65. rcc_periph_clock_enable(RCC_GPIOB);
  66. rcc_periph_clock_enable(RCC_GPIOC);
  67. gpio_mode_setup(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO3 | GPIO4 | GPIO5);
  68. gpio_mode_setup(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO0 | GPIO1);
  69. nvic_enable_irq(NVIC_EXTI9_5_IRQ);
  70. nvic_enable_irq(NVIC_EXTI0_IRQ);
  71. nvic_enable_irq(NVIC_EXTI1_IRQ);
  72. nvic_enable_irq(NVIC_EXTI3_IRQ);
  73. nvic_enable_irq(NVIC_EXTI4_IRQ);
  74. nvic_set_priority(NVIC_EXTI9_5_IRQ, 1);
  75. nvic_set_priority(NVIC_EXTI0_IRQ, 1);
  76. nvic_set_priority(NVIC_EXTI1_IRQ, 1);
  77. nvic_set_priority(NVIC_EXTI3_IRQ, 1);
  78. nvic_set_priority(NVIC_EXTI4_IRQ, 1);
  79. exti_select_source(GPIO0, GPIOB);
  80. exti_select_source(GPIO1, GPIOB);
  81. exti_select_source(GPIO3, GPIOC);
  82. exti_select_source(GPIO4, GPIOC);
  83. exti_select_source(GPIO5, GPIOC);
  84. }
  85. static volatile uint32_t rot_up = 0;
  86. static volatile uint32_t rot_down = 0;
  87. static void button_start_read(void)
  88. {
  89. exti_set_trigger(GPIO0|GPIO1|GPIO3, EXTI_TRIGGER_RISING);
  90. exti_set_trigger(GPIO4, EXTI_TRIGGER_FALLING);
  91. exti_enable_request(GPIO0);
  92. exti_enable_request(GPIO1);
  93. exti_enable_request(GPIO3);
  94. exti_enable_request(GPIO4);
  95. }
  96. static volatile uint32_t last_rot_ev = 0;
  97. void isr_exti_rot0(void)
  98. {
  99. uint32_t rot_val = gpio_get(GPIOC, GPIO4 | GPIO5);
  100. if ((jiffies - last_rot_ev) > 100) {
  101. if ((rot_val & GPIO4) == 0) {
  102. if ((rot_val & GPIO5) == 0)
  103. rot_down++;
  104. else
  105. rot_up++;
  106. }
  107. }
  108. exti_reset_request(GPIO4);
  109. exti_reset_request(GPIO5);
  110. }
  111. void isr_exti_button(void)
  112. {
  113. uint32_t pending;
  114. pending = (gpio_get(GPIOB, GPIO0|GPIO1));
  115. if ((pending & GPIO0) != 0) {
  116. button_press_pending = '-';
  117. }
  118. if ((pending & GPIO1) != 0) {
  119. button_press_pending = '+';
  120. }
  121. if (!pending) {
  122. pending = (gpio_get(GPIOC, GPIO3));
  123. if ((pending & GPIO3) != 0) {
  124. button_press_pending = '*';
  125. }
  126. }
  127. exti_reset_request(GPIO0);
  128. exti_reset_request(GPIO1);
  129. exti_reset_request(GPIO3);
  130. }
  131. static uint32_t t0s, t0us;
  132. static uint32_t t1s, t1us;
  133. static uint32_t time_diff_ms(uint32_t s_a, uint32_t us_a, uint32_t s_b, uint32_t us_b)
  134. {
  135. uint32_t res = 0;
  136. res = (s_a - s_b) * 1000;
  137. if (us_b > us_a) {
  138. us_a += 1000000;
  139. res -= 1000;
  140. }
  141. res += (us_a - us_b) / 1000;
  142. return res;
  143. }
  144. /* Button interface */
  145. struct user_button
  146. {
  147. enum button_state state;
  148. uint32_t transition_start_timestamp;
  149. };
  150. static struct user_button Buttons[N_BUTTONS];
  151. int button_poll(void (*callback)(uint8_t press, int hold))
  152. {
  153. int b = 0;
  154. int st;
  155. static uint32_t last_event = 0;
  156. static uint32_t pressed_start = 0;
  157. while(rot_down > 0) {
  158. callback('D',0);
  159. rot_down--;
  160. }
  161. while(rot_up > 0) {
  162. callback('U',0);
  163. rot_up--;
  164. }
  165. if (jiffies - last_event < BUTTON_DEBOUNCE_TIME)
  166. return;
  167. last_event = jiffies;
  168. st = !!(gpio_get(GPIOB, GPIO0 | GPIO1) | gpio_get(GPIOC, GPIO3));
  169. if (!st) {
  170. pressed_start = 0;
  171. }
  172. if ((button_press_pending) && st) {
  173. if ((pressed_start == 0) || ((jiffies - pressed_start) > BUTTON_HOLD_TIME)) {
  174. pressed_start = jiffies;
  175. callback(button_press_pending, 0);
  176. return 1;
  177. }
  178. }
  179. button_press_pending = 0;
  180. return 0;
  181. }
  182. void button_init(void)
  183. {
  184. memset(Buttons, 0, sizeof(struct user_button) * N_BUTTONS);
  185. button_setup();
  186. button_start_read();
  187. }