Skip to content

Commit b2b14af

Browse files
committed
Preliminary Giga Touch support on Zephyr
Zephyr: Added in our preliminary support for touch on the display In ArduinoCore-zephyr added a callback to register with the input class. When set it simply forwards the callbacks to this function. Then added some support. We still don't have things like gestures as I don't think the zephyr input class has support for it. Have a simple touch paint sketch (now supporting multiple touches, that appears to work
1 parent 24490f4 commit b2b14af

File tree

2 files changed

+238
-22
lines changed

2 files changed

+238
-22
lines changed

src/Arduino_GigaDisplayTouch.cpp

Lines changed: 130 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,123 @@
2222
* @brief Source file for the Arduino Giga Display Touch library.
2323
*/
2424

25+
26+
#ifdef __ZEPHYR__
27+
/*
28+
* Copyright 2023 Arduino SA
29+
*
30+
* This program is free software: you can redistribute it and/or modify
31+
* it under the terms of the GNU Lesser General Public License as published by
32+
* the Free Software Foundation, either version 3 of the License, or
33+
* (at your option) any later version.
34+
*
35+
* This program is distributed in the hope that it will be useful,
36+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
37+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38+
* GNU Lesser General Public License for more details.
39+
*
40+
* You should have received a copy of the GNU Lesser General Public License
41+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
42+
*
43+
*/
44+
45+
/**
46+
* @file Arduino_GigaDisplayTouch.cpp
47+
* @author Leonardo Cavagnis
48+
* @brief Source file for the Arduino Giga Display Touch library.
49+
*/
50+
51+
/* Includes -----------------------------------------------------------------*/
52+
#include "Arduino_GigaDisplayTouch.h"
53+
54+
#include <zephyr/kernel.h>
55+
#include <zephyr/device.h>
56+
#include <zephyr/input/input.h>
57+
#include <zephyr/drivers/display.h>
58+
#include <zephyr/sys/util.h>
59+
60+
61+
62+
/* Callbacks from Zephyr ----------------------- */
63+
64+
// Static members defined
65+
Arduino_GigaDisplayTouch::touch_point_t Arduino_GigaDisplayTouch::zephyr_touch_points[CONFIG_INPUT_GT911_MAX_TOUCH_POINTS];
66+
67+
uint8_t Arduino_GigaDisplayTouch::zephyr_touch_cb_slot_num = 0;
68+
struct k_sem Arduino_GigaDisplayTouch::zephyr_touch_event_sync;
69+
70+
71+
void Arduino_GigaDisplayTouch::touch_event_callback(struct input_event *evt, void *user_data) {
72+
UNUSED(user_data);
73+
//printk("touch_event_callback(%p %p): %p %u %u %u %d\n", evt, user_data,
74+
// evt->dev, evt->sync, evt->type, evt->code, evt->value);
75+
switch(evt->code) {
76+
case INPUT_ABS_MT_SLOT:
77+
zephyr_touch_cb_slot_num = evt->value;
78+
break;
79+
case INPUT_ABS_X:
80+
zephyr_touch_points[zephyr_touch_cb_slot_num].x = evt->value;
81+
break;
82+
case INPUT_ABS_Y:
83+
zephyr_touch_points[zephyr_touch_cb_slot_num].y = evt->value;
84+
break;
85+
case INPUT_BTN_TOUCH:
86+
zephyr_touch_points[zephyr_touch_cb_slot_num].pressed = evt->value;
87+
break;
88+
}
89+
90+
if (evt->sync) {
91+
k_sem_give(&zephyr_touch_event_sync);
92+
}
93+
}
94+
95+
96+
/* Functions -----------------------------------------------------------------*/
97+
Arduino_GigaDisplayTouch::Arduino_GigaDisplayTouch()
98+
{
99+
}
100+
101+
Arduino_GigaDisplayTouch::~Arduino_GigaDisplayTouch()
102+
{
103+
}
104+
105+
extern "C" void registerGigaTouchCallback(void (*cb)(struct input_event *evt, void *user_data));
106+
107+
bool Arduino_GigaDisplayTouch::begin() {
108+
k_sem_init(&zephyr_touch_event_sync, 0, 1);
109+
registerGigaTouchCallback(&touch_event_callback);
110+
return true;
111+
}
112+
113+
114+
void Arduino_GigaDisplayTouch::end()
115+
{
116+
registerGigaTouchCallback(nullptr);
117+
}
118+
119+
uint8_t Arduino_GigaDisplayTouch::getTouchPoints(GDTpoint_t* points, uint32_t timeout) {
120+
121+
// First wait to see if we get any events.
122+
if (k_sem_take(&zephyr_touch_event_sync, timeout? K_MSEC(timeout) : K_NO_WAIT) != 0) return 0;
123+
124+
uint8_t count_pressed = 0;
125+
for (uint8_t i = 0; i <= zephyr_touch_cb_slot_num; i++) {
126+
if (zephyr_touch_points[i].pressed) {
127+
points[count_pressed].x = zephyr_touch_points[i].x;
128+
points[count_pressed].y = zephyr_touch_points[i].y;
129+
count_pressed++;
130+
}
131+
}
132+
return count_pressed;
133+
}
134+
135+
void Arduino_GigaDisplayTouch::onDetect(void (*handler)(uint8_t, GDTpoint_t*)) {
136+
UNUSED(handler);
137+
}
138+
139+
/**** END OF FILE ****/
140+
#else
141+
25142
/* Includes -----------------------------------------------------------------*/
26143
#include "Arduino_GigaDisplayTouch.h"
27144

@@ -35,7 +152,7 @@
35152

36153
/* Private variables ---------------------------------------------------------*/
37154
rtos::Thread t;
38-
events::EventQueue queue(32 * EVENTS_EVENT_SIZE);
155+
events::EventQueue queue(32 * EVENTS_EVENT_SIZE);
39156
Arduino_GigaDisplayTouch * gThis;
40157

41158
/* Private function prototypes -----------------------------------------------*/
@@ -52,7 +169,7 @@ Arduino_GigaDisplayTouch::Arduino_GigaDisplayTouch(TwoWire& wire, uint8_t intPin
52169
: _wire{wire}, _intPin{intPin}, _rstPin{rstPin}, _addr{addr}, _irqInt{digitalPinToPinName(intPin)}
53170
{ }
54171

55-
Arduino_GigaDisplayTouch::~Arduino_GigaDisplayTouch()
172+
Arduino_GigaDisplayTouch::~Arduino_GigaDisplayTouch()
56173
{ }
57174

58175
bool Arduino_GigaDisplayTouch::begin() {
@@ -143,7 +260,7 @@ void _lvglTouchCb(lv_indev_drv_t * indev, lv_indev_data_t * data) {
143260
#endif
144261
#endif
145262

146-
void Arduino_GigaDisplayTouch::end()
263+
void Arduino_GigaDisplayTouch::end()
147264
{ }
148265

149266
uint8_t Arduino_GigaDisplayTouch::getTouchPoints(GDTpoint_t* points) {
@@ -159,12 +276,12 @@ uint8_t Arduino_GigaDisplayTouch::getTouchPoints(GDTpoint_t* points) {
159276
}
160277

161278
for (uint8_t i = 0; i < contacts; i++) {
162-
points[i].trackId = rawpoints[1 + 8*i];
279+
points[i].trackId = rawpoints[1 + 8*i];
163280
points[i].x = ((uint16_t)rawpoints[3 + 8*i] << 8) + rawpoints[2 + 8*i];
164281
points[i].y = ((uint16_t)rawpoints[5 + 8*i] << 8) + rawpoints[4 + 8*i];
165282
points[i].area = ((uint16_t)rawpoints[7 + 8*i] << 8) + rawpoints[6 + 8*i];
166283
}
167-
284+
168285
_gt911WriteOp(GT911_REG_GESTURE_START_POINT, 0); /* Reset buffer status to finish the reading */
169286

170287
return contacts;
@@ -192,7 +309,7 @@ uint8_t Arduino_GigaDisplayTouch::_gt911WriteBytesOp(uint16_t reg, uint8_t * dat
192309

193310
/* Data [0..n] */
194311
for (uint8_t i = 0; i < len; i++) {
195-
_wire.write(data[i]);
312+
_wire.write(data[i]);
196313
}
197314

198315
status = _wire.endTransmission();
@@ -233,33 +350,35 @@ void Arduino_GigaDisplayTouch::_gt911onIrq() {
233350
}
234351

235352
for (uint8_t i = 0; i < contacts; i++) {
236-
_points[i].trackId = rawpoints[1 + 8*i];
353+
_points[i].trackId = rawpoints[1 + 8*i];
237354
_points[i].x = ((uint16_t)rawpoints[3 + 8*i] << 8) + rawpoints[2 + 8*i];
238355
_points[i].y = ((uint16_t)rawpoints[5 + 8*i] << 8) + rawpoints[4 + 8*i];
239356
_points[i].area = ((uint16_t)rawpoints[7 + 8*i] << 8) + rawpoints[6 + 8*i];
240357
}
241358

242359
if (contacts > 0 && _gt911TouchHandler != nullptr) _gt911TouchHandler(contacts, _points);
243-
360+
244361
_gt911WriteOp(GT911_REG_GESTURE_START_POINT, 0); /* Reset buffer status to finish the reading */
245362
}
246363

247364
uint8_t Arduino_GigaDisplayTouch::_gt911ReadInputCoord(uint8_t * pointsbuf, uint8_t& contacts) {
248365
uint8_t error;
249-
366+
250367
contacts = 0;
251368
error = _gt911ReadOp(GT911_REG_GESTURE_START_POINT, pointsbuf, GT911_CONTACT_SIZE * GT911_MAX_CONTACTS);
252369

253370
if (error) {
254371
return 1; /* I2C comm error */
255372
}
256-
257-
if (!(pointsbuf[0] & 0x80)) {
373+
374+
if (!(pointsbuf[0] & 0x80)) {
258375
return 2; /* Data buffer not ready */
259376
}
260377

261378
contacts = pointsbuf[0] & 0xF;
262379
return 0;
263380
}
264381

382+
#endif /* zephyr */
383+
265384
/**** END OF FILE ****/

src/Arduino_GigaDisplayTouch.h

Lines changed: 108 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,101 @@
2828
#ifndef __ARDUINO_GIGADISPLAYTOUCH_H
2929
#define __ARDUINO_GIGADISPLAYTOUCH_H
3030

31+
#ifdef __ZEPHYR__
32+
/* Note a lot of this is exact duplicate of the MBed define */
33+
34+
/* Includes ------------------------------------------------------------------*/
35+
#include <Arduino.h>
36+
#include "Wire.h"
37+
//#include "pinDefinitions.h"
38+
39+
/* Exported defines ----------------------------------------------------------*/
40+
#define GT911_I2C_ADDR_BA_BB (0x5D | 0x80) // 0xBA/0xBB - 0x5D (7bit address)
41+
#define GT911_I2C_ADDR_28_29 (0x14 | 0x80) // 0x28/0x29 - 0x14 (7bit address)
42+
43+
#define GT911_CONTACT_SIZE 8
44+
#define GT911_MAX_CONTACTS 5
45+
46+
/* Exported types ------------------------------------------------------------*/
47+
typedef struct GDTpoint_s GDTpoint_t;
48+
49+
/* Exported enumeration ------------------------------------------------------*/
50+
51+
/* Exported struct -----------------------------------------------------------*/
52+
53+
/**
54+
* @brief Struct representing a touch point.
55+
*/
56+
struct GDTpoint_s {
57+
// 0x814F-0x8156, ... 0x8176 (5 points)
58+
uint8_t trackId;
59+
uint16_t x;
60+
uint16_t y;
61+
uint16_t area;
62+
uint8_t reserved;
63+
};
64+
65+
66+
/* Class ----------------------------------------------------------------------*/
67+
68+
/**
69+
* @class Arduino_GigaDisplayTouch
70+
* @brief Class for Giga Display Touch controller driver.
71+
*/
72+
class Arduino_GigaDisplayTouch {
73+
public:
74+
Arduino_GigaDisplayTouch();
75+
~Arduino_GigaDisplayTouch();
76+
77+
78+
/**
79+
* @brief Initialize the touch controller.
80+
*
81+
* @return true If the touch controller is successfully initialized, false Otherwise
82+
*/
83+
bool begin();
84+
85+
/**
86+
* @brief De-initialize the touch controller.
87+
*/
88+
void end();
89+
90+
/**
91+
* @brief Check if a touch event is detected and get the touch points.
92+
* @param points The array containing the coordinates of the touch points.
93+
* @return uint8_t The number of detected touch points.
94+
*/
95+
uint8_t getTouchPoints(GDTpoint_t* points, uint32_t timeout=0);
96+
97+
/**
98+
* @brief Attach an interrupt handler function for touch detection callbacks.
99+
* @param handler The pointer to the user-defined handler function.
100+
*/
101+
void onDetect(void (*handler)(uint8_t, GDTpoint_t*));
102+
103+
104+
/*
105+
* @brief Support for callbacks from zephyr
106+
*/
107+
typedef struct {
108+
size_t x;
109+
size_t y;
110+
bool pressed;
111+
} touch_point_t;
112+
113+
static touch_point_t zephyr_touch_points[CONFIG_INPUT_GT911_MAX_TOUCH_POINTS];
114+
115+
static uint8_t zephyr_touch_cb_slot_num;
116+
static struct k_sem zephyr_touch_event_sync;
117+
118+
static void touch_event_callback(struct input_event *evt, void *user_data);
119+
120+
protected:
121+
122+
};
123+
124+
#else
125+
31126
/* Includes ------------------------------------------------------------------*/
32127
#include <Arduino.h>
33128
#include "Wire.h"
@@ -52,7 +147,7 @@ typedef struct GDTpoint_s GDTpoint_t;
52147
* @brief Struct representing a touch point.
53148
*/
54149
struct GDTpoint_s {
55-
// 0x814F-0x8156, ... 0x8176 (5 points)
150+
// 0x814F-0x8156, ... 0x8176 (5 points)
56151
uint8_t trackId;
57152
uint16_t x;
58153
uint16_t y;
@@ -67,7 +162,7 @@ struct GDTpoint_s {
67162
* @brief Class for Giga Display Touch controller driver.
68163
*/
69164
class Arduino_GigaDisplayTouch {
70-
public:
165+
public:
71166
/**
72167
* @brief Construct a new touch controller for Giga Display Shield.
73168
*
@@ -77,19 +172,19 @@ class Arduino_GigaDisplayTouch {
77172
* @param addr The device address for the touch controller.
78173
*/
79174
#if defined(ARDUINO_GIGA)
80-
Arduino_GigaDisplayTouch(TwoWire& wire = Wire1,
175+
Arduino_GigaDisplayTouch(TwoWire& wire = Wire1,
81176
uint8_t intPin = PinNameToIndex(PI_1),
82-
uint8_t rstPin = PinNameToIndex(PI_2),
177+
uint8_t rstPin = PinNameToIndex(PI_2),
83178
uint8_t addr = GT911_I2C_ADDR_BA_BB);
84179
#elif defined(ARDUINO_PORTENTA_H7_M7)
85-
Arduino_GigaDisplayTouch(TwoWire& wire = Wire,
180+
Arduino_GigaDisplayTouch(TwoWire& wire = Wire,
86181
uint8_t intPin = PinNameToIndex(PD_4),
87-
uint8_t rstPin = PinNameToIndex(PD_5),
182+
uint8_t rstPin = PinNameToIndex(PD_5),
88183
uint8_t addr = GT911_I2C_ADDR_BA_BB);
89-
#else
90-
Arduino_GigaDisplayTouch(TwoWire& wire,
91-
uint8_t intPin,
92-
uint8_t rstPin,
184+
#else
185+
Arduino_GigaDisplayTouch(TwoWire& wire,
186+
uint8_t intPin,
187+
uint8_t rstPin,
93188
uint8_t addr);
94189
#endif
95190
~Arduino_GigaDisplayTouch();
@@ -122,7 +217,7 @@ class Arduino_GigaDisplayTouch {
122217
private:
123218
TwoWire& _wire;
124219
uint8_t _intPin;
125-
mbed::InterruptIn _irqInt;
220+
mbed::InterruptIn _irqInt;
126221
uint8_t _rstPin;
127222
uint8_t _addr;
128223
GDTpoint_t _points[GT911_MAX_CONTACTS];
@@ -135,4 +230,6 @@ class Arduino_GigaDisplayTouch {
135230
uint8_t _gt911ReadInputCoord(uint8_t * pointsbuf, uint8_t& contacts);
136231
};
137232

233+
#endif /* Zephyr */
234+
138235
#endif /* __ARDUINO_GIGADISPLAYTOUCH_H */

0 commit comments

Comments
 (0)