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