key.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  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. * 2010-10-01 Yi.Qiu first version
  9. */
  10. /*
  11. * Warning, this keypad driver can only work on QEMU emulator
  12. */
  13. #include <rtthread.h>
  14. #include <s3c24x0.h>
  15. #include <rthw.h>
  16. #define KEY_RX_BUFFER_SIZE 32
  17. struct rt_key_device
  18. {
  19. struct rt_device parent;
  20. rt_uint32_t rx_buffer[KEY_RX_BUFFER_SIZE];
  21. rt_uint32_t read_index, save_index;
  22. };
  23. static struct rt_key_device *key_device = RT_NULL;
  24. /* save a char to serial buffer */
  25. static void rt_key_savechar(char ch)
  26. {
  27. rt_base_t level;
  28. /* disable interrupt */
  29. level = rt_hw_interrupt_disable();
  30. key_device->rx_buffer[key_device->save_index] = ch;
  31. key_device->save_index ++;
  32. if (key_device->save_index >= KEY_RX_BUFFER_SIZE)
  33. key_device->save_index = 0;
  34. /* if the next position is read index, discard this 'read char' */
  35. if (key_device->save_index == key_device->read_index)
  36. {
  37. key_device->read_index ++;
  38. if (key_device->read_index >= KEY_RX_BUFFER_SIZE)
  39. key_device->read_index = 0;
  40. }
  41. /* enable interrupt */
  42. rt_hw_interrupt_enable(level);
  43. }
  44. /* ISR for serial interrupt */
  45. static void rt_hw_key_isr(void)
  46. {
  47. /* save on rx buffer */
  48. rt_key_savechar(URXH1 & 0xff);
  49. /* invoke callback */
  50. if (key_device->parent.rx_indicate != RT_NULL)
  51. {
  52. rt_size_t rx_length;
  53. /* get rx length */
  54. rx_length = key_device->read_index > key_device->save_index ?
  55. KEY_RX_BUFFER_SIZE - key_device->read_index + key_device->save_index :
  56. key_device->save_index - key_device->read_index;
  57. key_device->parent.rx_indicate(&key_device->parent, rx_length);
  58. }
  59. }
  60. /**
  61. * This function is only for QEMU emulation
  62. */
  63. static void rt_key_handler(int vector, void *param)
  64. {
  65. INTSUBMSK |= (BIT_SUB_RXD1);
  66. rt_hw_key_isr();
  67. SUBSRCPND |= BIT_SUB_RXD1;
  68. /*Unmask sub interrupt (RXD0)*/
  69. INTSUBMSK &=~(BIT_SUB_RXD1);
  70. }
  71. /**
  72. * This function is only for QEMU emulation
  73. */
  74. static void key_init(void)
  75. {
  76. int i = 0;
  77. GPHCON |= 0xa0;
  78. /*PULLUP is enable */
  79. GPHUP |= 0x0c;
  80. /* FIFO enable, Tx/Rx FIFO clear */
  81. UFCON1 = 0x0;
  82. /* disable the flow control */
  83. UMCON1= 0x0;
  84. /* Normal,No parity,1 stop,8 bit */
  85. ULCON1 = 0x3;
  86. /*
  87. * tx=level,rx=edge,disable timeout int.,enable rx error int.,
  88. * normal,interrupt or polling
  89. */
  90. UCON1 = 0x245;
  91. //UBRD0 = div;
  92. // UBRD0 = 0x500; /* baudrate = 19200bps */
  93. UBRD1 = 0x1a;
  94. UTXH1 = 0x2;
  95. URXH1 = 0x1;
  96. /* output PCLK to UART0/1, PWMTIMER */
  97. CLKCON |= 0x0D00;
  98. for (i = 0; i < 100; i++);
  99. /* install key isr */
  100. INTSUBMSK &= ~(BIT_SUB_RXD1);
  101. rt_hw_interrupt_install(INTUART1, rt_key_handler, RT_NULL , "INTUART1");
  102. rt_hw_interrupt_umask(INTUART1);
  103. }
  104. static rt_err_t rt_key_init(rt_device_t dev)
  105. {
  106. if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
  107. {
  108. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  109. {
  110. rt_memset(key_device->rx_buffer, 0,
  111. sizeof(key_device->rx_buffer));
  112. key_device->read_index = key_device->save_index = 0;
  113. }
  114. dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
  115. }
  116. return RT_EOK;
  117. }
  118. static rt_err_t rt_key_open(rt_device_t dev, rt_uint16_t oflag)
  119. {
  120. return RT_EOK;
  121. }
  122. static rt_err_t rt_key_close(rt_device_t dev)
  123. {
  124. return RT_EOK;
  125. }
  126. static rt_size_t rt_key_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  127. {
  128. rt_uint8_t* ptr;
  129. rt_err_t err_code;
  130. rt_base_t level;
  131. ptr = buffer;
  132. err_code = RT_EOK;
  133. /* interrupt mode Rx */
  134. while (size)
  135. {
  136. if (key_device->read_index != key_device->save_index)
  137. {
  138. *ptr++ = key_device->rx_buffer[key_device->read_index];
  139. size --;
  140. /* disable interrupt */
  141. level = rt_hw_interrupt_disable();
  142. key_device->read_index ++;
  143. if (key_device->read_index >= KEY_RX_BUFFER_SIZE)
  144. key_device->read_index = 0;
  145. /* enable interrupt */
  146. rt_hw_interrupt_enable(level);
  147. }
  148. else
  149. {
  150. /* set error code */
  151. err_code = -RT_EEMPTY;
  152. break;
  153. }
  154. }
  155. /* set error code */
  156. rt_set_errno(err_code);
  157. return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  158. }
  159. static rt_err_t rt_key_control(rt_device_t dev, int cmd, void *args)
  160. {
  161. return RT_EOK;
  162. }
  163. #ifdef RT_USING_RTGUI
  164. #include <rtgui/event.h>
  165. #include <rtgui/rtgui_server.h>
  166. #include <rtgui/kbddef.h>
  167. static int s_key_map[0xff] = {0};
  168. static void rt_keymap_init(void)
  169. {
  170. s_key_map[0x1] = RTGUIK_ESCAPE;
  171. s_key_map[0xc] = RTGUIK_MINUS;
  172. s_key_map[0x39] = RTGUIK_SPACE;
  173. s_key_map[0xd] = RTGUIK_KP_EQUALS;
  174. s_key_map[0xe] = RTGUIK_BACKSPACE;
  175. s_key_map[0xf] = RTGUIK_TAB;
  176. s_key_map[0x1c] = RTGUIK_KP_ENTER;
  177. s_key_map[0xb] = RTGUIK_0;
  178. s_key_map[0x2] = RTGUIK_1;
  179. s_key_map[0x3] = RTGUIK_2;
  180. s_key_map[0x4] = RTGUIK_3;
  181. s_key_map[0x5] = RTGUIK_4;
  182. s_key_map[0x6] = RTGUIK_5;
  183. s_key_map[0x7] = RTGUIK_6;
  184. s_key_map[0x8] = RTGUIK_7;
  185. s_key_map[0x9] = RTGUIK_8;
  186. s_key_map[0xa] = RTGUIK_9;
  187. s_key_map[0x3b] = RTGUIK_F1;
  188. s_key_map[0x3c] = RTGUIK_F2;
  189. s_key_map[0x3d] = RTGUIK_F3;
  190. s_key_map[0x3e] = RTGUIK_F4;
  191. s_key_map[0xef] = RTGUIK_F5;
  192. s_key_map[0x40] = RTGUIK_F6;
  193. s_key_map[0x41] = RTGUIK_F7;
  194. s_key_map[0x42] = RTGUIK_F8;
  195. s_key_map[0x43] = RTGUIK_F9;
  196. s_key_map[0x1e] = RTGUIK_a;
  197. s_key_map[0x30] = RTGUIK_b;
  198. s_key_map[0x2c] = RTGUIK_c;
  199. s_key_map[0x20] = RTGUIK_d;
  200. s_key_map[0x12] = RTGUIK_e;
  201. s_key_map[0x21] = RTGUIK_f;
  202. s_key_map[0x22] = RTGUIK_g;
  203. s_key_map[0x23] = RTGUIK_h;
  204. s_key_map[0x17] = RTGUIK_i;
  205. s_key_map[0x24] = RTGUIK_j;
  206. s_key_map[0x25] = RTGUIK_k;
  207. s_key_map[0x26] = RTGUIK_l;
  208. s_key_map[0x32] = RTGUIK_m;
  209. s_key_map[0x31] = RTGUIK_n;
  210. s_key_map[0x18] = RTGUIK_o;
  211. s_key_map[0x19] = RTGUIK_p;
  212. s_key_map[0x10] = RTGUIK_q;
  213. s_key_map[0x13] = RTGUIK_r;
  214. s_key_map[0x1f] = RTGUIK_s;
  215. s_key_map[0x14] = RTGUIK_t;
  216. s_key_map[0x16] = RTGUIK_u;
  217. s_key_map[0x2f] = RTGUIK_v;
  218. s_key_map[0x11] = RTGUIK_w;
  219. s_key_map[0x2d] = RTGUIK_x;
  220. s_key_map[0x15] = RTGUIK_y;
  221. s_key_map[0x2c] = RTGUIK_z;
  222. s_key_map[0x4b] = RTGUIK_LEFT;
  223. s_key_map[0x4d] = RTGUIK_RIGHT;
  224. s_key_map[0x50] = RTGUIK_DOWN;
  225. s_key_map[0x2e] = RTGUIK_DELETE;
  226. s_key_map[0x48] = RTGUIK_UP;
  227. }
  228. static rt_err_t rtgui_key_rx(rt_device_t dev, rt_size_t size)
  229. {
  230. struct rtgui_event_kbd kbd_event;
  231. char key_value;
  232. while(rt_device_read(dev, 0, &key_value, 1) == 1)
  233. {
  234. /* init keyboard event */
  235. RTGUI_EVENT_KBD_INIT(&kbd_event);
  236. kbd_event.mod = RTGUI_KMOD_NONE;
  237. kbd_event.unicode = 0;
  238. kbd_event.key = RTGUIK_UNKNOWN;
  239. if(key_value & 0x80)
  240. {
  241. kbd_event.type = RTGUI_KEYUP;
  242. }
  243. else
  244. {
  245. kbd_event.type = RTGUI_KEYDOWN;
  246. }
  247. kbd_event.key = s_key_map[key_value & 0x7F];
  248. }
  249. if (kbd_event.key != RTGUIK_UNKNOWN)
  250. {
  251. /* post down event */
  252. rtgui_server_post_event(&(kbd_event.parent), sizeof(kbd_event));
  253. }
  254. return RT_EOK;
  255. }
  256. #endif
  257. /*
  258. * key driver register
  259. */
  260. void rt_hw_key_init(void)
  261. {
  262. /* hardware init */
  263. key_init();
  264. key_device = (struct rt_key_device*)rt_malloc (sizeof(struct rt_key_device));
  265. if (key_device == RT_NULL) return; /* no memory yet */
  266. /* clear device structure */
  267. rt_memset(&(key_device->parent), 0, sizeof(struct rt_device));
  268. key_device->parent.type = RT_Device_Class_Char;
  269. key_device->parent.tx_complete = RT_NULL;
  270. key_device->parent.init = rt_key_init;
  271. key_device->parent.open = rt_key_open;
  272. key_device->parent.close = rt_key_close;
  273. key_device->parent.read = rt_key_read;
  274. key_device->parent.write = RT_NULL;
  275. key_device->parent.control = rt_key_control;
  276. key_device->parent.user_data = RT_NULL;
  277. #ifdef RT_USING_RTGUI
  278. key_device->parent.rx_indicate = rtgui_key_rx;
  279. /* init keymap */
  280. rt_keymap_init();
  281. #endif
  282. /* register key device to RT-Thread */
  283. rt_device_register(&(key_device->parent), "key", RT_DEVICE_FLAG_RDONLY | RT_DEVICE_FLAG_INT_RX);
  284. }