Skip to content

Commit 4170005

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

File tree

2 files changed

+67
-36
lines changed

2 files changed

+67
-36
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: 56 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,80 +24,105 @@
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 zephyr_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(&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+
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(&zephyr_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(&zephyr_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) {
79+
void touch_event_callback(struct input_event *evt, void *user_data) {
80+
static int8_t tp_index = 0;
81+
static bool sem_taken = false;
7782
static const struct device *const touch_dev =
7883
DEVICE_DT_GET(DT_CHOSEN(zephyr_touch));
84+
Arduino_GigaDisplayTouch *touch = (Arduino_GigaDisplayTouch *)user_data;
85+
86+
if (!touch || evt->dev != touch_dev) {
87+
return;
88+
}
7989

80-
if (evt->dev != touch_dev) {
90+
// Take semaphore on first event.
91+
if (evt->code == INPUT_ABS_MT_SLOT) {
92+
// If the semaphore is already taken do Not try to take it again.
93+
// This could only happen if the event queue dropped BTN_TOUCH.
94+
if (!sem_taken && k_sem_take(&zephyr_touch_sem, K_NO_WAIT)) {
95+
return;
96+
}
97+
sem_taken = true;
98+
} else if (!sem_taken) {
99+
// On subsequent events, return if we don't have the semaphore.
81100
return;
82101
}
83102

84103
switch (evt->code) {
85104
case INPUT_ABS_MT_SLOT:
86-
zephyr_touch_cb_slot_num = evt->value;
105+
tp_index = evt->value;
106+
touch->_points[tp_index].trackId = evt->value;
87107
break;
88108
case INPUT_ABS_X:
89-
zephyr_touch_points[zephyr_touch_cb_slot_num].x = evt->value;
109+
touch->_points[tp_index].x = evt->value;
90110
break;
91111
case INPUT_ABS_Y:
92-
zephyr_touch_points[zephyr_touch_cb_slot_num].y = evt->value;
112+
touch->_points[tp_index].y = evt->value;
93113
break;
94114
case INPUT_BTN_TOUCH:
95-
zephyr_touch_points[zephyr_touch_cb_slot_num].pressed = evt->value;
115+
touch->_points[tp_index].pressed = evt->value;
96116
break;
97117
}
98118

99-
if (evt->sync) {
100-
k_sem_give(&zephyr_touch_event_sync);
119+
// Release the semaphore only after updating all of the data.
120+
if (evt->code == INPUT_BTN_TOUCH && evt->value) {
121+
sem_taken = false;
122+
k_sem_give(&zephyr_touch_sem);
123+
if (touch->_gt911TouchHandler) {
124+
touch->_gt911TouchHandler(GT911_MAX_CONTACTS, touch->_points);
125+
}
101126
}
102127
}
103128
#endif

0 commit comments

Comments
 (0)