MPLSensor.cpp revision f92a8fa0b3caa9e6a1363b485c392adee3f5aa81
1/*
2 * Copyright (C) 2011 Invensense, Inc.
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//#define LOG_NDEBUG 0
18//see also the EXTRA_VERBOSE define, below
19
20#include <fcntl.h>
21#include <errno.h>
22#include <math.h>
23#include <float.h>
24#include <poll.h>
25#include <unistd.h>
26#include <dirent.h>
27#include <stdlib.h>
28#include <sys/select.h>
29#include <dlfcn.h>
30#include <pthread.h>
31
32#include <cutils/log.h>
33#include <utils/KeyedVector.h>
34
35#include "MPLSensor.h"
36
37#include "math.h"
38#include "ml.h"
39#include "mlFIFO.h"
40#include "mlsl.h"
41#include "mlos.h"
42#include "ml_mputest.h"
43#include "ml_stored_data.h"
44#include "mldl_cfg.h"
45#include "mldl.h"
46
47#include "mpu.h"
48#include "accel.h"
49#include "compass.h"
50#include "kernel/timerirq.h"
51#include "kernel/mpuirq.h"
52#include "kernel/slaveirq.h"
53
54extern "C" {
55#include "mlsupervisor.h"
56}
57
58#include "mlcontrol.h"
59#include "sensor_params.h"
60
61#define EXTRA_VERBOSE (0)
62//#define FUNC_LOG ALOGV("%s", __PRETTY_FUNCTION__)
63#define FUNC_LOG
64#define VFUNC_LOG ALOGV_IF(EXTRA_VERBOSE, "%s", __PRETTY_FUNCTION__)
65/* this mask must turn on only the sensors that are present and managed by the MPL */
66#define ALL_MPL_SENSORS_NP (INV_THREE_AXIS_ACCEL | INV_THREE_AXIS_COMPASS | INV_THREE_AXIS_GYRO)
67
68#define CALL_MEMBER_FN(pobject,ptrToMember)  ((pobject)->*(ptrToMember))
69
70/******************************************/
71
72/* Base values for the sensor list, these need to be in the order defined in MPLSensor.h */
73static struct sensor_t sSensorList[] =
74    { { "MPL Gyroscope", "Invensense", 1,
75         SENSORS_GYROSCOPE_HANDLE,
76         SENSOR_TYPE_GYROSCOPE, 2000.0f, 1.0f, 0.5f, 10000, 0, 0, { } },
77      { "MPL Accelerometer", "Invensense", 1,
78         SENSORS_ACCELERATION_HANDLE,
79         SENSOR_TYPE_ACCELEROMETER, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, { } },
80      { "MPL Magnetic Field", "Invensense", 1,
81         SENSORS_MAGNETIC_FIELD_HANDLE,
82         SENSOR_TYPE_MAGNETIC_FIELD, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, { } },
83      { "MPL Orientation", "Invensense", 1,
84         SENSORS_ORIENTATION_HANDLE,
85         SENSOR_TYPE_ORIENTATION, 360.0f, 1.0f, 9.7f, 10000, 0, 0, { } },
86      { "MPL Rotation Vector", "Invensense", 1,
87         SENSORS_ROTATION_VECTOR_HANDLE,
88         SENSOR_TYPE_ROTATION_VECTOR, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, { } },
89      { "MPL Linear Acceleration", "Invensense", 1,
90         SENSORS_LINEAR_ACCEL_HANDLE,
91         SENSOR_TYPE_LINEAR_ACCELERATION, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, { } },
92      { "MPL Gravity", "Invensense", 1,
93         SENSORS_GRAVITY_HANDLE,
94         SENSOR_TYPE_GRAVITY, 10240.0f, 1.0f, 0.5f, 10000, 0, 0, { } },
95};
96
97static unsigned long long irq_timestamp = 0;
98/* ***************************************************************************
99 * MPL interface misc.
100 */
101//static pointer to the object that will handle callbacks
102static MPLSensor* gMPLSensor = NULL;
103
104/* we need to pass some callbacks to the MPL.  The mpl is a C library, so
105 * wrappers for the C++ callback implementations are required.
106 */
107extern "C" {
108//callback wrappers go here
109void mot_cb_wrapper(uint16_t val)
110{
111    if (gMPLSensor) {
112        gMPLSensor->cbOnMotion(val);
113    }
114}
115
116void procData_cb_wrapper()
117{
118    if(gMPLSensor) {
119        gMPLSensor->cbProcData();
120    }
121}
122
123} //end of extern C
124
125void setCallbackObject(MPLSensor* gbpt)
126{
127    gMPLSensor = gbpt;
128}
129
130
131/*****************************************************************************
132 * sensor class implementation
133 */
134
135#define GY_ENABLED ((1<<ID_GY) & enabled_sensors)
136#define A_ENABLED  ((1<<ID_A)  & enabled_sensors)
137#define O_ENABLED  ((1<<ID_O)  & enabled_sensors)
138#define M_ENABLED  ((1<<ID_M)  & enabled_sensors)
139#define LA_ENABLED ((1<<ID_LA) & enabled_sensors)
140#define GR_ENABLED ((1<<ID_GR) & enabled_sensors)
141#define RV_ENABLED ((1<<ID_RV) & enabled_sensors)
142
143MPLSensor::MPLSensor() :
144    SensorBase(NULL, NULL),
145            mNewData(0),
146            mDmpStarted(false),
147            mMasterSensorMask(INV_ALL_SENSORS),
148            mLocalSensorMask(ALL_MPL_SENSORS_NP), mPollTime(-1),
149            mCurFifoRate(-1), mHaveGoodMpuCal(false), mHaveGoodCompassCal(false),
150            mUseTimerIrqAccel(false), mUsetimerIrqCompass(true),
151            mUseTimerirq(false), mSampleCount(0),
152            mEnabled(0), mPendingMask(0)
153{
154    FUNC_LOG;
155    inv_error_t rv;
156    int mpu_int_fd, i;
157    char *port = NULL;
158
159    ALOGV_IF(EXTRA_VERBOSE, "MPLSensor constructor: numSensors = %d", numSensors);
160
161    pthread_mutex_init(&mMplMutex, NULL);
162
163    mForceSleep = false;
164
165    /* used for identifying whether 9axis is enabled or not             */
166    /* this variable will be changed in initMPL() when libmpl is loaded */
167    /* sensor list will be changed based on this variable               */
168    mNineAxisEnabled = false;
169
170    for (i = 0; i < ARRAY_SIZE(mPollFds); i++) {
171        mPollFds[i].fd = -1;
172        mPollFds[i].events = 0;
173    }
174
175    pthread_mutex_lock(&mMplMutex);
176
177    mpu_int_fd = open("/dev/mpuirq", O_RDWR);
178    if (mpu_int_fd == -1) {
179        ALOGE("could not open the mpu irq device node");
180    } else {
181        fcntl(mpu_int_fd, F_SETFL, O_NONBLOCK);
182        //ioctl(mpu_int_fd, MPUIRQ_SET_TIMEOUT, 0);
183        mIrqFds.add(MPUIRQ_FD, mpu_int_fd);
184        mPollFds[MPUIRQ_FD].fd = mpu_int_fd;
185        mPollFds[MPUIRQ_FD].events = POLLIN;
186    }
187
188    accel_fd = open("/dev/accelirq", O_RDWR);
189    if (accel_fd == -1) {
190        ALOGE("could not open the accel irq device node");
191    } else {
192        fcntl(accel_fd, F_SETFL, O_NONBLOCK);
193        //ioctl(accel_fd, SLAVEIRQ_SET_TIMEOUT, 0);
194        mIrqFds.add(ACCELIRQ_FD, accel_fd);
195        mPollFds[ACCELIRQ_FD].fd = accel_fd;
196        mPollFds[ACCELIRQ_FD].events = POLLIN;
197    }
198
199    timer_fd = open("/dev/timerirq", O_RDWR);
200    if (timer_fd == -1) {
201        ALOGE("could not open the timer irq device node");
202    } else {
203        fcntl(timer_fd, F_SETFL, O_NONBLOCK);
204        //ioctl(timer_fd, TIMERIRQ_SET_TIMEOUT, 0);
205        mIrqFds.add(TIMERIRQ_FD, timer_fd);
206        mPollFds[TIMERIRQ_FD].fd = timer_fd;
207        mPollFds[TIMERIRQ_FD].events = POLLIN;
208    }
209
210    data_fd = mpu_int_fd;
211
212    if ((accel_fd == -1) && (timer_fd != -1)) {
213        //no accel irq and timer available
214        mUseTimerIrqAccel = true;
215        //ALOGD("MPLSensor falling back to timerirq for accel data");
216    }
217
218    memset(mPendingEvents, 0, sizeof(mPendingEvents));
219
220    mPendingEvents[RotationVector].version = sizeof(sensors_event_t);
221    mPendingEvents[RotationVector].sensor = ID_RV;
222    mPendingEvents[RotationVector].type = SENSOR_TYPE_ROTATION_VECTOR;
223
224    mPendingEvents[LinearAccel].version = sizeof(sensors_event_t);
225    mPendingEvents[LinearAccel].sensor = ID_LA;
226    mPendingEvents[LinearAccel].type = SENSOR_TYPE_LINEAR_ACCELERATION;
227
228    mPendingEvents[Gravity].version = sizeof(sensors_event_t);
229    mPendingEvents[Gravity].sensor = ID_GR;
230    mPendingEvents[Gravity].type = SENSOR_TYPE_GRAVITY;
231
232    mPendingEvents[Gyro].version = sizeof(sensors_event_t);
233    mPendingEvents[Gyro].sensor = ID_GY;
234    mPendingEvents[Gyro].type = SENSOR_TYPE_GYROSCOPE;
235
236    mPendingEvents[Accelerometer].version = sizeof(sensors_event_t);
237    mPendingEvents[Accelerometer].sensor = ID_A;
238    mPendingEvents[Accelerometer].type = SENSOR_TYPE_ACCELEROMETER;
239
240    mPendingEvents[MagneticField].version = sizeof(sensors_event_t);
241    mPendingEvents[MagneticField].sensor = ID_M;
242    mPendingEvents[MagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD;
243    mPendingEvents[MagneticField].magnetic.status = SENSOR_STATUS_ACCURACY_HIGH;
244
245    mPendingEvents[Orientation].version = sizeof(sensors_event_t);
246    mPendingEvents[Orientation].sensor = ID_O;
247    mPendingEvents[Orientation].type = SENSOR_TYPE_ORIENTATION;
248    mPendingEvents[Orientation].orientation.status
249            = SENSOR_STATUS_ACCURACY_HIGH;
250
251    mHandlers[RotationVector] = &MPLSensor::rvHandler;
252    mHandlers[LinearAccel] = &MPLSensor::laHandler;
253    mHandlers[Gravity] = &MPLSensor::gravHandler;
254    mHandlers[Gyro] = &MPLSensor::gyroHandler;
255    mHandlers[Accelerometer] = &MPLSensor::accelHandler;
256    mHandlers[MagneticField] = &MPLSensor::compassHandler;
257    mHandlers[Orientation] = &MPLSensor::orienHandler;
258
259    for (int i = 0; i < numSensors; i++)
260        mDelays[i] = 30000000LLU; // 30 ms by default
261
262    if (inv_serial_start(port) != INV_SUCCESS) {
263        ALOGE("Fatal Error : could not open MPL serial interface");
264    }
265
266    //initialize library parameters
267    initMPL();
268
269    //setup the FIFO contents
270    setupFIFO();
271
272    //we start the motion processing only when a sensor is enabled...
273    //rv = inv_dmp_start();
274    //ALOGE_IF(rv != INV_SUCCESS, "Fatal error: could not start the DMP correctly. (code = %d)\n", rv);
275    //dmp_started = true;
276
277    pthread_mutex_unlock(&mMplMutex);
278
279}
280
281MPLSensor::~MPLSensor()
282{
283    FUNC_LOG;
284    pthread_mutex_lock(&mMplMutex);
285    if (inv_dmp_stop() != INV_SUCCESS) {
286        ALOGW("Error: could not stop the DMP correctly.\n");
287    }
288
289    if (inv_dmp_close() != INV_SUCCESS) {
290        ALOGW("Error: could not close the DMP");
291    }
292
293    if (inv_serial_stop() != INV_SUCCESS) {
294        ALOGW("Error : could not close the serial port");
295    }
296    pthread_mutex_unlock(&mMplMutex);
297    pthread_mutex_destroy(&mMplMutex);
298}
299
300/* clear any data from our various filehandles */
301void MPLSensor::clearIrqData(bool* irq_set)
302{
303    unsigned int i;
304    int nread;
305    struct mpuirq_data irqdata;
306
307    poll(mPollFds, ARRAY_SIZE(mPollFds), 0); //check which ones need to be cleared
308
309    for (i = 0; i < ARRAY_SIZE(mPollFds); i++) {
310        int cur_fd = mPollFds[i].fd;
311        int j = 0;
312        if (mPollFds[i].revents & POLLIN) {
313            nread = read(cur_fd, &irqdata, sizeof(irqdata));
314            if (nread > 0) {
315                irq_set[i] = true;
316                irq_timestamp = irqdata.irqtime;
317                //ALOGV_IF(EXTRA_VERBOSE, "irq: %d %d (%d)", i, irqdata.interruptcount, j++);
318            }
319        }
320        mPollFds[i].revents = 0;
321    }
322}
323
324/* set the power states of the various sensors based on the bits set in the
325 * enabled_sensors parameter.
326 * this function modifies globalish state variables.  It must be called with the mMplMutex held. */
327void MPLSensor::setPowerStates(int enabled_sensors)
328{
329    FUNC_LOG;
330    bool irq_set[5] = { false, false, false, false, false };
331
332    //ALOGV(" setPowerStates: %d dmp_started: %d", enabled_sensors, mDmpStarted);
333
334    do {
335
336        if (LA_ENABLED || GR_ENABLED || RV_ENABLED || O_ENABLED) {
337            mLocalSensorMask = ALL_MPL_SENSORS_NP;
338            break;
339        }
340
341        if (!A_ENABLED && !M_ENABLED && !GY_ENABLED) {
342            mLocalSensorMask = 0;
343            break;
344        }
345
346        if (GY_ENABLED) {
347            mLocalSensorMask |= INV_THREE_AXIS_GYRO;
348        } else {
349            mLocalSensorMask &= ~INV_THREE_AXIS_GYRO;
350        }
351
352        if (A_ENABLED) {
353            mLocalSensorMask |= (INV_THREE_AXIS_ACCEL);
354        } else {
355            mLocalSensorMask &= ~(INV_THREE_AXIS_ACCEL);
356        }
357
358        if (M_ENABLED) {
359            mLocalSensorMask |= INV_THREE_AXIS_COMPASS;
360        } else {
361            mLocalSensorMask &= ~(INV_THREE_AXIS_COMPASS);
362        }
363
364    } while (0);
365
366    //record the new sensor state
367    inv_error_t rv;
368
369    long sen_mask = mLocalSensorMask & mMasterSensorMask;
370
371    bool changing_sensors = ((inv_get_dl_config()->requested_sensors
372            != sen_mask) && (sen_mask != 0));
373    bool restart = (!mDmpStarted) && (sen_mask != 0);
374
375    if (changing_sensors || restart) {
376
377        ALOGV_IF(EXTRA_VERBOSE, "cs:%d rs:%d ", changing_sensors, restart);
378
379        if (mDmpStarted) {
380            inv_dmp_stop();
381            clearIrqData(irq_set);
382            mDmpStarted = false;
383        }
384
385        if (sen_mask != inv_get_dl_config()->requested_sensors) {
386            //ALOGV("setPowerStates: %lx", sen_mask);
387            rv = inv_set_mpu_sensors(sen_mask);
388            ALOGE_IF(rv != INV_SUCCESS,
389                    "error: unable to set MPL sensor power states (sens=%ld retcode = %d)",
390                    sen_mask, rv);
391        }
392
393        if (((mUsetimerIrqCompass && (sen_mask == INV_THREE_AXIS_COMPASS))
394                || (mUseTimerIrqAccel && (sen_mask & INV_THREE_AXIS_ACCEL)))
395                && ((sen_mask & INV_DMP_PROCESSOR) == 0)) {
396            ALOGV_IF(EXTRA_VERBOSE, "Allowing TimerIRQ");
397            mUseTimerirq = true;
398        } else {
399            if (mUseTimerirq) {
400                ioctl(mIrqFds.valueFor(TIMERIRQ_FD), TIMERIRQ_STOP, 0);
401                clearIrqData(irq_set);
402            }
403            ALOGV_IF(EXTRA_VERBOSE, "Not allowing TimerIRQ");
404            mUseTimerirq = false;
405        }
406
407        if (!mDmpStarted) {
408            if (mHaveGoodMpuCal || mHaveGoodCompassCal) {
409                rv = inv_store_calibration();
410                ALOGE_IF(rv != INV_SUCCESS,
411                        "error: unable to store MPL calibration file");
412                mHaveGoodMpuCal = false;
413                mHaveGoodCompassCal = false;
414            }
415            //ALOGV("Starting DMP");
416            rv = inv_dmp_start();
417            ALOGE_IF(rv != INV_SUCCESS, "unable to start dmp");
418            mDmpStarted = true;
419        }
420    }
421
422    //check if we should stop the DMP
423    if (mDmpStarted && (sen_mask == 0)) {
424        //ALOGV("Stopping DMP");
425        rv = inv_dmp_stop();
426        ALOGE_IF(rv != INV_SUCCESS, "error: unable to stop DMP (retcode = %d)",
427                rv);
428        if (mUseTimerirq) {
429            ioctl(mIrqFds.valueFor(TIMERIRQ_FD), TIMERIRQ_STOP, 0);
430        }
431        clearIrqData(irq_set);
432
433        mDmpStarted = false;
434        mPollTime = -1;
435        mCurFifoRate = -1;
436    }
437
438}
439
440/**
441 * container function for all the calls we make once to set up the MPL.
442 */
443void MPLSensor::initMPL()
444{
445    FUNC_LOG;
446    inv_error_t result;
447    unsigned short bias_update_mask = 0xFFFF;
448    struct mldl_cfg *mldl_cfg;
449
450    if (inv_dmp_open() != INV_SUCCESS) {
451        ALOGE("Fatal Error : could not open DMP correctly.\n");
452    }
453
454    result = inv_set_mpu_sensors(ALL_MPL_SENSORS_NP); //default to all sensors, also makes 9axis enable work
455    ALOGE_IF(result != INV_SUCCESS,
456            "Fatal Error : could not set enabled sensors.");
457
458    if (inv_load_calibration() != INV_SUCCESS) {
459        ALOGE("could not open MPL calibration file");
460    }
461
462    //check for the 9axis fusion library: if available load it and start 9x
463    void* h_dmp_lib=dlopen("libinvensense_mpl.so", RTLD_NOW);
464    if(h_dmp_lib) {
465        const char* error;
466        error = dlerror();
467        inv_error_t (*fp_inv_enable_9x_fusion)() =
468              (inv_error_t(*)()) dlsym(h_dmp_lib, "inv_enable_9x_fusion");
469        if((error = dlerror()) != NULL) {
470            ALOGE("%s %s", error, "inv_enable_9x_fusion");
471        } else if ((*fp_inv_enable_9x_fusion)() != INV_SUCCESS) {
472            ALOGE( "Warning : 9 axis sensor fusion not available "
473                  "- No compass detected.\n");
474        } else {
475            /*  9axis is loaded and enabled                            */
476            /*  this variable is used for coming up with sensor list   */
477            mNineAxisEnabled = true;
478        }
479    } else {
480        const char* error = dlerror();
481        ALOGE("libinvensense_mpl.so not found, 9x sensor fusion disabled (%s)",error);
482    }
483
484    mldl_cfg = inv_get_dl_config();
485
486    if (inv_set_bias_update(bias_update_mask) != INV_SUCCESS) {
487        ALOGE("Error : Bias update function could not be set.\n");
488    }
489
490    if (inv_set_motion_interrupt(1) != INV_SUCCESS) {
491        ALOGE("Error : could not set motion interrupt");
492    }
493
494    if (inv_set_fifo_interrupt(1) != INV_SUCCESS) {
495        ALOGE("Error : could not set fifo interrupt");
496    }
497
498    result = inv_set_fifo_rate(6);
499    if (result != INV_SUCCESS) {
500        ALOGE("Fatal error: inv_set_fifo_rate returned %d\n", result);
501    }
502
503    setupCallbacks();
504
505}
506
507/** setup the fifo contents.
508 */
509void MPLSensor::setupFIFO()
510{
511    FUNC_LOG;
512    inv_error_t result;
513
514    result = inv_send_accel(INV_ALL, INV_32_BIT);
515    if (result != INV_SUCCESS) {
516        ALOGE("Fatal error: inv_send_accel returned %d\n", result);
517    }
518
519    result = inv_send_quaternion(INV_32_BIT);
520    if (result != INV_SUCCESS) {
521        ALOGE("Fatal error: inv_send_quaternion returned %d\n", result);
522    }
523
524    result = inv_send_linear_accel(INV_ALL, INV_32_BIT);
525    if (result != INV_SUCCESS) {
526        ALOGE("Fatal error: inv_send_linear_accel returned %d\n", result);
527    }
528
529    result = inv_send_linear_accel_in_world(INV_ALL, INV_32_BIT);
530    if (result != INV_SUCCESS) {
531        ALOGE("Fatal error: inv_send_linear_accel_in_world returned %d\n",
532             result);
533    }
534
535    result = inv_send_gravity(INV_ALL, INV_32_BIT);
536    if (result != INV_SUCCESS) {
537        ALOGE("Fatal error: inv_send_gravity returned %d\n", result);
538    }
539
540    result = inv_send_gyro(INV_ALL, INV_32_BIT);
541    if (result != INV_SUCCESS) {
542        ALOGE("Fatal error: inv_send_gyro returned %d\n", result);
543    }
544
545}
546
547/**
548 *  set up the callbacks that we use in all cases (outside of gestures, etc)
549 */
550void MPLSensor::setupCallbacks()
551{
552    FUNC_LOG;
553    if (inv_set_motion_callback(mot_cb_wrapper) != INV_SUCCESS) {
554        ALOGE("Error : Motion callback could not be set.\n");
555
556    }
557
558    if (inv_set_fifo_processed_callback(procData_cb_wrapper) != INV_SUCCESS) {
559        ALOGE("Error : Processed data callback could not be set.");
560
561    }
562}
563
564/**
565 * handle the motion/no motion output from the MPL.
566 */
567void MPLSensor::cbOnMotion(uint16_t val)
568{
569    FUNC_LOG;
570    //after the first no motion, the gyro should be calibrated well
571    if (val == 2) {
572        if ((inv_get_dl_config()->requested_sensors) & INV_THREE_AXIS_GYRO) {
573            //if gyros are on and we got a no motion, set a flag
574            // indicating that the cal file can be written.
575            mHaveGoodMpuCal = true;
576        }
577    }
578
579    return;
580}
581
582
583void MPLSensor::cbProcData()
584{
585    mNewData = 1;
586    mSampleCount++;
587    //ALOGV_IF(EXTRA_VERBOSE, "new data (%d)", sampleCount);
588}
589
590//these handlers transform mpl data into one of the Android sensor types
591//  scaling and coordinate transforms should be done in the handlers
592
593void MPLSensor::gyroHandler(sensors_event_t* s, uint32_t* pending_mask,
594                             int index)
595{
596    VFUNC_LOG;
597    inv_error_t res;
598    res = inv_get_float_array(INV_GYROS, s->gyro.v);
599    s->gyro.v[0] = s->gyro.v[0] * M_PI / 180.0;
600    s->gyro.v[1] = s->gyro.v[1] * M_PI / 180.0;
601    s->gyro.v[2] = s->gyro.v[2] * M_PI / 180.0;
602    if (res == INV_SUCCESS)
603        *pending_mask |= (1 << index);
604}
605
606void MPLSensor::accelHandler(sensors_event_t* s, uint32_t* pending_mask,
607                              int index)
608{
609    //VFUNC_LOG;
610    inv_error_t res;
611    res = inv_get_float_array(INV_ACCELS, s->acceleration.v);
612    //res = inv_get_accel_float(s->acceleration.v);
613    s->acceleration.v[0] = s->acceleration.v[0] * 9.81;
614    s->acceleration.v[1] = s->acceleration.v[1] * 9.81;
615    s->acceleration.v[2] = s->acceleration.v[2] * 9.81;
616    //ALOGV_IF(EXTRA_VERBOSE, "accel data: %f %f %f", s->acceleration.v[0], s->acceleration.v[1], s->acceleration.v[2]);
617    if (res == INV_SUCCESS)
618        *pending_mask |= (1 << index);
619}
620
621int MPLSensor::estimateCompassAccuracy()
622{
623    inv_error_t res;
624    int rv;
625
626    res = inv_get_compass_accuracy(&rv);
627    if(rv >= SENSOR_STATUS_ACCURACY_MEDIUM) {
628         mHaveGoodCompassCal = true;
629    }
630    ALOGE_IF(res != INV_SUCCESS, "error returned from inv_get_compass_accuracy");
631
632    return rv;
633}
634
635void MPLSensor::compassHandler(sensors_event_t* s, uint32_t* pending_mask,
636                                int index)
637{
638    VFUNC_LOG;
639    inv_error_t res, res2;
640    float bias_error[3];
641    float total_be;
642    static int bias_error_settled = 0;
643
644    res = inv_get_float_array(INV_MAGNETOMETER, s->magnetic.v);
645
646    if (res != INV_SUCCESS) {
647        ALOGW(
648             "compass_handler inv_get_float_array(INV_MAGNETOMETER) returned %d",
649             res);
650    }
651
652    s->magnetic.status = estimateCompassAccuracy();
653
654    if (res == INV_SUCCESS)
655        *pending_mask |= (1 << index);
656}
657
658void MPLSensor::rvHandler(sensors_event_t* s, uint32_t* pending_mask,
659                           int index)
660{
661    VFUNC_LOG;
662    float quat[4];
663    float norm = 0;
664    float ang = 0;
665    inv_error_t r;
666
667    r = inv_get_float_array(INV_QUATERNION, quat);
668
669    if (r != INV_SUCCESS) {
670        *pending_mask &= ~(1 << index);
671        return;
672    } else {
673        *pending_mask |= (1 << index);
674    }
675
676    norm = quat[1] * quat[1] + quat[2] * quat[2] + quat[3] * quat[3]
677            + FLT_EPSILON;
678
679    if (norm > 1.0f) {
680        //renormalize
681        norm = sqrtf(norm);
682        float inv_norm = 1.0f / norm;
683        quat[1] = quat[1] * inv_norm;
684        quat[2] = quat[2] * inv_norm;
685        quat[3] = quat[3] * inv_norm;
686    }
687
688    if (quat[0] < 0.0) {
689        quat[1] = -quat[1];
690        quat[2] = -quat[2];
691        quat[3] = -quat[3];
692    }
693
694    s->gyro.v[0] = quat[1];
695    s->gyro.v[1] = quat[2];
696    s->gyro.v[2] = quat[3];
697
698}
699
700void MPLSensor::laHandler(sensors_event_t* s, uint32_t* pending_mask,
701                           int index)
702{
703    VFUNC_LOG;
704    inv_error_t res;
705    res = inv_get_float_array(INV_LINEAR_ACCELERATION, s->gyro.v);
706    s->gyro.v[0] *= 9.81;
707    s->gyro.v[1] *= 9.81;
708    s->gyro.v[2] *= 9.81;
709    if (res == INV_SUCCESS)
710        *pending_mask |= (1 << index);
711}
712
713void MPLSensor::gravHandler(sensors_event_t* s, uint32_t* pending_mask,
714                             int index)
715{
716    VFUNC_LOG;
717    inv_error_t res;
718    res = inv_get_float_array(INV_GRAVITY, s->gyro.v);
719    s->gyro.v[0] *= 9.81;
720    s->gyro.v[1] *= 9.81;
721    s->gyro.v[2] *= 9.81;
722    if (res == INV_SUCCESS)
723        *pending_mask |= (1 << index);
724}
725
726void MPLSensor::calcOrientationSensor(float *R, float *values)
727{
728    float tmp;
729
730    //Azimuth
731    if ((R[7] > 0.7071067f) || ((R[8] < 0) && (fabs(R[7]) > fabs(R[6])))) {
732        values[0] = (float) atan2f(-R[3], R[0]);
733    } else {
734        values[0] = (float) atan2f(R[1], R[4]);
735    }
736    values[0] *= 57.295779513082320876798154814105f;
737    if (values[0] < 0) {
738        values[0] += 360.0f;
739    }
740    //Pitch
741    tmp = R[7];
742    if (tmp > 1.0f)
743        tmp = 1.0f;
744    if (tmp < -1.0f)
745        tmp = -1.0f;
746    values[1] = -asinf(tmp) * 57.295779513082320876798154814105f;
747    if (R[8] < 0) {
748        values[1] = 180.0f - values[1];
749    }
750    if (values[1] > 180.0f) {
751        values[1] -= 360.0f;
752    }
753    //Roll
754    if ((R[7] > 0.7071067f)) {
755        values[2] = (float) atan2f(R[6], R[7]);
756    } else {
757        values[2] = (float) atan2f(R[6], R[8]);
758    }
759
760    values[2] *= 57.295779513082320876798154814105f;
761    if (values[2] > 90.0f) {
762        values[2] = 180.0f - values[2];
763    }
764    if (values[2] < -90.0f) {
765        values[2] = -180.0f - values[2];
766    }
767}
768
769void MPLSensor::orienHandler(sensors_event_t* s, uint32_t* pending_mask,
770                              int index) //note that this is the handler for the android 'orientation' sensor, not the mpl orientation output
771{
772    VFUNC_LOG;
773    inv_error_t res;
774    float euler[3];
775    float heading[1];
776    float rot_mat[9];
777
778    res = inv_get_float_array(INV_ROTATION_MATRIX, rot_mat);
779
780    //ComputeAndOrientation(heading[0], euler, s->orientation.v);
781    calcOrientationSensor(rot_mat, s->orientation.v);
782
783    s->orientation.status = estimateCompassAccuracy();
784
785    if (res == INV_SUCCESS)
786        *pending_mask |= (1 << index);
787    else
788        ALOGW("orienHandler: data not valid (%d)", (int) res);
789
790}
791
792int MPLSensor::enable(int32_t handle, int en)
793{
794    FUNC_LOG;
795    //ALOGV("handle : %d en: %d", handle, en);
796
797    int what = -1;
798
799    switch (handle) {
800    case ID_A:
801        what = Accelerometer;
802        break;
803    case ID_M:
804        what = MagneticField;
805        break;
806    case ID_O:
807        what = Orientation;
808        break;
809    case ID_GY:
810        what = Gyro;
811        break;
812    case ID_GR:
813        what = Gravity;
814        break;
815    case ID_RV:
816        what = RotationVector;
817        break;
818    case ID_LA:
819        what = LinearAccel;
820        break;
821    default: //this takes care of all the gestures
822        what = handle;
823        break;
824    }
825
826    if (uint32_t(what) >= numSensors)
827        return -EINVAL;
828
829    int newState = en ? 1 : 0;
830    int err = 0;
831    //ALOGV_IF((uint32_t(newState) << what) != (mEnabled & (1 << what)),
832    //        "sensor state change what=%d", what);
833
834    pthread_mutex_lock(&mMplMutex);
835    if ((uint32_t(newState) << what) != (mEnabled & (1 << what))) {
836        uint32_t sensor_type;
837        short flags = newState;
838        mEnabled &= ~(1 << what);
839        mEnabled |= (uint32_t(flags) << what);
840        ALOGV_IF(EXTRA_VERBOSE, "mEnabled = %x", mEnabled);
841        setPowerStates(mEnabled);
842        pthread_mutex_unlock(&mMplMutex);
843        if (!newState)
844            update_delay();
845        return err;
846    }
847    pthread_mutex_unlock(&mMplMutex);
848    return err;
849}
850
851int MPLSensor::setDelay(int32_t handle, int64_t ns)
852{
853    FUNC_LOG;
854    ALOGV_IF(EXTRA_VERBOSE,
855            " setDelay handle: %d rate %d", handle, (int) (ns / 1000000LL));
856    int what = -1;
857    switch (handle) {
858    case ID_A:
859        what = Accelerometer;
860        break;
861    case ID_M:
862        what = MagneticField;
863        break;
864    case ID_O:
865        what = Orientation;
866        break;
867    case ID_GY:
868        what = Gyro;
869        break;
870    case ID_GR:
871        what = Gravity;
872        break;
873    case ID_RV:
874        what = RotationVector;
875        break;
876    case ID_LA:
877        what = LinearAccel;
878        break;
879    default:
880        what = handle;
881        break;
882    }
883
884    if (uint32_t(what) >= numSensors)
885        return -EINVAL;
886
887    if (ns < 0)
888        return -EINVAL;
889
890    pthread_mutex_lock(&mMplMutex);
891    mDelays[what] = ns;
892    pthread_mutex_unlock(&mMplMutex);
893    return update_delay();
894}
895
896int MPLSensor::update_delay()
897{
898    FUNC_LOG;
899    int rv = 0;
900    bool irq_set[5];
901
902    pthread_mutex_lock(&mMplMutex);
903
904    if (mEnabled) {
905        uint64_t wanted = -1LLU;
906        for (int i = 0; i < numSensors; i++) {
907            if (mEnabled & (1 << i)) {
908                uint64_t ns = mDelays[i];
909                wanted = wanted < ns ? wanted : ns;
910            }
911        }
912
913        //Limit all rates to 100Hz max. 100Hz = 10ms = 10000000ns
914        if (wanted < 10000000LLU) {
915            wanted = 10000000LLU;
916        }
917
918        int rate = ((wanted) / 5000000LLU) - ((wanted % 5000000LLU == 0) ? 1
919                                                                         : 0); //mpu fifo rate is in increments of 5ms
920        if (rate == 0) //KLP disallow fifo rate 0
921            rate = 1;
922
923        if (rate != mCurFifoRate) {
924            //ALOGD("set fifo rate: %d %llu", rate, wanted);
925            inv_error_t res; // = inv_dmp_stop();
926            res = inv_set_fifo_rate(rate);
927            ALOGE_IF(res != INV_SUCCESS, "error setting FIFO rate");
928
929            //res = inv_dmp_start();
930            //ALOGE_IF(res != INV_SUCCESS, "error re-starting DMP");
931
932            mCurFifoRate = rate;
933            rv = (res == INV_SUCCESS);
934        }
935
936        if (((inv_get_dl_config()->requested_sensors & INV_DMP_PROCESSOR) == 0)) {
937            if (mUseTimerirq) {
938                ioctl(mIrqFds.valueFor(TIMERIRQ_FD), TIMERIRQ_STOP, 0);
939                clearIrqData(irq_set);
940                if (inv_get_dl_config()->requested_sensors
941                        == INV_THREE_AXIS_COMPASS) {
942                    ioctl(mIrqFds.valueFor(TIMERIRQ_FD), TIMERIRQ_START,
943                          (unsigned long) (wanted / 1000000LLU));
944                    ALOGV_IF(EXTRA_VERBOSE, "updated timerirq period to %d",
945                            (int) (wanted / 1000000LLU));
946                } else {
947                    ioctl(mIrqFds.valueFor(TIMERIRQ_FD), TIMERIRQ_START,
948                          (unsigned long) inv_get_sample_step_size_ms());
949                    ALOGV_IF(EXTRA_VERBOSE, "updated timerirq period to %d",
950                            (int) inv_get_sample_step_size_ms());
951                }
952            }
953        }
954
955    }
956    pthread_mutex_unlock(&mMplMutex);
957    return rv;
958}
959
960/* return the current time in nanoseconds */
961int64_t MPLSensor::now_ns(void)
962{
963    //FUNC_LOG;
964    struct timespec ts;
965
966    clock_gettime(CLOCK_MONOTONIC, &ts);
967    //ALOGV("Time %lld", (int64_t)ts.tv_sec * 1000000000 + ts.tv_nsec);
968    return (int64_t) ts.tv_sec * 1000000000 + ts.tv_nsec;
969}
970
971int MPLSensor::readEvents(sensors_event_t* data, int count)
972{
973    //VFUNC_LOG;
974    int i;
975    bool irq_set[5] = { false, false, false, false, false };
976    inv_error_t rv;
977    if (count < 1)
978        return -EINVAL;
979    int numEventReceived = 0;
980
981    clearIrqData(irq_set);
982
983    pthread_mutex_lock(&mMplMutex);
984    if (mDmpStarted) {
985        //ALOGV_IF(EXTRA_VERBOSE, "Update Data");
986        rv = inv_update_data();
987        ALOGE_IF(rv != INV_SUCCESS, "inv_update_data error (code %d)", (int) rv);
988    }
989
990    else {
991        //probably just one extra read after shutting down
992        ALOGV_IF(EXTRA_VERBOSE,
993                "MPLSensor::readEvents called, but there's nothing to do.");
994    }
995
996    pthread_mutex_unlock(&mMplMutex);
997
998    if (!mNewData) {
999        ALOGV_IF(EXTRA_VERBOSE, "no new data");
1000        return 0;
1001    }
1002    mNewData = 0;
1003
1004    /* google timestamp */
1005    pthread_mutex_lock(&mMplMutex);
1006    for (int i = 0; i < numSensors; i++) {
1007        if (mEnabled & (1 << i)) {
1008            CALL_MEMBER_FN(this,mHandlers[i])(mPendingEvents + i,
1009                                              &mPendingMask, i);
1010	    mPendingEvents[i].timestamp = irq_timestamp;
1011        }
1012    }
1013
1014    for (int j = 0; count && mPendingMask && j < numSensors; j++) {
1015        if (mPendingMask & (1 << j)) {
1016            mPendingMask &= ~(1 << j);
1017            if (mEnabled & (1 << j)) {
1018                *data++ = mPendingEvents[j];
1019                count--;
1020                numEventReceived++;
1021            }
1022        }
1023
1024    }
1025
1026    pthread_mutex_unlock(&mMplMutex);
1027    return numEventReceived;
1028}
1029
1030int MPLSensor::getFd() const
1031{
1032    //ALOGV("MPLSensor::getFd returning %d", data_fd);
1033    return data_fd;
1034}
1035
1036int MPLSensor::getAccelFd() const
1037{
1038    //ALOGV("MPLSensor::getAccelFd returning %d", accel_fd);
1039    return accel_fd;
1040}
1041
1042int MPLSensor::getTimerFd() const
1043{
1044    //ALOGV("MPLSensor::getTimerFd returning %d", timer_fd);
1045    return timer_fd;
1046}
1047
1048int MPLSensor::getPowerFd() const
1049{
1050    int hdl = (int) inv_get_serial_handle();
1051    //ALOGV("MPLSensor::getPowerFd returning %d", hdl);
1052    return hdl;
1053}
1054
1055int MPLSensor::getPollTime()
1056{
1057    return mPollTime;
1058}
1059
1060bool MPLSensor::hasPendingEvents() const
1061{
1062    //if we are using the polling workaround, force the main loop to check for data every time
1063    return (mPollTime != -1);
1064}
1065
1066void MPLSensor::handlePowerEvent()
1067{
1068    VFUNC_LOG;
1069    mpuirq_data irqd;
1070
1071    int fd = (int) inv_get_serial_handle();
1072    read(fd, &irqd, sizeof(irqd));
1073
1074    if (irqd.data == MPU_PM_EVENT_SUSPEND_PREPARE) {
1075        //going to sleep
1076        sleepEvent();
1077    } else if (irqd.data == MPU_PM_EVENT_POST_SUSPEND) {
1078        //waking up
1079        wakeEvent();
1080    }
1081
1082    ioctl(fd, MPU_PM_EVENT_HANDLED, 0);
1083}
1084
1085void MPLSensor::sleepEvent()
1086{
1087    VFUNC_LOG;
1088    pthread_mutex_lock(&mMplMutex);
1089    if (mEnabled != 0) {
1090        mForceSleep = true;
1091        mOldEnabledMask = mEnabled;
1092        setPowerStates(0);
1093    }
1094    pthread_mutex_unlock(&mMplMutex);
1095}
1096
1097void MPLSensor::wakeEvent()
1098{
1099    VFUNC_LOG;
1100    pthread_mutex_lock(&mMplMutex);
1101    if (mForceSleep) {
1102        setPowerStates((mOldEnabledMask | mEnabled));
1103    }
1104    mForceSleep = false;
1105    pthread_mutex_unlock(&mMplMutex);
1106}
1107
1108/** fill in the sensor list based on which sensors are configured.
1109 *  return the number of configured sensors.
1110 *  parameter list must point to a memory region of at least 7*sizeof(sensor_t)
1111 *  parameter len gives the length of the buffer pointed to by list
1112 */
1113
1114int MPLSensor::populateSensorList(struct sensor_t *list, int len)
1115{
1116    int numsensors;
1117
1118    if(len < 7*sizeof(sensor_t)) {
1119        ALOGE("sensor list too small, not populating.");
1120        return 0;
1121    }
1122
1123    /* fill in the base values */
1124    memcpy(list, sSensorList, sizeof (struct sensor_t) * 7);
1125
1126    /* first add gyro, accel and compass to the list */
1127
1128    /* fill in accel values                          */
1129    unsigned short accelId = inv_get_accel_id();
1130    if(accelId == 0)
1131    {
1132	ALOGE("Can not get accel id");
1133    }
1134    fillAccel(accelId, list);
1135
1136    /* fill in compass values                        */
1137    unsigned short compassId = inv_get_compass_id();
1138    if(compassId == 0)
1139    {
1140	ALOGE("Can not get compass id");
1141    }
1142    fillCompass(compassId, list);
1143
1144    /* fill in gyro values                           */
1145    fillGyro(MPU_NAME, list);
1146
1147    if(mNineAxisEnabled)
1148    {
1149        numsensors = 7;
1150        /* all sensors will be added to the list     */
1151        /* fill in orientation values	             */
1152        fillOrientation(list);
1153
1154        /* fill in rotation vector values	     */
1155        fillRV(list);
1156
1157        /* fill in gravity values			     */
1158        fillGravity(list);
1159
1160        /* fill in Linear accel values            */
1161        fillLinearAccel(list);
1162    } else {
1163        /* no 9-axis sensors, zero fill that part of the list */
1164        numsensors = 3;
1165        memset(list+3, 0, 4*sizeof(struct sensor_t));
1166    }
1167
1168    return numsensors;
1169}
1170
1171void MPLSensor::fillAccel(unsigned char accel, struct sensor_t *list)
1172{
1173    switch (accel) {
1174    case ACCEL_ID_LIS331:
1175        list[Accelerometer].maxRange = ACCEL_LIS331_RANGE;
1176        list[Accelerometer].resolution = ACCEL_LIS331_RESOLUTION;
1177        list[Accelerometer].power = ACCEL_LIS331_POWER;
1178        break;
1179
1180    case ACCEL_ID_LIS3DH:
1181        list[Accelerometer].maxRange = ACCEL_LIS3DH_RANGE;
1182        list[Accelerometer].resolution = ACCEL_LIS3DH_RESOLUTION;
1183        list[Accelerometer].power = ACCEL_LIS3DH_POWER;
1184        break;
1185
1186    case ACCEL_ID_KXSD9:
1187        list[Accelerometer].maxRange = ACCEL_KXSD9_RANGE;
1188        list[Accelerometer].resolution = ACCEL_KXSD9_RESOLUTION;
1189        list[Accelerometer].power = ACCEL_KXSD9_POWER;
1190        break;
1191
1192    case ACCEL_ID_KXTF9:
1193        list[Accelerometer].maxRange = ACCEL_KXTF9_RANGE;
1194        list[Accelerometer].resolution = ACCEL_KXTF9_RESOLUTION;
1195        list[Accelerometer].power = ACCEL_KXTF9_POWER;
1196        break;
1197
1198    case ACCEL_ID_BMA150:
1199        list[Accelerometer].maxRange = ACCEL_BMA150_RANGE;
1200        list[Accelerometer].resolution = ACCEL_BMA150_RESOLUTION;
1201        list[Accelerometer].power = ACCEL_BMA150_POWER;
1202        break;
1203
1204    case ACCEL_ID_BMA222:
1205        list[Accelerometer].maxRange = ACCEL_BMA222_RANGE;
1206        list[Accelerometer].resolution = ACCEL_BMA222_RESOLUTION;
1207        list[Accelerometer].power = ACCEL_BMA222_POWER;
1208        break;
1209
1210    case ACCEL_ID_BMA250:
1211        list[Accelerometer].maxRange = ACCEL_BMA250_RANGE;
1212        list[Accelerometer].resolution = ACCEL_BMA250_RESOLUTION;
1213        list[Accelerometer].power = ACCEL_BMA250_POWER;
1214        break;
1215
1216    case ACCEL_ID_ADXL34X:
1217        list[Accelerometer].maxRange = ACCEL_ADXL34X_RANGE;
1218        list[Accelerometer].resolution = ACCEL_ADXL34X_RESOLUTION;
1219        list[Accelerometer].power = ACCEL_ADXL34X_POWER;
1220        break;
1221
1222    case ACCEL_ID_MMA8450:
1223        list[Accelerometer].maxRange = ACCEL_MMA8450_RANGE;
1224        list[Accelerometer].maxRange = ACCEL_MMA8450_RANGE;
1225        list[Accelerometer].maxRange = ACCEL_MMA8450_RANGE;
1226        break;
1227
1228    case ACCEL_ID_MMA845X:
1229        list[Accelerometer].maxRange = ACCEL_MMA845X_RANGE;
1230        list[Accelerometer].resolution = ACCEL_MMA845X_RESOLUTION;
1231        list[Accelerometer].power = ACCEL_MMA845X_POWER;
1232        break;
1233
1234    case ACCEL_ID_MPU6050:
1235        list[Accelerometer].maxRange = ACCEL_MPU6050_RANGE;
1236        list[Accelerometer].resolution = ACCEL_MPU6050_RESOLUTION;
1237        list[Accelerometer].power = ACCEL_MPU6050_POWER;
1238        break;
1239    default:
1240        ALOGE("unknown accel id -- accel params will be wrong.");
1241        break;
1242    }
1243}
1244
1245void MPLSensor::fillCompass(unsigned char compass, struct sensor_t *list)
1246{
1247    switch (compass) {
1248    case COMPASS_ID_AK8975:
1249        list[MagneticField].maxRange = COMPASS_AKM8975_RANGE;
1250        list[MagneticField].resolution = COMPASS_AKM8975_RESOLUTION;
1251        list[MagneticField].power = COMPASS_AKM8975_POWER;
1252        break;
1253    case COMPASS_ID_AMI30X:
1254        list[MagneticField].maxRange = COMPASS_AMI30X_RANGE;
1255        list[MagneticField].resolution = COMPASS_AMI30X_RESOLUTION;
1256        list[MagneticField].power = COMPASS_AMI30X_POWER;
1257        break;
1258    case COMPASS_ID_AMI306:
1259        list[MagneticField].maxRange = COMPASS_AMI306_RANGE;
1260        list[MagneticField].resolution = COMPASS_AMI306_RESOLUTION;
1261        list[MagneticField].power = COMPASS_AMI306_POWER;
1262        break;
1263    case COMPASS_ID_YAS529:
1264        list[MagneticField].maxRange = COMPASS_YAS529_RANGE;
1265        list[MagneticField].resolution = COMPASS_AMI306_RESOLUTION;
1266        list[MagneticField].power = COMPASS_AMI306_POWER;
1267        break;
1268    case COMPASS_ID_YAS530:
1269        list[MagneticField].maxRange = COMPASS_YAS530_RANGE;
1270        list[MagneticField].resolution = COMPASS_YAS530_RESOLUTION;
1271        list[MagneticField].power = COMPASS_YAS530_POWER;
1272        break;
1273    case COMPASS_ID_HMC5883:
1274        list[MagneticField].maxRange = COMPASS_HMC5883_RANGE;
1275        list[MagneticField].resolution = COMPASS_HMC5883_RESOLUTION;
1276        list[MagneticField].power = COMPASS_HMC5883_POWER;
1277        break;
1278    case COMPASS_ID_MMC314X:
1279        list[MagneticField].maxRange = COMPASS_MMC314X_RANGE;
1280        list[MagneticField].resolution = COMPASS_MMC314X_RESOLUTION;
1281        list[MagneticField].power = COMPASS_MMC314X_POWER;
1282        break;
1283    case COMPASS_ID_HSCDTD002B:
1284        list[MagneticField].maxRange = COMPASS_HSCDTD002B_RANGE;
1285        list[MagneticField].resolution = COMPASS_HSCDTD002B_RESOLUTION;
1286        list[MagneticField].power = COMPASS_HSCDTD002B_POWER;
1287        break;
1288    case COMPASS_ID_HSCDTD004A:
1289        list[MagneticField].maxRange = COMPASS_HSCDTD004A_RANGE;
1290        list[MagneticField].resolution = COMPASS_HSCDTD004A_RESOLUTION;
1291        list[MagneticField].power = COMPASS_HSCDTD004A_POWER;
1292        break;
1293    default:
1294        ALOGE("unknown compass id -- compass parameters will be wrong");
1295    }
1296}
1297
1298void MPLSensor::fillGyro(const char* gyro, struct sensor_t *list)
1299{
1300    if ((gyro != NULL) && (strcmp(gyro, "mpu3050") == 0)) {
1301        list[Gyro].maxRange = GYRO_MPU3050_RANGE;
1302        list[Gyro].resolution = GYRO_MPU3050_RESOLUTION;
1303        list[Gyro].power = GYRO_MPU3050_POWER;
1304    } else {
1305        list[Gyro].maxRange = GYRO_MPU6050_RANGE;
1306        list[Gyro].resolution = GYRO_MPU6050_RESOLUTION;
1307        list[Gyro].power = GYRO_MPU6050_POWER;
1308    }
1309    return;
1310}
1311
1312
1313/* fillRV depends on values of accel and compass in the list	*/
1314void MPLSensor::fillRV(struct sensor_t *list)
1315{
1316    /* compute power on the fly */
1317    list[RotationVector].power = list[Gyro].power + list[Accelerometer].power
1318            + list[MagneticField].power;
1319    list[RotationVector].resolution = .00001;
1320    list[RotationVector].maxRange = 1.0;
1321    return;
1322}
1323
1324void MPLSensor::fillOrientation(struct sensor_t *list)
1325{
1326    list[Orientation].power = list[Gyro].power + list[Accelerometer].power
1327            + list[MagneticField].power;
1328    list[Orientation].resolution = .00001;
1329    list[Orientation].maxRange = 360.0;
1330    return;
1331}
1332
1333void MPLSensor::fillGravity( struct sensor_t *list)
1334{
1335    list[Gravity].power = list[Gyro].power + list[Accelerometer].power
1336            + list[MagneticField].power;
1337    list[Gravity].resolution = .00001;
1338    list[Gravity].maxRange = 9.81;
1339    return;
1340}
1341
1342void MPLSensor::fillLinearAccel(struct sensor_t *list)
1343{
1344    list[Gravity].power = list[Gyro].power + list[Accelerometer].power
1345            + list[MagneticField].power;
1346    list[Gravity].resolution = list[Accelerometer].resolution;
1347    list[Gravity].maxRange = list[Accelerometer].maxRange;
1348    return;
1349}
1350