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