/***************************************************************************//** * @file dev_keys.c * @brief Keys driver of RT-Thread RTOS for EFM32 * COPYRIGHT (C) 2012, RT-Thread Development Team * @author onelife * @version 1.0 ******************************************************************************* * @section License * The license and distribution terms for this file may be found in the file * LICENSE in this distribution or at http://www.rt-thread.org/license/LICENSE ******************************************************************************* * @section Change Logs * Date Author Notes * 2011-12-29 onelife Initial creation for EFM32GG_DK3750 board ******************************************************************************/ /***************************************************************************//** * @addtogroup EFM32GG_DK3750 * @{ ******************************************************************************/ /* Includes ------------------------------------------------------------------*/ #include "board.h" #include "hdl_interrupt.h" #include "dev_keys.h" #if defined(EFM32_USING_KEYS) #if defined(RT_USING_RTGUI) #include #endif /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ #ifdef EFM32_KEYS_DEBUG #define keys_debug(format,args...) rt_kprintf(format, ##args) #else #define keys_debug(format,args...) #endif /* Private function prototypes -----------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ static struct efm32_joy_device joy; static struct rt_device joy_dev; static struct rtgui_event_mouse mouse; static rt_bool_t click; /* Private functions ---------------------------------------------------------*/ /***************************************************************************//** * @brief * Keys interrupt handler * * @details * * @note * * @param[in] device * Pointer to device descriptor ******************************************************************************/ static void efm32_keys_isr(rt_device_t dev) { rt_uint16_t flag, joystick; /* Clear DEK interrupt */ flag = DVK_getInterruptFlags(); DVK_clearInterruptFlags(flag); if (flag & BC_INTFLAG_PB) { } if (flag & BC_INTFLAG_DIP) { } if (flag & BC_INTFLAG_JOYSTICK) { joystick = DVK_getJoystick(); keys_debug("Keys: joystick %x\n", joystick); #ifdef RT_USING_RTGUI switch (joystick) { case BC_UIF_JOYSTICK_RIGHT: joy.x += 2; if (joy.x > joy.max_x) { joy.x = joy.max_x; } break; case BC_UIF_JOYSTICK_LEFT: joy.x -= 2; if (joy.x < joy.min_x) { joy.x = joy.min_x; } break; case BC_UIF_JOYSTICK_DOWN: joy.y += 2; if (joy.y > joy.max_y) { joy.y = joy.max_y; } break; case BC_UIF_JOYSTICK_UP: joy.y -= 2; if (joy.y < joy.min_y) { joy.y = joy.min_y; } break; case BC_UIF_JOYSTICK_CENTER: break; default: break; } #endif if (joystick) { if (joystick != BC_UIF_JOYSTICK_CENTER) { mouse.parent.type = RTGUI_EVENT_MOUSE_MOTION; mouse.x = joy.x; mouse.y = joy.y; rtgui_server_post_event((&mouse.parent), sizeof(mouse)); rt_timer_start(&joy.timer); } else { click = RT_TRUE; mouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; mouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN; rtgui_server_post_event((&mouse.parent), sizeof(mouse)); } } else { if (click) { click = RT_FALSE; mouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; mouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP; rtgui_server_post_event((&mouse.parent), sizeof(mouse)); } else { rt_timer_stop(&joy.timer); } } } if (flag & BC_INTFLAG_AEM) { } } /***************************************************************************//** * @brief * Keys timeout handler * * @details * * @note * * @param[in] param * Parameter ******************************************************************************/ static void efm32_keys_timer_isr(void *param) { rt_uint16_t joystick; joystick = DVK_getJoystick(); #ifdef RT_USING_RTGUI switch (joystick) { case BC_UIF_JOYSTICK_RIGHT: joy.x += 2; if (joy.x > joy.max_x) { joy.x = joy.max_x; } break; case BC_UIF_JOYSTICK_LEFT: joy.x -= 2; if (joy.x < joy.min_x) { joy.x = joy.min_x; } break; case BC_UIF_JOYSTICK_DOWN: joy.y += 2; if (joy.y > joy.max_y) { joy.y = joy.max_y; } break; case BC_UIF_JOYSTICK_UP: joy.y -= 2; if (joy.y < joy.min_y) { joy.y = joy.min_y; } break; } if (joystick) { mouse.parent.type = RTGUI_EVENT_MOUSE_MOTION; mouse.x = joy.x; mouse.y = joy.y; rtgui_server_post_event((&mouse.parent), sizeof(mouse)); } #endif } /***************************************************************************//** * @brief * Initialize keys device * * @details * * @note * * @param[in] dev * Pointer to device descriptor * * @return * Error code ******************************************************************************/ static rt_err_t efm32_keys_init (rt_device_t dev) { struct rt_device_graphic_info lcd_info; rt_device_t lcd; lcd = rt_device_find(LCD_DEVICE_NAME); if (lcd == RT_NULL) { keys_debug("Keys err: Can't find LCD\n"); return -RT_ERROR; } lcd->control(lcd, RTGRAPHIC_CTRL_GET_INFO, (void *)&lcd_info); click = RT_FALSE; joy.x = 0; joy.y = 0; joy.min_x = 0; joy.max_x = lcd_info.width; joy.min_y = 0; joy.max_y = lcd_info.height; mouse.parent.sender = RT_NULL; mouse.wid = RT_NULL; mouse.button = 0; return RT_EOK; } /***************************************************************************//** * @brief * Initialize keys related hardware and register joystic device to kernel * * @details * * @note * ******************************************************************************/ void efm32_hw_keys_init(void) { /* Configure joystick interrupt pin */ GPIO_PinModeSet(KEYS_INT_PORT, KEYS_INT_PIN, gpioModeInputPullFilter, 1); /* Enable joystick interrupt */ GPIO_IntConfig(KEYS_INT_PORT, KEYS_INT_PIN, true, true, true); efm32_irq_hook_init_t hook; hook.type = efm32_irq_type_gpio; hook.unit = KEYS_INT_PIN; hook.cbFunc = efm32_keys_isr; hook.userPtr = RT_NULL; efm32_irq_hook_register(&hook); if ((rt_uint8_t)KEYS_INT_PIN % 2) { NVIC_ClearPendingIRQ(GPIO_ODD_IRQn); NVIC_SetPriority(GPIO_ODD_IRQn, EFM32_IRQ_PRI_DEFAULT); NVIC_EnableIRQ(GPIO_ODD_IRQn); } else { NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn); NVIC_SetPriority(GPIO_EVEN_IRQn, EFM32_IRQ_PRI_DEFAULT); NVIC_EnableIRQ(GPIO_EVEN_IRQn); } /* Enable DVK joystick interrupt */ DVK_enableInterrupt(BC_INTEN_JOYSTICK); rt_timer_init(&joy.timer, "joy_tmr", efm32_keys_timer_isr, RT_NULL, KEYS_POLL_TIME, RT_TIMER_FLAG_PERIODIC); joy_dev.init = efm32_keys_init; joy_dev.open = RT_NULL; joy_dev.close = RT_NULL; joy_dev.read = RT_NULL; joy_dev.write = RT_NULL; joy_dev.control = RT_NULL; joy_dev.user_data = (void *)&joy; /* register joy stick device */ rt_device_register(&joy_dev, "joy", RT_DEVICE_FLAG_RDWR); keys_debug("Keys: H/W init OK!\n"); } #endif /* defined(EFM32_USING_KEYS) */ /***************************************************************************//** * @} ******************************************************************************/