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