/* * Copyright (c) 2006-2022, 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 * 2019-04-11 sundm75 modify for ls1c300 & RTGUI */ #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 TINA_USING_TOUCH #if (defined PKG_USING_GUIENGINE) || (defined RT_USING_RTGUI) #include #include #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) { #if (defined PKG_USING_GUIENGINE) || (defined RT_USING_RTGUI) 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; #ifdef PKG_USING_GUIENGINE emouse.ts = rt_tick_get(); emouse.id = id; #endif #ifdef PKG_USING_GUIENGINE 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); #else rtgui_server_post_event(&emouse.parent, sizeof(emouse)); #endif 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) { #if (defined PKG_USING_GUIENGINE) || (defined RT_USING_RTGUI) 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; #ifdef PKG_USING_GUIENGINE emouse.ts = rt_tick_get(); emouse.id = id; #endif 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) { #if (defined PKG_USING_GUIENGINE) || (defined RT_USING_RTGUI) 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; #ifdef PKG_USING_GUIENGINE emouse.ts = rt_tick_get(); emouse.id = id; #endif #ifdef PKG_USING_GUIENGINE 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); #else rtgui_server_post_event(&emouse.parent, sizeof(emouse)); #endif 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; } #endif