BMA250
authorPaul Kocialkowski <contact@paulk.fr>
Thu, 21 Feb 2013 17:48:15 +0000 (18:48 +0100)
committerPaul Kocialkowski <contact@paulk.fr>
Thu, 21 Feb 2013 17:48:15 +0000 (18:48 +0100)
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
Android.mk
bh1721.c
bma250.c [new file with mode: 0644]
input.c
piranha_sensors.c
piranha_sensors.h

index bafe58c..36b7638 100644 (file)
@@ -22,6 +22,7 @@ include $(CLEAR_VARS)
 LOCAL_SRC_FILES := \
        piranha_sensors.c \
        input.c \
+       bma250.c \
        bh1721.c
 
 LOCAL_SHARED_LIBRARIES := libutils libcutils liblog libhardware
index d7fec25..256c514 100644 (file)
--- a/bh1721.c
+++ b/bh1721.c
@@ -167,7 +167,7 @@ int bh1721_set_delay(struct piranha_sensors_handlers *handlers, int64_t delay)
        int c;
        int fd;
 
-       LOGD("%s(%p, %ld)", __func__, handlers, (long int) delay);
+//     LOGD("%s(%p, %ld)", __func__, handlers, (long int) delay);
 
        if (handlers == NULL || handlers->data == NULL)
                return -EINVAL;
