Skip to content

Commit c25db92

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 Edit: clang-format zephyr parts.
1 parent 24490f4 commit c25db92

File tree

2 files changed

+232
-22
lines changed

2 files changed

+232
-22
lines changed

src/Arduino_GigaDisplayTouch.cpp

Lines changed: 125 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,118 @@
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/device.h>
55+
#include <zephyr/drivers/display.h>
56+
#include <zephyr/input/input.h>
57+
#include <zephyr/kernel.h>
58+
#include <zephyr/sys/util.h>
59+
60+
/* Callbacks from Zephyr ----------------------- */
61+
62+
// Static members defined
63+
Arduino_GigaDisplayTouch::touch_point_t Arduino_GigaDisplayTouch::
64+
zephyr_touch_points[CONFIG_INPUT_GT911_MAX_TOUCH_POINTS];
65+
66+
uint8_t Arduino_GigaDisplayTouch::zephyr_touch_cb_slot_num = 0;
67+
struct k_sem Arduino_GigaDisplayTouch::zephyr_touch_event_sync;
68+
69+
void Arduino_GigaDisplayTouch::touch_event_callback(struct input_event *evt,
70+
void *user_data) {
71+
UNUSED(user_data);
72+
// printk("touch_event_callback(%p %p): %p %u %u %u %d\n", evt, user_data,
73+
// evt->dev, evt->sync, evt->type, evt->code, evt->value);
74+
switch (evt->code) {
75+
case INPUT_ABS_MT_SLOT:
76+
zephyr_touch_cb_slot_num = evt->value;
77+
break;
78+
case INPUT_ABS_X:
79+
zephyr_touch_points[zephyr_touch_cb_slot_num].x = evt->value;
80+
break;
81+
case INPUT_ABS_Y:
82+
zephyr_touch_points[zephyr_touch_cb_slot_num].y = evt->value;
83+
break;
84+
case INPUT_BTN_TOUCH:
85+
zephyr_touch_points[zephyr_touch_cb_slot_num].pressed = evt->value;
86+
break;
87+
}
88+
89+
if (evt->sync) {
90+
k_sem_give(&zephyr_touch_event_sync);
91+
}
92+
}
93+
94+
/* Functions -----------------------------------------------------------------*/
95+
Arduino_GigaDisplayTouch::Arduino_GigaDisplayTouch() {}
96+
97+
Arduino_GigaDisplayTouch::~Arduino_GigaDisplayTouch() {}
98+
99+
extern "C" void registerGigaTouchCallback(void (*cb)(struct input_event *evt,
100+
void *user_data));
101+
102+
bool Arduino_GigaDisplayTouch::begin() {
103+
k_sem_init(&zephyr_touch_event_sync, 0, 1);
104+
registerGigaTouchCallback(&touch_event_callback);
105+
return true;
106+
}
107+
108+
void Arduino_GigaDisplayTouch::end() { registerGigaTouchCallback(nullptr); }
109+
110+
uint8_t Arduino_GigaDisplayTouch::getTouchPoints(GDTpoint_t *points,
111+
uint32_t timeout) {
112+
113+
// First wait to see if we get any events.
114+
if (k_sem_take(&zephyr_touch_event_sync,
115+
timeout ? K_MSEC(timeout) : K_NO_WAIT) != 0)
116+
return 0;
117+
118+
uint8_t count_pressed = 0;
119+
for (uint8_t i = 0; i <= zephyr_touch_cb_slot_num; i++) {
120+
if (zephyr_touch_points[i].pressed) {
121+
points[count_pressed].x = zephyr_touch_points[i].x;
122+
points[count_pressed].y = zephyr_touch_points[i].y;
123+
count_pressed++;
124+
}
125+
}
126+
return count_pressed;
127+
}
128+
129+
void Arduino_GigaDisplayTouch::onDetect(void (*handler)(uint8_t,
130+
GDTpoint_t *)) {
131+
UNUSED(handler);
132+
}
133+
134+
/**** END OF FILE ****/
135+
#else
136+
25137
/* Includes -----------------------------------------------------------------*/
26138
#include "Arduino_GigaDisplayTouch.h"
27139

@@ -35,7 +147,7 @@
35147

36148
/* Private variables ---------------------------------------------------------*/
37149
rtos::Thread t;
38-
events::EventQueue queue(32 * EVENTS_EVENT_SIZE);
150+
events::EventQueue queue(32 * EVENTS_EVENT_SIZE);
39151
Arduino_GigaDisplayTouch * gThis;
40152

