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