Skip to content

Commit d40f88a

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

File tree

2 files changed

+69
-41
lines changed

2 files changed

+69
-41
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 & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -24,80 +24,102 @@
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;
27+
static struct k_sem zephyr_touch_sem;
3228

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];
29+
typedef void (*zephyr_input_callback_t)(struct input_event *evt, void *user_data);
30+
extern "C" void zephyr_input_register_callback(zephyr_input_callback_t cb, void *user_data);
31+
void touch_event_callback(struct input_event *evt, void *user_data);
3632

37-
typedef void (*zephyr_input_callback_t)(struct input_event *evt,
38-
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);
33+
Arduino_GigaDisplayTouch::Arduino_GigaDisplayTouch() {
4134

42-
Arduino_GigaDisplayTouch::Arduino_GigaDisplayTouch() {}
35+
}
36+
37+
Arduino_GigaDisplayTouch::~Arduino_GigaDisplayTouch() {
4338

44-
Arduino_GigaDisplayTouch::~Arduino_GigaDisplayTouch() {}
39+
}
4540

4641
bool Arduino_GigaDisplayTouch::begin() {
47-
k_sem_init(&zephyr_touch_event_sync, 0, 1);
48-
zephyr_input_register_callback(touch_event_callback);
42+
_gt911TouchHandler = nullptr;
43+
k_sem_init(&zephyr_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+
}
5352

5453
uint8_t Arduino_GigaDisplayTouch::getTouchPoints(GDTpoint_t *points) {
5554
// First wait to see if we get any events.
56-
if (k_sem_take(&zephyr_touch_event_sync, K_NO_WAIT) != 0) {
55+
if (k_sem_take(&zephyr_touch_sem, K_NO_WAIT)) {
5756
return 0;
5857
}
5958

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;
59+
size_t count_pressed = 0;
60+
for (int i = 0; i < GT911_MAX_CONTACTS; i++) {
61+
if (_points[i].pressed) {
62+
points[count_pressed].trackId = _points[i].trackId;
63+
points[count_pressed].x = _points[i].x;
64+
points[count_pressed].y = _points[i].y;
6565
count_pressed++;
6666
}
6767
}
68+
69+
k_sem_give(&zephyr_touch_sem);
6870
return count_pressed;
6971
}
7072

71-
void Arduino_GigaDisplayTouch::onDetect(void (*handler)(uint8_t,
72-
GDTpoint_t *)) {
73-
UNUSED(handler);
73+
void Arduino_GigaDisplayTouch::onDetect(GDTTouchHandler_t handler) {
74+
_gt911TouchHandler = handler;
7475
}
7576

76-
static void touch_event_callback(struct input_event *evt, void *user_data) {
77-
static const struct device *const touch_dev =
78-
DEVICE_DT_GET(DT_CHOSEN(zephyr_touch));
77+
void touch_event_callback(struct input_event *evt, void *user_data) {
78+
static int8_t tp_index = 0;
79+
static bool sem_taken = false;
80+
static const struct device *const touch_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_touch));
81+
Arduino_GigaDisplayTouch *touch = (Arduino_GigaDisplayTouch *) user_data;
7982

80-
if (evt->dev != touch_dev) {
83+
if (!touch || evt->dev != touch_dev) {
84+
return;
85+
}
86+
87+
// Take semaphore on first event.
88+
if (evt->code == INPUT_ABS_MT_SLOT) {
89+
// If the semaphore is already taken do Not try to take it again.
90+
// This could only happen if the event queue dropped BTN_TOUCH.
91+
if (!sem_taken && k_sem_take(&zephyr_touch_sem, K_NO_WAIT)) {
92+
return;
93+
}
94+
sem_taken = true;
95+
} else if (!sem_taken) {
96+
// On subsequent events, return if we don't have the semaphore.
8197
return;
8298
}
8399

84100
switch (evt->code) {
85101
case INPUT_ABS_MT_SLOT:
86-
zephyr_touch_cb_slot_num = evt->value;
102+
tp_index = evt->value;
103+
touch->_points[tp_index].trackId = evt->value;
87104
break;
88105
case INPUT_ABS_X:
89-
zephyr_touch_points[zephyr_touch_cb_slot_num].x = evt->value;
106+
touch->_points[tp_index].x = evt->value;
90107
break;
91108
case INPUT_ABS_Y:
92-
zephyr_touch_points[zephyr_touch_cb_slot_num].y = evt->value;
109+
touch->_points[tp_index].y = evt->value;
93110
break;
94111
case INPUT_BTN_TOUCH:
95-
zephyr_touch_points[zephyr_touch_cb_slot_num].pressed = evt->value;
112+
touch->_points[tp_index].pressed = evt->value;
96113
break;
97114
}
98115

99-
if (evt->sync) {
100-
k_sem_give(&zephyr_touch_event_sync);
116+
// Release the semaphore only after updating all of the data.
117+
if (evt->code == INPUT_BTN_TOUCH) {
118+
sem_taken = false;
119+
k_sem_give(&zephyr_touch_sem);
120+
if (touch->_gt911TouchHandler) {
121+
touch->_gt911TouchHandler(GT911_MAX_CONTACTS, touch->_points);
122+
}
101123
}
102124
}
103125
#endif

0 commit comments

Comments
 (0)