254 lines
5.6 KiB
C
254 lines
5.6 KiB
C
|
/*
|
||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||
|
*
|
||
|
* SPDX-License-Identifier: Apache-2.0
|
||
|
*
|
||
|
* Change Logs:
|
||
|
* Date Author Notes
|
||
|
* 2018-02-08 Zhangyihong the first version
|
||
|
* 2018-10-29 XY
|
||
|
*/
|
||
|
#include "drv_touch.h"
|
||
|
|
||
|
|
||
|
#define TOUCH_I2C_NAME "i2c1"
|
||
|
|
||
|
#ifndef TOUCH_SAMPLE_HZ
|
||
|
#define TOUCH_SAMPLE_HZ (50)
|
||
|
#endif
|
||
|
|
||
|
#ifndef TOUCH_I2C_NAME
|
||
|
#error "Please define touch i2c name!"
|
||
|
#endif
|
||
|
|
||
|
#ifdef PKG_USING_GUIENGINE
|
||
|
#include <rtgui/event.h>
|
||
|
#include <rtgui/rtgui_server.h>
|
||
|
#endif
|
||
|
|
||
|
#if 0
|
||
|
#define TPDEBUG rt_kprintf
|
||
|
#else
|
||
|
#define TPDEBUG(...)
|
||
|
#endif
|
||
|
|
||
|
static rt_slist_t _driver_list;
|
||
|
static struct rt_i2c_bus_device *i2c_bus = RT_NULL;
|
||
|
|
||
|
static void post_down_event(rt_uint16_t x, rt_uint16_t y, rt_uint32_t id)
|
||
|
{
|
||
|
#ifdef PKG_USING_GUIENGINE
|
||
|
rt_err_t result;
|
||
|
struct rtgui_event_mouse emouse;
|
||
|
|
||
|
emouse.parent.sender = RT_NULL;
|
||
|
emouse.wid = RT_NULL;
|
||
|
|
||
|
emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
|
||
|
emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN;
|
||
|
emouse.x = x;
|
||
|
emouse.y = y;
|
||
|
emouse.ts = rt_tick_get();
|
||
|
emouse.id = id;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
result = rtgui_server_post_event(&emouse.parent, sizeof(emouse));
|
||
|
if (result != RT_EOK)
|
||
|
{
|
||
|
rt_thread_delay(RT_TICK_PER_SECOND / TOUCH_SAMPLE_HZ);
|
||
|
}
|
||
|
}
|
||
|
while (result != RT_EOK);
|
||
|
|
||
|
TPDEBUG("[TP] touch down [%d, %d]\n", emouse.x, emouse.y);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
static void post_motion_event(rt_uint16_t x, rt_uint16_t y, rt_uint32_t id)
|
||
|
{
|
||
|
#ifdef PKG_USING_GUIENGINE
|
||
|
struct rtgui_event_mouse emouse;
|
||
|
|
||
|
emouse.parent.sender = RT_NULL;
|
||
|
emouse.wid = RT_NULL;
|
||
|
|
||
|
emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN;
|
||
|
emouse.parent.type = RTGUI_EVENT_MOUSE_MOTION;
|
||
|
emouse.x = x;
|
||
|
emouse.y = y;
|
||
|
emouse.ts = rt_tick_get();
|
||
|
emouse.id = id;
|
||
|
rtgui_server_post_event(&emouse.parent, sizeof(emouse));
|
||
|
TPDEBUG("[TP] touch motion [%d, %d]\n", emouse.x, emouse.y);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
static void post_up_event(rt_uint16_t x, rt_uint16_t y, rt_uint32_t id)
|
||
|
{
|
||
|
#ifdef PKG_USING_GUIENGINE
|
||
|
rt_err_t result;
|
||
|
struct rtgui_event_mouse emouse;
|
||
|
|
||
|
emouse.parent.sender = RT_NULL;
|
||
|
emouse.wid = RT_NULL;
|
||
|
|
||
|
emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
|
||
|
emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP;
|
||
|
emouse.x = x;
|
||
|
emouse.y = y;
|
||
|
emouse.ts = rt_tick_get();
|
||
|
emouse.id = id;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
result = rtgui_server_post_event(&emouse.parent, sizeof(emouse));
|
||
|
if (result != RT_EOK)
|
||
|
{
|
||
|
rt_thread_delay(RT_TICK_PER_SECOND / TOUCH_SAMPLE_HZ);
|
||
|
}
|
||
|
}
|
||
|
while (result != RT_EOK);
|
||
|
|
||
|
TPDEBUG("[TP] touch up [%d, %d]\n", emouse.x, emouse.y);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
static void touch_run(void* parameter)
|
||
|
{
|
||
|
rt_tick_t emouse_id = 0;
|
||
|
struct touch_message msg;
|
||
|
rt_slist_t *driver_list = NULL;
|
||
|
struct touch_driver *current_driver = RT_NULL;
|
||
|
|
||
|
i2c_bus = rt_i2c_bus_device_find(TOUCH_I2C_NAME);
|
||
|
RT_ASSERT(i2c_bus);
|
||
|
|
||
|
if(rt_device_open(&i2c_bus->parent, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
rt_slist_for_each(driver_list, &_driver_list)
|
||
|
{
|
||
|
current_driver = (struct touch_driver *)driver_list;
|
||
|
if(current_driver->probe(i2c_bus) == RT_TRUE)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
current_driver = RT_NULL;
|
||
|
}
|
||
|
|
||
|
if(current_driver == RT_NULL)
|
||
|
{
|
||
|
rt_kprintf("[TP] No touch pad or driver.\n");
|
||
|
rt_device_close((rt_device_t)i2c_bus);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
current_driver->ops->init(i2c_bus);
|
||
|
|
||
|
while (1)
|
||
|
{
|
||
|
if (rt_sem_take(current_driver->isr_sem, RT_WAITING_FOREVER) != RT_EOK)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (current_driver->ops->read_point(&msg) != RT_EOK)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
switch (msg.event)
|
||
|
{
|
||
|
case TOUCH_EVENT_MOVE:
|
||
|
post_motion_event(msg.x, msg.y, emouse_id);
|
||
|
break;
|
||
|
|
||
|
case TOUCH_EVENT_DOWN:
|
||
|
emouse_id = rt_tick_get();
|
||
|
post_down_event(msg.x, msg.y, emouse_id);
|
||
|
break;
|
||
|
|
||
|
case TOUCH_EVENT_UP:
|
||
|
post_up_event(msg.x, msg.y, emouse_id);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
rt_thread_delay(RT_TICK_PER_SECOND / TOUCH_SAMPLE_HZ);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
rt_err_t rt_touch_drivers_register(touch_driver_t drv)
|
||
|
{
|
||
|
RT_ASSERT(drv != RT_NULL);
|
||
|
RT_ASSERT(drv->ops != RT_NULL);
|
||
|
RT_ASSERT(drv->probe != RT_NULL);
|
||
|
|
||
|
rt_slist_append(&_driver_list, &drv->list);
|
||
|
|
||
|
return RT_EOK;
|
||
|
}
|
||
|
|
||
|
static int rt_touch_list_init(void)
|
||
|
{
|
||
|
rt_slist_init(&_driver_list);
|
||
|
|
||
|
return RT_EOK;
|
||
|
}
|
||
|
INIT_BOARD_EXPORT(rt_touch_list_init);
|
||
|
|
||
|
static int rt_touch_init(void)
|
||
|
{
|
||
|
rt_thread_t thread = RT_NULL;
|
||
|
|
||
|
thread = rt_thread_create("touch", touch_run, RT_NULL, 2048, 28, 20);
|
||
|
if(thread)
|
||
|
{
|
||
|
return rt_thread_startup(thread);
|
||
|
}
|
||
|
|
||
|
return RT_ERROR;
|
||
|
}
|
||
|
INIT_APP_EXPORT(rt_touch_init);
|
||
|
|
||
|
int rt_touch_read(rt_uint16_t addr, void *cmd_buf, size_t cmd_len, void *data_buf, size_t data_len)
|
||
|
{
|
||
|
struct rt_i2c_msg msgs[2];
|
||
|
|
||
|
msgs[0].addr = addr;
|
||
|
msgs[0].flags = RT_I2C_WR;
|
||
|
msgs[0].buf = cmd_buf;
|
||
|
msgs[0].len = cmd_len;
|
||
|
|
||
|
msgs[1].addr = addr;
|
||
|
msgs[1].flags = RT_I2C_RD;
|
||
|
msgs[1].buf = data_buf;
|
||
|
msgs[1].len = data_len;
|
||
|
|
||
|
if (rt_i2c_transfer(i2c_bus, msgs, 2) == 2)
|
||
|
return 0;
|
||
|
else
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
int rt_touch_write(rt_uint16_t addr, void *data_buf, size_t data_len)
|
||
|
{
|
||
|
struct rt_i2c_msg msgs[1];
|
||
|
|
||
|
msgs[0].addr = addr;
|
||
|
msgs[0].flags = RT_I2C_WR;
|
||
|
msgs[0].buf = data_buf;
|
||
|
msgs[0].len = data_len;
|
||
|
|
||
|
if (rt_i2c_transfer(i2c_bus, msgs, 1) == 1)
|
||
|
return 0;
|
||
|
else
|
||
|
return -1;
|
||
|
}
|