1 /*
2  * Copyright (C) 2015 Intel Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <cutils/log.h>
18 #include "LSM303dAccelerometer.hpp"
19 #include "SensorsHAL.hpp"
20 #include "SensorUtils.hpp"
21 
22 struct sensor_t LSM303dAccelerometer::sensorDescription = {
23   .name = "LSM303d Accelerometer",
24   .vendor = "Unknown",
25   .version = 1,
26   .handle = -1,
27   .type = SENSOR_TYPE_ACCELEROMETER,
28   .maxRange = 16.0f,
29   .resolution = 0.00003f,
30   .power = 0.0003f,
31   .minDelay = 0,
32   .fifoReservedEventCount = 0,
33   .fifoMaxEventCount = 0,
34   .stringType = SENSOR_STRING_TYPE_ACCELEROMETER,
35   .requiredPermission = "",
36   .maxDelay = 0,
37   .flags = SENSOR_FLAG_CONTINUOUS_MODE,
38   .reserved = {},
39 };
40 
createSensor(int pollFd)41 Sensor * LSM303dAccelerometer::createSensor(int pollFd) {
42   return new LSM303dAccelerometer(pollFd, SensorUtils::getI2cBusNumber());
43 }
44 
initModule()45 void LSM303dAccelerometer::initModule() {
46   SensorContext::addSensorModule(&sensorDescription, createSensor);
47 }
48 
LSM303dAccelerometer(int pollFd,int bus,int address,int scale)49 LSM303dAccelerometer::LSM303dAccelerometer(int pollFd,
50     int bus, int address, int scale)
51     : LSM303d(bus, address, scale), pollFd(pollFd), scale(scale) {
52   this->type = SENSOR_TYPE_ACCELEROMETER;
53   this->handle = sensorDescription.handle;
54 }
55 
~LSM303dAccelerometer()56 LSM303dAccelerometer::~LSM303dAccelerometer() {}
57 
58 /*
59  * The raw data from the X,Y,Z axis are expressed in a 16 bit two's complement
60  * format.
61  *   1. We divide the 16bit value by (2**15) to convert it to floating point +-[0..1]
62  *   2. We multiply by the scaling factor to adjust for max range (2,4,6,8,16 G)
63  *   3. We multiply by the gravitational accelleration to convert from "g" to m/s**2
64  */
pollEvents(sensors_event_t * data,int count)65 int LSM303dAccelerometer::pollEvents(sensors_event_t* data, int count) {
66   getAcceleration();
67   int16_t *rawdatap = getRawAccelData();
68   double conversion_constant = (double)scale * (double)Sensor::kGravitationalAcceleration / pow(2,15);
69   data->acceleration.x = (double)rawdatap[0] * conversion_constant;
70   data->acceleration.y = (double)rawdatap[1] * conversion_constant;
71   data->acceleration.z = (double)rawdatap[2] * conversion_constant;
72   return 1;
73 }
74 
activate(int handle,int enabled)75 int LSM303dAccelerometer::activate(int handle, int enabled) {
76   /* start or stop the acquisition thread */
77   return activateAcquisitionThread(pollFd, handle, enabled);
78 }
79