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