aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 */
-