diff options
-rw-r--r-- | src/accelerometers.c | 144 | ||||
-rw-r--r-- | src/types.h | 16 |
2 files changed, 119 insertions, 41 deletions
diff --git a/src/accelerometers.c b/src/accelerometers.c index 14921c6..e965b2f 100644 --- a/src/accelerometers.c +++ b/src/accelerometers.c @@ -53,10 +53,79 @@ struct input_event { #define REL_Y (0x01) #define REL_Z (0x02) -AccelHandle *accelerometer_open() { +static void accelerometer_freerunner_try_threshold(AccelHandle *accel) +{ + FILE *fh; + int rval; + /* Save the old threshold */ + fh = fopen("/sys/devices/platform/lis302dl.2/threshold", "r"); + if ( fh == NULL ) { + fprintf(stderr, "Failed to disable accelerometer threshold.\n"); + return; + } + rval = fscanf(fh, "%i", &accel->old_threshold); + if ( rval != 1 ) { + /* Failed */ + fprintf(stderr, "Couldn't read old accelerometer threshold.\n"); + accel->old_threshold = -1; + } + printf("Old threshold was %i\n", accel->old_threshold); + fclose(fh); + + /* Set the threshold to zero */ + fh = fopen("/sys/devices/platform/lis302dl.2/threshold", "w"); + if ( fh == NULL ) { + fprintf(stderr, "Failed to disable accelerometer threshold.\n"); + return; + } + fprintf(fh, "0\n"); + printf("Successfully disabled accelerometer threshold.\n"); + fclose(fh); +} + +static void accelerometer_freerunner_try_restore_threshold(AccelHandle *accel) +{ + FILE *fh; + int rval; + int new_threshold; + + if ( accel->old_threshold < 0 ) { + printf("Not restoring threshold.\n"); + } + + fh = fopen("/sys/devices/platform/lis302dl.2/threshold", "r"); + if ( fh == NULL ) { + fprintf(stderr, "Failed to restore accelerometer threshold.\n"); + return; + } + rval = fscanf(fh, "%i", &new_threshold); + if ( rval != 1 ) { + fprintf(stderr, "Couldn't read new accelerometer threshold\n"); + } + fclose(fh); + + /* Restore only if it hasn't been altered externally */ + if ( new_threshold != 0 ) { + printf("Threshold changed - not restoring.\n"); + return; + } + + /* Set it back to the old value */ + fh = fopen("/sys/devices/platform/lis302dl.2/threshold", "w"); + if ( fh == NULL ) { + fprintf(stderr, "Failed to restore accelerometer threshold.\n"); + return; + } + fprintf(fh, "%i\n", accel->old_threshold); + printf("Successfully restored accelerometer threshold.\n"); + fclose(fh); +} + +AccelHandle *accelerometer_open() +{ AccelHandle *accel; - + /* Initialise accelerometer data structure */ accel = malloc(sizeof(AccelHandle)); if ( accel == NULL ) return NULL; @@ -68,7 +137,7 @@ AccelHandle *accelerometer_open() { accel->lz = 0; accel->state = 0; accel->type = ACCEL_UNKNOWN; - + /* Determine accelerometer type */ accel->fd = open("/dev/input/by-path/platform-hdaps-event-joystick", O_RDONLY, O_NONBLOCK); if ( accel->fd != -1 ) { @@ -79,23 +148,32 @@ AccelHandle *accelerometer_open() { accel->fd = open("/dev/input/event3", O_RDONLY, 0); if ( accel->fd != -1 ) { + accel->type = ACCEL_FREERUNNER; printf("Neo Freerunner detected\n"); + accelerometer_freerunner_try_threshold(accel); + return accel; } - + /* Try other types here */ - + fprintf(stderr, "Couldn't determine accelerometer type\n"); return accel; - } -int accelerometer_moo_hdaps(AccelHandle *accel) { +static void accelerometer_shutdown(AccelHandle *accel) +{ + if ( accel->type == ACCEL_FREERUNNER ) { + accelerometer_freerunner_try_restore_threshold(accel); + } +} +int accelerometer_moo_hdaps(AccelHandle *accel) +{ struct input_event ev; size_t rval; - + rval = read(accel->fd, &ev, sizeof(ev)); if ( rval != sizeof(ev) ) { fprintf(stderr, "Couldn't read accelerometer data"); @@ -113,7 +191,7 @@ int accelerometer_moo_hdaps(AccelHandle *accel) { accel->state=2; return 1; } - + if (accel->state == 2 && abs(ev.value)<20) { // Laptop almost at center, enable another round accel->state=0; @@ -122,41 +200,41 @@ int accelerometer_moo_hdaps(AccelHandle *accel) { } return 0; - + /* fprintf(stderr, "Event: time %ld.%06ld, type %s, code %d, value %d\n", ev.time.tv_sec, ev.time.tv_usec, - ev.type == EV_REL ? "REL" : + ev.type == EV_REL ? "REL" : ev.type == EV_ABS ? "ABS" : "Other" , ev.code, ev.value); */ } -int accelerometer_moo_freerunner(AccelHandle *accel) { - +int accelerometer_moo_freerunner(AccelHandle *accel) +{ struct input_event ev; size_t rval; fd_set fds; struct timeval t; - + FD_ZERO(&fds); FD_SET(accel->fd, &fds); t.tv_sec = 0; t.tv_usec = 0; select(1+accel->fd, &fds, NULL, NULL, &t); - + if ( FD_ISSET(accel->fd, &fds) ) { - + rval = read(accel->fd, &ev, sizeof(ev)); if ( rval != sizeof(ev) ) { fprintf(stderr, "Couldn't read accelerometer data"); return 0; } - + } else { return 0; /* No data */ } - + if ( ev.type == EV_REL ) { if ( ev.code == REL_X ) { accel->lx = ev.value; @@ -190,8 +268,8 @@ int accelerometer_moo_freerunner(AccelHandle *accel) { return 0; } -int accelerometer_moo(AccelHandle *accel) { - +int accelerometer_moo(AccelHandle *accel) +{ switch ( accel->type ) { case ACCEL_UNKNOWN : { return 0; @@ -209,30 +287,30 @@ int accelerometer_moo(AccelHandle *accel) { } /* The accelerometer work thread */ -static void *accel_work(void *data) { - +static void *accel_work(void *data) +{ AccelHandle *accel; int *finished = data; - + accel = accelerometer_open(); audio_setup(); - + while ( !(*finished) ) { - + if (accelerometer_moo(accel)) audio_trigger_moo(); - + usleep(25000); - + } - + + accelerometer_shutdown(accel); audio_shutdown(); - - return NULL; + return NULL; } -GThread *accelerometer_start(int *finished) { - return g_thread_create(accel_work, finished, TRUE, NULL); +GThread *accelerometer_start(int *finished) +{ + return g_thread_create(accel_work, finished, TRUE, NULL); } - diff --git a/src/types.h b/src/types.h index 7870081..8dce08e 100644 --- a/src/types.h +++ b/src/types.h @@ -40,20 +40,21 @@ typedef enum { typedef struct { int fd; - + AccelType type; - + int x; int y; int z; - + /* Temporary values for use during reading */ int lx; int ly; int lz; - + /* Current state (driver dependent) */ int state; + signed int old_threshold; } AccelHandle; @@ -62,17 +63,16 @@ typedef struct { long moo_len; long moo_pos; Sint16 *moo_buf; - + unsigned int mootex; - + } AudioContext; typedef struct { GtkWidget *window; GtkWidget *cow; - + } MainWindow; #endif /* TYPES_H */ - |