drv_key.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-07-19 Magicoe The first version for LPC55S6x, refered github.com/Guozhanxin/RTT-BeepPlayer-pkg
  9. */
  10. #include <rtthread.h>
  11. #include "rtconfig.h"
  12. #include "fsl_common.h"
  13. #include "fsl_iocon.h"
  14. #include "fsl_gpio.h"
  15. #include "fsl_inputmux.h"
  16. #include "drv_key.h"
  17. /**** Debug ****/
  18. #define DBG_ENABLE
  19. #define DBG_SECTION_NAME "button"
  20. #define DBG_LEVEL DBG_INFO
  21. #define DBG_COLOR
  22. #include <rtdbg.h>
  23. #define MY_BUTTON_CALL(func, argv) \
  24. do { if ((func) != RT_NULL) func argv; } while (0)
  25. struct my_button_manage
  26. {
  27. rt_uint8_t num;
  28. rt_timer_t timer;
  29. struct my_button *button_list[MY_BUTTON_LIST_MAX];
  30. };
  31. static struct my_button_manage button_manage;
  32. int my_button_register(struct my_button *button)
  33. {
  34. if (button->press_logic_level == 0)
  35. {
  36. rt_pin_mode(button->pin, PIN_MODE_INPUT_PULLUP);
  37. }
  38. else
  39. {
  40. rt_pin_mode(button->pin, PIN_MODE_INPUT_PULLDOWN);
  41. }
  42. button->cnt = 0;
  43. button->event = BUTTON_EVENT_NONE;
  44. button_manage.button_list[button_manage.num++] = button;
  45. return 0;
  46. }
  47. static void my_button_scan(void *param)
  48. {
  49. rt_uint8_t i;
  50. rt_uint16_t cnt_old;
  51. for (i = 0; i < button_manage.num; i++)
  52. {
  53. cnt_old = button_manage.button_list[i]->cnt;
  54. if (rt_pin_read(button_manage.button_list[i]->pin) == button_manage.button_list[i]->press_logic_level)
  55. {
  56. button_manage.button_list[i]->cnt ++;
  57. if (button_manage.button_list[i]->cnt == MY_BUTTON_DOWN_MS / MY_BUTTON_SCAN_SPACE_MS) /* BUTTON_DOWN */
  58. {
  59. LOG_D("BUTTON_DOWN");
  60. button_manage.button_list[i]->event = BUTTON_EVENT_CLICK_DOWN;
  61. MY_BUTTON_CALL(button_manage.button_list[i]->cb, (button_manage.button_list[i]));
  62. }
  63. else if (button_manage.button_list[i]->cnt == MY_BUTTON_HOLD_MS / MY_BUTTON_SCAN_SPACE_MS) /* BUTTON_HOLD */
  64. {
  65. LOG_D("BUTTON_HOLD");
  66. button_manage.button_list[i]->event = BUTTON_EVENT_HOLD;
  67. MY_BUTTON_CALL(button_manage.button_list[i]->cb, (button_manage.button_list[i]));
  68. }
  69. else if (button_manage.button_list[i]->cnt > MY_BUTTON_HOLD_MS / MY_BUTTON_SCAN_SPACE_MS) /* BUTTON_HOLD_CYC */
  70. {
  71. LOG_D("BUTTON_HOLD_CYC");
  72. button_manage.button_list[i]->event = BUTTON_EVENT_HOLD_CYC;
  73. if (button_manage.button_list[i]->hold_cyc_period && button_manage.button_list[i]->cnt % (button_manage.button_list[i]->hold_cyc_period / MY_BUTTON_SCAN_SPACE_MS) == 0)
  74. MY_BUTTON_CALL(button_manage.button_list[i]->cb, (button_manage.button_list[i]));
  75. }
  76. }
  77. else
  78. {
  79. button_manage.button_list[i]->cnt = 0;
  80. if (cnt_old >= MY_BUTTON_DOWN_MS / MY_BUTTON_SCAN_SPACE_MS && cnt_old < MY_BUTTON_HOLD_MS / MY_BUTTON_SCAN_SPACE_MS) /* BUTTON_CLICK_UP */
  81. {
  82. LOG_D("BUTTON_CLICK_UP");
  83. button_manage.button_list[i]->event = BUTTON_EVENT_CLICK_UP;
  84. MY_BUTTON_CALL(button_manage.button_list[i]->cb, (button_manage.button_list[i]));
  85. }
  86. else if (cnt_old >= MY_BUTTON_HOLD_MS / MY_BUTTON_SCAN_SPACE_MS) /* BUTTON_HOLD_UP */
  87. {
  88. LOG_D("BUTTON_HOLD_UP");
  89. button_manage.button_list[i]->event = BUTTON_EVENT_HOLD_UP;
  90. MY_BUTTON_CALL(button_manage.button_list[i]->cb, (button_manage.button_list[i]));
  91. }
  92. }
  93. }
  94. }
  95. int my_button_start(void)
  96. {
  97. if (button_manage.timer != RT_NULL)
  98. return -1;
  99. /* Create Timer 1 */
  100. button_manage.timer = rt_timer_create("timer1", /* Timer name is: timer1 */
  101. my_button_scan, /* Timeout callback func */
  102. RT_NULL, /* Timeout func entry */
  103. RT_TICK_PER_SECOND * MY_BUTTON_SCAN_SPACE_MS / 1000,
  104. RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER);
  105. /* Start Timer */
  106. if (button_manage.timer != RT_NULL)
  107. rt_timer_start(button_manage.timer);
  108. return 0;
  109. }
  110. #ifdef RT_USING_FINSH
  111. #include <finsh.h>
  112. #ifdef FINSH_USING_MSH
  113. #define KEY_PIN 51
  114. #define KEY_PRESS_VALUE 0
  115. void key_cb(struct my_button *button)
  116. {
  117. switch (button->event)
  118. {
  119. case BUTTON_EVENT_CLICK_UP:
  120. rt_kprintf("This is click up callback!\n");
  121. break;
  122. case BUTTON_EVENT_HOLD_CYC:
  123. rt_kprintf("This is hold cyc callback!\n");
  124. break;
  125. default:
  126. ;
  127. }
  128. }
  129. void key_test(rt_uint32_t led_num, rt_uint32_t value)
  130. {
  131. /* user app entry */
  132. static struct my_button key = {0};
  133. key.press_logic_level = KEY_PRESS_VALUE;
  134. key.hold_cyc_period = 100;
  135. key.cb = (my_button_callback)key_cb;
  136. key.pin = KEY_PIN;
  137. my_button_register(&key);
  138. my_button_start();
  139. }
  140. MSH_CMD_EXPORT(key_test, key_test);
  141. #endif /* FINSH_USING_MSH */
  142. #endif /* RT_USING_FINSH */