1 /*
2  * Copyright (c) 2006-2022, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date         Author      Notes
8  * 2011-12-29   onelife     Initial creation for EFM32GG_DK3750 board
9  */
10 
11 /***************************************************************************//**
12  * @addtogroup EFM32GG_DK3750
13  * @{
14  ******************************************************************************/
15 
16 /* Includes ------------------------------------------------------------------*/
17 #include "board.h"
18 #include "hdl_interrupt.h"
19 #include "dev_keys.h"
20 
21 #if defined(EFM32_USING_KEYS)
22 #if defined(RT_USING_RTGUI)
23 #include <rtgui/event.h>
24 #endif
25 
26 /* Private typedef -----------------------------------------------------------*/
27 /* Private define ------------------------------------------------------------*/
28 /* Private macro -------------------------------------------------------------*/
29 #ifdef EFM32_KEYS_DEBUG
30 #define keys_debug(format,args...)          rt_kprintf(format, ##args)
31 #else
32 #define keys_debug(format,args...)
33 #endif
34 
35 /* Private function prototypes -----------------------------------------------*/
36 /* Private variables ---------------------------------------------------------*/
37 static struct efm32_joy_device              joy;
38 static struct rt_device                     joy_dev;
39 static struct rtgui_event_mouse             mouse;
40 static rt_bool_t                            click;
41 
42 /* Private functions ---------------------------------------------------------*/
43 /***************************************************************************//**
44  * @brief
45  *  Keys interrupt handler
46  *
47  * @details
48  *
49  * @note
50  *
51  * @param[in] device
52  *  Pointer to device descriptor
53  ******************************************************************************/
efm32_keys_isr(rt_device_t dev)54 static void efm32_keys_isr(rt_device_t dev)
55 {
56     rt_uint16_t flag, joystick;
57 
58     /* Clear DEK interrupt */
59     flag = DVK_getInterruptFlags();
60     DVK_clearInterruptFlags(flag);
61 
62     if (flag & BC_INTFLAG_PB)
63     {
64     }
65 
66     if (flag & BC_INTFLAG_DIP)
67     {
68 
69     }
70 
71     if (flag & BC_INTFLAG_JOYSTICK)
72     {
73         joystick = DVK_getJoystick();
74         keys_debug("Keys: joystick %x\n", joystick);
75 
76 #ifdef RT_USING_RTGUI
77         switch (joystick)
78         {
79         case BC_UIF_JOYSTICK_RIGHT:
80             joy.x += 2;
81             if (joy.x > joy.max_x)
82             {
83                 joy.x = joy.max_x;
84             }
85             break;
86         case BC_UIF_JOYSTICK_LEFT:
87             joy.x -= 2;
88             if (joy.x < joy.min_x)
89             {
90                 joy.x = joy.min_x;
91             }
92             break;
93         case BC_UIF_JOYSTICK_DOWN:
94             joy.y += 2;
95             if (joy.y > joy.max_y)
96             {
97                 joy.y = joy.max_y;
98             }
99             break;
100         case BC_UIF_JOYSTICK_UP:
101             joy.y -= 2;
102             if (joy.y < joy.min_y)
103             {
104                 joy.y = joy.min_y;
105             }
106             break;
107         case BC_UIF_JOYSTICK_CENTER:
108             break;
109         default:
110             break;
111         }
112 #endif
113 
114         if (joystick)
115         {
116             if (joystick != BC_UIF_JOYSTICK_CENTER)
117             {
118                 mouse.parent.type = RTGUI_EVENT_MOUSE_MOTION;
119                 mouse.x = joy.x;
120                 mouse.y = joy.y;
121                 rtgui_server_post_event((&mouse.parent), sizeof(mouse));
122                 rt_timer_start(&joy.timer);
123             }
124             else
125             {
126                 click = RT_TRUE;
127                 mouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
128                 mouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN;
129                 rtgui_server_post_event((&mouse.parent), sizeof(mouse));
130             }
131         }
132         else
133         {
134             if (click)
135             {
136                 click = RT_FALSE;
137                 mouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
138                 mouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP;
139                 rtgui_server_post_event((&mouse.parent), sizeof(mouse));
140             }
141             else
142             {
143                 rt_timer_stop(&joy.timer);
144             }
145         }
146     }
147 
148     if (flag & BC_INTFLAG_AEM)
149     {
150     }
151 }
152 
153 /***************************************************************************//**
154  * @brief
155  *  Keys timeout handler
156  *
157  * @details
158  *
159  * @note
160  *
161  * @param[in] param
162  *  Parameter
163  ******************************************************************************/
efm32_keys_timer_isr(void * param)164 static void efm32_keys_timer_isr(void *param)
165 {
166     rt_uint16_t joystick;
167 
168     joystick = DVK_getJoystick();
169 
170 #ifdef RT_USING_RTGUI
171     switch (joystick)
172     {
173     case BC_UIF_JOYSTICK_RIGHT:
174         joy.x += 2;
175         if (joy.x > joy.max_x)
176         {
177             joy.x = joy.max_x;
178         }
179         break;
180     case BC_UIF_JOYSTICK_LEFT:
181         joy.x -= 2;
182         if (joy.x < joy.min_x)
183         {
184             joy.x = joy.min_x;
185         }
186         break;
187     case BC_UIF_JOYSTICK_DOWN:
188         joy.y += 2;
189         if (joy.y > joy.max_y)
190         {
191             joy.y = joy.max_y;
192         }
193         break;
194     case BC_UIF_JOYSTICK_UP:
195         joy.y -= 2;
196         if (joy.y < joy.min_y)
197         {
198             joy.y = joy.min_y;
199         }
200         break;
201     }
202 
203     if (joystick)
204     {
205         mouse.parent.type = RTGUI_EVENT_MOUSE_MOTION;
206         mouse.x = joy.x;
207         mouse.y = joy.y;
208         rtgui_server_post_event((&mouse.parent), sizeof(mouse));
209     }
210 #endif
211 }
212 
213 /***************************************************************************//**
214  * @brief
215  *   Initialize keys device
216  *
217  * @details
218  *
219  * @note
220  *
221  * @param[in] dev
222  *   Pointer to device descriptor
223  *
224  * @return
225  *   Error code
226  ******************************************************************************/
efm32_keys_init(rt_device_t dev)227 static rt_err_t efm32_keys_init (rt_device_t dev)
228 {
229     struct rt_device_graphic_info lcd_info;
230     rt_device_t lcd;
231 
232     lcd = rt_device_find(LCD_DEVICE_NAME);
233     if (lcd == RT_NULL)
234     {
235         keys_debug("Keys err: Can't find LCD\n");
236         return -RT_ERROR;
237     }
238 
239     lcd->control(lcd, RTGRAPHIC_CTRL_GET_INFO, (void *)&lcd_info);
240 
241     click               = RT_FALSE;
242     joy.x               = 0;
243     joy.y               = 0;
244     joy.min_x           = 0;
245     joy.max_x           = lcd_info.width;
246     joy.min_y           = 0;
247     joy.max_y           = lcd_info.height;
248 
249     mouse.parent.sender = RT_NULL;
250     mouse.wid           = RT_NULL;
251     mouse.button        = 0;
252 
253     return RT_EOK;
254 }
255 
256 /***************************************************************************//**
257  * @brief
258  *   Initialize keys related hardware and register joystic device to kernel
259  *
260  * @details
261  *
262  * @note
263  *
264  ******************************************************************************/
efm32_hw_keys_init(void)265 void efm32_hw_keys_init(void)
266 {
267     /* Configure joystick interrupt pin */
268     GPIO_PinModeSet(KEYS_INT_PORT, KEYS_INT_PIN, gpioModeInputPullFilter, 1);
269 
270     /* Enable joystick interrupt */
271     GPIO_IntConfig(KEYS_INT_PORT, KEYS_INT_PIN, true, true, true);
272 
273     efm32_irq_hook_init_t hook;
274     hook.type       = efm32_irq_type_gpio;
275     hook.unit       = KEYS_INT_PIN;
276     hook.cbFunc     = efm32_keys_isr;
277     hook.userPtr    = RT_NULL;
278     efm32_irq_hook_register(&hook);
279 
280     if ((rt_uint8_t)KEYS_INT_PIN % 2)
281     {
282         NVIC_ClearPendingIRQ(GPIO_ODD_IRQn);
283         NVIC_SetPriority(GPIO_ODD_IRQn, EFM32_IRQ_PRI_DEFAULT);
284         NVIC_EnableIRQ(GPIO_ODD_IRQn);
285     }
286     else
287     {
288         NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn);
289         NVIC_SetPriority(GPIO_EVEN_IRQn, EFM32_IRQ_PRI_DEFAULT);
290         NVIC_EnableIRQ(GPIO_EVEN_IRQn);
291     }
292 
293     /* Enable DVK joystick interrupt */
294     DVK_enableInterrupt(BC_INTEN_JOYSTICK);
295 
296     rt_timer_init(&joy.timer,
297         "joy_tmr",
298         efm32_keys_timer_isr,
299         RT_NULL,
300         KEYS_POLL_TIME,
301         RT_TIMER_FLAG_PERIODIC);
302 
303     joy_dev.init        = efm32_keys_init;
304     joy_dev.open        = RT_NULL;
305     joy_dev.close       = RT_NULL;
306     joy_dev.read        = RT_NULL;
307     joy_dev.write       = RT_NULL;
308     joy_dev.control     = RT_NULL;
309     joy_dev.user_data   = (void *)&joy;
310 
311     /* register joy stick device */
312     rt_device_register(&joy_dev, "joy", RT_DEVICE_FLAG_RDWR);
313 
314     keys_debug("Keys: H/W init OK!\n");
315 }
316 
317 #endif /* defined(EFM32_USING_KEYS) */
318 /***************************************************************************//**
319  * @}
320  ******************************************************************************/
321