board_key.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /*
  2. * File : drv_gpio_keyboard.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2015-11-19 Urey the first version
  23. */
  24. /*********************************************************************************************************
  25. ** Include Files
  26. *********************************************************************************************************/
  27. #include <rthw.h>
  28. #include <rtthread.h>
  29. #include <rtdevice.h>
  30. #include "board.h"
  31. #include "drv_gpio.h"
  32. #include "board_key.h"
  33. #ifdef RT_USING_AUDIO_PLAYER
  34. #include <player_app.h>
  35. #endif
  36. #define KEY_DEBUG
  37. #ifdef KEY_DEBUG
  38. #define KEY_DBG(...) rt_kprintf("[KEY]"),rt_kprintf(__VA_ARGS__)
  39. #else
  40. #define KEY_DBG(...)
  41. #endif
  42. static keyboard_event_handler_t _handler = RT_NULL;
  43. #if defined(BOARD_HALLEY2)
  44. /* 4 keys
  45. * SW1 SW2 SW3 SW5
  46. * Vol- Vol+ Play/Pause Mode/Config
  47. * PA10 PA11 PB28 PB31
  48. */
  49. static struct keyboard_io_def keyboard_io_tbl[] =
  50. {
  51. //Vol-/Next Song
  52. {
  53. GPIO_PORT_A, GPIO_Pin_10 ,
  54. KEY_NEXT, KEY_VOLDEC,
  55. },
  56. //Vol+/Prev Song
  57. {
  58. GPIO_PORT_A, GPIO_Pin_11 ,
  59. KEY_PREV, KEY_VOLINC,
  60. },
  61. //Play_Pause
  62. {
  63. GPIO_PORT_B, GPIO_Pin_28 ,
  64. KEY_UNKNOWN, KEY_PLAY_PAUSE,
  65. },
  66. //Mode/Config
  67. {
  68. GPIO_PORT_B, GPIO_Pin_31,
  69. KEY_CONFIG, KEY_NETWORK_MODE,
  70. },
  71. };
  72. #elif defined(BOARD_HALLEY2_REALBOARD)
  73. /* 6 keys
  74. * 11 12 21 22 31 32
  75. * ON/OFF MODE V+ V- BT/MUTE WIFI
  76. */
  77. static struct keyboard_io_def keyboard_io_tbl[] =
  78. {
  79. //ON/OFF
  80. {
  81. GPIO_PORT_B, GPIO_Pin_31,
  82. KEY_UNKNOWN, KEY_PWROFF,
  83. },
  84. //V+
  85. {
  86. GPIO_PORT_B, GPIO_Pin_25,
  87. KEY_UNKNOWN, KEY_VOLINC,
  88. },
  89. //V-
  90. {
  91. GPIO_PORT_B, GPIO_Pin_2,
  92. KEY_UNKNOWN, KEY_VOLDEC,
  93. },
  94. //BT/MUTE
  95. {
  96. GPIO_PORT_B, GPIO_Pin_3,
  97. KEY_SOURCE, KEY_MUTE,
  98. },
  99. //WIFI
  100. {
  101. GPIO_PORT_B, GPIO_Pin_28,
  102. KEY_UNKNOWN, KEY_CONFIG,
  103. },
  104. };
  105. #elif defined(BOARD_HALLEY2_REALBOARD_V2)
  106. struct keyboard_io_def keyboard_io_tbl[] =
  107. {
  108. //ON/OFF
  109. {
  110. GPIO_PORT_D, GPIO_Pin_0,
  111. KEY_UNKNOWN, KEY_UNKNOWN,
  112. },
  113. //V+
  114. {
  115. GPIO_PORT_B, GPIO_Pin_28,
  116. KEY_UNKNOWN, KEY_UNKNOWN,
  117. },
  118. //V-
  119. {
  120. GPIO_PORT_B, GPIO_Pin_31,
  121. KEY_UNKNOWN, KEY_UNKNOWN,
  122. },
  123. //WIFI config
  124. {
  125. GPIO_PORT_D, GPIO_Pin_2,
  126. KEY_UNKNOWN, KEY_UNKNOWN,
  127. },
  128. };
  129. #else
  130. struct keyboard_io_def keyboard_io_tbl[] =
  131. {
  132. //PWRKEY KEY
  133. {
  134. GPIO_PORT_B, GPIO_Pin_31,
  135. KEY_UNKNOWN, KEY_UNKNOWN
  136. },
  137. };
  138. #endif
  139. #define CFG_MAX_KEY_NBR sizeof(keyboard_io_tbl)/sizeof(keyboard_io_tbl[0])
  140. static struct rt_mailbox* _keyMb = RT_NULL;
  141. void keyboard_irq_callback(void *param)
  142. {
  143. KEY_DBG("%d\n", (int)param);
  144. if (_keyMb)
  145. {
  146. struct keyboard_io_def* key;
  147. int value = (int)param;
  148. key = &keyboard_io_tbl[value];
  149. if(rt_mb_send(_keyMb, (rt_uint32_t)param) == RT_EOK)
  150. gpio_mask_irq(key->port, key->pin);
  151. }
  152. }
  153. #define KEY_EVENT_DOWN 0x01
  154. #define KEY_EVENT_HOLD 0x02
  155. #define KEY_EVENT_UP 0x04
  156. #define KEY_SCAN_STEP_TIME 10
  157. #define KEY_SCAN_HOLD_THRESHOLD 2000
  158. //Scan the single key
  159. rt_uint8_t key_scan(struct keyboard_io_def *keyIO)
  160. {
  161. static rt_uint8_t keyTrigger = 0;
  162. static rt_uint8_t keyRelease = 0;
  163. static rt_uint8_t keyHold = 0;
  164. rt_uint8_t keyValue = 0;
  165. //elimination buffeting
  166. do
  167. {
  168. keyValue = gpio_get_value(keyIO->port,keyIO->pin);
  169. rt_thread_delay(rt_tick_from_millisecond(KEY_SCAN_STEP_TIME));
  170. }while(keyValue != gpio_get_value(keyIO->port,keyIO->pin));
  171. keyValue ^= 0x01;
  172. keyTrigger = keyValue &(keyValue ^ keyHold);
  173. keyRelease = (keyValue ^ keyTrigger ^ keyHold);
  174. keyHold = keyValue;
  175. // KEY_DBG("keyValue = %x\n,keyTrigger = %x\n,keyRelese = %x\n,keyHold = %x\n",keyValue,keyTrigger,keyRelease,keyHold);
  176. if(keyTrigger != 0)
  177. return KEY_EVENT_DOWN;
  178. else if(keyHold != 0)
  179. return KEY_EVENT_HOLD;
  180. return KEY_EVENT_UP;
  181. }
  182. void kbd_thread(void* parameter)
  183. {
  184. int keyId;
  185. rt_uint8_t keyEvent;
  186. rt_uint8_t keyValue;
  187. rt_uint32_t keyHoldTime;
  188. _keyMb = rt_mb_create("key", 4, RT_IPC_FLAG_FIFO);
  189. while (1)
  190. {
  191. if(rt_mb_recv(_keyMb, (rt_uint32_t*)&keyId, RT_TICK_PER_SECOND) != RT_EOK)
  192. {
  193. //if no key pressed,check power key...
  194. keyId = 0;
  195. }
  196. {
  197. struct keyboard_io_def* key;
  198. // Check key ID
  199. if(keyId >= CFG_MAX_KEY_NBR)
  200. {
  201. rt_kprintf("keyID error\n");
  202. continue;
  203. }
  204. key = &keyboard_io_tbl[keyId];
  205. keyEvent = key_scan(key);
  206. /* No key input */
  207. if(keyEvent == KEY_EVENT_UP)
  208. {
  209. gpio_unmask_irq(key->port, key->pin);
  210. continue;
  211. }
  212. KEY_DBG("key %d down\n", keyId);
  213. //Wait for key RELEASE
  214. keyHoldTime = 0;
  215. do
  216. {
  217. keyEvent = key_scan(key);
  218. if(keyEvent == KEY_EVENT_HOLD)
  219. {
  220. keyHoldTime += KEY_SCAN_STEP_TIME;
  221. if(keyHoldTime > KEY_SCAN_HOLD_THRESHOLD)
  222. break;
  223. }
  224. } while (keyEvent != KEY_EVENT_UP);
  225. KEY_DBG("key %d up,hold time = %dms\n", keyId,keyHoldTime);
  226. if(keyHoldTime > KEY_SCAN_HOLD_THRESHOLD)
  227. keyValue = key->longKey;
  228. else
  229. keyValue = key->shortKey;
  230. //send key event
  231. if (_handler) _handler(EVENT_KEY_DOWN | keyValue);
  232. //Wait for KEYUP
  233. while (keyEvent != KEY_EVENT_UP)
  234. {
  235. keyEvent = key_scan(key);
  236. rt_thread_delay(RT_TICK_PER_SECOND / 10);
  237. }
  238. if (_handler) _handler(EVENT_KEY_UP | keyValue);
  239. gpio_unmask_irq(key->port, key->pin);
  240. }
  241. }
  242. }
  243. void rt_hw_keyboard_set_handler(keyboard_event_handler_t handler)
  244. {
  245. _handler = handler;
  246. }
  247. void rt_hw_keyboard_init(void)
  248. {
  249. int i;
  250. rt_thread_t tid;
  251. tid = rt_thread_create("key", kbd_thread, RT_NULL, 2048, 16, 10);
  252. if (tid)
  253. rt_thread_startup(tid);
  254. /* initialize all IO for keyboard */
  255. for (i = 0; i < CFG_MAX_KEY_NBR; ++i)
  256. {
  257. gpio_set_func(keyboard_io_tbl[i].port,keyboard_io_tbl[i].pin,GPIO_INPUT_PULL | GPIO_INT_FE);
  258. gpio_set_irq_callback(keyboard_io_tbl[i].port,keyboard_io_tbl[i].pin,keyboard_irq_callback, (void*)i);
  259. gpio_unmask_irq(keyboard_io_tbl[i].port,keyboard_io_tbl[i].pin);
  260. }
  261. }