Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers: fix touch driver #306

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
13 changes: 0 additions & 13 deletions examples/tests/touch/Makefile

This file was deleted.

77 changes: 0 additions & 77 deletions examples/tests/touch/main.c

This file was deleted.

9 changes: 3 additions & 6 deletions examples/touch/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
86 changes: 56 additions & 30 deletions libtock/touch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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) {
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}
14 changes: 6 additions & 8 deletions libtock/touch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);