11/*
2- * Copyright (c) 2006-2022 , RT-Thread Development Team
2+ * Copyright (c) 2006-2026 , RT-Thread Development Team
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 *
66 * Change Logs:
77 * Date Author Notes
88 * 2022-6-27 solar first version
9+ * 2026-01-12 LinuxMint-User fix touch event bug with LVGL
10+ * 2026-01-13 LinuxMint-User improve the touch sliding experience of resistive screens
911 */
1012
1113#include <rtdevice.h>
@@ -42,6 +44,7 @@ void xpt2046_init_hw(void)
4244 rt_kprintf ("can't find touch device:%s\n" , TOUCH_DEVICE_NAME );
4345 return ;
4446 }
47+
4548 if (rt_device_open (touch , RT_DEVICE_FLAG_INT_RX ) != RT_EOK )
4649 {
4750 rt_kprintf ("can't open touch device:%s\n" , TOUCH_DEVICE_NAME );
@@ -87,38 +90,157 @@ void xpt2046_init_hw(void)
8790
8891void xpt2046_entry (void * parameter )
8992{
90- /* Find the touch device */
9193 rt_device_t touch = rt_device_find (TOUCH_DEVICE_NAME );
9294 if (touch == RT_NULL )
9395 {
9496 rt_kprintf ("can't find touch device:%s\n" , TOUCH_DEVICE_NAME );
9597 return ;
9698 }
97- #ifndef PKG_USING_LVGL
99+
100+ #ifndef PKG_USING_LVGL
98101 rt_device_t lcd = rt_device_find (TFTLCD_DEVICE_NAME );
99102 if (lcd == RT_NULL )
100103 {
101- rt_kprintf ("can't find display device:%s\n" , TFTLCD_DEVICE_NAME );
102- return ;
104+ rt_kprintf ("can't find display device:%s\n" , TFTLCD_DEVICE_NAME );
105+ return ;
103106 }
104- #endif /* PKG_USING_LVGL */
107+ #endif
108+
109+ static rt_bool_t is_touching = RT_FALSE ;
110+ static int no_touch_count = 0 ;
111+ static int touch_hold_count = 0 ;
112+ static int last_x = 0 , last_y = 0 ;
113+ static int stable_x = 0 , stable_y = 0 ;
114+
115+ /* 5-point moving average filter for coordinate smoothing */
116+ #define HISTORY_SIZE 5
117+ static int history_x [HISTORY_SIZE ] = {0 };
118+ static int history_y [HISTORY_SIZE ] = {0 };
119+ static int history_index = 0 ;
120+ static int history_count = 0 ;
121+
122+ static const int DEBOUNCE_COUNT = 2 ;
123+ static const int RELEASE_DEBOUNCE_COUNT = 5 ;
124+ static const int MIN_MOVE_DISTANCE = 3 ;
125+ static const int SMOOTHING_FACTOR = 2 ;
126+
127+ rt_memset (history_x , 0 , sizeof (history_x ));
128+ rt_memset (history_y , 0 , sizeof (history_y ));
129+
105130 while (1 )
106131 {
107- /* Prepare variable to read out the touch data */
108132 struct rt_touch_data read_data ;
109133 rt_memset (& read_data , 0 , sizeof (struct rt_touch_data ));
134+
110135 if (rt_device_read (touch , 0 , & read_data , 1 ) == 1 )
111136 {
112- #ifdef PKG_USING_LVGL
113- lv_port_indev_input (read_data .x_coordinate , read_data .y_coordinate ,
114- ((read_data .event = RT_TOUCH_EVENT_DOWN ) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL ));
115- #else /* PKG_USING_LVGL */
137+ int current_x = read_data .x_coordinate ;
138+ int current_y = read_data .y_coordinate ;
139+
140+ history_x [history_index ] = current_x ;
141+ history_y [history_index ] = current_y ;
142+ history_index = (history_index + 1 ) % HISTORY_SIZE ;
143+ if (history_count < HISTORY_SIZE ) history_count ++ ;
144+
145+ int avg_x = 0 , avg_y = 0 ;
146+ if (history_count > 0 )
147+ {
148+ for (int i = 0 ; i < history_count ; i ++ )
149+ {
150+ avg_x += history_x [i ];
151+ avg_y += history_y [i ];
152+ }
153+ avg_x /= history_count ;
154+ avg_y /= history_count ;
155+ }
156+ else
157+ {
158+ avg_x = current_x ;
159+ avg_y = current_y ;
160+ }
161+
162+ no_touch_count = 0 ;
163+
164+ #ifdef PKG_USING_LVGL
165+ if (!is_touching )
166+ {
167+ touch_hold_count ++ ;
168+
169+ if (touch_hold_count >= DEBOUNCE_COUNT )
170+ {
171+ is_touching = true;
172+ stable_x = avg_x ;
173+ stable_y = avg_y ;
174+ touch_hold_count = 0 ;
175+
176+ lv_port_indev_input (stable_x , stable_y , LV_INDEV_STATE_PR );
177+
178+ last_x = stable_x ;
179+ last_y = stable_y ;
180+ }
181+ }
182+ else
183+ {
184+ touch_hold_count = 0 ;
185+
186+ int dx = avg_x - last_x ;
187+ int dy = avg_y - last_y ;
188+ int distance = dx * dx + dy * dy ;
189+
190+ if (distance >= MIN_MOVE_DISTANCE * MIN_MOVE_DISTANCE )
191+ {
192+ /* Interpolation smoothing to reduce jitter */
193+ int smooth_x = last_x + (avg_x - last_x ) / SMOOTHING_FACTOR ;
194+ int smooth_y = last_y + (avg_y - last_y ) / SMOOTHING_FACTOR ;
195+
196+ lv_port_indev_input (smooth_x , smooth_y , LV_INDEV_STATE_PR );
197+
198+ last_x = smooth_x ;
199+ last_y = smooth_y ;
200+ stable_x = smooth_x ;
201+ stable_y = smooth_y ;
202+ }
203+ else
204+ {
205+ lv_port_indev_input (stable_x , stable_y , LV_INDEV_STATE_PR );
206+ }
207+ }
208+
209+ #else
116210 const rt_uint32_t black = 0x0 ;
117- rt_graphix_ops (lcd )-> set_pixel ((const char * )(& black ),
118- read_data .x_coordinate ,
119- read_data .y_coordinate );
120- #endif /* PKG_USING_LVGL */
211+ rt_graphix_ops (lcd )-> set_pixel ((const char * )(& black ), avg_x , avg_y );
212+ #endif
121213 }
214+ else
215+ {
216+ no_touch_count ++ ;
217+ touch_hold_count = 0 ;
218+
219+ if (is_touching )
220+ {
221+ if (no_touch_count >= RELEASE_DEBOUNCE_COUNT )
222+ {
223+ #ifdef PKG_USING_LVGL
224+ lv_port_indev_input (stable_x , stable_y , LV_INDEV_STATE_REL );
225+ #endif
226+
227+ is_touching = RT_FALSE ;
228+ no_touch_count = 0 ;
229+
230+ history_count = 0 ;
231+ history_index = 0 ;
232+ rt_memset (history_x , 0 , sizeof (history_x ));
233+ rt_memset (history_y , 0 , sizeof (history_y ));
234+ }
235+ else
236+ {
237+ #ifdef PKG_USING_LVGL
238+ lv_port_indev_input (stable_x , stable_y , LV_INDEV_STATE_PR );
239+ #endif
240+ }
241+ }
242+ }
243+
122244 rt_thread_mdelay (1 );
123245 }
124246}
@@ -134,3 +256,4 @@ static int touch_xpt2046_init(void)
134256INIT_COMPONENT_EXPORT (touch_xpt2046_init );
135257
136258#endif /* BSP_USING_TOUCH_RES */
259+
0 commit comments