Skip to content

Commit 270cde5

Browse files
committed
Implement onDetect for Zephyr port.
Signed-off-by: iabdalkader <[email protected]>
1 parent 3dd4836 commit 270cde5

File tree

2 files changed

+69
-37
lines changed

2 files changed

+69
-37
lines changed

src/Arduino_GigaDisplayTouch.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,15 @@
4141
#define GT911_I2C_ADDR_28_29 (0x14 | 0x80) // 0x28/0x29 - 0x14 (7bit address)
4242

4343
#define GT911_CONTACT_SIZE 8
44+
#if defined(__MBED__)
4445
#define GT911_MAX_CONTACTS 5
46+
#else
47+
#define GT911_MAX_CONTACTS CONFIG_INPUT_GT911_MAX_TOUCH_POINTS
48+
#endif
4549

4650
/* Exported types ------------------------------------------------------------*/
4751
typedef struct GDTpoint_s GDTpoint_t;
52+
typedef void (*GDTTouchHandler_t)(uint8_t, GDTpoint_t *);
4853

4954
/* Exported enumeration ------------------------------------------------------*/
5055

@@ -59,7 +64,7 @@ struct GDTpoint_s {
5964
uint16_t x;
6065
uint16_t y;
6166
uint16_t area;
62-
uint8_t reserved;
67+
uint8_t pressed;
6368
};
6469

6570
/* Class
@@ -123,24 +128,25 @@ class Arduino_GigaDisplayTouch {
123128
* @brief Attach an interrupt handler function for touch detection callbacks.
124129
* @param handler The pointer to the user-defined handler function.
125130
*/
126-
void onDetect(void (*handler)(uint8_t, GDTpoint_t *));
131+
void onDetect(GDTTouchHandler_t handler);
127132

128133
private:
134+
GDTTouchHandler_t _gt911TouchHandler;
135+
GDTpoint_t _points[GT911_MAX_CONTACTS];
129136
#if defined(__MBED__)
130137
TwoWire &_wire;
131138
uint8_t _intPin;
132139
uint8_t _rstPin;
133140
uint8_t _addr;
134141
mbed::InterruptIn _irqInt;
135-
GDTpoint_t _points[GT911_MAX_CONTACTS];
136-
void (*_gt911TouchHandler)(uint8_t, GDTpoint_t *);
137142

138143
uint8_t _gt911WriteOp(uint16_t reg, uint8_t data);
139144
uint8_t _gt911WriteBytesOp(uint16_t reg, uint8_t *data, uint8_t len);
140145
uint8_t _gt911ReadOp(uint16_t reg, uint8_t *data, uint8_t len);
141146
void _gt911onIrq();
142147
uint8_t _gt911ReadInputCoord(uint8_t *pointsbuf, uint8_t &contacts);
143-
148+
#elif defined(__ZEPHYR__)
149+
friend void touch_event_callback(struct input_event *evt, void *user_data);
144150
#endif
145151
};
146152

src/Arduino_GigaDisplayTouchZephyr.cpp

Lines changed: 58 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,80 +24,106 @@
2424
#include <zephyr/kernel.h>
2525
#include <zephyr/sys/util.h>
2626

27-
typedef struct {
28-
size_t x;
29-
size_t y;
30-
bool pressed;
31-
} touch_point_t;
32-
33-
static uint8_t zephyr_touch_cb_slot_num;
34-
static struct k_sem zephyr_touch_event_sync;
35-
static touch_point_t zephyr_touch_points[CONFIG_INPUT_GT911_MAX_TOUCH_POINTS];
27+
static struct k_sem touch_sem;
3628

3729
typedef void (*zephyr_input_callback_t)(struct input_event *evt,
3830
void *user_data);
39-
extern "C" void zephyr_input_register_callback(zephyr_input_callback_t cb);
40-
static void touch_event_callback(struct input_event *evt, void *user_data);
31+
extern "C" void zephyr_input_register_callback(zephyr_input_callback_t cb,
32+
void *user_data);
33+
void touch_event_callback(struct input_event *evt, void *user_data);
4134

4235
Arduino_GigaDisplayTouch::Arduino_GigaDisplayTouch() {}
4336

4437
Arduino_GigaDisplayTouch::~Arduino_GigaDisplayTouch() {}
4538

4639
bool Arduino_GigaDisplayTouch::begin() {
47-
k_sem_init(&zephyr_touch_event_sync, 0, 1);
48-
zephyr_input_register_callback(touch_event_callback);
40+
_gt911TouchHandler = nullptr;
41+
// Initialize to 1 to prevent deadlock by ensuring that
42+
// at least one function can always proceed initially.
43+
k_sem_init(&touch_sem, 1, 1);
44+
zephyr_input_register_callback(touch_event_callback, this);
4945
return true;
5046
}
5147

