You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.4 KiB

3 years ago
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "who_button.h"
  4. typedef struct
  5. {
  6. gpio_num_t io_num;
  7. key_state_t state;
  8. } key_scan_state_t;
  9. #define LONG_PRESS_THRESH 700000
  10. #define DOUBLE_CLICK_THRESH 300000
  11. static xQueueHandle gpio_evt_queue = NULL;
  12. static QueueHandle_t xQueueKeyStateO = NULL;
  13. static void IRAM_ATTR gpio_isr_handler_key(void *arg)
  14. {
  15. uint32_t gpio_num = (uint32_t)arg;
  16. xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
  17. }
  18. int key_scan(TickType_t ticks_to_wait)
  19. {
  20. gpio_num_t io_num;
  21. BaseType_t press_key = pdFALSE;
  22. BaseType_t lift_key = pdFALSE;
  23. int64_t backup_time = 0;
  24. int64_t interval_time = 0;
  25. static int64_t last_time = 0;
  26. for (;;)
  27. {
  28. xQueueReceive(gpio_evt_queue, &io_num, ticks_to_wait);
  29. if (gpio_get_level(io_num) == 0)
  30. {
  31. press_key = pdTRUE;
  32. backup_time = esp_timer_get_time();
  33. interval_time = backup_time - last_time;
  34. }
  35. else if (press_key)
  36. {
  37. lift_key = pdTRUE;
  38. last_time = esp_timer_get_time();
  39. backup_time = last_time - backup_time;
  40. }
  41. if (press_key & lift_key)
  42. {
  43. press_key = pdFALSE;
  44. lift_key = pdFALSE;
  45. if (backup_time > LONG_PRESS_THRESH)
  46. {
  47. return KEY_LONG_PRESS;
  48. }
  49. else
  50. {
  51. if ((interval_time < DOUBLE_CLICK_THRESH) && (interval_time > 0))
  52. return KEY_DOUBLE_CLICK;
  53. else
  54. return KEY_SHORT_PRESS;
  55. }
  56. }
  57. }
  58. }
  59. void key_trigger(void *arg)
  60. {
  61. int ret = 0;
  62. while (1)
  63. {
  64. ret = key_scan(portMAX_DELAY);
  65. xQueueOverwrite(xQueueKeyStateO, &ret);
  66. }
  67. vTaskDelete(NULL);
  68. }
  69. void key_init(gpio_num_t gpio_num)
  70. {
  71. gpio_config_t io_conf = {0};
  72. io_conf.mode = GPIO_MODE_INPUT;
  73. io_conf.intr_type = GPIO_INTR_ANYEDGE;
  74. io_conf.pin_bit_mask = 1LL << gpio_num;
  75. io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
  76. gpio_config(&io_conf);
  77. gpio_evt_queue = xQueueCreate(5, sizeof(uint32_t));
  78. gpio_install_isr_service(0);
  79. gpio_isr_handler_add(gpio_num, gpio_isr_handler_key, (void *)gpio_num);
  80. }
  81. void register_button(const gpio_num_t key_io_num, const QueueHandle_t key_state_o)
  82. {
  83. xQueueKeyStateO = key_state_o;
  84. key_init(key_io_num);
  85. xTaskCreatePinnedToCore(key_trigger, "key_scan_task", 1024, NULL, 5, NULL, 0);
  86. }