/* * accelerometers.c * * Accelerometer stuff * * (c) 2008 Thomas White * * This file is part of OpenMooCow - accelerometer moobox simulator * * OpenMooCow is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenMooCow is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenMooCow. If not, see . * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include "types.h" #include "audio.h" struct input_event { struct timeval time; uint16_t type; uint16_t code; int32_t value; }; #define EV_SYN (0x00) #define EV_REL (0x02) #define SYN_REPORT (0x00) #define REL_X (0x00) #define REL_Y (0x01) #define REL_Z (0x02) AccelHandle *accelerometer_open() { AccelHandle *accel; /* Initialise accelerometer data structure */ accel = malloc(sizeof(AccelHandle)); if ( accel == NULL ) return NULL; accel->x = 0; accel->y = 0; accel->z = 0; accel->lx = 0; accel->ly = 0; accel->lz = 0; accel->type = ACCEL_UNKNOWN; /* Determine accelerometer type */ accel->fd = open("/dev/input/event3", O_RDONLY, 0); if ( accel->fd != -1 ) { accel->type = ACCEL_FREERUNNER; printf("Neo Freerunner detected\n"); return accel; } /* Try other types here */ fprintf(stderr, "Couldn't determine accelerometer type\n"); return accel; } double utils_highresms() { struct timeval tv; suseconds_t us; time_t sec; gettimeofday(&tv, NULL); us = tv.tv_usec; sec = tv.tv_sec; return ((double)us+1000000.0*sec)/1000.0; } void accelerometer_update_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; } } else { return; /* No data */ } if ( ev.type == EV_REL ) { if ( ev.code == REL_X ) { accel->lx = ev.value; } if ( ev.code == REL_Y ) { accel->ly = ev.value; } if ( ev.code == REL_Z ) { accel->lz = ev.value; } } if ( ev.type == EV_SYN ) { if ( ev.code == SYN_REPORT ) { accel->x = accel->lx; accel->y = accel->ly; accel->z = accel->lz; } } } void accelerometer_update(AccelHandle *accel) { switch ( accel->type ) { case ACCEL_UNKNOWN : { return; } case ACCEL_FREERUNNER : { accelerometer_update_freerunner(accel); break; } /* Add other types here. You simply need to provide the "y" * component of acceleration in milli-g in the relevant * structure. */ } } /* The accelerometer work thread */ static void *accel_work(void *data) { AccelHandle *accel; int *finished = data; int pos = 0; accel = accelerometer_open(); audio_setup(); while ( !(*finished) ) { accelerometer_update(accel); if ( (accel->y < -500) && (pos > -1000) ) { pos = -1000; audio_trigger_moo(); } else if ( (accel->y > 500) && (pos < 1000) ) { pos = 1000; audio_trigger_moo(); } usleep(25000); } audio_shutdown(); return NULL; } GThread *accelerometer_start(int *finished) { return g_thread_create(accel_work, finished, TRUE, NULL); }