luckfox-pico-sdk/sysdrv/source/mcu/rt-thread/applications/common/touchpanel/touchpanel.c
luckfox-eng29 8f34c2760d project:build.sh: Added fastboot support; custom modifications to U-Boot and kernel implemented using patches.
project:cfg:BoardConfig_IPC: Added fastboot BoardConfig file and firmware post-scripts, distinguishing between
the BoardConfigs for Luckfox Pico Pro and Luckfox Pico Max. project:app: Added fastboot_client and rk_smart_door
for quick boot applications; updated rkipc app to adapt to the latest media library. media:samples: Added more
usage examples. media:rockit: Fixed bugs; removed support for retrieving data frames from VPSS. media:isp:
Updated rkaiq library and related tools to support connection to RKISP_Tuner. sysdrv:Makefile: Added support for
compiling drv_ko on Luckfox Pico Ultra W using Ubuntu; added support for custom root filesystem.
sysdrv:tools:board: Updated Buildroot optional mirror sources, updated some software versions, and stored device
tree files and configuration files that undergo multiple modifications for U-Boot and kernel separately.
sysdrv:source:mcu: Used RISC-V MCU SDK with RT-Thread system, mainly for initializing camera AE during quick
boot. sysdrv:source:uboot: Added support for fastboot; added high baud rate DDR bin for serial firmware upgrades.
sysdrv:source:kernel: Upgraded to version 5.10.160; increased NPU frequency for RV1106G3; added support for
fastboot.

Signed-off-by: luckfox-eng29 <eng29@luckfox.com>
2024-10-14 09:47:04 +08:00

288 lines
8.1 KiB
C