41153
/* Private function prototypes -----------------------------------------------*/
@@ -52,7 +164,7 @@ Arduino_GigaDisplayTouch::Arduino_GigaDisplayTouch(TwoWire& wire, uint8_t intPin
52164
: _wire{wire}, _intPin{intPin}, _rstPin{rstPin}, _addr{addr}, _irqInt{digitalPinToPinName(intPin)}
53165
{ }
54166

55-
Arduino_GigaDisplayTouch::~Arduino_GigaDisplayTouch()
167+
Arduino_GigaDisplayTouch::~Arduino_GigaDisplayTouch()
56168
{ }
57169

58170
bool Arduino_GigaDisplayTouch::begin() {
@@ -143,7 +255,7 @@ void _lvglTouchCb(lv_indev_drv_t * indev, lv_indev_data_t * data) {
143255
#endif
144256
#endif
145257

146-
void Arduino_GigaDisplayTouch::end()
258+
void Arduino_GigaDisplayTouch::end()
147259
{ }
148260

149261
uint8_t Arduino_GigaDisplayTouch::getTouchPoints(GDTpoint_t* points) {
@@ -159,12 +271,12 @@ uint8_t Arduino_GigaDisplayTouch::getTouchPoints(GDTpoint_t* points) {
159271
}
160272

161273
for (uint8_t i = 0; i < contacts; i++) {
162-
points[i].trackId = rawpoints[1 + 8*i];
274+
points[i].trackId = rawpoints[1 + 8*i];
163275
points[i].x = ((uint16_t)rawpoints[3 + 8*i] << 8) + rawpoints[2 + 8*i];
164276
points[i].y = ((uint16_t)rawpoints[5 + 8*i] << 8) + rawpoints[4 + 8*i];
165277
points[i].area = ((uint16_t)rawpoints[7 + 8*i] << 8) + rawpoints[6 + 8*i];
166278
}
167-
279+
168280
_gt911WriteOp(GT911_REG_GESTURE_START_POINT, 0); /* Reset buffer status to finish the reading */
169281

170282
return contacts;
@@ -192,7 +304,7 @@ uint8_t Arduino_GigaDisplayTouch::_gt911WriteBytesOp(uint16_t reg, uint8_t * dat
192304

193305
/* Data [0..n] */
194306
for (uint8_t i = 0; i < len; i++) {
195-
_wire.write(data[i]);
307+
_wire.write(data[i]);
196308
}
197309

198310
status = _wire.endTransmission();
@@ -233,33 +345,35 @@ void Arduino_GigaDisplayTouch::_gt911onIrq() {
233345
}
234346

235347
for (uint8_t i = 0; i < contacts; i++) {
236-
_points[i].trackId = rawpoints[1 + 8*i];
348+
_points[i].trackId = rawpoints[1 + 8*i];
237349
_points[i].x = ((uint16_t)rawpoints[3 + 8*i] << 8) + rawpoints[2 + 8*i];
238350
_points[i].y = ((uint16_t)rawpoints[5 + 8*i] << 8) + rawpoints[4 + 8*i];
239351
_points[i].area = ((uint16_t)rawpoints[7 + 8*i] << 8) + rawpoints[6 + 8*i];
240352
}
241353

242354
if (contacts > 0 && _gt911TouchHandler != nullptr) _gt911TouchHandler(contacts, _points);
243-
355+
244356
_gt911WriteOp(GT911_REG_GESTURE_START_POINT, 0); /* Reset buffer status to finish the reading */
245357
}
246358

247359
uint8_t Arduino_GigaDisplayTouch::_gt911ReadInputCoord(uint8_t * pointsbuf, uint8_t& contacts) {
248360
uint8_t error;
249-
361+
250362
contacts = 0;
251363
error = _gt911ReadOp(GT911_REG_GESTURE_START_POINT, pointsbuf, GT911_CONTACT_SIZE * GT911_MAX_CONTACTS);
252364

253365
if (error) {
254366
return 1; /* I2C comm error */
255367
}
256-
257-
if (!(pointsbuf[0] & 0x80)) {
368+
369+
if (!(pointsbuf[0] & 0x80)) {
258370
return 2; /* Data buffer not ready */
259371
}
260372

261373
contacts = pointsbuf[0] & 0xF;
262374
return 0;
263375
}
264376

377+
#endif /* zephyr */
378+
265379
/**** END OF FILE ****/

src/Arduino_GigaDisplayTouch.h

Lines changed: 107 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,100 @@
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 "Wire.h"
36+
#include <Arduino.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+
/* Class
66+
* ----------------------------------------------------------------------*/
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+
* @brief Initialize the touch controller.
79+
*
80+
* @return true If the touch controller is successfully initialized, false
81+
* 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+
* @brief Support for callbacks from zephyr
105+
*/
106+
typedef struct {
107+
size_t x;
108+
size_t y;
109+
bool pressed;
110+
} touch_point_t;
111+
112+
static touch_point_t zephyr_touch_points[CONFIG_INPUT_GT911_MAX_TOUCH_POINTS];
113+
114+
static uint8_t zephyr_touch_cb_slot_num;
115+
static struct k_sem zephyr_touch_event_sync;
116+
117+
static void touch_event_callback(struct input_event *evt, void *user_data);
118+
119+
protected:
120+
};
121+
122+
123+
#else
124+
31125
/* Includes ------------------------------------------------------------------*/
32126
#include <Arduino.h>
33127
#include "Wire.h"
@@ -52,7 +146,7 @@ typedef struct GDTpoint_s GDTpoint_t;
52146
* @brief Struct representing a touch point.
53147
*/
54148
struct GDTpoint_s {
55-
// 0x814F-0x8156, ... 0x8176 (5 points)
149+
// 0x814F-0x8156, ... 0x8176 (5 points)
56150
uint8_t trackId;
57151
uint16_t x;
58152
uint16_t y;
@@ -67,7 +161,7 @@ struct GDTpoint_s {
67161
* @brief Class for Giga Display Touch controller driver.
68162
*/
69163
class Arduino_GigaDisplayTouch {
70-
public:
164+
public:
71165
/**
72166
* @brief Construct a new touch controller for Giga Display Shield.
73167
*
@@ -77,19 +171,19 @@ class Arduino_GigaDisplayTouch {
77171
* @param addr The device address for the touch controller.
78172
*/
79173
#if defined(ARDUINO_GIGA)
80-
Arduino_GigaDisplayTouch(TwoWire& wire = Wire1,
174+
Arduino_GigaDisplayTouch(TwoWire& wire = Wire1,
81175
uint8_t intPin = PinNameToIndex(PI_1),
82-
uint8_t rstPin = PinNameToIndex(PI_2),
176+
uint8_t rstPin = PinNameToIndex(PI_2),
83177
uint8_t addr = GT911_I2C_ADDR_BA_BB);
84178
#elif defined(ARDUINO_PORTENTA_H7_M7)
85-
Arduino_GigaDisplayTouch(TwoWire& wire = Wire,
179+
Arduino_GigaDisplayTouch(TwoWire& wire = Wire,
86180
uint8_t intPin = PinNameToIndex(PD_4),
87-
uint8_t rstPin = PinNameToIndex(PD_5),
181+
uint8_t rstPin = PinNameToIndex(PD_5),
88182
uint8_t addr = GT911_I2C_ADDR_BA_BB);
89-
#else
90-
Arduino_GigaDisplayTouch(TwoWire& wire,
91-
uint8_t intPin,
92-
uint8_t rstPin,
183+
#else
184+
Arduino_GigaDisplayTouch(TwoWire& wire,
185+
uint8_t intPin,
186+
uint8_t rstPin,
93187
uint8_t addr);
94188
#endif
95189
~Arduino_GigaDisplayTouch();
@@ -122,7 +216,7 @@ class Arduino_GigaDisplayTouch {
122216
private:
123217
TwoWire& _wire;
124218
uint8_t _intPin;
125-
mbed::InterruptIn _irqInt;
219+
mbed::InterruptIn _irqInt;
126220
uint8_t _rstPin;
127221
uint8_t _addr;
128222
GDTpoint_t _points[GT911_MAX_CONTACTS];
@@ -135,4 +229,6 @@ class Arduino_GigaDisplayTouch {
135229
uint8_t _gt911ReadInputCoord(uint8_t * pointsbuf, uint8_t& contacts);
136230
};
137231

232+
#endif /* Zephyr */
233+
138234
#endif /* __ARDUINO_GIGADISPLAYTOUCH_H */

0 commit comments

Comments
 (0)