1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2019 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_common.h"
10 #include "fsl_lpi2c.h"
11 #include "fsl_ft5406_rt.h"
12
13 typedef struct _ft5406_rt_touch_point
14 {
15 uint8_t XH;
16 uint8_t XL;
17 uint8_t YH;
18 uint8_t YL;
19 uint8_t RESERVED[2];
20 } ft5406_rt_touch_point_t;
21
22 typedef struct _ft5406_rt_touch_data
23 {
24 uint8_t GEST_ID;
25 uint8_t TD_STATUS;
26 ft5406_rt_touch_point_t TOUCH[FT5406_RT_MAX_TOUCHES];
27 } ft5406_rt_touch_data_t;
28
29 #define TOUCH_POINT_GET_EVENT(T) ((T).XH >> 6U)
30 #define TOUCH_POINT_GET_ID(T) ((T).YH >> 4U)
31 #define TOUCH_POINT_GET_X(T) ((((uint16_t)(T).XH & 0x0fU) << 8U) | (T).XL)
32 #define TOUCH_POINT_GET_Y(T) ((((uint16_t)(T).YH & 0x0fU) << 8U) | (T).YL)
33
34 static status_t FT5406_RT_ReadTouchData(ft5406_rt_handle_t *handle);
35
FT5406_RT_Init(ft5406_rt_handle_t * handle,LPI2C_Type * base)36 status_t FT5406_RT_Init(ft5406_rt_handle_t *handle, LPI2C_Type *base)
37 {
38 lpi2c_master_transfer_t *xfer = &(handle->xfer);
39 status_t status;
40 uint8_t mode;
41
42 if ((NULL == handle) || (NULL == base))
43 {
44 return kStatus_InvalidArgument;
45 }
46
47 handle->base = base;
48
49 /* clear transfer structure and buffer */
50 (void)memset(xfer, 0, sizeof(*xfer));
51 (void)memset(handle->touch_buf, 0, FT5406_RT_TOUCH_DATA_LEN);
52
53 /* set device mode to normal operation */
54 mode = 0;
55 xfer->slaveAddress = FT5406_RT_I2C_ADDRESS;
56 xfer->direction = kLPI2C_Write;
57 xfer->subaddress = 0;
58 xfer->subaddressSize = 1;
59 xfer->data = &mode;
60 xfer->dataSize = 1;
61 xfer->flags = (uint32_t)kLPI2C_TransferDefaultFlag;
62
63 status = LPI2C_MasterTransferBlocking(handle->base, &handle->xfer);
64
65 /* prepare transfer structure for reading touch data */
66 xfer->slaveAddress = FT5406_RT_I2C_ADDRESS;
67 xfer->direction = kLPI2C_Read;
68 xfer->subaddress = 1;
69 xfer->subaddressSize = 1;
70 xfer->data = handle->touch_buf;
71 xfer->dataSize = FT5406_RT_TOUCH_DATA_LEN;
72 xfer->flags = (uint32_t)kLPI2C_TransferDefaultFlag;
73
74 return status;
75 }
76
FT5406_RT_Denit(ft5406_rt_handle_t * handle)77 status_t FT5406_RT_Denit(ft5406_rt_handle_t *handle)
78 {
79 if (NULL == handle)
80 {
81 return kStatus_InvalidArgument;
82 }
83
84 handle->base = NULL;
85 return kStatus_Success;
86 }
87
FT5406_RT_ReadTouchData(ft5406_rt_handle_t * handle)88 static status_t FT5406_RT_ReadTouchData(ft5406_rt_handle_t *handle)
89 {
90 if (NULL == handle)
91 {
92 return kStatus_InvalidArgument;
93 }
94
95 return LPI2C_MasterTransferBlocking(handle->base, &handle->xfer);
96 }
97
FT5406_RT_GetSingleTouch(ft5406_rt_handle_t * handle,touch_event_t * touch_event,int * touch_x,int * touch_y)98 status_t FT5406_RT_GetSingleTouch(ft5406_rt_handle_t *handle, touch_event_t *touch_event, int *touch_x, int *touch_y)
99 {
100 status_t status;
101 touch_event_t touch_event_local;
102
103 status = FT5406_RT_ReadTouchData(handle);
104
105 if (status == kStatus_Success)
106 {
107 ft5406_rt_touch_data_t *touch_data = (ft5406_rt_touch_data_t *)(void *)(handle->touch_buf);
108
109 touch_event_local = (touch_event_t)(uint8_t)TOUCH_POINT_GET_EVENT(touch_data->TOUCH[0]);
110
111 if (touch_event != NULL)
112 {
113 *touch_event = touch_event_local;
114 }
115
116 /* Update coordinates only if there is touch detected */
117 if ((touch_event_local == kTouch_Down) || (touch_event_local == kTouch_Contact))
118 {
119 if (NULL != touch_x)
120 {
121 *touch_x = (int)(uint16_t)TOUCH_POINT_GET_X(touch_data->TOUCH[0]);
122 }
123 if (NULL != touch_y)
124 {
125 *touch_y = (int)(uint16_t)TOUCH_POINT_GET_Y(touch_data->TOUCH[0]);
126 }
127 }
128 }
129
130 return status;
131 }
132
FT5406_RT_GetMultiTouch(ft5406_rt_handle_t * handle,int * touch_count,touch_point_t touch_array[FT5406_RT_MAX_TOUCHES])133 status_t FT5406_RT_GetMultiTouch(ft5406_rt_handle_t *handle,
134 int *touch_count,
135 touch_point_t touch_array[FT5406_RT_MAX_TOUCHES])
136 {
137 status_t status;
138
139 status = FT5406_RT_ReadTouchData(handle);
140
141 if (status == kStatus_Success)
142 {
143 ft5406_rt_touch_data_t *touch_data = (ft5406_rt_touch_data_t *)(void *)(handle->touch_buf);
144 unsigned int i;
145
146 /* Check for valid number of touches - otherwise ignore touch information */
147 if (touch_data->TD_STATUS > FT5406_RT_MAX_TOUCHES)
148 {
149 touch_data->TD_STATUS = 0U;
150 }
151
152 /* Decode number of touches */
153 if (NULL != touch_count)
154 {
155 *touch_count = (int)touch_data->TD_STATUS;
156 }
157
158 /* Decode valid touch points */
159 for (i = 0; i < touch_data->TD_STATUS; i++)
160 {
161 touch_array[i].TOUCH_ID = TOUCH_POINT_GET_ID(touch_data->TOUCH[i]);
162 touch_array[i].TOUCH_EVENT = (touch_event_t)(uint8_t)TOUCH_POINT_GET_EVENT(touch_data->TOUCH[i]);
163 touch_array[i].TOUCH_X = TOUCH_POINT_GET_X(touch_data->TOUCH[i]);
164 touch_array[i].TOUCH_Y = TOUCH_POINT_GET_Y(touch_data->TOUCH[i]);
165 }
166
167 /* Clear vacant elements of touch_array */
168 for (; i < FT5406_RT_MAX_TOUCHES; i++)
169 {
170 touch_array[i].TOUCH_ID = 0;
171 touch_array[i].TOUCH_EVENT = kTouch_Reserved;
172 touch_array[i].TOUCH_X = 0;
173 touch_array[i].TOUCH_Y = 0;
174 }
175 }
176
177 return status;
178 }
179