rt-thread/bsp/efm32/dev_keys.c

325 lines
8.7 KiB
C

/***************************************************************************//**
* @file dev_keys.c
* @brief Keys driver of RT-Thread RTOS for EFM32
* COPYRIGHT (C) 2011, RT-Thread Development Team
* @author onelife
* @version 0.4 beta
*******************************************************************************
* @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)
#include <rtgui/event.h>
/* 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) */
/***************************************************************************//**
* @}
******************************************************************************/