1 /*
2 * Copyright 2019 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_ektf2k.h"
9
10 /*******************************************************************************
11 * Definitions
12 ******************************************************************************/
13 /*! @brief EKTF2K I2C address. */
14 #define EKTF2K_I2C_ADDRESS (0x15)
15
16 /*! @brief EKTF2K hello packet data length. */
17 #define EKTF2K_TOUCH_HELLO_DATA_LEN (0x04)
18
19 /*! @brief Retry times to get the hello packet. */
20 #define EKTF2K_TOUCH_HELLO_RETRY_TIME (20)
21
22 __PACKED_STRUCT _ektf2k_touch_point
23 {
24 uint8_t XHYH;
25 uint8_t XL;
26 uint8_t YL;
27 };
28
29 typedef struct _ektf2k_touch_point ektf2k_touch_point_t;
30
31 __PACKED_STRUCT _ektf2k_touch_data
32 {
33 uint8_t PKT_TYPE;
34 ektf2k_touch_point_t TOUCH[EKTF2K_MAX_TOUCHES];
35 uint8_t BTN_FID;
36 };
37
38 typedef struct _ektf2k_touch_data ektf2k_touch_data_t;
39
40 enum _ektf2k_pkt_type
41 {
42 kEKTF2K_Pkt2Finger = 0x5A,
43 };
44
45 /*******************************************************************************
46 * Prototypes
47 ******************************************************************************/
48
49 /*******************************************************************************
50 * Variables
51 ******************************************************************************/
52
53 /*******************************************************************************
54 * Code
55 ******************************************************************************/
56
EKTF2K_Init(ektf2k_handle_t * handle,const ektf2k_config_t * config)57 status_t EKTF2K_Init(ektf2k_handle_t *handle, const ektf2k_config_t *config)
58 {
59 status_t status;
60 uint32_t helloPkt;
61 int retryTime = EKTF2K_TOUCH_HELLO_RETRY_TIME;
62 const uint8_t cmd_x[] = {0x53, 0x60, 0x00, 0x00};
63 const uint8_t cmd_y[] = {0x53, 0x63, 0x00, 0x00};
64 uint8_t buf_recv[4];
65
66 assert(handle);
67
68 memset(handle, 0, sizeof(*handle));
69
70 handle->I2C_SendFunc = config->I2C_SendFunc;
71 handle->I2C_ReceiveFunc = config->I2C_ReceiveFunc;
72 handle->timeDelayMsFunc = config->timeDelayMsFunc;
73 handle->pullResetPin = config->pullResetPin;
74
75 /* Reset the panel. */
76 handle->pullResetPin(false);
77 handle->timeDelayMsFunc(5);
78 handle->pullResetPin(true);
79
80 handle->timeDelayMsFunc(400);
81
82 while (--retryTime > 0)
83 {
84 status = handle->I2C_ReceiveFunc(EKTF2K_I2C_ADDRESS, 0, 0, (uint8_t *)&helloPkt, 4);
85
86 if ((kStatus_Success == status) && (helloPkt == 0x55555555))
87 {
88 break;
89 }
90 else
91 {
92 handle->timeDelayMsFunc(5);
93 }
94 }
95
96 if (retryTime <= 0)
97 {
98 return kStatus_Fail;
99 }
100
101 status = handle->I2C_SendFunc(EKTF2K_I2C_ADDRESS, 0, 0, cmd_x, 4);
102 if (kStatus_Success != status)
103 {
104 return status;
105 }
106
107 status = handle->I2C_ReceiveFunc(EKTF2K_I2C_ADDRESS, 0, 0, buf_recv, 4);
108 if (kStatus_Success != status)
109 {
110 return status;
111 }
112
113 handle->resolutionX = ((buf_recv[2])) | ((buf_recv[3] & 0xf0U) << 4U);
114
115 status = handle->I2C_SendFunc(EKTF2K_I2C_ADDRESS, 0, 0, cmd_y, 4);
116 if (kStatus_Success != status)
117 {
118 return status;
119 }
120
121 status = handle->I2C_ReceiveFunc(EKTF2K_I2C_ADDRESS, 0, 0, buf_recv, 4);
122 if (kStatus_Success != status)
123 {
124 return status;
125 }
126
127 handle->resolutionY = ((buf_recv[2])) | ((buf_recv[3] & 0xf0U) << 4U);
128
129 return kStatus_Success;
130 }
131
EKTF2K_Deinit(ektf2k_handle_t * handle)132 status_t EKTF2K_Deinit(ektf2k_handle_t *handle)
133 {
134 handle->pullResetPin(false);
135 return kStatus_Success;
136 }
137
EKTF2K_ParseTouchData(const ektf2k_touch_point_t * data,int * touch_x,int * touch_y)138 static void EKTF2K_ParseTouchData(const ektf2k_touch_point_t *data, int *touch_x, int *touch_y)
139 {
140 *touch_x = data->XL + ((data->XHYH & 0xF0U) << 4U);
141 *touch_y = data->YL + ((data->XHYH & 0x0FU) << 8U);
142 }
143
EKTF2K_GetSingleTouch(ektf2k_handle_t * handle,int * touch_x,int * touch_y)144 status_t EKTF2K_GetSingleTouch(ektf2k_handle_t *handle, int *touch_x, int *touch_y)
145 {
146 status_t status;
147 uint32_t i;
148
149 touch_point_t touch_array[EKTF2K_MAX_TOUCHES];
150
151 status = EKTF2K_GetMultiTouch(handle, touch_array);
152
153 if (kStatus_Success == status)
154 {
155 for (i = 0; i < EKTF2K_MAX_TOUCHES; i++)
156 {
157 if (touch_array[i].valid)
158 {
159 *touch_x = touch_array[i].x;
160 *touch_y = touch_array[i].y;
161 break;
162 }
163 }
164
165 if (i >= EKTF2K_MAX_TOUCHES)
166 {
167 status = kStatus_Fail;
168 }
169 }
170
171 return status;
172 }
173
EKTF2K_GetMultiTouch(ektf2k_handle_t * handle,touch_point_t touch_array[EKTF2K_MAX_TOUCHES])174 status_t EKTF2K_GetMultiTouch(ektf2k_handle_t *handle, touch_point_t touch_array[EKTF2K_MAX_TOUCHES])
175 {
176 status_t status;
177 uint32_t i;
178 int x, y;
179
180 for (i = 0; i < EKTF2K_MAX_TOUCHES; i++)
181 {
182 touch_array[i].valid = false;
183 }
184
185 status = handle->I2C_ReceiveFunc(EKTF2K_I2C_ADDRESS, 0, 0, handle->receiveBuf, EKTF2K_TOUCH_DATA_LEN);
186
187 if (status == kStatus_Success)
188 {
189 ektf2k_touch_data_t *touch_data = (ektf2k_touch_data_t *)(void *)(handle->receiveBuf);
190
191 if (kEKTF2K_Pkt2Finger == touch_data->PKT_TYPE)
192 {
193 /* Decode valid touch points */
194 for (i = 0; i < EKTF2K_MAX_TOUCHES; i++)
195 {
196 touch_array[i].touchID = i;
197
198 if (touch_data->BTN_FID & (1U << i))
199 {
200 EKTF2K_ParseTouchData(&touch_data->TOUCH[i], &x, &y);
201 touch_array[i].x = x;
202 touch_array[i].y = y;
203 touch_array[i].valid = true;
204 }
205 }
206 }
207 else
208 {
209 status = kStatus_Fail;
210 }
211 }
212
213 return status;
214 }
215
EKTF2K_GetResolution(ektf2k_handle_t * handle,int * resolutionX,int * resolutionY)216 status_t EKTF2K_GetResolution(ektf2k_handle_t *handle, int *resolutionX, int *resolutionY)
217 {
218 *resolutionX = handle->resolutionX;
219 *resolutionY = handle->resolutionY;
220
221 return kStatus_Success;
222 }
223