Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions src/Arduino_GigaDisplayTouch.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,15 @@
#define GT911_I2C_ADDR_28_29 (0x14 | 0x80) // 0x28/0x29 - 0x14 (7bit address)

#define GT911_CONTACT_SIZE 8
#if defined(__MBED__)
#define GT911_MAX_CONTACTS 5
#else
#define GT911_MAX_CONTACTS CONFIG_INPUT_GT911_MAX_TOUCH_POINTS
#endif

/* Exported types ------------------------------------------------------------*/
typedef struct GDTpoint_s GDTpoint_t;
typedef void (*GDTTouchHandler_t)(uint8_t, GDTpoint_t *);

/* Exported enumeration ------------------------------------------------------*/

Expand All @@ -59,7 +64,7 @@ struct GDTpoint_s {
uint16_t x;
uint16_t y;
uint16_t area;
uint8_t reserved;
uint8_t pressed;
};

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

private:
GDTTouchHandler_t _gt911TouchHandler;
GDTpoint_t _points[GT911_MAX_CONTACTS];
#if defined(__MBED__)
TwoWire &_wire;
uint8_t _intPin;
uint8_t _rstPin;
uint8_t _addr;
mbed::InterruptIn _irqInt;
GDTpoint_t _points[GT911_MAX_CONTACTS];
void (*_gt911TouchHandler)(uint8_t, GDTpoint_t *);

uint8_t _gt911WriteOp(uint16_t reg, uint8_t data);
uint8_t _gt911WriteBytesOp(uint16_t reg, uint8_t *data, uint8_t len);
uint8_t _gt911ReadOp(uint16_t reg, uint8_t *data, uint8_t len);
void _gt911onIrq();
uint8_t _gt911ReadInputCoord(uint8_t *pointsbuf, uint8_t &contacts);

#elif defined(__ZEPHYR__)
friend void touch_event_callback(struct input_event *evt, void *user_data);
#endif
};

Expand Down
94 changes: 58 additions & 36 deletions src/Arduino_GigaDisplayTouchZephyr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,80 +24,102 @@
#include <zephyr/kernel.h>
#include <zephyr/sys/util.h>

typedef struct {
size_t x;
size_t y;
bool pressed;
} touch_point_t;
static struct k_sem zephyr_touch_sem;

static uint8_t zephyr_touch_cb_slot_num;
static struct k_sem zephyr_touch_event_sync;
static touch_point_t zephyr_touch_points[CONFIG_INPUT_GT911_MAX_TOUCH_POINTS];
typedef void (*zephyr_input_callback_t)(struct input_event *evt, void *user_data);
extern "C" void zephyr_input_register_callback(zephyr_input_callback_t cb, void *user_data);
void touch_event_callback(struct input_event *evt, void *user_data);

typedef void (*zephyr_input_callback_t)(struct input_event *evt,
void *user_data);
extern "C" void zephyr_input_register_callback(zephyr_input_callback_t cb);
static void touch_event_callback(struct input_event *evt, void *user_data);
Arduino_GigaDisplayTouch::Arduino_GigaDisplayTouch() {

Arduino_GigaDisplayTouch::Arduino_GigaDisplayTouch() {}
}

Arduino_GigaDisplayTouch::~Arduino_GigaDisplayTouch() {

Arduino_GigaDisplayTouch::~Arduino_GigaDisplayTouch() {}
}

bool Arduino_GigaDisplayTouch::begin() {
k_sem_init(&zephyr_touch_event_sync, 0, 1);
zephyr_input_register_callback(touch_event_callback);
_gt911TouchHandler = nullptr;
k_sem_init(&zephyr_touch_sem, 1, 1);
zephyr_input_register_callback(touch_event_callback, this);
return true;
}

void Arduino_GigaDisplayTouch::end() {}
void Arduino_GigaDisplayTouch::end() {
_gt911TouchHandler = nullptr;
zephyr_input_register_callback(NULL, NULL);
}

uint8_t Arduino_GigaDisplayTouch::getTouchPoints(GDTpoint_t *points) {
// First wait to see if we get any events.
if (k_sem_take(&zephyr_touch_event_sync, K_NO_WAIT) != 0) {
if (k_sem_take(&zephyr_touch_sem, K_NO_WAIT)) {
return 0;
}

uint8_t count_pressed = 0;
for (uint8_t i = 0; i <= zephyr_touch_cb_slot_num; i++) {
if (zephyr_touch_points[i].pressed) {
points[count_pressed].x = zephyr_touch_points[i].x;
points[count_pressed].y = zephyr_touch_points[i].y;
size_t count_pressed = 0;
for (int i = 0; i < GT911_MAX_CONTACTS; i++) {
if (_points[i].pressed) {
points[count_pressed].trackId = _points[i].trackId;
points[count_pressed].x = _points[i].x;
points[count_pressed].y = _points[i].y;
count_pressed++;
}
}

k_sem_give(&zephyr_touch_sem);
return count_pressed;
}

void Arduino_GigaDisplayTouch::onDetect(void (*handler)(uint8_t,
GDTpoint_t *)) {
UNUSED(handler);
void Arduino_GigaDisplayTouch::onDetect(GDTTouchHandler_t handler) {
_gt911TouchHandler = handler;
}

static void touch_event_callback(struct input_event *evt, void *user_data) {
static const struct device *const touch_dev =
DEVICE_DT_GET(DT_CHOSEN(zephyr_touch));
void touch_event_callback(struct input_event *evt, void *user_data) {
static int8_t tp_index = 0;
static bool sem_taken = false;
static const struct device *const touch_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_touch));
Arduino_GigaDisplayTouch *touch = (Arduino_GigaDisplayTouch *) user_data;

if (evt->dev != touch_dev) {
if (!touch || evt->dev != touch_dev) {
return;
}

// Take semaphore on first event.
if (evt->code == INPUT_ABS_MT_SLOT) {
// If the semaphore is already taken do Not try to take it again.
// This could only happen if the event queue dropped BTN_TOUCH.
if (!sem_taken && k_sem_take(&zephyr_touch_sem, K_NO_WAIT)) {
return;
}
sem_taken = true;
} else if (!sem_taken) {
// On subsequent events, return if we don't have the semaphore.
return;
}

switch (evt->code) {
case INPUT_ABS_MT_SLOT:
zephyr_touch_cb_slot_num = evt->value;
tp_index = evt->value;
touch->_points[tp_index].trackId = evt->value;
break;
case INPUT_ABS_X:
zephyr_touch_points[zephyr_touch_cb_slot_num].x = evt->value;
touch->_points[tp_index].x = evt->value;
break;
case INPUT_ABS_Y:
zephyr_touch_points[zephyr_touch_cb_slot_num].y = evt->value;
touch->_points[tp_index].y = evt->value;
break;
case INPUT_BTN_TOUCH:
zephyr_touch_points[zephyr_touch_cb_slot_num].pressed = evt->value;
touch->_points[tp_index].pressed = evt->value;
break;
}

if (evt->sync) {
k_sem_give(&zephyr_touch_event_sync);
// Release the semaphore only after updating all of the data.
if (evt->code == INPUT_BTN_TOUCH) {
sem_taken = false;
k_sem_give(&zephyr_touch_sem);
if (touch->_gt911TouchHandler) {
touch->_gt911TouchHandler(GT911_MAX_CONTACTS, touch->_points);
}
}
}
#endif
Loading