aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw27@cam.ac.uk>2008-12-18 21:07:33 +0000
committerThomas White <taw27@cam.ac.uk>2008-12-18 21:09:46 +0000
commita1eaaf9abc872adc2485a2d93c653ee5c9ae3276 (patch)
tree53ac958b3a4f6fe50ac73f458b335b71c8c467fb
parent8b0f6945202ea891b87873688dbf9b4990cac44b (diff)
Disable Freerunner accelerometer threshold while running
This sets the accelerometer threshold value to zero, making the cow much more responsive. It gets reset to its original value afterwards, but only if it hasn't changed from zero meanwhile. Signed-off-by: Thomas White <taw27@cam.ac.uk>
-rw-r--r--src/accelerometers.c144
-rw-r--r--src/types.h16
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 */
-