23
23
// Macro helpers.
24
24
#define TS_GET_BOOTLOADERMODE (reg ) (((reg) & 0x10 ) >> 4 )
25
25
26
+ // Interrupt function callback for Touch Interruput event.
27
+ static volatile bool _tsFlag = false ;
28
+ static void IRAM_ATTR tsInt ()
29
+ {
30
+ _tsFlag = true ;
31
+ }
32
+
26
33
/* *
27
34
* @brief touchInArea checks if touch occured in given rectangle area
28
35
*
39
46
*/
40
47
bool Touch::touchInArea (int16_t x1, int16_t y1, int16_t w, int16_t h)
41
48
{
49
+ int16_t x2 = x1 + w, y2 = y1 + h;
50
+ if (tsAvailable ())
51
+ {
52
+ uint8_t n;
53
+ uint16_t x[2 ], y[2 ];
54
+ uint8_t z[2 ];
55
+ n = tsGetData (x, y, z);
56
+
57
+ // Ugh...touchscreen expects to get handshake packet after each interrupt event, but this
58
+ // is not possible on EPS32 easly (there should be I2C communication inside ISR). This is a
59
+ // workaround; get the X and Y position and wait for 100ms. If multiple INT events have been
60
+ // detected, code will wait until no more new INT events have been detected.
61
+ unsigned long _tsIntTimeout = millis ();
62
+ while ((millis () - _tsIntTimeout) < 100ULL )
63
+ {
64
+ if (_tsFlag)
65
+ {
66
+ _tsIntTimeout = millis ();
67
+ _tsFlag = false ;
68
+ tsHandshake ();
69
+ }
70
+ }
71
+
72
+ if (n && z[0 ] > 0 )
73
+ {
74
+ touchT = millis ();
75
+ touchN = n;
76
+ memcpy (touchX, x, 2 );
77
+ memcpy (touchY, y, 2 );
78
+ }
79
+ }
42
80
81
+ if (millis () - touchT < 100 )
82
+ {
83
+ if (touchN == 1 && BOUND (x1, touchX[0 ], x2) && BOUND (y1, touchY[0 ], y2))
84
+ return true ;
85
+ if (touchN == 2 && ((BOUND (x1, touchX[0 ], x2) && BOUND (y1, touchY[0 ], y2)) ||
86
+ (BOUND (x1, touchX[1 ], x2) && BOUND (y1, touchY[1 ], y2))))
87
+ return true ;
88
+ }
89
+ return false ;
43
90
}
44
91
45
92
/* *
@@ -95,6 +142,9 @@ bool Touch::tsInit(uint8_t _pwrState)
95
142
pinMode (TS_INT, INPUT);
96
143
attachInterrupt (TS_INT, tsInt, FALLING);
97
144
145
+ // Wait a little bit.
146
+ delay (50 );
147
+
98
148
// Clear the interrpt flag.
99
149
_tsFlag = false ;
100
150
}
@@ -126,7 +176,7 @@ void Touch::tsShutdown()
126
176
*/
127
177
void Touch::tsGetRawData (uint8_t *b)
128
178
{
129
-
179
+ tsReadI2CRegs (CYPRESS_TOUCH_BASE_ADDR, b, 16 );
130
180
}
131
181
132
182
/* *
@@ -143,9 +193,188 @@ void Touch::tsGetRawData(uint8_t *b)
143
193
* @note touch screen doesn't return data for two fingers when fingers
144
194
* are align at the y axis, or one above another
145
195
*/
146
- uint8_t Touch::tsGetData (uint16_t *xPos, uint16_t *yPos)
196
+ uint8_t Touch::tsGetData (uint16_t *xPos, uint16_t *yPos, uint8_t *z )
147
197
{
198
+ // Struct typedef for touch data report from the touchscreen controller IC.
199
+ struct cypressTouchData _touchReport;
200
+
201
+ // Check for the null-pointer.
202
+ if (xPos == NULL || yPos == NULL ) return 0 ;
203
+
204
+ // Fill the array with zeros.
205
+ xPos[0 ] = 0 ;
206
+ xPos[1 ] = 0 ;
207
+ yPos[0 ] = 0 ;
208
+ yPos[1 ] = 0 ;
209
+
210
+ // Copy Z into array only if array address is passed as argument in function.
211
+ if (z != NULL )
212
+ {
213
+ z[0 ] = 0 ;
214
+ z[1 ] = 0 ;
215
+ }
216
+
217
+ // Check the flag for the new data.
218
+ if (!_tsFlag) return 0 ;
219
+
220
+ // If there is new data, clear the interrupt flag.
221
+ _tsFlag = false ;
222
+
223
+ // Read the new data from the touchscreen controller IC.
224
+ // Return zero detected fingers if reading has failed.
225
+ if (!tsGetTouchData (&_touchReport)) return 0 ;
226
+
227
+ // Scale it to fit the screen.
228
+ tsScale (&_touchReport, E_INK_WIDTH - 1 , E_INK_HEIGHT - 1 , false , true , true );
229
+
230
+ // Copy values into ararys.
231
+ for (int i = 0 ; i < _touchReport.fingers ; i++)
232
+ {
233
+ // Save values into the arrays.
234
+ xPos[i] = _touchReport.x [i];
235
+ yPos[i] = _touchReport.y [i];
236
+
237
+ // Copy Z into array only if array address is passed as argument in function.
238
+ if (z != NULL )
239
+ {
240
+ z[i] = _touchReport.z [i];
241
+ }
242
+ }
243
+
244
+ // Rotate it if needed.
245
+ // Rotation 0 does not need swapping (defalut rotation).
246
+ if (getRotation () != 0 )
247
+ {
248
+ // Temp variable for swap.
249
+ uint16_t _temp;
148
250
251
+ // Check for each finger.
252
+ for (int i = 0 ; i < _touchReport.fingers ; i++)
253
+ {
254
+ switch (getRotation ())
255
+ {
256
+ case 1 :
257
+ // Rotation clockwise (to the right - aka. portrait mode).
258
+ _temp = xPos[i];
259
+ xPos[i] = map (yPos[i], 0 , E_INK_HEIGHT, 0 , E_INK_HEIGHT);
260
+ yPos[i] = map (_temp, 0 , E_INK_WIDTH - 1 , E_INK_WIDTH - 1 , 0 );
261
+ break ;
262
+ case 2 :
263
+ // Flipped by 180 deg.
264
+ xPos[i] = map (xPos[i], 0 , E_INK_WIDTH - 1 , E_INK_WIDTH - 1 , 0 );
265
+ yPos[i] = map (yPos[i], 0 , E_INK_HEIGHT - 1 , E_INK_HEIGHT - 1 , 0 );
266
+ break ;
267
+ case 3 :
268
+ // Rotation counter-clockwise from default rotation (90 degs to the left).
269
+ _temp = xPos[i];
270
+ xPos[i] = map (yPos[i], 0 , E_INK_HEIGHT - 1 , E_INK_HEIGHT - 1 , 0 );
271
+ yPos[i] = map (_temp, 0 , E_INK_WIDTH - 1 , 0 , E_INK_WIDTH - 1 );
272
+ break ;
273
+ }
274
+ }
275
+ }
276
+
277
+ // Return number of detected fingers on the touchscreen.
278
+ return _touchReport.fingers ;
279
+ }
280
+
281
+ /* *
282
+ * @brief Get the new touch event data from the touchscreen controller.
283
+ *
284
+ * @param struct cypressTouchData _touchData
285
+ * Pointer to the structure for the touch report data (such as X, Y and
286
+ * Z values of each touch channel, nuber of fingers etc.)
287
+ *
288
+ * @return bool
289
+ * true - Touch data is successfully read and the data is valid.
290
+ * false - Touch data read has failed.
291
+ */
292
+ bool Touch::tsGetTouchData (struct cypressTouchData *_touchData)
293
+ {
294
+ // Check for the null-pointer trap.
295
+ if (_touchData == NULL ) return false ;
296
+
297
+ // Clear struct for touchscreen data.
298
+ memset (_touchData, 0 , sizeof (cypressTouchData));
299
+
300
+ // Buffer for the I2C registers.
301
+ uint8_t _regs[32 ];
302
+
303
+ // Read registers for the touch data (32 bytes of data).
304
+ // If read failed for some reason, return false.
305
+ if (!tsReadI2CRegs (CYPRESS_TOUCH_BASE_ADDR, _regs, sizeof (_regs))) return false ;
306
+
307
+ // Send a handshake.
308
+ tsHandshake ();
309
+
310
+ // Parse the data!
311
+ // Data goes as follows:
312
+ // [1 byte] Handshake bit - Must be written back with xor on last MSB bit for TSC knows that INT has been read.
313
+ // [1 byte] Something? It changes with every new data. Data is always 0x00, 0x40, 0x80, 0xC0)
314
+ // [1 byte] Number of fingers detected - Zero, one or two.
315
+ // [2 bytes] X value position of the finger that has been detected first.
316
+ // [2 bytes] Y value position of the finger that has been detected first.
317
+ // [1 byte] Z value or the presusre os the touch on the first finger.
318
+ // [1 byte] Type of detection - 0 or 255 finger released
319
+ // [2 bytes] X value position of the finger that has been detected second.
320
+ // [2 bytes] Y value position of the finger that has been detected second.
321
+ // [1 byte] Z value or the presusre os the touch on the second finger.
322
+ _touchData->x [0 ] = _regs[3 ] << 8 | _regs[4 ];
323
+ _touchData->y [0 ] = _regs[5 ] << 8 | _regs[6 ];
324
+ _touchData->z [0 ] = _regs[7 ];
325
+ _touchData->x [1 ] = _regs[9 ] << 8 | _regs[10 ];
326
+ _touchData->y [1 ] = _regs[11 ] << 8 | _regs[12 ];
327
+ _touchData->z [1 ] = _regs[13 ];
328
+ _touchData->detectionType = _regs[8 ];
329
+ _touchData->fingers = _regs[2 ];
330
+
331
+ // Everything went ok? Return true.
332
+ return true ;
333
+ }
334
+
335
+ /* *
336
+ * @brief Method scales, flips and swaps X and Y cooridinates to ensure X and Y matches the screen.
337
+ *
338
+ * @param struct cypressTouchData _touchData
339
+ * Defined in cypressTouchTypedefs.h. Filled touch data report.
340
+ * @param uint16_t _xSize
341
+ * Screen size in pixels for X axis.
342
+ * @param uint16_t _ySize
343
+ * Screen size in pixels for Y axis.
344
+ * @param bool _flipX
345
+ * Flip the direction of the X axis.
346
+ * @param bool _flipY
347
+ * Flip the direction of the Y axis.
348
+ * @param bool _swapXY
349
+ * Swap X and Y cooridinates.
350
+ */
351
+ void Touch::tsScale (struct cypressTouchData *_touchData, uint16_t _xSize, uint16_t _ySize, bool _flipX, bool _flipY, bool _swapXY)
352
+ {
353
+ // Temp. variables for the mapped value.
354
+ uint16_t _mappedX = 0 ;
355
+ uint16_t _mappedY = 0 ;
356
+
357
+ // Map both touch channels.
358
+ for (int i = 0 ; i < _touchData->fingers ; i++)
359
+ {
360
+ // Check for the flip.
361
+ if (_flipX) _touchData->x [i] = CYPRESS_TOUCH_MAX_X - _touchData->x [i];
362
+ if (_flipY) _touchData->y [i] = CYPRESS_TOUCH_MAX_Y - _touchData->y [i];
363
+
364
+ // Check for X and Y swap.
365
+ if (_swapXY)
366
+ {
367
+ uint16_t _temp = _touchData->x [i];
368
+ _touchData->x [i] = _touchData->y [i];
369
+ _touchData->y [i] = _temp;
370
+ }
371
+
372
+ // Map X value.
373
+ _mappedX = map (_touchData->x [i], 0 , CYPRESS_TOUCH_MAX_X, 0 , _xSize);
374
+
375
+ // Map Y value.
376
+ _mappedX = map (_touchData->y [i], 0 , CYPRESS_TOUCH_MAX_Y, 0 , _ySize);
377
+ }
149
378
}
150
379
151
380
/* *
@@ -195,11 +424,7 @@ uint8_t Touch::tsGetPowerState()
195
424
*/
196
425
bool Touch::tsAvailable ()
197
426
{
198
- // Check for the handshake.
199
- if (_tsFlag) tsHandshake ();
200
- bool _temp = _tsFlag;
201
- _tsFlag = false ;
202
- return _temp;
427
+ return _tsFlag;
203
428
}
204
429
205
430
0 commit comments