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 * 2022-6-27 solar first version
9 */
10
11 #include <rtdevice.h>
12 #include "drv_touch_xpt.h"
13 #include "drv_soft_spi.h"
14
15 #ifdef PKG_USING_GUIENGINE
16 #include <rtgui/event.h>
17 #include <rtgui/rtgui_server.h>
18 #elif defined(PKG_USING_LITTLEVGL2RTT)
19 #include <littlevgl2rtt.h>
20 #elif defined(PKG_USING_LVGL)
21 #include <lvgl.h>
22 extern void lv_port_indev_input(rt_int16_t x, rt_int16_t y, lv_indev_state_t state);
23 static rt_bool_t touch_down = RT_FALSE;
24 #endif /* PKG_USING_GUIENGINE */
25
26 #ifdef BSP_USING_TOUCH_RES
27
28 /* If calibration is not required, please manually modify the contents of
29 * the drv_touch_xpt.h file,and set BSP_TOUCH_CALIBRATE to RT_FALSE */
30 #define BSP_TOUCH_CALIBRATE RT_TRUE
31
32 #define BSP_XPT2046_SPI_BUS "sspi1"
33 #define TOUCH_DEVICE_NAME "xpt0"
34 #define TFTLCD_DEVICE_NAME "lcd"
35
xpt2046_init_hw(void)36 void xpt2046_init_hw(void)
37 {
38 /* Find the touch device */
39 rt_device_t touch = rt_device_find(TOUCH_DEVICE_NAME);
40 if (touch == RT_NULL)
41 {
42 rt_kprintf("can't find touch device:%s\n", TOUCH_DEVICE_NAME);
43 return;
44 }
45 if (rt_device_open(touch, RT_DEVICE_FLAG_INT_RX) != RT_EOK)
46 {
47 rt_kprintf("can't open touch device:%s\n", TOUCH_DEVICE_NAME);
48 return;
49 }
50
51 rt_uint8_t dev_num = 0;
52 char dev_name[RT_NAME_MAX];
53 do
54 {
55 rt_sprintf(dev_name, "%s%d", BSP_XPT2046_SPI_BUS, dev_num++);
56 if (dev_num == 255)
57 {
58 return;
59 }
60 } while (rt_device_find(dev_name));
61
62 /* Mount the spi device to the spi bus, here is the soft spi,
63 * if you use other spi, please modify the following */
64 rt_hw_softspi_device_attach(BSP_XPT2046_SPI_BUS, dev_name, rt_pin_get(BSP_XPT2046_CS_PIN));
65
66 /* configure spi device */
67 rt_xpt2046_t tc = (rt_xpt2046_t)touch;
68 tc->spi = (struct rt_spi_device *)rt_device_find(dev_name);
69 struct rt_spi_configuration spi_config;
70 spi_config.data_width = 8;
71 spi_config.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
72 /* Max freq of XPT2046 is 2MHz */
73 spi_config.max_hz = 2000000;
74 rt_spi_configure(tc->spi, &spi_config);
75
76 #if (BSP_TOUCH_CALIBRATE == RT_TRUE)
77 /* Calibrate touch */
78 xpt2046_calibration(TFTLCD_DEVICE_NAME,TOUCH_DEVICE_NAME);
79 #endif /* BSP_TOUCH_CALIBRATE == RT_TRUE */
80
81 /* init the TFT LCD */
82 rt_device_t lcd = RT_NULL;
83
84 lcd = rt_device_find("lcd");
85 rt_device_init(lcd);
86 }
87
xpt2046_entry(void * parameter)88 void xpt2046_entry(void *parameter)
89 {
90 /* Find the touch device */
91 rt_device_t touch = rt_device_find(TOUCH_DEVICE_NAME);
92 if (touch == RT_NULL)
93 {
94 rt_kprintf("can't find touch device:%s\n", TOUCH_DEVICE_NAME);
95 return;
96 }
97 #ifndef PKG_USING_LVGL
98 rt_device_t lcd = rt_device_find(TFTLCD_DEVICE_NAME);
99 if (lcd == RT_NULL)
100 {
101 rt_kprintf("can't find display device:%s\n", TFTLCD_DEVICE_NAME);
102 return;
103 }
104 #endif /* PKG_USING_LVGL */
105 while (1)
106 {
107 /* Prepare variable to read out the touch data */
108 struct rt_touch_data read_data;
109 rt_memset(&read_data, 0, sizeof(struct rt_touch_data));
110 if (rt_device_read(touch, 0, &read_data, 1) == 1)
111 {
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 */
116 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 */
121 }
122 rt_thread_mdelay(1);
123 }
124 }
125
touch_xpt2046_init(void)126 static int touch_xpt2046_init(void)
127 {
128 xpt2046_init_hw();
129 rt_thread_t tid = rt_thread_create("xpt2046", xpt2046_entry, RT_NULL, 1024, 8, 20);
130 RT_ASSERT(tid != RT_NULL);
131 rt_thread_startup(tid);
132 return RT_EOK;
133 }
134 INIT_COMPONENT_EXPORT(touch_xpt2046_init);
135
136 #endif /* BSP_USING_TOUCH_RES */
137