1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 * Copyright 2022 NXP
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Change Logs:
8 * Date Author Notes
9 * 2021-10-18 Meco Man The first version
10 * 2022-05-17 Ting Liu Support touchpad
11 */
12
13 #define LOG_TAG "LVGL.port.indev"
14 #include <drv_log.h>
15
16 #include "lvgl.h"
17
18 #include "board.h"
19 #include "touchpad.h"
20 #include "fsl_video_common.h"
21 #include "fsl_lpi2c.h"
22 #include "fsl_gpio.h"
23 #ifdef DEMO_PANEL_RK043FN66HS
24 #include "fsl_gt911.h"
25 #else
26 #include "fsl_ft5406_rt.h"
27 #endif
28
29 #if LV_USE_GPU_NXP_PXP
30 #include "src/gpu/lv_gpu_nxp_pxp.h"
31 #include "src/gpu/lv_gpu_nxp_pxp_osa.h"
32 #endif
33
34 /*******************************************************************************
35 * Definitions
36 ******************************************************************************/
37
38 /* @Brief Board touch panel configuration */
39 #define BOARD_TOUCH_I2C_BASEADDR LPI2C1
40 #define BOARD_TOUCH_RST_GPIO GPIO1
41 #define BOARD_TOUCH_RST_PIN 2
42 #define BOARD_TOUCH_INT_GPIO GPIO1
43 #define BOARD_TOUCH_INT_PIN 11
44
45 /* Macros for the touch touch controller. */
46 #define TOUCH_I2C LPI2C1
47
48 /* Select USB1 PLL (480 MHz) as master lpi2c clock source */
49 #define TOUCH_LPI2C_CLOCK_SOURCE_SELECT (0U)
50 /* Clock divider for master lpi2c clock source */
51 #define TOUCH_LPI2C_CLOCK_SOURCE_DIVIDER (5U)
52
53 #define TOUCH_I2C_CLOCK_FREQ ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (TOUCH_LPI2C_CLOCK_SOURCE_DIVIDER + 1U))
54 #define TOUCH_I2C_BAUDRATE 100000U
55
56 /*******************************************************************************
57 * Prototypes
58 ******************************************************************************/
59 static void DEMO_InitTouch(void);
60
61 static void DEMO_ReadTouch(lv_indev_drv_t *drv, lv_indev_data_t *data);
62 #ifdef DEMO_PANEL_RK043FN66HS
63 static void BOARD_PullTouchResetPin(bool pullUp);
64
65 static void BOARD_ConfigTouchIntPin(gt911_int_pin_mode_t mode);
66 #endif
67
68 /*******************************************************************************
69 * Variables
70 ******************************************************************************/
71 #ifdef DEMO_PANEL_RK043FN66HS
72 static gt911_handle_t s_touchHandle;
73 static const gt911_config_t s_touchConfig = {
74 .I2C_SendFunc = BOARD_Touch_I2C_Send,
75 .I2C_ReceiveFunc = BOARD_Touch_I2C_Receive,
76 .pullResetPinFunc = BOARD_PullTouchResetPin,
77 .intPinFunc = BOARD_ConfigTouchIntPin,
78 .timeDelayMsFunc = VIDEO_DelayMs,
79 .touchPointNum = 1,
80 .i2cAddrMode = kGT911_I2cAddrMode0,
81 .intTrigMode = kGT911_IntRisingEdge,
82 };
83 static int s_touchResolutionX;
84 static int s_touchResolutionY;
85 #else
86 static ft5406_rt_handle_t touchHandle;
87 #endif
88
lv_port_indev_init(void)89 void lv_port_indev_init(void)
90 {
91 static lv_indev_drv_t indev_drv;
92
93 /*------------------
94 * Touchpad
95 * -----------------*/
96
97 /*Initialize your touchpad */
98 DEMO_InitTouch();
99
100 /*Register a touchpad input device*/
101 lv_indev_drv_init(&indev_drv);
102 indev_drv.type = LV_INDEV_TYPE_POINTER;
103 indev_drv.read_cb = DEMO_ReadTouch;
104 lv_indev_drv_register(&indev_drv);
105 }
106
107 #ifdef DEMO_PANEL_RK043FN66HS
BOARD_PullTouchResetPin(bool pullUp)108 static void BOARD_PullTouchResetPin(bool pullUp)
109 {
110 if (pullUp)
111 {
112 GPIO_PinWrite(BOARD_TOUCH_RST_GPIO, BOARD_TOUCH_RST_PIN, 1);
113 }
114 else
115 {
116 GPIO_PinWrite(BOARD_TOUCH_RST_GPIO, BOARD_TOUCH_RST_PIN, 0);
117 }
118 }
119
BOARD_ConfigTouchIntPin(gt911_int_pin_mode_t mode)120 static void BOARD_ConfigTouchIntPin(gt911_int_pin_mode_t mode)
121 {
122 if (mode == kGT911_IntPinInput)
123 {
124 BOARD_TOUCH_INT_GPIO->GDIR &= ~(1UL << BOARD_TOUCH_INT_PIN);
125 }
126 else
127 {
128 if (mode == kGT911_IntPinPullDown)
129 {
130 GPIO_PinWrite(BOARD_TOUCH_INT_GPIO, BOARD_TOUCH_INT_PIN, 0);
131 }
132 else
133 {
134 GPIO_PinWrite(BOARD_TOUCH_INT_GPIO, BOARD_TOUCH_INT_PIN, 1);
135 }
136
137 BOARD_TOUCH_INT_GPIO->GDIR |= (1UL << BOARD_TOUCH_INT_PIN);
138 }
139 }
140
141 /*Initialize your touchpad*/
DEMO_InitTouch(void)142 static void DEMO_InitTouch(void)
143 {
144 status_t status;
145
146 const gpio_pin_config_t resetPinConfig = {
147 .direction = kGPIO_DigitalOutput, .outputLogic = 0, .interruptMode = kGPIO_NoIntmode};
148 GPIO_PinInit(BOARD_TOUCH_INT_GPIO, BOARD_TOUCH_INT_PIN, &resetPinConfig);
149 GPIO_PinInit(BOARD_TOUCH_RST_GPIO, BOARD_TOUCH_RST_PIN, &resetPinConfig);
150
151 /*Clock setting for LPI2C*/
152 CLOCK_SetMux(kCLOCK_Lpi2cMux, TOUCH_LPI2C_CLOCK_SOURCE_SELECT);
153 CLOCK_SetDiv(kCLOCK_Lpi2cDiv, TOUCH_LPI2C_CLOCK_SOURCE_DIVIDER);
154
155 BOARD_LPI2C_Init(TOUCH_I2C, TOUCH_I2C_CLOCK_FREQ);
156
157 status = GT911_Init(&s_touchHandle, &s_touchConfig);
158
159 if (kStatus_Success != status)
160 {
161 //PRINTF("Touch IC initialization failed\r\n");
162 assert(false);
163 }
164
165 GT911_GetResolution(&s_touchHandle, &s_touchResolutionX, &s_touchResolutionY);
166 }
167
168 /* Will be called by the library to read the touchpad */
DEMO_ReadTouch(lv_indev_drv_t * drv,lv_indev_data_t * data)169 static void DEMO_ReadTouch(lv_indev_drv_t *drv, lv_indev_data_t *data)
170 {
171 static int touch_x = 0;
172 static int touch_y = 0;
173
174 if (kStatus_Success == GT911_GetSingleTouch(&s_touchHandle, &touch_x, &touch_y))
175 {
176 data->state = LV_INDEV_STATE_PR;
177 }
178 else
179 {
180 data->state = LV_INDEV_STATE_REL;
181 }
182
183 /*Set the last pressed coordinates*/
184 data->point.x = touch_x * LCD_WIDTH / s_touchResolutionX;
185 data->point.y = touch_y * LCD_HEIGHT / s_touchResolutionY;
186 }
187 #else
188 /*Initialize your touchpad*/
DEMO_InitTouch(void)189 static void DEMO_InitTouch(void)
190 {
191 status_t status;
192
193 lpi2c_master_config_t masterConfig = {0};
194
195 /*Clock setting for LPI2C*/
196 CLOCK_SetMux(kCLOCK_Lpi2cMux, TOUCH_LPI2C_CLOCK_SOURCE_SELECT);
197 CLOCK_SetDiv(kCLOCK_Lpi2cDiv, TOUCH_LPI2C_CLOCK_SOURCE_DIVIDER);
198
199 /*
200 * masterConfig.debugEnable = false;
201 * masterConfig.ignoreAck = false;
202 * masterConfig.pinConfig = kLPI2C_2PinOpenDrain;
203 * masterConfig.baudRate_Hz = 100000U;
204 * masterConfig.busIdleTimeout_ns = 0;
205 * masterConfig.pinLowTimeout_ns = 0;
206 * masterConfig.sdaGlitchFilterWidth_ns = 0;
207 * masterConfig.sclGlitchFilterWidth_ns = 0;
208 */
209 LPI2C_MasterGetDefaultConfig(&masterConfig);
210
211 /* Change the default baudrate configuration */
212 masterConfig.baudRate_Hz = TOUCH_I2C_BAUDRATE;
213
214 /* Initialize the LPI2C master peripheral */
215 LPI2C_MasterInit(TOUCH_I2C, &masterConfig, TOUCH_I2C_CLOCK_FREQ);
216
217 /* Initialize touch panel controller */
218 status = FT5406_RT_Init(&touchHandle, TOUCH_I2C);
219 if (status != kStatus_Success)
220 {
221 //PRINTF("Touch panel init failed\n");
222 assert(0);
223 }
224 }
225
226 /* Will be called by the library to read the touchpad */
DEMO_ReadTouch(lv_indev_drv_t * drv,lv_indev_data_t * data)227 static void DEMO_ReadTouch(lv_indev_drv_t *drv, lv_indev_data_t *data)
228 {
229 touch_event_t touch_event;
230 static int touch_x = 0;
231 static int touch_y = 0;
232
233 data->state = LV_INDEV_STATE_REL;
234
235 if (kStatus_Success == FT5406_RT_GetSingleTouch(&touchHandle, &touch_event, &touch_x, &touch_y))
236 {
237 if ((touch_event == kTouch_Down) || (touch_event == kTouch_Contact))
238 {
239 data->state = LV_INDEV_STATE_PR;
240 }
241 }
242
243 /*Set the last pressed coordinates*/
244 data->point.x = touch_y;
245 data->point.y = touch_x;
246 }
247 #endif
248