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