52-
void Arduino_GigaDisplayTouch::end() {}
48+
void Arduino_GigaDisplayTouch::end() {
49+
_gt911TouchHandler = nullptr;
50+
zephyr_input_register_callback(NULL, NULL);
51+
memset(_points, 0, sizeof(_points));
52+
}
5353

5454
uint8_t Arduino_GigaDisplayTouch::getTouchPoints(GDTpoint_t *points) {
5555
// First wait to see if we get any events.
56-
if (k_sem_take(&zephyr_touch_event_sync, K_NO_WAIT) != 0) {
56+
if (k_sem_take(&touch_sem, K_NO_WAIT)) {
5757
return 0;
5858
}
5959

60-
uint8_t count_pressed = 0;
61-
for (uint8_t i = 0; i <= zephyr_touch_cb_slot_num; i++) {
62-
if (zephyr_touch_points[i].pressed) {
63-
points[count_pressed].x = zephyr_touch_points[i].x;
64-
points[count_pressed].y = zephyr_touch_points[i].y;
60+
size_t count_pressed = 0;
61+
for (int i = 0; i < GT911_MAX_CONTACTS; i++) {
62+
if (_points[i].pressed) {
63+
_points[i].pressed = 0;
64+
points[count_pressed].trackId = _points[i].trackId;
65+
points[count_pressed].x = _points[i].x;
66+
points[count_pressed].y = _points[i].y;
6567
count_pressed++;
6668
}
6769
}
70+
71+
k_sem_give(&touch_sem);
6872
return count_pressed;
6973
}
7074

71-
void Arduino_GigaDisplayTouch::onDetect(void (*handler)(uint8_t,
72-
GDTpoint_t *)) {
73-
UNUSED(handler);
75+
void Arduino_GigaDisplayTouch::onDetect(GDTTouchHandler_t handler) {
76+
_gt911TouchHandler = handler;
7477
}
7578

76-
static void touch_event_callback(struct input_event *evt, void *user_data) {
77-
static const struct device *const touch_dev =
79+
void touch_event_callback(struct input_event *evt, void *user_data) {
80+
static int8_t index = 0;
81+
static bool sem_taken = false;
82+
83+
static const struct device *const dev =
7884
DEVICE_DT_GET(DT_CHOSEN(zephyr_touch));
85+
Arduino_GigaDisplayTouch *touch = (Arduino_GigaDisplayTouch *)user_data;
7986

80-
if (evt->dev != touch_dev) {
87+
if (!touch || evt->dev != dev) {
88+
return;
89+
}
90+
91+
// Take semaphore on first event.
92+
if (evt->code == INPUT_ABS_MT_SLOT) {
93+
// Check if the semaphore is already taken by this callback.
94+
// This could only happen if the event queue dropped BTN_TOUCH.
95+
if (!sem_taken && k_sem_take(&touch_sem, K_NO_WAIT) != 0) {
96+
return;
97+
}
98+
sem_taken = true;
99+
} else if (!sem_taken) {
100+
// On subsequent events, return if we don't have the semaphore.
81101
return;
82102
}
83103

84104
switch (evt->code) {
85105
case INPUT_ABS_MT_SLOT:
86-
zephyr_touch_cb_slot_num = evt->value;
106+
index = evt->value;
107+
touch->_points[index].trackId = evt->value;
87108
break;
88109
case INPUT_ABS_X:
89-
zephyr_touch_points[zephyr_touch_cb_slot_num].x = evt->value;
110+
touch->_points[index].x = evt->value;
90111
break;
91112
case INPUT_ABS_Y:
92-
zephyr_touch_points[zephyr_touch_cb_slot_num].y = evt->value;
113+
touch->_points[index].y = evt->value;
93114
break;
94115
case INPUT_BTN_TOUCH:
95-
zephyr_touch_points[zephyr_touch_cb_slot_num].pressed = evt->value;
116+
touch->_points[index].pressed = evt->value;
96117
break;
97118
}
98119

99-
if (evt->sync) {
100-
k_sem_give(&zephyr_touch_event_sync);
120+
// Release the semaphore on the last event (BTN_TOUCH pressed).
121+
if (evt->code == INPUT_BTN_TOUCH && evt->value) {
122+
sem_taken = false;
123+
k_sem_give(&touch_sem);
124+
if (touch->_gt911TouchHandler) {
125+
touch->_gt911TouchHandler(GT911_MAX_CONTACTS, touch->_points);
126+
}
101127
}
102128
}
103129
#endif

0 commit comments

Comments
 (0)