Fix: fix xpt2046_touch_readpoint type error

Fix & Improve: fix touch event bug with LVGL

Fix touch event bug with LVGL.
Improve the touch sliding experience of resistive screens.

[ci][stm32f407] add lcd attach config CI check

Fix: minor modification

Fix format issue.

Fix Ci attach file.
This commit is contained in:
Eric Chan
2026-01-13 20:43:02 +08:00
committed by R b b666
parent d76eca1384
commit b3c71a6f34
3 changed files with 179 additions and 19 deletions

View File

@@ -0,0 +1,32 @@
CONFIG_RT_USING_SPI=y
CONFIG_RT_USING_SPI_ISR=y
CONFIG_RT_USING_SPI_BITOPS=y
CONFIG_RT_USING_SOFT_SPI=y
CONFIG_RT_USING_SOFT_SPI0=y
CONFIG_RT_SOFT_SPI0_SCK_PIN=1
CONFIG_RT_SOFT_SPI0_MISO_PIN=2
CONFIG_RT_SOFT_SPI0_MOSI_PIN=3
CONFIG_RT_SOFT_SPI0_BUS_NAME="spi0"
CONFIG_RT_SOFT_SPI0_TIMING_DELAY=1
CONFIG_RT_USING_SOFT_SPI1=y
CONFIG_RT_SOFT_SPI1_SCK_PIN=4
CONFIG_RT_SOFT_SPI1_MISO_PIN=5
CONFIG_RT_SOFT_SPI1_MOSI_PIN=6
CONFIG_RT_SOFT_SPI1_BUS_NAME="spi1"
CONFIG_RT_SOFT_SPI1_TIMING_DELAY=1
CONFIG_RT_USING_TOUCH=y
CONFIG_RT_TOUCH_PIN_IRQ=y
CONFIG_BSP_USING_SRAM=y
CONFIG_BSP_USING_ONBOARD_LCD=y
CONFIG_BSP_USING_ONBOARD_LCD_TEST=y
CONFIG_BSP_USING_TOUCH=y
CONFIG_BSP_USING_TOUCH_RES=y
CONFIG_BSP_XPT2046_CS_PIN="PC.13"
CONFIG_BSP_XPT2046_IRQ_PIN="PB.1"
CONFIG_BSP_USING_SOFT_SPI=y
CONFIG_BSP_USING_SOFT_SPI1=y
CONFIG_BSP_S_SPI1_SCK_PIN=16
CONFIG_BSP_S_SPI1_MISO_PIN=18
CONFIG_BSP_S_SPI1_MOSI_PIN=91
CONFIG_BSP_USING_EXT_FMC_IO=y
CONFIG_BSP_USING_FMC=y

View File