diff --git a/bma250.c b/bma250.c
new file mode 100644 (file)
index 0000000..f35dc2e
--- /dev/null
+++ b/bma250.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2013 Paul Kocialkowski
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <linux/ioctl.h>
+#include <linux/input.h>
+
+#include <hardware/sensors.h>
+#include <hardware/hardware.h>
+
+#define LOG_TAG "piranha_sensors"
+#include <utils/Log.h>
+
+#include "piranha_sensors.h"
+
+#define FLAG_X         (1 << 0)
+#define FLAG_Y         (1 << 1)
+#define FLAG_Z         (1 << 2)
+#define FLAG_ALL       (FLAG_X | FLAG_Y | FLAG_Z)
+
+struct bma250_data {
+       char path_enable[PATH_MAX];
+       char path_delay[PATH_MAX];
+
+       sensors_vec_t acceleration;
+};
+
+int bma250_init(struct piranha_sensors_handlers *handlers)
+{
+       struct bma250_data *data = NULL;
+       char path[PATH_MAX] = { 0 };
+       int input_fd = -1;
+       int rc;
+
+       LOGD("%s(%p)", __func__, handlers);
+
+       if (handlers == NULL)
+               return -EINVAL;
+
+       input_fd = input_open("accelerometer");
+       if (input_fd < 0) {
+               LOGE("%s: Unable to open input", __func__);
+               goto error;
+       }
+
+       rc = sysfs_path_prefix("accelerometer", (char *) &path);
+       if (rc < 0 || path[0] == '\0') {
+               LOGE("%s: Unable to open sysfs", __func__);
+               goto error;
+       }
+
+       data = (struct bma250_data *) calloc(1, sizeof(struct bma250_data));
+
+       snprintf(data->path_enable, PATH_MAX, "%s/enable", path);
+       snprintf(data->path_delay, PATH_MAX, "%s/delay", path);
+
+       handlers->poll_fd = input_fd;
+       handlers->data = (void *) data;
+
+       return 0;
+
+error:
+       if (input_fd >= 0)
+               close(input_fd);
+
+       if (data != NULL)
+               free(data);
+
+       handlers->poll_fd = -1;
+       handlers->data = NULL;
+
+       return -1;
+}
+
+int bma250_deinit(struct piranha_sensors_handlers *handlers)
+{
+       int input_fd;
+
+       LOGD("%s(%p)", __func__, handlers);
+
+       if (handlers == NULL)
+               return -EINVAL;
+
+       input_fd = handlers->poll_fd;
+       if (input_fd >= 0)
+               close(input_fd);
+
+       handlers->poll_fd = -1;
+
+       if (handlers->data != NULL)
+               free(handlers->data);
+
+       handlers->data = NULL;
+
+       return 0;
+}
+
+int bma250_activate(struct piranha_sensors_handlers *handlers)
+{
+       struct bma250_data *data;
+       char enable[] = "1\n";
+       int fd;
+
+       LOGD("%s(%p)", __func__, handlers);
+
+       if (handlers == NULL || handlers->data == NULL)
+               return -EINVAL;
+
+       data = (struct bma250_data *) handlers->data;
+
+       fd = open(data->path_enable, O_WRONLY);
+       if (fd < 0) {
+               LOGE("%s: Unable to open enable path", __func__);
+               return -1;
+       }
+
+       write(fd, &enable, sizeof(enable));
+       close(fd);
+
+       handlers->activated = 1;
+
+       return 0;
+}
+
+int bma250_deactivate(struct piranha_sensors_handlers *handlers)
+{
+       struct bma250_data *data;
+       char enable[] = "0\n";
+       int fd;
+
+       LOGD("%s(%p)", __func__, handlers);
+
+       if (handlers == NULL || handlers->data == NULL)
+               return -EINVAL;
+
+       data = (struct bma250_data *) handlers->data;
+
+       fd = open(data->path_enable, O_WRONLY);
+       if (fd < 0) {
+               LOGE("%s: Unable to open enable path", __func__);
+               return -1;
+       }
+
+       write(fd, &enable, sizeof(enable));
+       close(fd);
+
+       handlers->activated = 0;
+
+       return 0;
+}
+
+int bma250_set_delay(struct piranha_sensors_handlers *handlers, int64_t delay)
+{
+       struct bma250_data *data;
+       char *value = NULL;
+       int d;
+       int c;
+       int fd;
+
+//     LOGD("%s(%p, %ld)", __func__, handlers, (long int) delay);
+
+       if (handlers == NULL || handlers->data == NULL)
+               return -EINVAL;
+
+       data = (struct bma250_data *) handlers->data;
+
+       fd = open(data->path_delay, O_WRONLY);
+       if (fd < 0) {
+               LOGE("%s: Unable to open delay path", __func__);
+               return -1;
+       }
+
+       if (delay < 1000000)
+               d = 0;
+       else
+               d = (int) (delay / 1000000);
+
+       c = asprintf(&value, "%d\n", d);
+
+       write(fd, value, c);
+       close(fd);
+
+       if (value != NULL)
+               free(value);
+
+       return 0;
+}
+
+float bma250_acceleration(int value)
+{
+       return (float) (value * GRAVITY_EARTH) / 256.0f;
+}
+
+int bma250_get_data(struct piranha_sensors_handlers *handlers,
+       struct sensors_event_t *event)
+{
+       struct bma250_data *data;
+       struct input_event input_event;
+       int input_fd;
+       int flag;
+       int rc;
+
+       if (handlers == NULL || handlers->data == NULL || event == NULL)
+               return -EINVAL;
+
+       data = (struct bma250_data *) handlers->data;
+
+       input_fd = handlers->poll_fd;
+       if (input_fd < 0)
+               return -EINVAL;
+
+       event->version = sizeof(struct sensors_event_t);
+       event->sensor = handlers->handle;
+       event->type = handlers->handle;
+
+       event->acceleration.x = data->acceleration.x;
+       event->acceleration.y = data->acceleration.y;
+       event->acceleration.z = data->acceleration.z;
+
+       flag = 0;
+       while ((flag & FLAG_ALL) != FLAG_ALL) {
+               rc = read(input_fd, &input_event, sizeof(input_event));
+               if (rc < (int) sizeof(input_event)) {
+                       if (flag & FLAG_ALL)
+                               break;
+                       else
+                               return -EINVAL;
+               }
+
+               if (input_event.type != EV_ABS)
+                       continue;
+
+               switch (input_event.code) {
+                       case ABS_X:
+                               flag |= FLAG_X;
+                               event->acceleration.x = bma250_acceleration(input_event.value);
+                               break;
+                       case ABS_Y:
+                               flag |= FLAG_Y;
+                               event->acceleration.y = bma250_acceleration(input_event.value);
+                               break;
+                       case ABS_Z:
+                               flag |= FLAG_Z;
+                               event->acceleration.z = bma250_acceleration(input_event.value);
+                               break;
+                       default:
+                               continue;
+               }
+               event->timestamp = input_timestamp(&input_event);
+       }
+
+       if (data->acceleration.x != event->acceleration.x)
+               data->acceleration.x = event->acceleration.x;
+       if (data->acceleration.y != event->acceleration.y)
+               data->acceleration.y = event->acceleration.y;
+       if (data->acceleration.z != event->acceleration.z)
+               data->acceleration.z = event->acceleration.z;
+
+       return 0;
+}
+
+struct piranha_sensors_handlers bma250 = {
+       .name = "BMA250",
+       .handle = SENSOR_TYPE_ACCELEROMETER,
+       .init = bma250_init,
+       .deinit = bma250_deinit,
+       .activate = bma250_activate,
+       .deactivate = bma250_deactivate,
+       .set_delay = bma250_set_delay,
+       .get_data = bma250_get_data,
+       .activated = 0,
+       .poll_fd = -1,
+       .data = NULL,
+};
diff --git a/input.c b/input.c
index 811c106..b871da9 100644 (file)
--- a/input.c
+++ b/input.c
@@ -59,7 +59,7 @@ int input_open(char *name)
                        continue;
 
                snprintf(path, PATH_MAX, "/dev/input/%s", di->d_name);
-               fd = open(path, O_RDONLY);
+               fd = open(path, O_RDONLY | O_NONBLOCK);
                if (fd < 0)
                        continue;
 
index 0d21a0c..4f86537 100644 (file)
@@ -46,6 +46,7 @@ struct sensor_t piranha_sensors[] = {
 int piranha_sensors_count = sizeof(piranha_sensors) / sizeof(struct sensor_t);
 
 struct piranha_sensors_handlers *piranha_sensors_handlers[] = {
+       &bma250,
        &bh1721,
 };
 
index 38478c6..bd41872 100644 (file)
@@ -64,6 +64,7 @@ int sysfs_path_prefix(char *name, char *path_prefix);
  * Sensors
  */
 
+extern struct piranha_sensors_handlers bma250;
 extern struct piranha_sensors_handlers bh1721;
 
 #endif