button.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  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. #ifdef BUTTON_DEBUG
  24. # define DBG printf
  25. #else
  26. # define DBG(...) do {} while (0)
  27. #endif
  28. #define BUTTON_DEBOUNCE_TIME 50
  29. #define BUTTON_HOLD_TIME 1500
  30. static volatile int button_press_pending = 0;
  31. static void input_run(uint32_t ev, void *arg);
  32. static void input_init(void);
  33. const char button_task_name[] = "Input";
  34. // PA8 + PA9 // ROTARY encoder
  35. // PC0 // BUTTON
  36. void pin_exti_init(void)
  37. {
  38. int i;
  39. uint32_t exti_irq;
  40. rcc_periph_clock_enable(RCC_SYSCFG);
  41. rcc_periph_clock_enable(RCC_GPIOA);
  42. gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO9 | GPIO8 | GPIO7 | GPIO6 | GPIO5);
  43. nvic_enable_irq(NVIC_EXTI9_5_IRQ);
  44. nvic_set_priority(NVIC_EXTI9_5_IRQ, 1);
  45. exti_select_source(GPIO5, GPIOA);
  46. exti_select_source(GPIO6, GPIOA);
  47. exti_select_source(GPIO7, GPIOA);
  48. exti_select_source(GPIO8, GPIOA);
  49. exti_select_source(GPIO9, GPIOA);
  50. }
  51. void pin_exti_start_read(void)
  52. {
  53. exti_set_trigger(GPIO5|GPIO6|GPIO7|GPIO8|GPIO9, EXTI_TRIGGER_BOTH);
  54. exti_enable_request(GPIO5);
  55. exti_enable_request(GPIO6);
  56. exti_enable_request(GPIO7);
  57. exti_enable_request(GPIO8);
  58. exti_enable_request(GPIO9);
  59. }
  60. static void button_setup(void)
  61. {
  62. int i;
  63. uint32_t exti_irq;
  64. rcc_periph_clock_enable(RCC_SYSCFG);
  65. rcc_periph_clock_enable(RCC_GPIOA);
  66. rcc_periph_clock_enable(RCC_GPIOB);
  67. rcc_periph_clock_enable(RCC_GPIOC);
  68. gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO10);
  69. gpio_mode_setup(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO4);
  70. gpio_mode_setup(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO0);
  71. nvic_enable_irq(NVIC_EXTI4_IRQ);
  72. nvic_enable_irq(NVIC_EXTI0_IRQ);
  73. nvic_enable_irq(NVIC_EXTI15_10_IRQ);
  74. nvic_set_priority(NVIC_EXTI4_IRQ, 1);
  75. nvic_set_priority(NVIC_EXTI0_IRQ, 1);
  76. nvic_set_priority(NVIC_EXTI15_10_IRQ, 1);
  77. exti_select_source(GPIO10, GPIOA);
  78. exti_select_source(GPIO4, GPIOB);
  79. exti_select_source(GPIO0, GPIOC);
  80. }
  81. enum button_state {
  82. IDLE = 0,
  83. PRESSING,
  84. PRESSED,
  85. HOLD,
  86. RELEASING,
  87. };
  88. static volatile enum button_state button_status = 0;
  89. static volatile uint32_t rot_up = 0;
  90. static volatile uint32_t rot_down = 0;
  91. static void button_start_read(void)
  92. {
  93. exti_set_trigger(GPIO0, EXTI_TRIGGER_RISING);
  94. exti_set_trigger(GPIO10|GPIO4, EXTI_TRIGGER_RISING);
  95. exti_enable_request(GPIO10);
  96. exti_enable_request(GPIO4);
  97. exti_enable_request(GPIO0);
  98. }
  99. void isr_exti_rot1(void)
  100. {
  101. exti_reset_request(GPIO4);
  102. if (gpio_get(GPIOA, GPIO10) == 0)
  103. return;
  104. rot_down++;
  105. }
  106. void isr_exti_rot0(void)
  107. {
  108. exti_reset_request(GPIO10);
  109. if (gpio_get(GPIOB, GPIO4) == 0)
  110. return;
  111. rot_up++;
  112. }
  113. void isr_exti_button(void)
  114. {
  115. button_press_pending = !!(gpio_get(GPIOC, GPIO0));
  116. exti_reset_request(GPIO0);
  117. }
  118. static uint32_t t0s, t0us;
  119. static uint32_t t1s, t1us;
  120. static uint32_t time_diff_ms(uint32_t s_a, uint32_t us_a, uint32_t s_b, uint32_t us_b)
  121. {
  122. uint32_t res = 0;
  123. res = (s_a - s_b) * 1000;
  124. if (us_b > us_a) {
  125. us_a += 1000000;
  126. res -= 1000;
  127. }
  128. res += (us_a - us_b) / 1000;
  129. return res;
  130. }
  131. typedef void (*exti_trigger_callback_fn)(uint32_t pin, uint8_t front, uint32_t s, uint32_t us);
  132. static exti_trigger_callback_fn exti_trigger_callback[5];
  133. void exti_set_callback(uint32_t pin, void (*cb)(uint32_t pin, uint8_t front, uint32_t s, uint32_t us))
  134. {
  135. int i;
  136. for (i = 0; i < 5; i++) {
  137. if (Channel_Pin[i] == pin) {
  138. DBG("Setting callback for EXTI on ch %d\r\n", i);
  139. exti_trigger_callback[i] = cb;
  140. return;
  141. }
  142. }
  143. }
  144. void exti_clear_callback(uint32_t pin)
  145. {
  146. int i;
  147. for (i = 0; i < 5; i++) {
  148. if (Channel_Pin[i] == pin) {
  149. DBG("Clearing callback for EXTI on ch %d\r\n", i);
  150. exti_trigger_callback[i] = NULL;
  151. return;
  152. }
  153. }
  154. }
  155. struct trig_timeval {
  156. int channel;
  157. uint32_t pin;
  158. int front;
  159. uint32_t tv_sec;
  160. uint32_t tv_usec;
  161. };
  162. static struct trig_timeval trig_tv[32] = {};
  163. static volatile uint8_t trig_pending = 0;
  164. void isr_exti_channel(void)
  165. {
  166. uint32_t ts, tus;
  167. gettime(&ts, &tus);
  168. DBG("EXTI\r\n");
  169. if (exti_get_flag_status(GPIO9)) {
  170. DBG("c1\r\n");
  171. if (exti_trigger_callback[1]) {
  172. gettime(&ts, &tus);
  173. trig_tv[trig_pending].channel = 1;
  174. trig_tv[trig_pending].pin = GPIO9;
  175. trig_tv[trig_pending].front = !!gpio_get(GPIOA,GPIO9);
  176. trig_tv[trig_pending].tv_sec = ts;
  177. trig_tv[trig_pending].tv_usec = tus;
  178. trig_pending++;
  179. }
  180. exti_reset_request(GPIO9);
  181. }
  182. if (exti_get_flag_status(GPIO8)) {
  183. DBG("c0\r\n");
  184. if (exti_trigger_callback[0]) {
  185. gettime(&ts, &tus);
  186. trig_tv[trig_pending].channel = 0;
  187. trig_tv[trig_pending].pin = GPIO8;
  188. trig_tv[trig_pending].front = !!gpio_get(GPIOA,GPIO8);
  189. trig_tv[trig_pending].tv_sec = ts;
  190. trig_tv[trig_pending].tv_usec = tus;
  191. trig_pending++;
  192. }
  193. exti_reset_request(GPIO8);
  194. }
  195. if (exti_get_flag_status(GPIO7)) {
  196. if (exti_trigger_callback[2]) {
  197. gettime(&ts, &tus);
  198. trig_tv[trig_pending].channel = 2;
  199. trig_tv[trig_pending].pin = GPIO7;
  200. trig_tv[trig_pending].front = !!gpio_get(GPIOA,GPIO7);
  201. trig_tv[trig_pending].tv_sec = ts;
  202. trig_tv[trig_pending].tv_usec = tus;
  203. trig_pending++;
  204. }
  205. exti_reset_request(GPIO7);
  206. }
  207. if (exti_get_flag_status(GPIO6)) {
  208. if (exti_trigger_callback[3]) {
  209. gettime(&ts, &tus);
  210. trig_tv[trig_pending].channel = 3;
  211. trig_tv[trig_pending].pin = GPIO6;
  212. trig_tv[trig_pending].front = !!gpio_get(GPIOA,GPIO6);
  213. trig_tv[trig_pending].tv_sec = ts;
  214. trig_tv[trig_pending].tv_usec = tus;
  215. trig_pending++;
  216. }
  217. exti_reset_request(GPIO6);
  218. }
  219. if (exti_get_flag_status(GPIO5)) {
  220. if (exti_trigger_callback[4]) {
  221. gettime(&ts, &tus);
  222. trig_tv[trig_pending].channel = 4;
  223. trig_tv[trig_pending].pin = GPIO5;
  224. trig_tv[trig_pending].front = !!gpio_get(GPIOA,GPIO5);
  225. trig_tv[trig_pending].tv_sec = ts;
  226. trig_tv[trig_pending].tv_usec = tus;
  227. trig_pending++;
  228. }
  229. exti_reset_request(GPIO5);
  230. }
  231. }
  232. void exti_poll(void)
  233. {
  234. int i;
  235. uint32_t pin;
  236. for (i = 0; i < trig_pending; i++) {
  237. if (exti_trigger_callback[trig_tv[i].channel]) {
  238. DBG("EXTI cb!\r\n");
  239. 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);
  240. }
  241. }
  242. trig_pending = 0;
  243. }
  244. /* Button interface */
  245. struct user_button
  246. {
  247. enum button_state state;
  248. uint32_t transition_start_timestamp;
  249. };
  250. static struct user_button Buttons[N_BUTTONS];
  251. int button_poll(void (*callback)(uint8_t press, int hold))
  252. {
  253. int b = 0;
  254. int st;
  255. static uint32_t last_event = 0;
  256. static uint32_t pressed_start = 0;
  257. while(rot_down > 0) {
  258. callback('-',0);
  259. rot_down--;
  260. }
  261. while(rot_up > 0) {
  262. callback('+',0);
  263. rot_up--;
  264. }
  265. if (jiffies - last_event < BUTTON_DEBOUNCE_TIME)
  266. return;
  267. last_event = jiffies;
  268. st = !!gpio_get(GPIOC, GPIO0);
  269. if (!st) {
  270. pressed_start = 0;
  271. }
  272. if ((button_press_pending) && st) {
  273. if ((pressed_start == 0) || ((jiffies - pressed_start) > BUTTON_HOLD_TIME)) {
  274. pressed_start = jiffies;
  275. callback('*', 0);
  276. return 1;
  277. }
  278. }
  279. button_press_pending = 0;
  280. return 0;
  281. }
  282. void button_init(void)
  283. {
  284. memset(Buttons, 0, sizeof(struct user_button) * N_BUTTONS);
  285. button_setup();
  286. button_start_read();
  287. }