From 84084a722de88cba042157dce1a671ff94c81556 Mon Sep 17 00:00:00 2001 From: Alexandru RADOVICI Date: Fri, 30 Sep 2022 14:45:09 +0300 Subject: [PATCH 1/2] fix touch driver to use double buffering --- examples/touch/main.c | 9 ++--- libtock/touch.c | 86 ++++++++++++++++++++++++++++--------------- libtock/touch.h | 14 +++---- 3 files changed, 65 insertions(+), 44 deletions(-) diff --git a/examples/touch/main.c b/examples/touch/main.c index 0c9860858..43a035d06 100644 --- a/examples/touch/main.c +++ b/examples/touch/main.c @@ -24,8 +24,7 @@ static void touch_event (int status, int x, int y, void *ud __attribute__ ((unus printf("(%d): %d y %d\n", status, x, y); } -static void multi_touch_event (int num_touches, int data2 __attribute__ ((unused)), int data3 __attribute__ ( - (unused)), void *ud __attribute__ ((unused))) { +static void multi_touch_event (int num_touches, int dropped_events, void *ud __attribute__ ((unused))) { for (int i = 0; i < num_touches; i++) { unsigned char id, status; unsigned short x, y; @@ -47,11 +46,9 @@ static void multi_touch_event (int num_touches, int data2 __attribute__ ((unused default: printf("error "); } - printf("(%d): %d y %d, ", status, x, y); + printf("(%d): x %d y %d, ", status, x, y); } - printf("\n"); - // ack the multi touch event and enable the next event - multi_touch_next(); + printf("dropped %d\n", dropped_events); } int main(void) { diff --git a/libtock/touch.c b/libtock/touch.c index fc1013089..c1911031a 100644 --- a/libtock/touch.c +++ b/libtock/touch.c @@ -6,23 +6,35 @@ static int touch_subscribe(int subscribe_num, subscribe_upcall callback, void* c return tock_subscribe_return_to_returncode(sval); } -static int touch_allow(int allow_num, void* data, int len) { +static int touch_allow(int allow_num, touch_t* data, int len, touch_t **prev_buffer) { allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_TOUCH, allow_num, data, len); + if (prev_buffer != NULL) { + *prev_buffer = aval.ptr; + } return tock_allow_rw_return_to_returncode(aval); } +static bool registered = false; static touch_t *multi_touch_buffer = NULL; -static unsigned char num_touches = 0; -static touch_callback *single_touch_upcall = NULL; -static gesture_callback *gesture_upcall = NULL; +static unsigned char num_registered_touches = 0; + +static touch_single_touch_callback *single_touch_upcall = NULL; +static touch_multi_touch_callback *multi_touch_upcall = NULL; +static touch_gesture_callback *gesture_upcall = NULL; -static void touch_single_touch_callback (int status, int xy, int data2 __attribute__((unused)), void *ud) { +static void single_touch_callback (int status, int xy, int data2 __attribute__((unused)), void *ud) { if (single_touch_upcall) single_touch_upcall(status, ((unsigned int)xy >> 16), (unsigned int)xy & 0xFFFF, ud); } -static void touch_gesture_callback (int gesture, int data1 __attribute__((unused)), int data2 __attribute__( - (unused)), void *ud) { +static void multi_touch_callback (int num_touches, int dropped_events, int data2 __attribute__( + (unused)), void *ud) { + touch_allow(0, multi_touch_buffer, num_registered_touches * sizeof(touch_t), &multi_touch_buffer); + if (multi_touch_upcall) multi_touch_upcall(num_touches, dropped_events, ud); +} + +static void gesture_callback (int gesture, int data1 __attribute__((unused)), int data2 __attribute__( + (unused)), void *ud) { if (gesture_upcall) gesture_upcall(gesture, ud); } @@ -41,9 +53,9 @@ int disable_single_touch(void) { return tock_command_return_novalue_to_returncode(cval); } -int single_touch_set_callback (touch_callback cb, void* ud) { +int single_touch_set_callback (touch_single_touch_callback cb, void* ud) { single_touch_upcall = cb; - return touch_subscribe(0, cb != NULL ? touch_single_touch_callback : NULL, ud); + return touch_subscribe(0, cb != NULL ? single_touch_callback : NULL, ud); } int enable_multi_touch(void) { @@ -56,20 +68,34 @@ int disable_multi_touch(void) { return tock_command_return_novalue_to_returncode(cval); } -int multi_touch_set_callback (touch_callback cb, void* ud, int max_touches) { +int multi_touch_set_callback (touch_multi_touch_callback cb, void* ud, int max_touches) { int err = RETURNCODE_SUCCESS; if (cb != NULL) { - if (multi_touch_buffer == NULL) { + if (registered == false) { multi_touch_buffer = (touch_t*)malloc(max_touches * sizeof(touch_t)); if (multi_touch_buffer) { - num_touches = max_touches; - err = touch_allow(2, multi_touch_buffer, max_touches * sizeof(touch_t)); - if (err == RETURNCODE_SUCCESS) { - err = touch_subscribe(2, cb, ud); - } - if (err != RETURNCODE_SUCCESS) { + touch_t * shared_buffer = (touch_t*)malloc(max_touches * sizeof(touch_t)); + if (shared_buffer) { + num_registered_touches = max_touches; + err = touch_allow(0, shared_buffer, max_touches * sizeof(touch_t), NULL); + if (err == RETURNCODE_SUCCESS) { + shared_buffer = NULL; + multi_touch_upcall = cb; + err = touch_subscribe(2, multi_touch_callback, ud); + } + if (err != RETURNCODE_SUCCESS) { + free(multi_touch_buffer); + multi_touch_buffer = NULL; + touch_allow(0, NULL, 0, &shared_buffer); + if (shared_buffer != NULL) { + free(shared_buffer); + } + } else { + registered = true; + } + } else { free(multi_touch_buffer); - multi_touch_buffer = NULL; + err = RETURNCODE_ENOMEM; } } else { err = RETURNCODE_ENOMEM; @@ -78,26 +104,31 @@ int multi_touch_set_callback (touch_callback cb, void* ud, int max_touches) { err = RETURNCODE_EALREADY; } } else { - if (multi_touch_buffer != NULL) { - num_touches = 0; - touch_allow(2, NULL, 0); - err = touch_subscribe(2, cb, ud); + if (registered) { + num_registered_touches = 0; + touch_t * buffer = NULL; + touch_allow(0, NULL, 0, &buffer); + if (buffer != NULL) { + free(buffer); + } + err = touch_subscribe(2, NULL, ud); free(multi_touch_buffer); multi_touch_buffer = NULL; + registered = false; } } return err; } -int gesture_set_callback (gesture_callback cb, void* ud) { +int gesture_set_callback (touch_gesture_callback cb, void* ud) { gesture_upcall = cb; - return touch_subscribe(1, cb != NULL ? touch_gesture_callback : NULL, ud); + return touch_subscribe(1, cb != NULL ? gesture_callback : NULL, ud); } // get multi touch int read_touch (int index, unsigned char *id, unsigned char *status, unsigned short *x, unsigned short *y) { - if (index < num_touches) { + if (index < num_registered_touches) { if (multi_touch_buffer != NULL) { *id = multi_touch_buffer[index].id; *status = multi_touch_buffer[index].status; @@ -125,8 +156,3 @@ int read_touch_full (int index, unsigned char *id, unsigned char *status, unsign return RETURNCODE_ENOMEM; } } - -int multi_touch_next (void) { - syscall_return_t cval = command(DRIVER_NUM_TOUCH, 10, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} diff --git a/libtock/touch.h b/libtock/touch.h index 0e86fa97d..a4d998000 100644 --- a/libtock/touch.h +++ b/libtock/touch.h @@ -19,8 +19,9 @@ #define GESTURE_ZOOM_IN 5 #define GESTURE_ZOOM_OUT 6 -typedef void (touch_callback)(int, int, int, void*); -typedef void (gesture_callback)(int, void*); +typedef void (touch_single_touch_callback)(int, int, int, void*); +typedef void (touch_multi_touch_callback)(int, int, void*); +typedef void (touch_gesture_callback)(int, void*); typedef struct __attribute__((__packed__)) { unsigned char id; @@ -42,15 +43,12 @@ int get_number_of_touches (int* touches); int enable_single_touch(void); int disable_single_touch(void); -int single_touch_set_callback (touch_callback cb, void* ud); +int single_touch_set_callback (touch_single_touch_callback cb, void* ud); int enable_multi_touch(void); int disable_multi_touch(void); -int multi_touch_set_callback (touch_callback cb, void* ud, int max_touches); -int gesture_set_callback (gesture_callback cb, void* ud); +int multi_touch_set_callback (touch_multi_touch_callback cb, void* ud, int max_touches); +int gesture_set_callback (touch_gesture_callback cb, void* ud); int read_touch (int index, unsigned char *id, unsigned char *status, unsigned short *x, unsigned short *y); int read_touch_full (int index, unsigned char *id, unsigned char *status, unsigned short *x, unsigned short *y, unsigned char *size, unsigned char *pressure); - -// Every multi touch event needs to be acked -int multi_touch_next (void); From 864b5faede3e628166f517e34701d6f56daf2996 Mon Sep 17 00:00:00 2001 From: Alexandru RADOVICI Date: Fri, 30 Sep 2022 14:59:21 +0300 Subject: [PATCH 2/2] delete duplicate touch --- examples/tests/touch/Makefile | 13 ------ examples/tests/touch/main.c | 77 ----------------------------------- 2 files changed, 90 deletions(-) delete mode 100644 examples/tests/touch/Makefile delete mode 100644 examples/tests/touch/main.c diff --git a/examples/tests/touch/Makefile b/examples/tests/touch/Makefile deleted file mode 100644 index a92109392..000000000 --- a/examples/tests/touch/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# Makefile for user application - -# Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../../.. - -# Which files to compile. -C_SRCS := $(wildcard *.c) - -APP_HEAP_SIZE := 20000 - -# Include userland master makefile. Contains rules and flags for actually -# building the application. -include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk diff --git a/examples/tests/touch/main.c b/examples/tests/touch/main.c deleted file mode 100644 index d1d45dd33..000000000 --- a/examples/tests/touch/main.c +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include - -#include -#include -#include - -static void tocuh_event (int status, int x, int y, void *ud __attribute__ ((unused))) { - switch (status) { - case TOUCH_STATUS_PRESSED: { - printf("pressed "); - break; - } - case TOUCH_STATUS_RELEASED: { - printf("released "); - break; - } - case TOUCH_STATUS_MOVED: { - printf("moved "); - break; - } - default: - printf("error "); - } - printf("%d x %d y %d\n", status, x, y); -} - -static void multi_tocuh_event (int num_touches, int data2 __attribute__ ((unused)), int data3 __attribute__ ( - (unused)), void *ud __attribute__ ((unused))) { - for (int i = 0; i < num_touches; i++) { - unsigned char id, status; - unsigned short x, y; - read_touch(i, &id, &status, &x, &y); - printf("%d: ", id); - switch (status) { - case TOUCH_STATUS_PRESSED: { - printf("pressed "); - break; - } - case TOUCH_STATUS_RELEASED: { - printf("released "); - break; - } - case TOUCH_STATUS_MOVED: { - printf("moved "); - break; - } - default: - printf("error "); - } - printf("%d x %d y %d, ", status, x, y); - } - printf("\n"); - // ack the multi touch event and enable the next event - multi_touch_next(); -} - -int main(void) { - int err; - int num_touches; - err = get_number_of_touches(&num_touches); - if (err < 0) { - return -1; - } - printf("Number of touches: %d\n", num_touches); - - if (num_touches == 0) { - printf("No touch found\n"); - } else if (num_touches == 1) { - // single touch - single_touch_set_callback(tocuh_event, NULL); - } else { - // multi touch - multi_touch_set_callback(multi_tocuh_event, NULL, num_touches); - } - return 0; -}