1 /*
2  * Copyright (c) 2006-2024 RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2019-05-20     tyustli      the first version
9  */
10 
11 #ifndef __DEV_TOUCH_H__
12 #define __DEV_TOUCH_H__
13 
14 #include <rtthread.h>
15 #include "dev_pin.h"
16 /**
17  * @defgroup    group_drivers_touch Touch
18  * @brief       Touch driver api
19  * @ingroup     group_device_driver
20  *
21  * <b>Example</b>
22  * @code {.c}
23  * #include <rtthread.h>
24  * #include "rtdevice.h"
25  *
26  * static rt_thread_t  gt9147_thread = RT_NULL;
27  * static rt_sem_t     gt9147_sem = RT_NULL;
28  * static rt_device_t  dev = RT_NULL;
29  * static struct       rt_touch_data *read_data;
30  *
31  * // 读取数据线程入口函数
32  * static void gt9147_entry(void *parameter)
33  * {
34  *     struct rt_touch_data *read_data;
35  *     read_data = (struct rt_touch_data *)rt_malloc(sizeof(struct rt_touch_data) * 5);
36  *
37  *     while (1)
38  *     {
39  *         // 请求信号量
40  *         rt_sem_take(gt9147_sem, RT_WAITING_FOREVER);
41  *         // 读取五个点的触摸信息
42  *         if (rt_device_read(dev, 0, read_data, 5) == 5)
43  *         {
44  *             for (rt_uint8_t i = 0; i < 5; i++)
45  *             {
46  *                 if (read_data[i].event == RT_TOUCH_EVENT_DOWN || read_data[i].event == RT_TOUCH_EVENT_MOVE)
47  *                 {
48  *                     rt_kprintf("%d %d %d %d %d\n",
49  *                                 read_data[i].track_id,
50  *                                 read_data[i].x_coordinate,
51  *                                 read_data[i].y_coordinate,
52  *                                 read_data[i].timestamp,
53  *                                 read_data[i].width);
54  *                 }
55  *             }
56  *         }
57  *         // 打开中断
58  *         rt_device_control(dev, RT_TOUCH_CTRL_ENABLE_INT, RT_NULL);
59  *     }
60  * }
61  *
62  * // 接收回调函数
63  * static rt_err_t rx_callback(rt_device_t dev, rt_size_t size)
64  * {
65  *     // 关闭中断
66  *     rt_device_control(dev, RT_TOUCH_CTRL_DISABLE_INT, RT_NULL);
67  *     // 释放信号量
68  *     rt_sem_release(gt9147_sem);
69  *     return 0;
70  * }
71  *
72  * static int gt9147_sample(void)
73  * {
74  *     // 查找 Touch 设备
75  *     dev = rt_device_find("touch");
76  *
77  *     if (dev == RT_NULL)
78  *     {
79  *         rt_kprintf("can't find device:%s\n", "touch");
80  *         return -1;
81  *     }
82  *     // 以中断的方式打开设备
83  *     if (rt_device_open(dev, RT_DEVICE_FLAG_INT_RX) != RT_EOK)
84  *     {
85  *         rt_kprintf("open device failed!");
86  *         return -1;
87  *     }
88  *     // 设置接收回调
89  *     rt_device_set_rx_indicate(dev, rx_callback);
90  *     // 创建信号量
91  *     gt9147_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_PRIO);
92  *
93  *     if (gt9147_sem == RT_NULL)
94  *     {
95  *         rt_kprintf("create dynamic semaphore failed.\n");
96  *         return -1;
97  *     }
98  *     // 创建读取数据线程
99  *     gt9147_thread = rt_thread_create("thread1",
100  *                                      gt9147_entry,
101  *                                      RT_NULL,
102  *                                      THREAD_STACK_SIZE,
103  *                                      THREAD_PRIORITY,
104  *                                      THREAD_TIMESLICE);
105  *     // 启动线程
106  *     if (gt9147_thread != RT_NULL)
107  *         rt_thread_startup(gt9147_thread);
108  *
109  *     return 0;
110  * }
111  * MSH_CMD_EXPORT(gt9147_sample, gt9147 sample);
112  * @endcode
113  */
114 
115 /*!
116  * @addtogroup group_drivers_touch
117  * @{
118  */
119 #ifdef __cplusplus
120 extern "C" {
121 #endif
122 
123 #ifdef RT_USING_RTC
124 #define  rt_touch_get_ts()  time(RT_NULL)          /* API for the touch to get the timestamp */
125 #else
126 #define  rt_touch_get_ts()  rt_tick_get()          /* API for the touch to get the timestamp */
127 #endif
128 
129 /* Touch vendor types */
130 #define RT_TOUCH_VENDOR_UNKNOWN          (0)  /* unknown */
131 #define RT_TOUCH_VENDOR_GT               (1)  /* GTxx series */
132 #define RT_TOUCH_VENDOR_FT               (2)  /* FTxx series */
133 
134 /* Touch ic type*/
135 #define  RT_TOUCH_TYPE_NONE              (0)  /* touch ic none */
136 #define  RT_TOUCH_TYPE_CAPACITANCE       (1)  /* capacitance ic */
137 #define  RT_TOUCH_TYPE_RESISTANCE        (2)  /* resistance ic */
138 
139 /* Touch control cmd types */
140 #define  RT_TOUCH_CTRL_GET_ID            (RT_DEVICE_CTRL_BASE(Touch) + 0)   /* Get device id */
141 #define  RT_TOUCH_CTRL_GET_INFO          (RT_DEVICE_CTRL_BASE(Touch) + 1)   /* Get touch info */
142 #define  RT_TOUCH_CTRL_SET_MODE          (RT_DEVICE_CTRL_BASE(Touch) + 2)   /* Set touch's work mode. ex. RT_TOUCH_MODE_POLLING,RT_TOUCH_MODE_INT */
143 #define  RT_TOUCH_CTRL_SET_X_RANGE       (RT_DEVICE_CTRL_BASE(Touch) + 3)   /* Set x coordinate range */
144 #define  RT_TOUCH_CTRL_SET_Y_RANGE       (RT_DEVICE_CTRL_BASE(Touch) + 4)   /* Set y coordinate range */
145 #define  RT_TOUCH_CTRL_SET_X_TO_Y        (RT_DEVICE_CTRL_BASE(Touch) + 5)   /* Set X Y coordinate exchange */
146 #define  RT_TOUCH_CTRL_DISABLE_INT       (RT_DEVICE_CTRL_BASE(Touch) + 6)   /* Disable interrupt */
147 #define  RT_TOUCH_CTRL_ENABLE_INT        (RT_DEVICE_CTRL_BASE(Touch) + 7)   /* Enable interrupt */
148 #define  RT_TOUCH_CTRL_POWER_ON          (RT_DEVICE_CTRL_BASE(Touch) + 8)   /* Touch Power On */
149 #define  RT_TOUCH_CTRL_POWER_OFF         (RT_DEVICE_CTRL_BASE(Touch) + 9)   /* Touch Power Off */
150 #define  RT_TOUCH_CTRL_GET_STATUS        (RT_DEVICE_CTRL_BASE(Touch) + 10)  /* Get Touch Power Status */
151 
152 /* Touch event */
153 #define RT_TOUCH_EVENT_NONE              (0)   /* Touch none */
154 #define RT_TOUCH_EVENT_UP                (1)   /* Touch up event */
155 #define RT_TOUCH_EVENT_DOWN              (2)   /* Touch down event */
156 #define RT_TOUCH_EVENT_MOVE              (3)   /* Touch move event */
157 
158 /**
159  * @brief Touch information
160 */
161 struct rt_touch_info
162 {
163     rt_uint8_t     type;                       /* The touch type */
164     rt_uint8_t     vendor;                     /* Vendor of touchs */
165     rt_uint8_t     point_num;                  /* Support point num */
166     rt_int32_t     range_x;                    /* X coordinate range */
167     rt_int32_t     range_y;                    /* Y coordinate range */
168 };
169 
170 /**
171  * @brief Touch configuration
172 */
173 struct rt_touch_config
174 {
175 #ifdef RT_TOUCH_PIN_IRQ
176     struct rt_device_pin_mode   irq_pin;       /* Interrupt pin, The purpose of this pin is to notification read data */
177 #endif
178     char                        *dev_name;     /* The name of the communication device */
179     void                        *user_data;
180 };
181 
182 typedef struct rt_touch_device *rt_touch_t;
183 /**
184  * @brief Touch device
185 */
186 struct rt_touch_device
187 {
188     struct rt_device            parent;        /* The standard device */
189     struct rt_touch_info        info;          /* The touch info data */
190     struct rt_touch_config      config;        /* The touch config data */
191 
192     const struct rt_touch_ops  *ops;           /* The touch ops */
193     rt_err_t (*irq_handle)(rt_touch_t touch);  /* Called when an interrupt is generated, registered by the driver */
194 };
195 
196 /**
197  * @brief Touch data
198 */
199 struct rt_touch_data
200 {
201     rt_uint8_t          event;                 /* The touch event of the data */
202     rt_uint8_t          track_id;              /* Track id of point */
203     rt_uint8_t          width;                 /* Point of width */
204     rt_uint16_t         x_coordinate;          /* Point of x coordinate */
205     rt_uint16_t         y_coordinate;          /* Point of y coordinate */
206     rt_tick_t           timestamp;             /* The timestamp when the data was received */
207 };
208 
209 /**
210  * @brief Touch device operations
211 */
212 struct rt_touch_ops
213 {
214     rt_size_t (*touch_readpoint)(struct rt_touch_device *touch, void *buf, rt_size_t touch_num);
215     rt_err_t (*touch_control)(struct rt_touch_device *touch, int cmd, void *arg);
216 };
217 
218 /**
219  * @brief register a touch device
220  * @param touch the touch device
221  * @param name the name of touch device
222  * @param flag the flag of touch device
223  * @param data the user data of touch device
224  * @return rt_err_t error code
225  */
226 int rt_hw_touch_register(rt_touch_t    touch,
227                          const char    *name,
228                          rt_uint32_t   flag,
229                          void          *data);
230 
231 /**
232  * @brief Touch irq handle
233  * @param touch the touch device
234  *
235  * @note If you doesn't use pin device. you must call this function in your touch irq callback
236  */
237 void rt_hw_touch_isr(rt_touch_t touch);
238 
239 #ifdef __cplusplus
240 }
241 #endif
242 
243 /*! @}*/
244 
245 #endif /* __DEV_TOUCH_H__ */
246