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