@@ -1,11 +1,12 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
* Copyright (c) 2006-2026, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-6-27 solar first version
* Date Author Notes
* 2022-6-27 solar first version
* 2026-01-12 LinuxMint-User fix xpt2046_touch_readpoint type error
*/
#include <drv_touch_xpt.h>
@@ -30,6 +31,7 @@ rt_err_t xpt2046_calibration(const char *lcd_name,const char *touch_name)
LOG_E(LOG_TAG " cannot find lcd device named %s", lcd_name);
return -RT_ERROR;
}
if (rt_device_open(lcd, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
{
LOG_E(LOG_TAG " cannot open lcd device named %s", lcd_name);
@@ -101,6 +103,7 @@ rt_err_t xpt2046_calibration(const char *lcd_name,const char *touch_name)
{
break;
}
switch (raw_idx)
{
case 1:
@@ -151,7 +154,7 @@ rt_err_t xpt2046_calibration(const char *lcd_name,const char *touch_name)
return RT_EOK;
}
static rt_ssize_t xpt2046_touch_readpoint(struct rt_touch_device *touch, void *buf, rt_size_t touch_num)
static rt_size_t xpt2046_touch_readpoint(struct rt_touch_device *touch, void *buf, rt_size_t touch_num)
{
if (touch_num != 0)
{
@@ -185,6 +188,7 @@ static rt_ssize_t xpt2046_touch_readpoint(struct rt_touch_device *touch, void *b
y_cum += temp;
}
}
if (!x_count || !y_count)
{
result->event = RT_TOUCH_EVENT_NONE;
@@ -264,3 +268,4 @@ static int xpt2046_hw_init(void)
INIT_DEVICE_EXPORT(xpt2046_hw_init);
#endif /* BSP_USING_TOUCH_RES */

View File

@@ -1,11 +1,13 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
* Copyright (c) 2006-2026, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-6-27 solar first version
* 2026-01-12 LinuxMint-User fix touch event bug with LVGL
* 2026-01-13 LinuxMint-User improve the touch sliding experience of resistive screens
*/
#include <rtdevice.h>
@@ -42,6 +44,7 @@ void xpt2046_init_hw(void)
rt_kprintf("can't find touch device:%s\n", TOUCH_DEVICE_NAME);
return;
}
if (rt_device_open(touch, RT_DEVICE_FLAG_INT_RX) != RT_EOK)
{
rt_kprintf("can't open touch device:%s\n", TOUCH_DEVICE_NAME);
@@ -87,38 +90,157 @@ void xpt2046_init_hw(void)
void xpt2046_entry(void *parameter)
{
/* Find the touch device */
rt_device_t touch = rt_device_find(TOUCH_DEVICE_NAME);
if (touch == RT_NULL)
{
rt_kprintf("can't find touch device:%s\n", TOUCH_DEVICE_NAME);
return;
}
#ifndef PKG_USING_LVGL
#ifndef PKG_USING_LVGL
rt_device_t lcd = rt_device_find(TFTLCD_DEVICE_NAME);
if (lcd == RT_NULL)
{
rt_kprintf("can't find display device:%s\n", TFTLCD_DEVICE_NAME);
return;
rt_kprintf("can't find display device:%s\n", TFTLCD_DEVICE_NAME);
return;
}
#endif /* PKG_USING_LVGL */
#endif
static rt_bool_t is_touching = RT_FALSE;
static int no_touch_count = 0;
static int touch_hold_count = 0;
static int last_x = 0, last_y = 0;
static int stable_x = 0, stable_y = 0;
/* 5-point moving average filter for coordinate smoothing */
#define HISTORY_SIZE 5
static int history_x[HISTORY_SIZE] = {0};
static int history_y[HISTORY_SIZE] = {0};
static int history_index = 0;
static int history_count = 0;
static const int DEBOUNCE_COUNT = 2;
static const int RELEASE_DEBOUNCE_COUNT = 5;
static const int MIN_MOVE_DISTANCE = 3;
static const int SMOOTHING_FACTOR = 2;
rt_memset(history_x, 0, sizeof(history_x));
rt_memset(history_y, 0, sizeof(history_y));
while (1)
{
/* Prepare variable to read out the touch data */
struct rt_touch_data read_data;
rt_memset(&read_data, 0, sizeof(struct rt_touch_data));
if (rt_device_read(touch, 0, &read_data, 1) == 1)
{
#ifdef PKG_USING_LVGL
lv_port_indev_input(read_data.x_coordinate, read_data.y_coordinate,
((read_data.event = RT_TOUCH_EVENT_DOWN) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL));
#else /* PKG_USING_LVGL */
int current_x = read_data.x_coordinate;
int current_y = read_data.y_coordinate;
history_x[history_index] = current_x;
history_y[history_index] = current_y;
history_index = (history_index + 1) % HISTORY_SIZE;
if (history_count < HISTORY_SIZE) history_count++;
int avg_x = 0, avg_y = 0;
if (history_count > 0)
{
for (int i = 0; i < history_count; i++)
{
avg_x += history_x[i];
avg_y += history_y[i];
}
avg_x /= history_count;
avg_y /= history_count;
}
else
{
avg_x = current_x;
avg_y = current_y;
}
no_touch_count = 0;
#ifdef PKG_USING_LVGL
if (!is_touching)
{
touch_hold_count++;
if (touch_hold_count >= DEBOUNCE_COUNT)
{
is_touching = true;
stable_x = avg_x;
stable_y = avg_y;
touch_hold_count = 0;
lv_port_indev_input(stable_x, stable_y, LV_INDEV_STATE_PR);
last_x = stable_x;
last_y = stable_y;
}
}
else
{
touch_hold_count = 0;
int dx = avg_x - last_x;
int dy = avg_y - last_y;
int distance = dx * dx + dy * dy;
if (distance >= MIN_MOVE_DISTANCE * MIN_MOVE_DISTANCE)
{
/* Interpolation smoothing to reduce jitter */
int smooth_x = last_x + (avg_x - last_x) / SMOOTHING_FACTOR;
int smooth_y = last_y + (avg_y - last_y) / SMOOTHING_FACTOR;
lv_port_indev_input(smooth_x, smooth_y, LV_INDEV_STATE_PR);
last_x = smooth_x;
last_y = smooth_y;
stable_x = smooth_x;
stable_y = smooth_y;
}
else
{
lv_port_indev_input(stable_x, stable_y, LV_INDEV_STATE_PR);
}
}
#else
const rt_uint32_t black = 0x0;
rt_graphix_ops(lcd)->set_pixel((const char *)(&black),
read_data.x_coordinate,
read_data.y_coordinate);
#endif /* PKG_USING_LVGL */
rt_graphix_ops(lcd)->set_pixel((const char *)(&black), avg_x, avg_y);
#endif
}
else
{
no_touch_count++;
touch_hold_count = 0;
if (is_touching)
{
if (no_touch_count >= RELEASE_DEBOUNCE_COUNT)
{
#ifdef PKG_USING_LVGL
lv_port_indev_input(stable_x, stable_y, LV_INDEV_STATE_REL);
#endif
is_touching = RT_FALSE;
no_touch_count = 0;
history_count = 0;
history_index = 0;
rt_memset(history_x, 0, sizeof(history_x));
rt_memset(history_y, 0, sizeof(history_y));
}
else
{
#ifdef PKG_USING_LVGL
lv_port_indev_input(stable_x, stable_y, LV_INDEV_STATE_PR);
#endif
}
}
}
rt_thread_mdelay(1);
}
}
@@ -134,3 +256,4 @@ static int touch_xpt2046_init(void)
INIT_COMPONENT_EXPORT(touch_xpt2046_init);
#endif /* BSP_USING_TOUCH_RES */