aboutsummaryrefslogtreecommitdiff
path: root/src/accelerometers.c
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 /src/accelerometers.c
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>
Diffstat (limited to 'src/accelerometers.c')
-rw-r--r--src/accelerometers.c144
1 files changed, 111 insertions, 33 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);
}
-