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  * 2018-02-08     Zhangyihong  the first version
9  * 2018-10-29     XY
10  * 2019-04-11     sundm75      modify for ls1c300 & RTGUI
11  */
12 
13 #include "drv_touch.h"
14 
15 #define TOUCH_I2C_NAME  "i2c1"
16 
17 #ifndef TOUCH_SAMPLE_HZ
18 #define TOUCH_SAMPLE_HZ (50)
19 #endif
20 
21 #ifndef TOUCH_I2C_NAME
22 #error "Please define touch i2c name!"
23 #endif
24 
25 #ifdef TINA_USING_TOUCH
26 #if (defined PKG_USING_GUIENGINE) || (defined RT_USING_RTGUI)
27 #include <rtgui/event.h>
28 #include <rtgui/rtgui_server.h>
29 #endif
30 
31 #if 0
32 #define TPDEBUG     rt_kprintf
33 #else
34 #define TPDEBUG(...)
35 #endif
36 
37 static rt_slist_t _driver_list;
38 static struct rt_i2c_bus_device *i2c_bus = RT_NULL;
39 
post_down_event(rt_uint16_t x,rt_uint16_t y,rt_uint32_t id)40 static void post_down_event(rt_uint16_t x, rt_uint16_t y, rt_uint32_t id)
41 {
42 #if (defined PKG_USING_GUIENGINE) || (defined RT_USING_RTGUI)
43     rt_err_t result;
44     struct rtgui_event_mouse emouse;
45 
46     emouse.parent.sender = RT_NULL;
47     emouse.wid = RT_NULL;
48 
49     emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
50     emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN;
51     emouse.x = x;
52     emouse.y = y;
53 #ifdef PKG_USING_GUIENGINE
54     emouse.ts = rt_tick_get();
55     emouse.id = id;
56 #endif
57 
58 #ifdef PKG_USING_GUIENGINE
59     do
60     {
61         result = rtgui_server_post_event(&emouse.parent, sizeof(emouse));
62         if (result != RT_EOK)
63         {
64             rt_thread_delay(RT_TICK_PER_SECOND / TOUCH_SAMPLE_HZ);
65         }
66     }
67     while (result != RT_EOK);
68 #else
69     rtgui_server_post_event(&emouse.parent, sizeof(emouse));
70 #endif
71 
72     TPDEBUG("[TP] touch down [%d, %d]\n", emouse.x, emouse.y);
73 #endif
74 }
75 
post_motion_event(rt_uint16_t x,rt_uint16_t y,rt_uint32_t id)76 static void post_motion_event(rt_uint16_t x, rt_uint16_t y, rt_uint32_t id)
77 {
78 #if (defined PKG_USING_GUIENGINE) || (defined RT_USING_RTGUI)
79     struct rtgui_event_mouse emouse;
80 
81     emouse.parent.sender = RT_NULL;
82     emouse.wid = RT_NULL;
83 
84     emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN;
85     emouse.parent.type = RTGUI_EVENT_MOUSE_MOTION;
86     emouse.x = x;
87     emouse.y = y;
88 #ifdef PKG_USING_GUIENGINE
89     emouse.ts = rt_tick_get();
90     emouse.id = id;
91 #endif
92     rtgui_server_post_event(&emouse.parent, sizeof(emouse));
93     TPDEBUG("[TP] touch motion [%d, %d]\n", emouse.x, emouse.y);
94 #endif
95 }
96 
post_up_event(rt_uint16_t x,rt_uint16_t y,rt_uint32_t id)97 static void post_up_event(rt_uint16_t x, rt_uint16_t y, rt_uint32_t id)
98 {
99 #if (defined PKG_USING_GUIENGINE) || (defined RT_USING_RTGUI)
100     rt_err_t result;
101     struct rtgui_event_mouse emouse;
102 
103     emouse.parent.sender = RT_NULL;
104     emouse.wid = RT_NULL;
105 
106     emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
107     emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP;
108     emouse.x = x;
109     emouse.y = y;
110 #ifdef PKG_USING_GUIENGINE
111     emouse.ts = rt_tick_get();
112     emouse.id = id;
113 #endif
114 
115 #ifdef PKG_USING_GUIENGINE
116     do
117     {
118         result = rtgui_server_post_event(&emouse.parent, sizeof(emouse));
119         if (result != RT_EOK)
120         {
121             rt_thread_delay(RT_TICK_PER_SECOND / TOUCH_SAMPLE_HZ);
122         }
123     }
124     while (result != RT_EOK);
125 #else
126     rtgui_server_post_event(&emouse.parent, sizeof(emouse));
127 #endif
128 
129     TPDEBUG("[TP] touch up [%d, %d]\n", emouse.x, emouse.y);
130 #endif
131 }
132 
touch_run(void * parameter)133 static void touch_run(void* parameter)
134 {
135     rt_tick_t emouse_id = 0;
136     struct touch_message msg;
137     rt_slist_t *driver_list = NULL;
138     struct touch_driver *current_driver = RT_NULL;
139 
140     i2c_bus = rt_i2c_bus_device_find(TOUCH_I2C_NAME);
141     RT_ASSERT(i2c_bus);
142 
143     if(rt_device_open(&i2c_bus->parent, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
144     {
145         return;
146     }
147 
148     rt_slist_for_each(driver_list, &_driver_list)
149     {
150         current_driver = (struct touch_driver *)driver_list;
151         if(current_driver->probe(i2c_bus) == RT_TRUE)
152         {
153             break;
154         }
155         current_driver = RT_NULL;
156     }
157 
158     if(current_driver == RT_NULL)
159     {
160         rt_kprintf("[TP] No touch pad or driver.\n");
161         rt_device_close((rt_device_t)i2c_bus);
162 
163         return;
164     }
165 
166     current_driver->ops->init(i2c_bus);
167 
168     while (1)
169     {
170         if (rt_sem_take(current_driver->isr_sem, RT_WAITING_FOREVER) != RT_EOK)
171         {
172             continue;
173         }
174 
175         if (current_driver->ops->read_point(&msg) != RT_EOK)
176         {
177             continue;
178         }
179 
180         switch (msg.event)
181         {
182         case TOUCH_EVENT_MOVE:
183             post_motion_event(msg.x, msg.y, emouse_id);
184             break;
185 
186         case TOUCH_EVENT_DOWN:
187             emouse_id = rt_tick_get();
188             post_down_event(msg.x, msg.y, emouse_id);
189             break;
190 
191         case TOUCH_EVENT_UP:
192             post_up_event(msg.x, msg.y, emouse_id);
193             break;
194 
195         default:
196             break;
197         }
198 
199         rt_thread_delay(RT_TICK_PER_SECOND / TOUCH_SAMPLE_HZ);
200     }
201 }
202 
rt_touch_drivers_register(touch_driver_t drv)203 rt_err_t rt_touch_drivers_register(touch_driver_t drv)
204 {
205     RT_ASSERT(drv != RT_NULL);
206     RT_ASSERT(drv->ops   != RT_NULL);
207     RT_ASSERT(drv->probe != RT_NULL);
208 
209     rt_slist_append(&_driver_list, &drv->list);
210 
211     return RT_EOK;
212 }
213 
rt_touch_list_init(void)214 static int rt_touch_list_init(void)
215 {
216     rt_slist_init(&_driver_list);
217 
218     return RT_EOK;
219 }
220 INIT_BOARD_EXPORT(rt_touch_list_init);
221 
rt_touch_init(void)222 static int rt_touch_init(void)
223 {
224     rt_thread_t thread = RT_NULL;
225 
226     thread = rt_thread_create("touch", touch_run, RT_NULL, 2048, 28, 20);
227     if(thread)
228     {
229         return rt_thread_startup(thread);
230     }
231 
232     return -RT_ERROR;
233 }
234 INIT_APP_EXPORT(rt_touch_init);
235 
rt_touch_read(rt_uint16_t addr,void * cmd_buf,size_t cmd_len,void * data_buf,size_t data_len)236 int rt_touch_read(rt_uint16_t addr, void *cmd_buf, size_t cmd_len, void *data_buf, size_t data_len)
237 {
238     struct rt_i2c_msg msgs[2];
239 
240     msgs[0].addr  = addr;
241     msgs[0].flags = RT_I2C_WR;
242     msgs[0].buf   = cmd_buf;
243     msgs[0].len   = cmd_len;
244 
245     msgs[1].addr  = addr;
246     msgs[1].flags = RT_I2C_RD;
247     msgs[1].buf   = data_buf;
248     msgs[1].len   = data_len;
249 
250     if (rt_i2c_transfer(i2c_bus, msgs, 2) == 2)
251         return 0;
252     else
253         return -1;
254 }
255 
rt_touch_write(rt_uint16_t addr,void * data_buf,size_t data_len)256 int rt_touch_write(rt_uint16_t addr, void *data_buf, size_t data_len)
257 {
258     struct rt_i2c_msg msgs[1];
259 
260     msgs[0].addr  = addr;
261     msgs[0].flags = RT_I2C_WR;
262     msgs[0].buf   = data_buf;
263     msgs[0].len   = data_len;
264 
265     if (rt_i2c_transfer(i2c_bus, msgs, 1) == 1)
266         return 0;
267     else
268         return -1;
269 }
270 #endif
271