/**
* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "board.h"
#include "touch.h"
#include "touchpanel.h"
//#define RT_TOUCHPANEL_DEBUG
#ifdef RT_TOUCHPANEL_DEBUG
#define touchpanel_dbg(...) \
do { \
rt_kprintf("%s: ", __FUNCTION__); \
rt_kprintf(__VA_ARGS__); \
} while(0)
#else
#define touchpanel_dbg(...)
#endif
static struct rt_touchpanel_data *g_tp_data = RT_NULL;
rt_err_t rt_touchpanel_block_register(struct rt_touchpanel_block *block)
{
struct rt_touchpanel_data *touch_data = g_tp_data;
rt_slist_t *pos, *head = &touch_data->b_list;
rt_mutex_take(touch_data->mutex, RT_WAITING_FOREVER);
/* check if node already registered */
rt_slist_for_each(pos, head)
{
if (pos == &block->slist)
{
rt_kprintf("rt_touchpanel_block_register fail, block(0x%x) already registered!\n", block);
rt_mutex_release(touch_data->mutex);
return RT_ERROR;
}
}
/* register node */
rt_slist_append(head, &block->slist);
rt_mutex_release(touch_data->mutex);
return RT_EOK;
}
rt_err_t rt_touchpanel_block_unregister(struct rt_touchpanel_block *block)
{
struct rt_touchpanel_data *touch_data = g_tp_data;
rt_slist_t *pos, *head = &touch_data->b_list;
rt_mutex_take(touch_data->mutex, RT_WAITING_FOREVER);
/* check if node already registered */
rt_slist_for_each(pos, head)
{
if (pos == &block->slist)
{
rt_slist_remove(head, pos);
rt_mutex_release(touch_data->mutex);
return RT_EOK;
}
}
rt_kprintf("rt_touchpanel_block_unregister fail, block(0x%x) can nod find!\n", block);
rt_mutex_release(touch_data->mutex);
return RT_ERROR;
}
rt_err_t rt_touchpoint_is_in_block(struct rt_touch_data *p, struct rt_touchpanel_block *block)
{
if (((block->x <= p->x_coordinate) && (p->x_coordinate <= block->x + block->w)) &&
((block->y <= p->y_coordinate) && (p->y_coordinate <= block->y + block->h)))
{
return RT_EOK;
}
return RT_ERROR;
}
rt_err_t rt_touchpoint_is_valid(struct rt_touch_data *p, struct rt_touchpanel_block *block)
{
rt_err_t ret = RT_ERROR;
if (p->event == RT_TOUCH_EVENT_DOWN)
{
if (RT_EOK == rt_touchpoint_is_in_block(p, block))
{
touchpanel_dbg("touch [%s] down.\n", block->name);
block->event = RT_TOUCH_EVENT_DOWN;
block->timestamp = p->timestamp;
ret = RT_EOK;
}
}
else if (p->event == RT_TOUCH_EVENT_MOVE)
{
if (RT_EOK == rt_touchpoint_is_in_block(p, block))
{
if ((block->event == RT_TOUCH_EVENT_DOWN) ||
(block->event == RT_TOUCH_EVENT_MOVE))
{
touchpanel_dbg("touch [%s] move.\n", block->name);
block->event = RT_TOUCH_EVENT_MOVE;
ret = RT_EOK;
}
}
else
{
if ((block->event == RT_TOUCH_EVENT_DOWN) ||
(block->event == RT_TOUCH_EVENT_MOVE))
{
touchpanel_dbg("touch [%s] outside.\n", block->name);
if (block->attribute & TOUCHPANEL_BLOCK_MOVE_ENABLE)
{
block->event = RT_TOUCH_EVENT_MOVE;
}
else
{
block->event = RT_TOUCH_EVENT_UP;
}
ret = RT_EOK;
}
}
}
else if (p->event == RT_TOUCH_EVENT_UP)
{
if ((block->event == RT_TOUCH_EVENT_DOWN) ||
(block->event == RT_TOUCH_EVENT_MOVE))
{
touchpanel_dbg("touch [%s] up.\n", block->name);
ret = RT_EOK;
}
block->event = RT_TOUCH_EVENT_UP;
}
return ret;
}
static void rt_touchpanel_blocks_handle(struct rt_touch_data *point, rt_uint8_t num)
{
struct rt_touchpanel_block *block;
struct rt_touchpanel_data *touch_data = g_tp_data;
rt_slist_t *pos, *head = &touch_data->b_list;
rt_mutex_take(touch_data->mutex, RT_WAITING_FOREVER);
rt_slist_for_each(pos, head)
{
block = rt_slist_entry(pos, struct rt_touchpanel_block, slist);
if (block->callback)
{
if (RT_EOK == block->callback(point, num))
{
rt_mutex_release(touch_data->mutex);
return;
}
}
}
rt_mutex_release(touch_data->mutex);
}
static rt_err_t rx_callback(rt_device_t dev, rt_size_t size)
{
rt_sem_release(g_tp_data->sem);
return 0;
}
static void rt_touchpanel_thread(void *parameter)
{
rt_err_t ret;
struct rt_touchpanel_data *touchpanel;
rt_device_t dev = rt_device_find(TOUCH_DEV_NAME);
if (dev == RT_NULL)
{
rt_kprintf("%s touch device can not find.\n", TOUCH_DEV_NAME);
return;
}
ret = rt_device_open(dev, RT_DEVICE_FLAG_INT_RX);
if (ret != RT_EOK)
{
rt_kprintf("%s: touch device open fail.\n", TOUCH_DEV_NAME);
return;
}
g_tp_data = touchpanel = (struct rt_touchpanel_data *)rt_malloc(sizeof(struct rt_touchpanel_data));
RT_ASSERT(touchpanel != RT_NULL);
rt_memset((void *)touchpanel, 0, sizeof(struct rt_touchpanel_data));
touchpanel->sem = rt_sem_create("tpsem", 0, RT_IPC_FLAG_FIFO);
RT_ASSERT(touchpanel->sem != RT_NULL);
touchpanel->mutex = rt_mutex_create("tpmutex", RT_IPC_FLAG_FIFO);
RT_ASSERT(touchpanel->mutex != RT_NULL);
rt_slist_init(&touchpanel->b_list);
touchpanel->dev = dev;
rt_device_set_rx_indicate(touchpanel->dev, rx_callback);
rt_device_control(touchpanel->dev, RT_TOUCH_CTRL_GET_ID, touchpanel->id);
touchpanel_dbg("id = %s\n", touchpanel->id);
rt_device_control(touchpanel->dev, RT_TOUCH_CTRL_GET_INFO, &touchpanel->info);
touchpanel_dbg("x_range = %d, y_range = %d, max_point = %d\n",
touchpanel->info.range_x,
touchpanel->info.range_y,
touchpanel->info.point_num);
touchpanel->point = (struct rt_touch_data *)rt_malloc(sizeof(struct rt_touch_data) * touchpanel->info.point_num);
RT_ASSERT(touchpanel->point != RT_NULL);
rt_memset(touchpanel->point, 0, sizeof(struct rt_touch_data) * touchpanel->info.point_num);
touchpanel->cur_point = (struct rt_touch_data *)rt_malloc(sizeof(struct rt_touch_data) * touchpanel->info.point_num);
RT_ASSERT(touchpanel->cur_point != RT_NULL);
rt_memset(touchpanel->cur_point, 0, sizeof(struct rt_touch_data) * touchpanel->info.point_num);
rt_uint8_t point_num = 0;
rt_uint8_t point_max = touchpanel->info.point_num;
struct rt_touch_data *read_data = touchpanel->point;
while (1)
{
rt_sem_take(touchpanel->sem, RT_WAITING_FOREVER);
rt_memset(read_data, 0, sizeof(struct rt_touch_data) * point_max);
point_num = rt_device_read(touchpanel->dev, 0, read_data, point_max);
if (point_num)
{
#ifdef RT_TOUCHPANEL_DEBUG
for (rt_uint8_t i = 0; i < point_num; i++)
{
rt_kprintf("%d %d %d %d %d %d\n",
read_data[i].track_id,
read_data[i].event,
read_data[i].x_coordinate,
read_data[i].y_coordinate,
read_data[i].timestamp,
read_data[i].width);
}
#endif
rt_touchpanel_blocks_handle(read_data, point_num);
}
}
ret = rt_sem_delete(touchpanel->sem);
RT_ASSERT(ret == RT_EOK);
ret = rt_device_close(touchpanel->dev);
RT_ASSERT(ret == RT_EOK);
rt_free(touchpanel->cur_point);
rt_free(touchpanel->point);
rt_free(touchpanel);
}
/**
* touchpanel init.
*/
int rt_touchpanel_thread_init(void)
{
rt_thread_t thread;
thread = rt_thread_create("touchpanel", rt_touchpanel_thread, RT_NULL, 2048, 5, 10);
RT_ASSERT(thread != RT_NULL);
rt_thread_startup(thread);
return RT_EOK;
}
INIT_ENV_EXPORT(rt_touchpanel_thread_init);