Hi Thomas, Am Donnerstag, den 27.11.2008, 22:09 +0000 schrieb Thomas White: > > It now moos when tilting your laptop 90° away from to or towards you > > (and again when you tilt it upright, due to the latest change). > > Hmmm...mooing when tilted either way makes more sense for something > like a phone than for a laptop. If you decide this doesn't feel > right, feel free to revert this when using the Thinkpad "driver" (not > that you need any permission for that, of course). When you're happy > with the Thinkpad support, could you send me a patch to for the next > version? (If a new version is ever necessary...).
I took this as an encouragement to hack slightly on your code, so I did a slightly larger modification. The diff is here: http://git.debian.org/?p=pkg-fso/openmoocow.git;a=commitdiff;h=6c2116a1df2bb5ff54754f87fc8eb216fe355dd2 And the patch comment is “Slight refactorization: The decision, whether a moo should happen, is moved to the driver-specific code (because it knows best what kind of device to expect). A member “state” is added to the accel struct which can be used to implement a state machine inside the driver (as was done before with pos).” One could probably change the -1000 and 1000 values in the freerunner driver now to 0 and 1, to indicate the two states (upside down or not), but I didn’t want to be too intrusive :-) I have attached the complete diff against your release. Greetings, Joachim -- Joachim "nomeata" Breitner Debian Developer [EMAIL PROTECTED] | ICQ# 74513189 | GPG-Keyid: 4743206C JID: [EMAIL PROTECTED] | http://people.debian.org/~nomeata
diff --git a/src/accelerometers.c b/src/accelerometers.c
index 61118fc..b1deb7c 100644
--- a/src/accelerometers.c
+++ b/src/accelerometers.c
@@ -45,6 +45,7 @@ struct input_event {
};
#define EV_SYN (0x00)
#define EV_REL (0x02)
+#define EV_ABS (0x03)
#define SYN_REPORT (0x00)
#define REL_X (0x00)
#define REL_Y (0x01)
@@ -63,9 +64,17 @@ AccelHandle *accelerometer_open() {
accel->lx = 0;
accel->ly = 0;
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 ) {
+ accel->type = ACCEL_HDAPS;
+ printf("ThinkPad HDAPS detected\n");
+ return accel;
+ }
+
accel->fd = open("/dev/input/event3", O_RDONLY, O_NONBLOCK);
if ( accel->fd != -1 ) {
accel->type = ACCEL_FREERUNNER;
@@ -80,7 +89,48 @@ AccelHandle *accelerometer_open() {
}
-void accelerometer_update_freerunner(AccelHandle *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");
+ return 0;
+ }
+ if (ev.type == EV_ABS && ev.code == REL_Y) {
+ if (accel->state == 0 && abs(ev.value)>100) {
+ // Laptop tilted far enough
+ accel->state=1;
+ return 0;
+ }
+
+ if (accel->state == 1 && abs(ev.value)<70) {
+ // Laptop tilted back, play sound
+ accel->state=2;
+ return 1;
+ }
+
+ if (accel->state == 2 && abs(ev.value)<20) {
+ // Laptop almost at center, enable another round
+ accel->state=0;
+ return 0;
+ }
+ }
+
+ 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_ABS ? "ABS" : "Other" ,
+ ev.code, ev.value);
+ */
+}
+
+int accelerometer_moo_freerunner(AccelHandle *accel) {
struct input_event ev;
size_t rval;
@@ -88,7 +138,7 @@ void accelerometer_update_freerunner(AccelHandle *accel) {
rval = read(accel->fd, &ev, sizeof(ev));
if ( rval != sizeof(ev) ) {
fprintf(stderr, "Couldn't read accelerometer data");
- return;
+ return 0;
}
if ( ev.type == EV_REL ) {
@@ -111,23 +161,35 @@ void accelerometer_update_freerunner(AccelHandle *accel) {
}
}
+ if ( (accel->y < -500) && (accel->state > -1000) ) {
+ accel->state = -1000;
+ return 1;
+ }
+
+ if ( (accel->y > 500) && (accel->state < 1000) ) {
+ accel->state = 1000;
+ return 1;
+ }
+
+ return 0;
}
-void accelerometer_update(AccelHandle *accel) {
+int accelerometer_moo(AccelHandle *accel) {
switch ( accel->type ) {
case ACCEL_UNKNOWN : {
- return;
+ return 0;
}
case ACCEL_FREERUNNER : {
- accelerometer_update_freerunner(accel);
- break;
+ return accelerometer_moo_freerunner(accel);
+ }
+ case ACCEL_HDAPS : {
+ return accelerometer_moo_hdaps(accel);
}
- /* Add other types here. You simply need to provide the "y"
- * component of acceleration in milli-g in the relevant
- * structure. */
+ /* Add other types here. */
}
+ return 0;
}
/* The accelerometer work thread */
@@ -135,22 +197,14 @@ 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;
+ if (accelerometer_moo(accel))
audio_trigger_moo();
- }
usleep(25000);
diff --git a/src/types.h b/src/types.h
index b864742..cc7a227 100644
--- a/src/types.h
+++ b/src/types.h
@@ -33,6 +33,7 @@
typedef enum {
ACCEL_UNKNOWN,
ACCEL_FREERUNNER, /* Openmoko Neo Freerunner */
+ ACCEL_HDAPS, /* Thinkpad HDAPS */
} AccelType;
typedef struct {
@@ -49,6 +50,9 @@ typedef struct {
int lx;
int ly;
int lz;
+
+ /* Current state (driver dependent) */
+ int state;
} AccelHandle;
signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil
_______________________________________________ Openmoko community mailing list [email protected] http://lists.openmoko.org/mailman/listinfo/community

