blob: 1cbe121cf3e132f44e4ce56356a752f2340a126f [file] [log] [blame]
Jean-Baptiste Queru42331852011-08-01 10:20:23 -07001/*
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 "kernel/timerirq.h"
49#include "kernel/mpuirq.h"
50#include "kernel/slaveirq.h"
51
52extern "C" {
53#include "mlsupervisor.h"
54}
55
56#include "mlcontrol.h"
57
58#define EXTRA_VERBOSE (0)
59#define FUNC_LOG LOGV("%s", __PRETTY_FUNCTION__)
60#define VFUNC_LOG LOGV_IF(EXTRA_VERBOSE, "%s", __PRETTY_FUNCTION__)
61/* this mask must turn on only the sensors that are present and managed by the MPL */
62#define ALL_MPL_SENSORS_NP (INV_THREE_AXIS_ACCEL | INV_THREE_AXIS_COMPASS | INV_THREE_AXIS_GYRO)
63
64#define CALL_MEMBER_FN(pobject,ptrToMember) ((pobject)->*(ptrToMember))
65
66/* ***************************************************************************
67 * MPL interface misc.
68 */
69//static pointer to the object that will handle callbacks
70static MPLSensor* gMPLSensor = NULL;
71
72/* we need to pass some callbacks to the MPL. The mpl is a C library, so
73 * wrappers for the C++ callback implementations are required.
74 */
75extern "C" {
76//callback wrappers go here
77void mot_cb_wrapper(uint16_t val)
78{
79 if (gMPLSensor) {
80 gMPLSensor->cbOnMotion(val);
81 }
82}
83
84void procData_cb_wrapper()
85{
86 if(gMPLSensor) {
87 gMPLSensor->cbProcData();
88 }
89}
90
91} //end of extern C
92
93void setCallbackObject(MPLSensor* gbpt)
94{
95 gMPLSensor = gbpt;
96}
97
98
99/*****************************************************************************
100 * sensor class implementation
101 */
102
103#define GY_ENABLED ((1<<ID_GY) & enabled_sensors)
104#define A_ENABLED ((1<<ID_A) & enabled_sensors)
105#define O_ENABLED ((1<<ID_O) & enabled_sensors)
106#define M_ENABLED ((1<<ID_M) & enabled_sensors)
107#define LA_ENABLED ((1<<ID_LA) & enabled_sensors)
108#define GR_ENABLED ((1<<ID_GR) & enabled_sensors)
109#define RV_ENABLED ((1<<ID_RV) & enabled_sensors)
110
111MPLSensor::MPLSensor() :
112 SensorBase(NULL, NULL), mEnabled(0), mPendingMask(0), mMpuAccuracy(0),
113 mNewData(0), mDmpStarted(false),
114 mMplMutex(PTHREAD_MUTEX_INITIALIZER),
115 mMasterSensorMask(INV_ALL_SENSORS),
116 mLocalSensorMask(ALL_MPL_SENSORS_NP), mPollTime(-1),
117 mCurFifoRate(-1), mHaveGoodMpuCal(false),
118 mUseTimerIrqAccel(false), mUsetimerIrqCompass(true),
119 mUseTimerirq(false), mSampleCount(0)
120{
121 FUNC_LOG;
122 inv_error_t rv;
123 int mpu_int_fd, i;
124 char *port = NULL;
125
126 LOGV_IF(EXTRA_VERBOSE, "MPLSensor constructor: numSensors = %d", numSensors);
127
128 mForceSleep = false;
129
130 for (i = 0; i < ARRAY_SIZE(mPollFds); i++) {
131 mPollFds[i].fd = -1;
132 mPollFds[i].events = 0;
133 }
134
135 pthread_mutex_lock(&mMplMutex);
136
137 mpu_int_fd = open("/dev/mpuirq", O_RDWR);
138 if (mpu_int_fd == -1) {
139 LOGE("could not open the mpu irq device node");
140 } else {
141 fcntl(mpu_int_fd, F_SETFL, O_NONBLOCK);
142 //ioctl(mpu_int_fd, MPUIRQ_SET_TIMEOUT, 0);
143 mIrqFds.add(MPUIRQ_FD, mpu_int_fd);
144 mPollFds[MPUIRQ_FD].fd = mpu_int_fd;
145 mPollFds[MPUIRQ_FD].events = POLLIN;
146 }
147
148 accel_fd = open("/dev/accelirq", O_RDWR);
149 if (accel_fd == -1) {
150 LOGE("could not open the accel irq device node");
151 } else {
152 fcntl(accel_fd, F_SETFL, O_NONBLOCK);
153 //ioctl(accel_fd, SLAVEIRQ_SET_TIMEOUT, 0);
154 mIrqFds.add(ACCELIRQ_FD, accel_fd);
155 mPollFds[ACCELIRQ_FD].fd = accel_fd;
156 mPollFds[ACCELIRQ_FD].events = POLLIN;
157 }
158
159 timer_fd = open("/dev/timerirq", O_RDWR);
160 if (timer_fd == -1) {
161 LOGE("could not open the timer irq device node");
162 } else {
163 fcntl(timer_fd, F_SETFL, O_NONBLOCK);
164 //ioctl(timer_fd, TIMERIRQ_SET_TIMEOUT, 0);
165 mIrqFds.add(TIMERIRQ_FD, timer_fd);
166 mPollFds[TIMERIRQ_FD].fd = timer_fd;
167 mPollFds[TIMERIRQ_FD].events = POLLIN;
168 }
169
170 data_fd = mpu_int_fd;
171
172 if ((accel_fd == -1) && (timer_fd != -1)) {
173 //no accel irq and timer available
174 mUseTimerIrqAccel = true;
175 LOGD("MPLSensor falling back to timerirq for accel data");
176 }
177
178 memset(mPendingEvents, 0, sizeof(mPendingEvents));
179
180 mPendingEvents[RotationVector].version = sizeof(sensors_event_t);
181 mPendingEvents[RotationVector].sensor = ID_RV;
182 mPendingEvents[RotationVector].type = SENSOR_TYPE_ROTATION_VECTOR;
183 mPendingEvents[RotationVector].acceleration.status
184 = SENSOR_STATUS_ACCURACY_HIGH;
185
186 mPendingEvents[LinearAccel].version = sizeof(sensors_event_t);
187 mPendingEvents[LinearAccel].sensor = ID_LA;
188 mPendingEvents[LinearAccel].type = SENSOR_TYPE_LINEAR_ACCELERATION;
189 mPendingEvents[LinearAccel].acceleration.status
190 = SENSOR_STATUS_ACCURACY_HIGH;
191
192 mPendingEvents[Gravity].version = sizeof(sensors_event_t);
193 mPendingEvents[Gravity].sensor = ID_GR;
194 mPendingEvents[Gravity].type = SENSOR_TYPE_GRAVITY;
195 mPendingEvents[Gravity].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
196
197 mPendingEvents[Gyro].version = sizeof(sensors_event_t);
198 mPendingEvents[Gyro].sensor = ID_GY;
199 mPendingEvents[Gyro].type = SENSOR_TYPE_GYROSCOPE;
200 mPendingEvents[Gyro].gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
201
202 mPendingEvents[Accelerometer].version = sizeof(sensors_event_t);
203 mPendingEvents[Accelerometer].sensor = ID_A;
204 mPendingEvents[Accelerometer].type = SENSOR_TYPE_ACCELEROMETER;
205 mPendingEvents[Accelerometer].acceleration.status
206 = SENSOR_STATUS_ACCURACY_HIGH;
207
208 mPendingEvents[MagneticField].version = sizeof(sensors_event_t);
209 mPendingEvents[MagneticField].sensor = ID_M;
210 mPendingEvents[MagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD;
211 mPendingEvents[MagneticField].magnetic.status = SENSOR_STATUS_ACCURACY_HIGH;
212
213 mPendingEvents[Orientation].version = sizeof(sensors_event_t);
214 mPendingEvents[Orientation].sensor = ID_O;
215 mPendingEvents[Orientation].type = SENSOR_TYPE_ORIENTATION;
216 mPendingEvents[Orientation].orientation.status
217 = SENSOR_STATUS_ACCURACY_HIGH;
218
219 mHandlers[RotationVector] = &MPLSensor::rvHandler;
220 mHandlers[LinearAccel] = &MPLSensor::laHandler;
221 mHandlers[Gravity] = &MPLSensor::gravHandler;
222 mHandlers[Gyro] = &MPLSensor::gyroHandler;
223 mHandlers[Accelerometer] = &MPLSensor::accelHandler;
224 mHandlers[MagneticField] = &MPLSensor::compassHandler;
225 mHandlers[Orientation] = &MPLSensor::orienHandler;
226
227 for (int i = 0; i < numSensors; i++)
228 mDelays[i] = 30000000LLU; // 30 ms by default
229
230 if (inv_serial_start(port) != INV_SUCCESS) {
231 LOGE("Fatal Error : could not open MPL serial interface");
232 }
233
234 //initialize library parameters
235 initMPL();
236
237 //setup the FIFO contents
238 setupFIFO();
239
240 //we start the motion processing only when a sensor is enabled...
241 //rv = inv_dmp_start();
242 //LOGE_IF(rv != INV_SUCCESS, "Fatal error: could not start the DMP correctly. (code = %d)\n", rv);
243 //dmp_started = true;
244
245 pthread_mutex_unlock(&mMplMutex);
246
247}
248
249MPLSensor::~MPLSensor()
250{
251 FUNC_LOG;
252 pthread_mutex_lock(&mMplMutex);
253 if (inv_dmp_stop() != INV_SUCCESS) {
254 LOGD("Error: could not stop the DMP correctly.\n");
255 }
256
257 if (inv_dmp_close() != INV_SUCCESS) {
258 LOGD("Error: could not close the DMP");
259 }
260
261 if (inv_serial_stop() != INV_SUCCESS) {
262 LOGD("Error : could not close the serial port");
263 }
264 pthread_mutex_unlock(&mMplMutex);
265}
266
267/* clear any data from our various filehandles */
268void MPLSensor::clearIrqData(bool* irq_set)
269{
270 unsigned int i;
271 int nread;
272 struct mpuirq_data irqdata;
273
274 poll(mPollFds, ARRAY_SIZE(mPollFds), 0); //check which ones need to be cleared
275
276 for (i = 0; i < ARRAY_SIZE(mPollFds); i++) {
277 int cur_fd = mPollFds[i].fd;
278 int j = 0;
279 if (mPollFds[i].revents & POLLIN) {
280 nread = read(cur_fd, &irqdata, sizeof(irqdata));
281 if (nread > 0) {
282 irq_set[i] = true;
283 //LOGV_IF(EXTRA_VERBOSE, "irq: %d %d (%d)", i, irqdata.interruptcount, j++);
284 }
285 }
286 mPollFds[i].revents = 0;
287 }
288}
289
290/* set the power states of the various sensors based on the bits set in the
291 * enabled_sensors parameter.
292 * this function modifies globalish state variables. It must be called with the mMplMutex held. */
293void MPLSensor::setPowerStates(int enabled_sensors)
294{
295 FUNC_LOG;
296 bool irq_set[5] = { false, false, false, false, false };
297
298 LOGV(" enabled_sensors: %d dmp_started: %d", enabled_sensors, mDmpStarted);
299
300 do {
301
302 if (LA_ENABLED || GR_ENABLED || RV_ENABLED || O_ENABLED) {
303 mLocalSensorMask = ALL_MPL_SENSORS_NP;
304 break;
305 }
306
307 if (!A_ENABLED && !M_ENABLED && !GY_ENABLED) {
308 mLocalSensorMask = 0;
309 break;
310 }
311
312 if (GY_ENABLED) {
313 mLocalSensorMask |= INV_THREE_AXIS_GYRO;
314 } else {
315 mLocalSensorMask &= ~INV_THREE_AXIS_GYRO;
316 }
317
318 if (A_ENABLED) {
319 mLocalSensorMask |= (INV_THREE_AXIS_ACCEL);
320 } else {
321 mLocalSensorMask &= ~(INV_THREE_AXIS_ACCEL);
322 }
323
324 if (M_ENABLED) {
325 mLocalSensorMask |= INV_THREE_AXIS_COMPASS;
326 } else {
327 mLocalSensorMask &= ~(INV_THREE_AXIS_COMPASS);
328 }
329
330 } while (0);
331
332 //record the new sensor state
333 inv_error_t rv;
334
335 long sen_mask = mLocalSensorMask & mMasterSensorMask;
336
337 bool changing_sensors = ((inv_get_dl_config()->requested_sensors
338 != sen_mask) && (sen_mask != 0));
339 bool restart = (!mDmpStarted) && (sen_mask != 0);
340
341 if (changing_sensors || restart) {
342
343 LOGV_IF(EXTRA_VERBOSE, "cs:%d rs:%d ", changing_sensors, restart);
344
345 if (mDmpStarted) {
346 inv_dmp_stop();
347 clearIrqData(irq_set);
348 mDmpStarted = false;
349 }
350
351 if (sen_mask != inv_get_dl_config()->requested_sensors) {
352 LOGV("inv_set_mpu_sensors: %lx", sen_mask);
353 rv = inv_set_mpu_sensors(sen_mask);
354 LOGE_IF(
355 rv != INV_SUCCESS,
356 "error: unable to set MPL sensor power states (sens=%ld retcode = %d)",
357 sen_mask, rv);
358 }
359
360 if (((mUsetimerIrqCompass && (sen_mask == INV_THREE_AXIS_COMPASS))
361 || (mUseTimerIrqAccel && (sen_mask & INV_THREE_AXIS_ACCEL)))
362 && ((sen_mask & INV_DMP_PROCESSOR) == 0)) {
363 LOGV_IF(EXTRA_VERBOSE, "Allowing TimerIRQ");
364 mUseTimerirq = true;
365 } else {
366 if (mUseTimerirq) {
367 ioctl(mIrqFds.valueFor(TIMERIRQ_FD), TIMERIRQ_STOP, 0);
368 clearIrqData(irq_set);
369 }
370 LOGV_IF(EXTRA_VERBOSE, "Not allowing TimerIRQ");
371 mUseTimerirq = false;
372 }
373
374 if (!mDmpStarted) {
Kevin Powell147e22f2011-07-29 15:57:44 -0700375 if (mHaveGoodMpuCal) {
376 rv = inv_store_calibration();
377 LOGE_IF(rv != INV_SUCCESS,
378 "error: unable to store MPL calibration file");
379 mHaveGoodMpuCal = false;
380 }
Jean-Baptiste Queru42331852011-08-01 10:20:23 -0700381 LOGV("Starting DMP");
382 rv = inv_dmp_start();
383 LOGE_IF(rv != INV_SUCCESS, "unable to start dmp");
384 mDmpStarted = true;
385 }
386 }
387
388 //check if we should stop the DMP
389 if (mDmpStarted && (sen_mask == 0)) {
390 LOGV("Stopping DMP");
391 rv = inv_dmp_stop();
392 LOGE_IF(rv != INV_SUCCESS, "error: unable to stop DMP (retcode = %d)",
393 rv);
394 if (mUseTimerirq) {
395 ioctl(mIrqFds.valueFor(TIMERIRQ_FD), TIMERIRQ_STOP, 0);
396 }
397 clearIrqData(irq_set);
Jean-Baptiste Queru42331852011-08-01 10:20:23 -0700398
399 mDmpStarted = false;
400 mPollTime = -1;
401 mCurFifoRate = -1;
402 }
403
404}
405
406/**
407 * container function for all the calls we make once to set up the MPL.
408 */
409void MPLSensor::initMPL()
410{
411 FUNC_LOG;
412 inv_error_t result;
413 unsigned short bias_update_mask = 0xFFFF;
414 struct mldl_cfg *mldl_cfg;
415
416 if (inv_dmp_open() != INV_SUCCESS) {
417 LOGE("Fatal Error : could not open DMP correctly.\n");
418 }
419
420 result = inv_set_mpu_sensors(ALL_MPL_SENSORS_NP); //default to all sensors, also makes 9axis enable work
421 LOGE_IF(result != INV_SUCCESS,
422 "Fatal Error : could not set enabled sensors.");
423
424 if (inv_load_calibration() != INV_SUCCESS) {
425 LOGE("could not open MPL calibration file");
426 }
427
428 //check for the 9axis fusion library: if available load it and start 9x
429 void* h_dmp_lib=dlopen("libmpl.so", RTLD_LAZY);
430 if(h_dmp_lib) {
431 const char* error;
432 inv_error_t (*fp_inv_enable_9x_fusion)() =
433 (inv_error_t(*)()) dlsym(h_dmp_lib, "inv_enable_9x_fusion");
434 if((error = dlerror()) != NULL) {
435 LOGE("%s", error);
436 } else if ((*fp_inv_enable_9x_fusion)() != INV_SUCCESS) {
437 LOGE( "Warning : 9 axis sensor fusion not available "
438 "- No compass detected.\n");
439 }
440 } else {
441 const char* error = dlerror();
442 LOGE("libmpl.so not found, 9x sensor fusion disabled (%s)",error);
443 }
444
445 mldl_cfg = inv_get_dl_config();
446
447 if (inv_set_bias_update(bias_update_mask) != INV_SUCCESS) {
448 LOGE("Error : Bias update function could not be set.\n");
449 }
450
451 if (inv_set_motion_interrupt(1) != INV_SUCCESS) {
452 LOGE("Error : could not set motion interrupt");
453 }
454
455 if (inv_set_fifo_interrupt(1) != INV_SUCCESS) {
456 LOGE("Error : could not set fifo interrupt");
457 }
458
459 result = inv_set_fifo_rate(6);
460 if (result != INV_SUCCESS) {
461 LOGE("Fatal error: inv_set_fifo_rate returned %d\n", result);
462 }
463
464 mMpuAccuracy = SENSOR_STATUS_ACCURACY_MEDIUM;
465 setupCallbacks();
466
467}
468
469/** setup the fifo contents.
470 */
471void MPLSensor::setupFIFO()
472{
473 FUNC_LOG;
474 inv_error_t result;
475
476 result = inv_send_accel(INV_ALL, INV_32_BIT);
477 if (result != INV_SUCCESS) {
478 LOGE("Fatal error: inv_send_accel returned %d\n", result);
479 }
480
481 result = inv_send_quaternion(INV_32_BIT);
482 if (result != INV_SUCCESS) {
483 LOGE("Fatal error: inv_send_quaternion returned %d\n", result);
484 }
485
486 result = inv_send_linear_accel(INV_ALL, INV_32_BIT);
487 if (result != INV_SUCCESS) {
488 LOGE("Fatal error: inv_send_linear_accel returned %d\n", result);
489 }
490
491 result = inv_send_linear_accel_in_world(INV_ALL, INV_32_BIT);
492 if (result != INV_SUCCESS) {
493 LOGE("Fatal error: inv_send_linear_accel_in_world returned %d\n",
494 result);
495 }
496
497 result = inv_send_gravity(INV_ALL, INV_32_BIT);
498 if (result != INV_SUCCESS) {
499 LOGE("Fatal error: inv_send_gravity returned %d\n", result);
500 }
501
502 result = inv_send_gyro(INV_ALL, INV_32_BIT);
503 if (result != INV_SUCCESS) {
504 LOGE("Fatal error: inv_send_gyro returned %d\n", result);
505 }
506
507}
508
509/**
510 * set up the callbacks that we use in all cases (outside of gestures, etc)
511 */
512void MPLSensor::setupCallbacks()
513{
514 FUNC_LOG;
515 if (inv_set_motion_callback(mot_cb_wrapper) != INV_SUCCESS) {
516 LOGE("Error : Motion callback could not be set.\n");
517
518 }
519
520 if (inv_set_fifo_processed_callback(procData_cb_wrapper) != INV_SUCCESS) {
521 LOGE("Error : Processed data callback could not be set.");
522
523 }
524}
525
526/**
527 * handle the motion/no motion output from the MPL.
528 */
529void MPLSensor::cbOnMotion(uint16_t val)
530{
531 FUNC_LOG;
532 //after the first no motion, the gyro should be calibrated well
533 if (val == 2) {
534 mMpuAccuracy = SENSOR_STATUS_ACCURACY_HIGH;
Kevin Powell147e22f2011-07-29 15:57:44 -0700535 if ((inv_get_dl_config()->requested_sensors) & INV_THREE_AXIS_GYRO) {
Jean-Baptiste Queru42331852011-08-01 10:20:23 -0700536 //if gyros are on and we got a no motion, set a flag
537 // indicating that the cal file can be written.
538 mHaveGoodMpuCal = true;
539 }
540 }
541
542 return;
543}
544
545
546void MPLSensor::cbProcData()
547{
548 mNewData = 1;
549 mSampleCount++;
550 //LOGV_IF(EXTRA_VERBOSE, "new data (%d)", sampleCount);
551}
552
553//these handlers transform mpl data into one of the Android sensor types
554// scaling and coordinate transforms should be done in the handlers
555
556void MPLSensor::gyroHandler(sensors_event_t* s, uint32_t* pending_mask,
557 int index)
558{
559 VFUNC_LOG;
560 inv_error_t res;
561 res = inv_get_float_array(INV_GYROS, s->gyro.v);
562 s->gyro.v[0] = s->gyro.v[0] * M_PI / 180.0;
563 s->gyro.v[1] = s->gyro.v[1] * M_PI / 180.0;
564 s->gyro.v[2] = s->gyro.v[2] * M_PI / 180.0;
565 s->gyro.status = mMpuAccuracy;
566 if (res == INV_SUCCESS)
567 *pending_mask |= (1 << index);
568}
569
570void MPLSensor::accelHandler(sensors_event_t* s, uint32_t* pending_mask,
571 int index)
572{
573 //VFUNC_LOG;
574 inv_error_t res;
575 res = inv_get_float_array(INV_ACCELS, s->acceleration.v);
576 //res = inv_get_accel_float(s->acceleration.v);
577 s->acceleration.v[0] = s->acceleration.v[0] * 9.81;
578 s->acceleration.v[1] = s->acceleration.v[1] * 9.81;
579 s->acceleration.v[2] = s->acceleration.v[2] * 9.81;
580 //LOGV_IF(EXTRA_VERBOSE, "accel data: %f %f %f", s->acceleration.v[0], s->acceleration.v[1], s->acceleration.v[2]);
581 s->acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
582 if (res == INV_SUCCESS)
583 *pending_mask |= (1 << index);
584}
585
586int MPLSensor::estimateCompassAccuracy()
587{
588 inv_error_t res;
589 int rv;
590
591 res = inv_get_compass_accuracy(&rv);
592 LOGE_IF(res != INV_SUCCESS, "error returned from inv_get_compass_accuracy");
593
594 return rv;
595}
596
597void MPLSensor::compassHandler(sensors_event_t* s, uint32_t* pending_mask,
598 int index)
599{
600 VFUNC_LOG;
601 inv_error_t res, res2;
602 float bias_error[3];
603 float total_be;
604 static int bias_error_settled = 0;
605
606 res = inv_get_float_array(INV_MAGNETOMETER, s->magnetic.v);
607
608 if (res != INV_SUCCESS) {
609 LOGD(
610 "compass_handler inv_get_float_array(INV_MAGNETOMETER) returned %d",
611 res);
612 }
613
614 s->magnetic.status = estimateCompassAccuracy();
615
616 if (res == INV_SUCCESS)
617 *pending_mask |= (1 << index);
618}
619
620void MPLSensor::rvHandler(sensors_event_t* s, uint32_t* pending_mask,
621 int index)
622{
623 VFUNC_LOG;
624 float quat[4];
625 float norm = 0;
626 float ang = 0;
627 inv_error_t r;
628
629 r = inv_get_float_array(INV_QUATERNION, quat);
630
631 if (r != INV_SUCCESS) {
632 *pending_mask &= ~(1 << index);
633 return;
634 } else {
635 *pending_mask |= (1 << index);
636 }
637
638 norm = quat[1] * quat[1] + quat[2] * quat[2] + quat[3] * quat[3]
639 + FLT_EPSILON;
640
641 if (norm > 1.0f) {
642 //renormalize
643 norm = sqrtf(norm);
644 float inv_norm = 1.0f / norm;
645 quat[1] = quat[1] * inv_norm;
646 quat[2] = quat[2] * inv_norm;
647 quat[3] = quat[3] * inv_norm;
648 }
649
650 if (quat[0] < 0.0) {
651 quat[1] = -quat[1];
652 quat[2] = -quat[2];
653 quat[3] = -quat[3];
654 }
655
656 s->gyro.v[0] = quat[1];
657 s->gyro.v[1] = quat[2];
658 s->gyro.v[2] = quat[3];
659
660 s->gyro.status
661 = ((mMpuAccuracy < estimateCompassAccuracy()) ? mMpuAccuracy
662 : estimateCompassAccuracy());
663}
664
665void MPLSensor::laHandler(sensors_event_t* s, uint32_t* pending_mask,
666 int index)
667{
668 VFUNC_LOG;
669 inv_error_t res;
670 res = inv_get_float_array(INV_LINEAR_ACCELERATION, s->gyro.v);
671 s->gyro.v[0] *= 9.81;
672 s->gyro.v[1] *= 9.81;
673 s->gyro.v[2] *= 9.81;
674 s->gyro.status = mMpuAccuracy;
675 if (res == INV_SUCCESS)
676 *pending_mask |= (1 << index);
677}
678
679void MPLSensor::gravHandler(sensors_event_t* s, uint32_t* pending_mask,
680 int index)
681{
682 VFUNC_LOG;
683 inv_error_t res;
684 res = inv_get_float_array(INV_GRAVITY, s->gyro.v);
685 s->gyro.v[0] *= 9.81;
686 s->gyro.v[1] *= 9.81;
687 s->gyro.v[2] *= 9.81;
688 s->gyro.status = mMpuAccuracy;
689 if (res == INV_SUCCESS)
690 *pending_mask |= (1 << index);
691}
692
693void MPLSensor::calcOrientationSensor(float *R, float *values)
694{
695 float tmp;
696
697 //Azimuth
698 if ((R[7] > 0.7071067f) || ((R[8] < 0) && (fabs(R[7]) > fabs(R[6])))) {
699 values[0] = (float) atan2f(-R[3], R[0]);
700 } else {
701 values[0] = (float) atan2f(R[1], R[4]);
702 }
703 values[0] *= 57.295779513082320876798154814105f;
704 if (values[0] < 0) {
705 values[0] += 360.0f;
706 }
707 //Pitch
708 tmp = R[7];
709 if (tmp > 1.0f)
710 tmp = 1.0f;
711 if (tmp < -1.0f)
712 tmp = -1.0f;
713 values[1] = -asinf(tmp) * 57.295779513082320876798154814105f;
714 if (R[8] < 0) {
715 values[1] = 180.0f - values[1];
716 }
717 if (values[1] > 180.0f) {
718 values[1] -= 360.0f;
719 }
720 //Roll
721 if ((R[7] > 0.7071067f)) {
722 values[2] = (float) atan2f(R[6], R[7]);
723 } else {
724 values[2] = (float) atan2f(R[6], R[8]);
725 }
726
727 values[2] *= 57.295779513082320876798154814105f;
728 if (values[2] > 90.0f) {
729 values[2] = 180.0f - values[2];
730 }
731 if (values[2] < -90.0f) {
732 values[2] = -180.0f - values[2];
733 }
734}
735
736void MPLSensor::orienHandler(sensors_event_t* s, uint32_t* pending_mask,
737 int index) //note that this is the handler for the android 'orientation' sensor, not the mpl orientation output
738{
739 VFUNC_LOG;
740 inv_error_t res;
741 float euler[3];
742 float heading[1];
743 float rot_mat[9];
744
745 res = inv_get_float_array(INV_ROTATION_MATRIX, rot_mat);
746
747 //ComputeAndOrientation(heading[0], euler, s->orientation.v);
748 calcOrientationSensor(rot_mat, s->orientation.v);
749
750 s->orientation.status
751 = ((mMpuAccuracy < estimateCompassAccuracy()) ? mMpuAccuracy
752 : estimateCompassAccuracy());
753
754 if (res == INV_SUCCESS)
755 *pending_mask |= (1 << index);
756 else
757 LOGD("orien_handler: data not valid (%d)", (int) res);
758
759}
760
761int MPLSensor::enable(int32_t handle, int en)
762{
763 FUNC_LOG;
764 LOGV("handle : %d en: %d", handle, en);
765
766 int what = -1;
767
768 switch (handle) {
769 case ID_A:
770 what = Accelerometer;
771 break;
772 case ID_M:
773 what = MagneticField;
774 break;
775 case ID_O:
776 what = Orientation;
777 break;
778 case ID_GY:
779 what = Gyro;
780 break;
781 case ID_GR:
782 what = Gravity;
783 break;
784 case ID_RV:
785 what = RotationVector;
786 break;
787 case ID_LA:
788 what = LinearAccel;
789 break;
790 default: //this takes care of all the gestures
791 what = handle;
792 break;
793 }
794
795 if (uint32_t(what) >= numSensors)
796 return -EINVAL;
797
798 int newState = en ? 1 : 0;
799 int err = 0;
800 LOGV_IF((uint32_t(newState) << what) != (mEnabled & (1 << what)),
801 "sensor state change what=%d", what);
802
803 pthread_mutex_lock(&mMplMutex);
804 if ((uint32_t(newState) << what) != (mEnabled & (1 << what))) {
805 uint32_t sensor_type;
806 short flags = newState;
807 mEnabled &= ~(1 << what);
808 mEnabled |= (uint32_t(flags) << what);
809 LOGV_IF(EXTRA_VERBOSE, "mEnabled = %x", mEnabled);
810 setPowerStates(mEnabled);
811 pthread_mutex_unlock(&mMplMutex);
812 if (!newState)
813 update_delay();
814 return err;
815 }
816 pthread_mutex_unlock(&mMplMutex);
817 return err;
818}
819
820int MPLSensor::setDelay(int32_t handle, int64_t ns)
821{
822 FUNC_LOG;
823 /* LOGV_IF(EXTRA_VERBOSE, */
824 LOGE(" setDelay handle: %d rate %d", handle, (int) (ns / 1000000LL));
825 int what = -1;
826 switch (handle) {
827 case ID_A:
828 what = Accelerometer;
829 break;
830 case ID_M:
831 what = MagneticField;
832 break;
833 case ID_O:
834 what = Orientation;
835 break;
836 case ID_GY:
837 what = Gyro;
838 break;
839 case ID_GR:
840 what = Gravity;
841 break;
842 case ID_RV:
843 what = RotationVector;
844 break;
845 case ID_LA:
846 what = LinearAccel;
847 break;
848 default:
849 what = handle;
850 break;
851 }
852
853 if (uint32_t(what) >= numSensors)
854 return -EINVAL;
855
856 if (ns < 0)
857 return -EINVAL;
858
859 pthread_mutex_lock(&mMplMutex);
860 mDelays[what] = ns;
861 pthread_mutex_unlock(&mMplMutex);
862 return update_delay();
863}
864
865int MPLSensor::update_delay()
866{
867 FUNC_LOG;
868 int rv = 0;
869 bool irq_set[5];
870
871 pthread_mutex_lock(&mMplMutex);
872
873 if (mEnabled) {
874 uint64_t wanted = -1LLU;
875 for (int i = 0; i < numSensors; i++) {
876 if (mEnabled & (1 << i)) {
877 uint64_t ns = mDelays[i];
878 wanted = wanted < ns ? wanted : ns;
879 }
880 }
881
882 //Limit all rates to 100Hz max. 100Hz = 10ms = 10000000ns
883 if (wanted < 10000000LLU) {
884 wanted = 10000000LLU;
885 }
886
887 int rate = ((wanted) / 5000000LLU) - ((wanted % 5000000LLU == 0) ? 1
888 : 0); //mpu fifo rate is in increments of 5ms
889 if (rate == 0) //KLP disallow fifo rate 0
890 rate = 1;
891
892 if (rate != mCurFifoRate) {
893 LOGV("set fifo rate: %d %llu", rate, wanted);
894 inv_error_t res; // = inv_dmp_stop();
895 res = inv_set_fifo_rate(rate);
896 LOGE_IF(res != INV_SUCCESS, "error setting FIFO rate");
897
898 //res = inv_dmp_start();
899 //LOGE_IF(res != INV_SUCCESS, "error re-starting DMP");
900
901 mCurFifoRate = rate;
902 rv = (res == INV_SUCCESS);
903 }
904
905 if (((inv_get_dl_config()->requested_sensors & INV_DMP_PROCESSOR) == 0)) {
906 if (mUseTimerirq) {
907 ioctl(mIrqFds.valueFor(TIMERIRQ_FD), TIMERIRQ_STOP, 0);
908 clearIrqData(irq_set);
909 if (inv_get_dl_config()->requested_sensors
910 == INV_THREE_AXIS_COMPASS) {
911 ioctl(mIrqFds.valueFor(TIMERIRQ_FD), TIMERIRQ_START,
912 (unsigned long) (wanted / 1000000LLU));
913 LOGV_IF(EXTRA_VERBOSE, "updated timerirq period to %d",
914 (int) (wanted / 1000000LLU));
915 } else {
916 ioctl(mIrqFds.valueFor(TIMERIRQ_FD), TIMERIRQ_START,
917 (unsigned long) inv_get_sample_step_size_ms());
918 LOGV_IF(EXTRA_VERBOSE, "updated timerirq period to %d",
919 (int) inv_get_sample_step_size_ms());
920 }
921 }
922 }
923
924 }
925 pthread_mutex_unlock(&mMplMutex);
926 return rv;
927}
928
929/* return the current time in nanoseconds */
930int64_t MPLSensor::now_ns(void)
931{
932 //FUNC_LOG;
933 struct timespec ts;
934
935 clock_gettime(CLOCK_MONOTONIC, &ts);
936 //LOGV("Time %lld", (int64_t)ts.tv_sec * 1000000000 + ts.tv_nsec);
937 return (int64_t) ts.tv_sec * 1000000000 + ts.tv_nsec;
938}
939
940int MPLSensor::readEvents(sensors_event_t* data, int count)
941{
942 //VFUNC_LOG;
943 int i;
944 bool irq_set[5] = { false, false, false, false, false };
945 inv_error_t rv;
946 if (count < 1)
947 return -EINVAL;
948 int numEventReceived = 0;
949
950 clearIrqData(irq_set);
951
952 pthread_mutex_lock(&mMplMutex);
953 if (mDmpStarted) {
954 //LOGV_IF(EXTRA_VERBOSE, "Update Data");
955 rv = inv_update_data();
956 LOGE_IF(rv != INV_SUCCESS, "inv_update_data error (code %d)", (int) rv);
957 }
958
959 else {
960 //probably just one extra read after shutting down
961 LOGV_IF(EXTRA_VERBOSE,
962 "MPLSensor::readEvents called, but there's nothing to do.");
963 }
964
965 pthread_mutex_unlock(&mMplMutex);
966
967 if (!mNewData) {
968 LOGV_IF(EXTRA_VERBOSE, "no new data");
969 return 0;
970 }
971 mNewData = 0;
972 int64_t tt = now_ns();
973 pthread_mutex_lock(&mMplMutex);
974 for (int i = 0; i < numSensors; i++) {
975 if (mEnabled & (1 << i)) {
976 CALL_MEMBER_FN(this,mHandlers[i])(mPendingEvents + i,
977 &mPendingMask, i);
978 mPendingEvents[i].timestamp = tt;
979 }
980 }
981
982 for (int j = 0; count && mPendingMask && j < numSensors; j++) {
983 if (mPendingMask & (1 << j)) {
984 mPendingMask &= ~(1 << j);
985 if (mEnabled & (1 << j)) {
986 *data++ = mPendingEvents[j];
987 count--;
988 numEventReceived++;
989 }
990 }
991
992 }
993
994 pthread_mutex_unlock(&mMplMutex);
995 return numEventReceived;
996}
997
998int MPLSensor::getFd() const
999{
1000 LOGV("MPLSensor::getFd returning %d", data_fd);
1001 return data_fd;
1002}
1003
1004int MPLSensor::getAccelFd() const
1005{
1006 LOGV("MPLSensor::getAccelFd returning %d", accel_fd);
1007 return accel_fd;
1008}
1009
1010int MPLSensor::getTimerFd() const
1011{
1012 LOGV("MPLSensor::getTimerFd returning %d", timer_fd);
1013 return timer_fd;
1014}
1015
1016int MPLSensor::getPowerFd() const
1017{
1018 int hdl = (int) inv_get_serial_handle();
1019 LOGV("MPLSensor::getPowerFd returning %d", hdl);
1020 return hdl;
1021}
1022
1023int MPLSensor::getPollTime()
1024{
1025 return mPollTime;
1026}
1027
1028bool MPLSensor::hasPendingEvents() const
1029{
1030 //if we are using the polling workaround, force the main loop to check for data every time
1031 return (mPollTime != -1);
1032}
1033
1034void MPLSensor::handlePowerEvent()
1035{
1036 VFUNC_LOG;
1037 mpuirq_data irqd;
1038
1039 int fd = (int) inv_get_serial_handle();
1040 read(fd, &irqd, sizeof(irqd));
1041
1042 if (irqd.data == MPU_PM_EVENT_SUSPEND_PREPARE) {
1043 //going to sleep
1044 sleepEvent();
1045 } else if (irqd.data == MPU_PM_EVENT_POST_SUSPEND) {
1046 //waking up
1047 wakeEvent();
1048 }
1049
1050 ioctl(fd, MPU_PM_EVENT_HANDLED, 0);
1051}
1052
1053void MPLSensor::sleepEvent()
1054{
1055 VFUNC_LOG;
1056 pthread_mutex_lock(&mMplMutex);
1057 if (mEnabled != 0) {
1058 mForceSleep = true;
1059 mOldEnabledMask = mEnabled;
1060 setPowerStates(0);
1061 }
1062 pthread_mutex_unlock(&mMplMutex);
1063}
1064
1065void MPLSensor::wakeEvent()
1066{
1067 VFUNC_LOG;
1068 pthread_mutex_lock(&mMplMutex);
1069 if (mForceSleep) {
1070 setPowerStates((mOldEnabledMask | mEnabled));
1071 }
1072 mForceSleep = false;
1073 pthread_mutex_unlock(&mMplMutex);
1074}