1/* 2* Copyright (C) 2014 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 19//see also the EXTRA_VERBOSE define in the MPLSensor.h header file 20 21#include <fcntl.h> 22#include <errno.h> 23#include <math.h> 24#include <float.h> 25#include <poll.h> 26#include <unistd.h> 27#include <dirent.h> 28#include <stdlib.h> 29#include <sys/select.h> 30#include <sys/syscall.h> 31#include <dlfcn.h> 32#include <pthread.h> 33#include <cutils/log.h> 34#include <utils/KeyedVector.h> 35#include <utils/Vector.h> 36#include <utils/String8.h> 37#include <string.h> 38#include <linux/input.h> 39#include <utils/Atomic.h> 40 41#include "MPLSensor.h" 42#include "PressureSensor.IIO.secondary.h" 43#include "MPLSupport.h" 44#include "sensor_params.h" 45 46#include "invensense.h" 47#include "invensense_adv.h" 48#include "ml_stored_data.h" 49#include "ml_load_dmp.h" 50#include "ml_sysfs_helper.h" 51 52#define ENABLE_MULTI_RATE 53// #define TESTING 54#define USE_LPQ_AT_FASTEST 55 56#ifdef THIRD_PARTY_ACCEL 57#pragma message("HAL:build third party accel support") 58#define USE_THIRD_PARTY_ACCEL (1) 59#else 60#define USE_THIRD_PARTY_ACCEL (0) 61#endif 62 63#define MAX_SYSFS_ATTRB (sizeof(struct sysfs_attrbs) / sizeof(char*)) 64 65/******************************************************************************/ 66/* MPL Interface */ 67/******************************************************************************/ 68 69//#define INV_PLAYBACK_DBG 70#ifdef INV_PLAYBACK_DBG 71static FILE *logfile = NULL; 72#endif 73 74/******************************************************************************* 75 * MPLSensor class implementation 76 ******************************************************************************/ 77 78static struct timespec mt_pre; 79 80// following extended initializer list would only be available with -std=c++11 81// or -std=gnu+11 82MPLSensor::MPLSensor(CompassSensor *compass, int (*m_pt2AccelCalLoadFunc)(long *)) 83 : SensorBase(NULL, NULL), 84 mMasterSensorMask(INV_ALL_SENSORS), 85 mLocalSensorMask(0), 86 mPollTime(-1), 87 mStepCountPollTime(-1), 88 mHaveGoodMpuCal(0), 89 mGyroAccuracy(0), 90 mAccelAccuracy(0), 91 mCompassAccuracy(0), 92 dmp_orient_fd(-1), 93 mDmpOrientationEnabled(0), 94 dmp_sign_motion_fd(-1), 95 mDmpSignificantMotionEnabled(0), 96 dmp_pedometer_fd(-1), 97 mDmpPedometerEnabled(0), 98 mDmpStepCountEnabled(0), 99 mEnabled(0), 100 mBatchEnabled(0), 101 mOldBatchEnabledMask(0), 102 mAccelInputReader(4), 103 mGyroInputReader(32), 104 mTempScale(0), 105 mTempOffset(0), 106 mTempCurrentTime(0), 107 mAccelScale(2), 108 mAccelSelfTestScale(2), 109 mGyroScale(2000), 110 mGyroSelfTestScale(2000), 111 mCompassScale(0), 112 mFactoryGyroBiasAvailable(false), 113 mGyroBiasAvailable(false), 114 mGyroBiasApplied(false), 115 mFactoryAccelBiasAvailable(false), 116 mAccelBiasAvailable(false), 117 mAccelBiasApplied(false), 118 mPendingMask(0), 119 mSensorMask(0), 120 mMplFeatureActiveMask(0), 121 mFeatureActiveMask(0), 122 mDmpOn(0), 123 mPedUpdate(0), 124 mPressureUpdate(0), 125 mQuatSensorTimestamp(0), 126 mStepSensorTimestamp(0), 127 mLastStepCount(-1), 128 mLeftOverBufferSize(0), 129 mInitial6QuatValueAvailable(0), 130 mFlushBatchSet(0), 131 mSkipReadEvents(0), 132 mDataMarkerDetected(0), 133 mEmptyDataMarkerDetected(0) { 134 VFUNC_LOG; 135 136 inv_error_t rv; 137 int i, fd; 138 char *port = NULL; 139 char *ver_str; 140 unsigned long mSensorMask; 141 int res; 142 FILE *fptr; 143 144 mCompassSensor = compass; 145 146 LOGV_IF(EXTRA_VERBOSE, 147 "HAL:MPLSensor constructor : NumSensors = %d", NumSensors); 148 149 pthread_mutex_init(&mMplMutex, NULL); 150 pthread_mutex_init(&mHALMutex, NULL); 151 memset(mGyroOrientation, 0, sizeof(mGyroOrientation)); 152 memset(mAccelOrientation, 0, sizeof(mAccelOrientation)); 153 memset(mInitial6QuatValue, 0, sizeof(mInitial6QuatValue)); 154 mFlushSensorEnabledVector.setCapacity(NumSensors); 155 156 /* setup sysfs paths */ 157 inv_init_sysfs_attributes(); 158 159 /* get chip name */ 160 if (inv_get_chip_name(chip_ID) != INV_SUCCESS) { 161 LOGE("HAL:ERR- Failed to get chip ID\n"); 162 } else { 163 LOGV_IF(PROCESS_VERBOSE, "HAL:Chip ID= %s\n", chip_ID); 164 } 165 166 enable_iio_sysfs(); 167 168#ifdef ENABLE_PRESSURE 169 /* instantiate pressure sensor on secondary bus */ 170 mPressureSensor = new PressureSensor((const char*)mSysfsPath); 171#endif 172 173 /* reset driver master enable */ 174 masterEnable(0); 175 176 /* Load DMP image if capable, ie. MPU6515 */ 177 loadDMP(); 178 179 /* open temperature fd for temp comp */ 180 LOGV_IF(EXTRA_VERBOSE, "HAL:gyro temperature path: %s", mpu.temperature); 181 gyro_temperature_fd = open(mpu.temperature, O_RDONLY); 182 if (gyro_temperature_fd == -1) { 183 LOGE("HAL:could not open temperature node"); 184 } else { 185 LOGV_IF(EXTRA_VERBOSE, 186 "HAL:temperature_fd opened: %s", mpu.temperature); 187 } 188 189 /* read gyro FSR to calculate accel scale later */ 190 char gyroBuf[5]; 191 int count = 0; 192 LOGV_IF(SYSFS_VERBOSE, 193 "HAL:sysfs:cat %s (%lld)", mpu.gyro_fsr, getTimestamp()); 194 195 fd = open(mpu.gyro_fsr, O_RDONLY); 196 if(fd < 0) { 197 LOGE("HAL:Error opening gyro FSR"); 198 } else { 199 memset(gyroBuf, 0, sizeof(gyroBuf)); 200 count = read_attribute_sensor(fd, gyroBuf, sizeof(gyroBuf)); 201 if(count < 1) { 202 LOGE("HAL:Error reading gyro FSR"); 203 } else { 204 count = sscanf(gyroBuf, "%ld", &mGyroScale); 205 if(count) 206 LOGV_IF(EXTRA_VERBOSE, "HAL:Gyro FSR used %ld", mGyroScale); 207 } 208 close(fd); 209 } 210 211 /* read gyro self test scale used to calculate factory cal bias later */ 212 char gyroScale[5]; 213 LOGV_IF(SYSFS_VERBOSE, 214 "HAL:sysfs:cat %s (%lld)", mpu.in_gyro_self_test_scale, getTimestamp()); 215 fd = open(mpu.in_gyro_self_test_scale, O_RDONLY); 216 if(fd < 0) { 217 LOGE("HAL:Error opening gyro self test scale"); 218 } else { 219 memset(gyroBuf, 0, sizeof(gyroBuf)); 220 count = read_attribute_sensor(fd, gyroScale, sizeof(gyroScale)); 221 if(count < 1) { 222 LOGE("HAL:Error reading gyro self test scale"); 223 } else { 224 count = sscanf(gyroScale, "%ld", &mGyroSelfTestScale); 225 if(count) 226 LOGV_IF(EXTRA_VERBOSE, "HAL:Gyro self test scale used %ld", mGyroSelfTestScale); 227 } 228 close(fd); 229 } 230 231 /* open Factory Gyro Bias fd */ 232 /* mFactoryGyBias contains bias values that will be used for device offset */ 233 memset(mFactoryGyroBias, 0, sizeof(mFactoryGyroBias)); 234 LOGV_IF(EXTRA_VERBOSE, "HAL:factory gyro x offset path: %s", mpu.in_gyro_x_offset); 235 LOGV_IF(EXTRA_VERBOSE, "HAL:factory gyro y offset path: %s", mpu.in_gyro_y_offset); 236 LOGV_IF(EXTRA_VERBOSE, "HAL:factory gyro z offset path: %s", mpu.in_gyro_z_offset); 237 gyro_x_offset_fd = open(mpu.in_gyro_x_offset, O_RDWR); 238 gyro_y_offset_fd = open(mpu.in_gyro_y_offset, O_RDWR); 239 gyro_z_offset_fd = open(mpu.in_gyro_z_offset, O_RDWR); 240 if (gyro_x_offset_fd == -1 || 241 gyro_y_offset_fd == -1 || gyro_z_offset_fd == -1) { 242 LOGE("HAL:could not open factory gyro calibrated bias"); 243 } else { 244 LOGV_IF(EXTRA_VERBOSE, 245 "HAL:gyro_offset opened"); 246 } 247 248 /* open Gyro Bias fd */ 249 /* mGyroBias contains bias values that will be used for framework */ 250 /* mGyroChipBias contains bias values that will be used for dmp */ 251 memset(mGyroBias, 0, sizeof(mGyroBias)); 252 memset(mGyroChipBias, 0, sizeof(mGyroChipBias)); 253 LOGV_IF(EXTRA_VERBOSE, "HAL: gyro x dmp bias path: %s", mpu.in_gyro_x_dmp_bias); 254 LOGV_IF(EXTRA_VERBOSE, "HAL: gyro y dmp bias path: %s", mpu.in_gyro_y_dmp_bias); 255 LOGV_IF(EXTRA_VERBOSE, "HAL: gyro z dmp bias path: %s", mpu.in_gyro_z_dmp_bias); 256 gyro_x_dmp_bias_fd = open(mpu.in_gyro_x_dmp_bias, O_RDWR); 257 gyro_y_dmp_bias_fd = open(mpu.in_gyro_y_dmp_bias, O_RDWR); 258 gyro_z_dmp_bias_fd = open(mpu.in_gyro_z_dmp_bias, O_RDWR); 259 if (gyro_x_dmp_bias_fd == -1 || 260 gyro_y_dmp_bias_fd == -1 || gyro_z_dmp_bias_fd == -1) { 261 LOGE("HAL:could not open gyro DMP calibrated bias"); 262 } else { 263 LOGV_IF(EXTRA_VERBOSE, 264 "HAL:gyro_dmp_bias opened"); 265 } 266 267 /* read accel FSR to calcuate accel scale later */ 268 if (USE_THIRD_PARTY_ACCEL == 0) { 269 char buf[3]; 270 int count = 0; 271 LOGV_IF(SYSFS_VERBOSE, 272 "HAL:sysfs:cat %s (%lld)", mpu.accel_fsr, getTimestamp()); 273 274 fd = open(mpu.accel_fsr, O_RDONLY); 275 if(fd < 0) { 276 LOGE("HAL:Error opening accel FSR"); 277 } else { 278 memset(buf, 0, sizeof(buf)); 279 count = read_attribute_sensor(fd, buf, sizeof(buf)); 280 if(count < 1) { 281 LOGE("HAL:Error reading accel FSR"); 282 } else { 283 count = sscanf(buf, "%d", &mAccelScale); 284 if(count) 285 LOGV_IF(EXTRA_VERBOSE, "HAL:Accel FSR used %d", mAccelScale); 286 } 287 close(fd); 288 } 289 290 /* read accel self test scale used to calculate factory cal bias later */ 291 char accelScale[5]; 292 LOGV_IF(SYSFS_VERBOSE, 293 "HAL:sysfs:cat %s (%lld)", mpu.in_accel_self_test_scale, getTimestamp()); 294 fd = open(mpu.in_accel_self_test_scale, O_RDONLY); 295 if(fd < 0) { 296 LOGE("HAL:Error opening gyro self test scale"); 297 } else { 298 memset(buf, 0, sizeof(buf)); 299 count = read_attribute_sensor(fd, accelScale, sizeof(accelScale)); 300 if(count < 1) { 301 LOGE("HAL:Error reading accel self test scale"); 302 } else { 303 count = sscanf(accelScale, "%ld", &mAccelSelfTestScale); 304 if(count) 305 LOGV_IF(EXTRA_VERBOSE, "HAL:Accel self test scale used %ld", mAccelSelfTestScale); 306 } 307 close(fd); 308 } 309 310 /* open Factory Accel Bias fd */ 311 /* mFactoryAccelBias contains bias values that will be used for device offset */ 312 memset(mFactoryAccelBias, 0, sizeof(mFactoryAccelBias)); 313 LOGV_IF(EXTRA_VERBOSE, "HAL:factory accel x offset path: %s", mpu.in_accel_x_offset); 314 LOGV_IF(EXTRA_VERBOSE, "HAL:factory accel y offset path: %s", mpu.in_accel_y_offset); 315 LOGV_IF(EXTRA_VERBOSE, "HAL:factory accel z offset path: %s", mpu.in_accel_z_offset); 316 accel_x_offset_fd = open(mpu.in_accel_x_offset, O_RDWR); 317 accel_y_offset_fd = open(mpu.in_accel_y_offset, O_RDWR); 318 accel_z_offset_fd = open(mpu.in_accel_z_offset, O_RDWR); 319 if (accel_x_offset_fd == -1 || 320 accel_y_offset_fd == -1 || accel_z_offset_fd == -1) { 321 LOGE("HAL:could not open factory accel calibrated bias"); 322 } else { 323 LOGV_IF(EXTRA_VERBOSE, 324 "HAL:accel_offset opened"); 325 } 326 327 /* open Accel Bias fd */ 328 /* mAccelBias contains bias that will be used for dmp */ 329 memset(mAccelBias, 0, sizeof(mAccelBias)); 330 LOGV_IF(EXTRA_VERBOSE, "HAL:accel x dmp bias path: %s", mpu.in_accel_x_dmp_bias); 331 LOGV_IF(EXTRA_VERBOSE, "HAL:accel y dmp bias path: %s", mpu.in_accel_y_dmp_bias); 332 LOGV_IF(EXTRA_VERBOSE, "HAL:accel z dmp bias path: %s", mpu.in_accel_z_dmp_bias); 333 accel_x_dmp_bias_fd = open(mpu.in_accel_x_dmp_bias, O_RDWR); 334 accel_y_dmp_bias_fd = open(mpu.in_accel_y_dmp_bias, O_RDWR); 335 accel_z_dmp_bias_fd = open(mpu.in_accel_z_dmp_bias, O_RDWR); 336 if (accel_x_dmp_bias_fd == -1 || 337 accel_y_dmp_bias_fd == -1 || accel_z_dmp_bias_fd == -1) { 338 LOGE("HAL:could not open accel DMP calibrated bias"); 339 } else { 340 LOGV_IF(EXTRA_VERBOSE, 341 "HAL:accel_dmp_bias opened"); 342 } 343 } 344 345 dmp_sign_motion_fd = open(mpu.event_smd, O_RDONLY | O_NONBLOCK); 346 if (dmp_sign_motion_fd < 0) { 347 LOGE("HAL:ERR couldn't open dmp_sign_motion node"); 348 } else { 349 LOGV_IF(ENG_VERBOSE, 350 "HAL:dmp_sign_motion_fd opened : %d", dmp_sign_motion_fd); 351 } 352#if 1 353 /* the following threshold can be modified for SMD sensitivity */ 354 int motionThreshold = 3000; 355 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 356 motionThreshold, mpu.smd_threshold, getTimestamp()); 357 res = write_sysfs_int(mpu.smd_threshold, motionThreshold); 358#endif 359#if 0 360 int StepCounterThreshold = 5; 361 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 362 StepCounterThreshold, mpu.pedometer_step_thresh, getTimestamp()); 363 res = write_sysfs_int(mpu.pedometer_step_thresh, StepCounterThreshold); 364#endif 365 366 dmp_pedometer_fd = open(mpu.event_pedometer, O_RDONLY | O_NONBLOCK); 367 if (dmp_pedometer_fd < 0) { 368 LOGE("HAL:ERR couldn't open dmp_pedometer node"); 369 } else { 370 LOGV_IF(ENG_VERBOSE, 371 "HAL:dmp_pedometer_fd opened : %d", dmp_pedometer_fd); 372 } 373 374 initBias(); 375 376 (void)inv_get_version(&ver_str); 377 LOGI("%s\n", ver_str); 378 379 /* setup MPL */ 380 inv_constructor_init(); 381 382#ifdef INV_PLAYBACK_DBG 383 LOGV_IF(PROCESS_VERBOSE, "HAL:inv_turn_on_data_logging"); 384 logfile = fopen("/data/playback.bin", "w+"); 385 if (logfile) 386 inv_turn_on_data_logging(logfile); 387#endif 388 389 /* setup orientation matrix and scale */ 390 inv_set_device_properties(); 391 392 /* initialize sensor data */ 393 memset(mPendingEvents, 0, sizeof(mPendingEvents)); 394 memset(mPendingFlushEvents, 0, sizeof(mPendingEvents)); 395 396 mPendingEvents[RotationVector].version = sizeof(sensors_event_t); 397 mPendingEvents[RotationVector].sensor = ID_RV; 398 mPendingEvents[RotationVector].type = SENSOR_TYPE_ROTATION_VECTOR; 399 mPendingEvents[RotationVector].acceleration.status 400 = SENSOR_STATUS_ACCURACY_HIGH; 401 402 mPendingEvents[GameRotationVector].version = sizeof(sensors_event_t); 403 mPendingEvents[GameRotationVector].sensor = ID_GRV; 404 mPendingEvents[GameRotationVector].type = SENSOR_TYPE_GAME_ROTATION_VECTOR; 405 mPendingEvents[GameRotationVector].acceleration.status 406 = SENSOR_STATUS_ACCURACY_HIGH; 407 408 mPendingEvents[LinearAccel].version = sizeof(sensors_event_t); 409 mPendingEvents[LinearAccel].sensor = ID_LA; 410 mPendingEvents[LinearAccel].type = SENSOR_TYPE_LINEAR_ACCELERATION; 411 mPendingEvents[LinearAccel].acceleration.status 412 = SENSOR_STATUS_ACCURACY_HIGH; 413 414 mPendingEvents[Gravity].version = sizeof(sensors_event_t); 415 mPendingEvents[Gravity].sensor = ID_GR; 416 mPendingEvents[Gravity].type = SENSOR_TYPE_GRAVITY; 417 mPendingEvents[Gravity].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH; 418 419 mPendingEvents[Gyro].version = sizeof(sensors_event_t); 420 mPendingEvents[Gyro].sensor = ID_GY; 421 mPendingEvents[Gyro].type = SENSOR_TYPE_GYROSCOPE; 422 mPendingEvents[Gyro].gyro.status = SENSOR_STATUS_ACCURACY_HIGH; 423 424 mPendingEvents[RawGyro].version = sizeof(sensors_event_t); 425 mPendingEvents[RawGyro].sensor = ID_RG; 426 mPendingEvents[RawGyro].type = SENSOR_TYPE_GYROSCOPE_UNCALIBRATED; 427 mPendingEvents[RawGyro].gyro.status = SENSOR_STATUS_ACCURACY_HIGH; 428 429 mPendingEvents[Accelerometer].version = sizeof(sensors_event_t); 430 mPendingEvents[Accelerometer].sensor = ID_A; 431 mPendingEvents[Accelerometer].type = SENSOR_TYPE_ACCELEROMETER; 432 mPendingEvents[Accelerometer].acceleration.status 433 = SENSOR_STATUS_ACCURACY_HIGH; 434 435 /* Invensense compass calibration */ 436 mPendingEvents[MagneticField].version = sizeof(sensors_event_t); 437 mPendingEvents[MagneticField].sensor = ID_M; 438 mPendingEvents[MagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD; 439 mPendingEvents[MagneticField].magnetic.status = 440 SENSOR_STATUS_ACCURACY_HIGH; 441 442 mPendingEvents[RawMagneticField].version = sizeof(sensors_event_t); 443 mPendingEvents[RawMagneticField].sensor = ID_RM; 444 mPendingEvents[RawMagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED; 445 mPendingEvents[RawMagneticField].magnetic.status = 446 SENSOR_STATUS_ACCURACY_HIGH; 447 448#ifdef ENABLE_PRESSURE 449 mPendingEvents[Pressure].version = sizeof(sensors_event_t); 450 mPendingEvents[Pressure].sensor = ID_PS; 451 mPendingEvents[Pressure].type = SENSOR_TYPE_PRESSURE; 452 mPendingEvents[Pressure].magnetic.status = 453 SENSOR_STATUS_ACCURACY_HIGH; 454#endif 455 456 mPendingEvents[Orientation].version = sizeof(sensors_event_t); 457 mPendingEvents[Orientation].sensor = ID_O; 458 mPendingEvents[Orientation].type = SENSOR_TYPE_ORIENTATION; 459 mPendingEvents[Orientation].orientation.status 460 = SENSOR_STATUS_ACCURACY_HIGH; 461 462 mPendingEvents[GeomagneticRotationVector].version = sizeof(sensors_event_t); 463 mPendingEvents[GeomagneticRotationVector].sensor = ID_GMRV; 464 mPendingEvents[GeomagneticRotationVector].type 465 = SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR; 466 mPendingEvents[GeomagneticRotationVector].acceleration.status 467 = SENSOR_STATUS_ACCURACY_HIGH; 468 469 mSmEvents.version = sizeof(sensors_event_t); 470 mSmEvents.sensor = ID_SM; 471 mSmEvents.type = SENSOR_TYPE_SIGNIFICANT_MOTION; 472 mSmEvents.acceleration.status = SENSOR_STATUS_UNRELIABLE; 473 474 mSdEvents.version = sizeof(sensors_event_t); 475 mSdEvents.sensor = ID_P; 476 mSdEvents.type = SENSOR_TYPE_STEP_DETECTOR; 477 mSdEvents.acceleration.status = SENSOR_STATUS_UNRELIABLE; 478 479 mScEvents.version = sizeof(sensors_event_t); 480 mScEvents.sensor = ID_SC; 481 mScEvents.type = SENSOR_TYPE_STEP_COUNTER; 482 mScEvents.acceleration.status = SENSOR_STATUS_UNRELIABLE; 483 484 /* Event Handlers for HW and Virtual Sensors */ 485 mHandlers[RotationVector] = &MPLSensor::rvHandler; 486 mHandlers[GameRotationVector] = &MPLSensor::grvHandler; 487 mHandlers[LinearAccel] = &MPLSensor::laHandler; 488 mHandlers[Gravity] = &MPLSensor::gravHandler; 489 mHandlers[Gyro] = &MPLSensor::gyroHandler; 490 mHandlers[RawGyro] = &MPLSensor::rawGyroHandler; 491 mHandlers[Accelerometer] = &MPLSensor::accelHandler; 492 mHandlers[MagneticField] = &MPLSensor::compassHandler; 493 mHandlers[RawMagneticField] = &MPLSensor::rawCompassHandler; 494 mHandlers[Orientation] = &MPLSensor::orienHandler; 495 mHandlers[GeomagneticRotationVector] = &MPLSensor::gmHandler; 496#ifdef ENABLE_PRESSURE 497 mHandlers[Pressure] = &MPLSensor::psHandler; 498#endif 499 500 /* initialize delays to reasonable values */ 501 for (int i = 0; i < NumSensors; i++) { 502 mDelays[i] = 1000000000LL; 503 mBatchDelays[i] = 1000000000LL; 504 mBatchTimeouts[i] = 100000000000LL; 505 } 506 507 /* initialize Compass Bias */ 508 memset(mCompassBias, 0, sizeof(mCompassBias)); 509 510 /* initialize Factory Accel Bias */ 511 memset(mFactoryAccelBias, 0, sizeof(mFactoryAccelBias)); 512 513 /* initialize Gyro Bias */ 514 memset(mGyroBias, 0, sizeof(mGyroBias)); 515 memset(mGyroChipBias, 0, sizeof(mGyroChipBias)); 516 517 /* load calibration file from /data/inv_cal_data.bin */ 518 rv = inv_load_calibration(); 519 if(rv == INV_SUCCESS) { 520 LOGV_IF(PROCESS_VERBOSE, "HAL:Calibration file successfully loaded"); 521 /* Get initial values */ 522 getCompassBias(); 523 getGyroBias(); 524 if (mGyroBiasAvailable) { 525 setGyroBias(); 526 } 527 getAccelBias(); 528 getFactoryGyroBias(); 529 if (mFactoryGyroBiasAvailable) { 530 setFactoryGyroBias(); 531 } 532 getFactoryAccelBias(); 533 if (mFactoryAccelBiasAvailable) { 534 setFactoryAccelBias(); 535 } 536 } 537 else 538 LOGE("HAL:Could not open or load MPL calibration file (%d)", rv); 539 540 /* takes external accel calibration load workflow */ 541 if( m_pt2AccelCalLoadFunc != NULL) { 542 long accel_offset[3]; 543 long tmp_offset[3]; 544 int result = m_pt2AccelCalLoadFunc(accel_offset); 545 if(result) 546 LOGW("HAL:Vendor accelerometer calibration file load failed %d\n", 547 result); 548 else { 549 LOGW("HAL:Vendor accelerometer calibration file successfully " 550 "loaded"); 551 inv_get_mpl_accel_bias(tmp_offset, NULL); 552 LOGV_IF(PROCESS_VERBOSE, 553 "HAL:Original accel offset, %ld, %ld, %ld\n", 554 tmp_offset[0], tmp_offset[1], tmp_offset[2]); 555 inv_set_accel_bias_mask(accel_offset, mAccelAccuracy,4); 556 inv_get_mpl_accel_bias(tmp_offset, NULL); 557 LOGV_IF(PROCESS_VERBOSE, "HAL:Set accel offset, %ld, %ld, %ld\n", 558 tmp_offset[0], tmp_offset[1], tmp_offset[2]); 559 } 560 } 561 /* end of external accel calibration load workflow */ 562 563 /* disable all sensors and features */ 564 masterEnable(0); 565 enableGyro(0); 566 enableLowPowerAccel(0); 567 enableAccel(0); 568 enableCompass(0,0); 569#ifdef ENABLE_PRESSURE 570 enablePressure(0); 571#endif 572 enableBatch(0); 573 574 if (isLowPowerQuatEnabled()) { 575 enableLPQuaternion(0); 576 } 577 578 if (isDmpDisplayOrientationOn()) { 579 // open DMP Orient Fd 580 openDmpOrientFd(); 581 enableDmpOrientation(!isDmpScreenAutoRotationEnabled()); 582 } 583} 584 585void MPLSensor::enable_iio_sysfs(void) 586{ 587 VFUNC_LOG; 588 589 char iio_device_node[MAX_CHIP_ID_LEN]; 590 FILE *tempFp = NULL; 591 592 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo 1 > %s (%lld)", 593 mpu.in_timestamp_en, getTimestamp()); 594 // Either fopen()/open() are okay for sysfs access 595 // developers could choose what they want 596 // with fopen(), the benefit is that fprintf()/fscanf() are available 597 tempFp = fopen(mpu.in_timestamp_en, "w"); 598 if (tempFp == NULL) { 599 LOGE("HAL:could not open timestamp enable"); 600 } else { 601 if(fprintf(tempFp, "%d", 1) < 0) { 602 LOGE("HAL:could not enable timestamp"); 603 } 604 if(fclose(tempFp) < 0) { 605 LOGE("HAL:could not close timestamp"); 606 } 607 } 608 609 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 610 IIO_BUFFER_LENGTH, mpu.buffer_length, getTimestamp()); 611 tempFp = fopen(mpu.buffer_length, "w"); 612 if (tempFp == NULL) { 613 LOGE("HAL:could not open buffer length"); 614 } else { 615 if (fprintf(tempFp, "%d", IIO_BUFFER_LENGTH) < 0) { 616 LOGE("HAL:could not write buffer length"); 617 } 618 if (fclose(tempFp) < 0) { 619 LOGE("HAL:could not close buffer length"); 620 } 621 } 622 623 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 624 1, mpu.chip_enable, getTimestamp()); 625 tempFp = fopen(mpu.chip_enable, "w"); 626 if (tempFp == NULL) { 627 LOGE("HAL:could not open chip enable"); 628 } else { 629 if (fprintf(tempFp, "%d", 1) < 0) { 630 LOGE("HAL:could not write chip enable"); 631 } 632 if (fclose(tempFp) < 0) { 633 LOGE("HAL:could not close chip enable"); 634 } 635 } 636 637 inv_get_iio_device_node(iio_device_node); 638 iio_fd = open(iio_device_node, O_RDONLY); 639 if (iio_fd < 0) { 640 LOGE("HAL:could not open iio device node"); 641 } else { 642 LOGV_IF(ENG_VERBOSE, "HAL:iio iio_fd opened : %d", iio_fd); 643 } 644} 645 646int MPLSensor::inv_constructor_init(void) 647{ 648 VFUNC_LOG; 649 650 inv_error_t result = inv_init_mpl(); 651 if (result) { 652 LOGE("HAL:inv_init_mpl() failed"); 653 return result; 654 } 655 result = inv_constructor_default_enable(); 656 result = inv_start_mpl(); 657 if (result) { 658 LOGE("HAL:inv_start_mpl() failed"); 659 LOG_RESULT_LOCATION(result); 660 return result; 661 } 662 663 return result; 664} 665 666int MPLSensor::inv_constructor_default_enable(void) 667{ 668 VFUNC_LOG; 669 670 inv_error_t result; 671 672/******************************************************************************* 673 674******************************************************************************** 675 676The InvenSense binary file (libmplmpu.so) is subject to Google's standard terms 677and conditions as accepted in the click-through agreement required to download 678this library. 679The library includes, but is not limited to the following function calls: 680inv_enable_quaternion(). 681 682ANY VIOLATION OF SUCH TERMS AND CONDITIONS WILL BE STRICTLY ENFORCED. 683 684******************************************************************************** 685 686*******************************************************************************/ 687 688 result = inv_enable_quaternion(); 689 if (result) { 690 LOGE("HAL:Cannot enable quaternion\n"); 691 return result; 692 } 693 694 result = inv_enable_in_use_auto_calibration(); 695 if (result) { 696 return result; 697 } 698 699 result = inv_enable_fast_nomot(); 700 if (result) { 701 return result; 702 } 703 704 result = inv_enable_gyro_tc(); 705 if (result) { 706 return result; 707 } 708 709 result = inv_enable_hal_outputs(); 710 if (result) { 711 return result; 712 } 713 714 if (!mCompassSensor->providesCalibration()) { 715 /* Invensense compass calibration */ 716 LOGV_IF(ENG_VERBOSE, "HAL:Invensense vector compass cal enabled"); 717 result = inv_enable_vector_compass_cal(); 718 if (result) { 719 LOG_RESULT_LOCATION(result); 720 return result; 721 } else { 722 mMplFeatureActiveMask |= INV_COMPASS_CAL; 723 } 724 // specify MPL's trust weight, used by compass algorithms 725 inv_vector_compass_cal_sensitivity(3); 726 727 /* disabled by default 728 result = inv_enable_compass_bias_w_gyro(); 729 if (result) { 730 LOG_RESULT_LOCATION(result); 731 return result; 732 } 733 */ 734 735 result = inv_enable_heading_from_gyro(); 736 if (result) { 737 LOG_RESULT_LOCATION(result); 738 return result; 739 } 740 741 result = inv_enable_magnetic_disturbance(); 742 if (result) { 743 LOG_RESULT_LOCATION(result); 744 return result; 745 } 746 //inv_enable_magnetic_disturbance_logging(); 747 } 748 749 result = inv_enable_9x_sensor_fusion(); 750 if (result) { 751 LOG_RESULT_LOCATION(result); 752 return result; 753 } else { 754 // 9x sensor fusion enables Compass fit 755 mMplFeatureActiveMask |= INV_COMPASS_FIT; 756 } 757 758 result = inv_enable_no_gyro_fusion(); 759 if (result) { 760 LOG_RESULT_LOCATION(result); 761 return result; 762 } 763 764 return result; 765} 766 767/* TODO: create function pointers to calculate scale */ 768void MPLSensor::inv_set_device_properties(void) 769{ 770 VFUNC_LOG; 771 772 unsigned short orient; 773 774 inv_get_sensors_orientation(); 775 776 inv_set_gyro_sample_rate(DEFAULT_MPL_GYRO_RATE); 777 inv_set_compass_sample_rate(DEFAULT_MPL_COMPASS_RATE); 778 779 /* gyro setup */ 780 orient = inv_orientation_matrix_to_scalar(mGyroOrientation); 781 inv_set_gyro_orientation_and_scale(orient, mGyroScale << 15); 782 LOGI_IF(EXTRA_VERBOSE, "HAL: Set MPL Gyro Scale %ld", mGyroScale << 15); 783 784 /* accel setup */ 785 orient = inv_orientation_matrix_to_scalar(mAccelOrientation); 786 /* use for third party accel input subsystem driver 787 inv_set_accel_orientation_and_scale(orient, 1LL << 22); 788 */ 789 inv_set_accel_orientation_and_scale(orient, (long)mAccelScale << 15); 790 LOGI_IF(EXTRA_VERBOSE, 791 "HAL: Set MPL Accel Scale %ld", (long)mAccelScale << 15); 792 793 /* compass setup */ 794 signed char orientMtx[9]; 795 mCompassSensor->getOrientationMatrix(orientMtx); 796 orient = 797 inv_orientation_matrix_to_scalar(orientMtx); 798 long sensitivity; 799 sensitivity = mCompassSensor->getSensitivity(); 800 inv_set_compass_orientation_and_scale(orient, sensitivity); 801 mCompassScale = sensitivity; 802 LOGI_IF(EXTRA_VERBOSE, 803 "HAL: Set MPL Compass Scale %ld", mCompassScale); 804} 805 806void MPLSensor::loadDMP(void) 807{ 808 VFUNC_LOG; 809 810 int res, fd; 811 FILE *fptr; 812 813 if (isMpuNonDmp()) { 814 return; 815 } 816 817 /* load DMP firmware */ 818 LOGV_IF(SYSFS_VERBOSE, 819 "HAL:sysfs:cat %s (%lld)", mpu.firmware_loaded, getTimestamp()); 820 fd = open(mpu.firmware_loaded, O_RDONLY); 821 if(fd < 0) { 822 LOGE("HAL:could not open dmp state"); 823 } else { 824 if(inv_read_dmp_state(fd) == 0) { 825 LOGV_IF(EXTRA_VERBOSE, "HAL:load dmp: %s", mpu.dmp_firmware); 826 fptr = fopen(mpu.dmp_firmware, "w"); 827 if(fptr == NULL) { 828 LOGE("HAL:could not open dmp_firmware"); 829 } else { 830 if (inv_load_dmp(fptr) < 0) { 831 LOGE("HAL:load DMP failed"); 832 } else { 833 LOGV_IF(PROCESS_VERBOSE, "HAL:DMP loaded"); 834 } 835 if (fclose(fptr) < 0) { 836 LOGE("HAL:could not close dmp firmware"); 837 } 838 } 839 } else { 840 LOGV_IF(ENG_VERBOSE, "HAL:DMP is already loaded"); 841 } 842 } 843 844 // onDmp(1); //Can't enable here. See note onDmp() 845} 846 847void MPLSensor::inv_get_sensors_orientation(void) 848{ 849 VFUNC_LOG; 850 851 FILE *fptr; 852 853 // get gyro orientation 854 LOGV_IF(SYSFS_VERBOSE, 855 "HAL:sysfs:cat %s (%lld)", mpu.gyro_orient, getTimestamp()); 856 fptr = fopen(mpu.gyro_orient, "r"); 857 if (fptr != NULL) { 858 int om[9]; 859 if (fscanf(fptr, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 860 &om[0], &om[1], &om[2], &om[3], &om[4], &om[5], 861 &om[6], &om[7], &om[8]) < 0) { 862 LOGE("HAL:Could not read gyro mounting matrix"); 863 } else { 864 LOGV_IF(EXTRA_VERBOSE, 865 "HAL:gyro mounting matrix: " 866 "%+d %+d %+d %+d %+d %+d %+d %+d %+d", 867 om[0], om[1], om[2], om[3], om[4], om[5], om[6], om[7], om[8]); 868 869 mGyroOrientation[0] = om[0]; 870 mGyroOrientation[1] = om[1]; 871 mGyroOrientation[2] = om[2]; 872 mGyroOrientation[3] = om[3]; 873 mGyroOrientation[4] = om[4]; 874 mGyroOrientation[5] = om[5]; 875 mGyroOrientation[6] = om[6]; 876 mGyroOrientation[7] = om[7]; 877 mGyroOrientation[8] = om[8]; 878 } 879 if (fclose(fptr) < 0) { 880 LOGE("HAL:Could not close gyro mounting matrix"); 881 } 882 } 883 884 // get accel orientation 885 LOGV_IF(SYSFS_VERBOSE, 886 "HAL:sysfs:cat %s (%lld)", mpu.accel_orient, getTimestamp()); 887 fptr = fopen(mpu.accel_orient, "r"); 888 if (fptr != NULL) { 889 int om[9]; 890 if (fscanf(fptr, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 891 &om[0], &om[1], &om[2], &om[3], &om[4], &om[5], 892 &om[6], &om[7], &om[8]) < 0) { 893 LOGE("HAL:could not read accel mounting matrix"); 894 } else { 895 LOGV_IF(EXTRA_VERBOSE, 896 "HAL:accel mounting matrix: " 897 "%+d %+d %+d %+d %+d %+d %+d %+d %+d", 898 om[0], om[1], om[2], om[3], om[4], om[5], om[6], om[7], om[8]); 899 900 mAccelOrientation[0] = om[0]; 901 mAccelOrientation[1] = om[1]; 902 mAccelOrientation[2] = om[2]; 903 mAccelOrientation[3] = om[3]; 904 mAccelOrientation[4] = om[4]; 905 mAccelOrientation[5] = om[5]; 906 mAccelOrientation[6] = om[6]; 907 mAccelOrientation[7] = om[7]; 908 mAccelOrientation[8] = om[8]; 909 } 910 if (fclose(fptr) < 0) { 911 LOGE("HAL:could not close accel mounting matrix"); 912 } 913 } 914} 915 916MPLSensor::~MPLSensor() 917{ 918 VFUNC_LOG; 919 920 /* Close open fds */ 921 if (iio_fd > 0) 922 close(iio_fd); 923 if( accel_fd > 0 ) 924 close(accel_fd ); 925 if (gyro_temperature_fd > 0) 926 close(gyro_temperature_fd); 927 if (sysfs_names_ptr) 928 free(sysfs_names_ptr); 929 930 closeDmpOrientFd(); 931 932 if (accel_x_dmp_bias_fd > 0) { 933 close(accel_x_dmp_bias_fd); 934 } 935 if (accel_y_dmp_bias_fd > 0) { 936 close(accel_y_dmp_bias_fd); 937 } 938 if (accel_z_dmp_bias_fd > 0) { 939 close(accel_z_dmp_bias_fd); 940 } 941 942 if (gyro_x_dmp_bias_fd > 0) { 943 close(gyro_x_dmp_bias_fd); 944 } 945 if (gyro_y_dmp_bias_fd > 0) { 946 close(gyro_y_dmp_bias_fd); 947 } 948 if (gyro_z_dmp_bias_fd > 0) { 949 close(gyro_z_dmp_bias_fd); 950 } 951 952 if (gyro_x_offset_fd > 0) { 953 close(gyro_x_dmp_bias_fd); 954 } 955 if (gyro_y_offset_fd > 0) { 956 close(gyro_y_offset_fd); 957 } 958 if (gyro_z_offset_fd > 0) { 959 close(accel_z_offset_fd); 960 } 961 962 /* Turn off Gyro master enable */ 963 /* A workaround until driver handles it */ 964 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 965 0, mpu.master_enable, getTimestamp()); 966 write_sysfs_int(mpu.master_enable, 0); 967 968#ifdef INV_PLAYBACK_DBG 969 inv_turn_off_data_logging(); 970 if (fclose(logfile) < 0) { 971 LOGE("cannot close debug log file"); 972 } 973#endif 974} 975 976#define GY_ENABLED ((1 << ID_GY) & enabled_sensors) 977#define RGY_ENABLED ((1 << ID_RG) & enabled_sensors) 978#define A_ENABLED ((1 << ID_A) & enabled_sensors) 979#define M_ENABLED ((1 << ID_M) & enabled_sensors) 980#define RM_ENABLED ((1 << ID_RM) & enabled_sensors) 981#define O_ENABLED ((1 << ID_O) & enabled_sensors) 982#define LA_ENABLED ((1 << ID_LA) & enabled_sensors) 983#define GR_ENABLED ((1 << ID_GR) & enabled_sensors) 984#define RV_ENABLED ((1 << ID_RV) & enabled_sensors) 985#define GRV_ENABLED ((1 << ID_GRV) & enabled_sensors) 986#define GMRV_ENABLED ((1 << ID_GMRV) & enabled_sensors) 987 988#ifdef ENABLE_PRESSURE 989#define PS_ENABLED ((1 << ID_PS) & enabled_sensors) 990#endif 991 992/* this applies to BMA250 Input Subsystem Driver only */ 993int MPLSensor::setAccelInitialState() 994{ 995 VFUNC_LOG; 996 997 struct input_absinfo absinfo_x; 998 struct input_absinfo absinfo_y; 999 struct input_absinfo absinfo_z; 1000 float value; 1001 if (!ioctl(accel_fd, EVIOCGABS(EVENT_TYPE_ACCEL_X), &absinfo_x) && 1002 !ioctl(accel_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Y), &absinfo_y) && 1003 !ioctl(accel_fd, EVIOCGABS(EVENT_TYPE_ACCEL_Z), &absinfo_z)) { 1004 value = absinfo_x.value; 1005 mPendingEvents[Accelerometer].data[0] = value * CONVERT_A_X; 1006 value = absinfo_y.value; 1007 mPendingEvents[Accelerometer].data[1] = value * CONVERT_A_Y; 1008 value = absinfo_z.value; 1009 mPendingEvents[Accelerometer].data[2] = value * CONVERT_A_Z; 1010 //mHasPendingEvent = true; 1011 } 1012 return 0; 1013} 1014 1015int MPLSensor::onDmp(int en) 1016{ 1017 VFUNC_LOG; 1018 1019 int res = -1; 1020 int status; 1021 mDmpOn = en; 1022 1023 //Sequence to enable DMP 1024 //1. Load DMP image if not already loaded 1025 //2. Either Gyro or Accel must be enabled/configured before next step 1026 //3. Enable DMP 1027 1028 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:cat %s (%lld)", 1029 mpu.firmware_loaded, getTimestamp()); 1030 if(read_sysfs_int(mpu.firmware_loaded, &status) < 0){ 1031 LOGE("HAL:ERR can't get firmware_loaded status"); 1032 } else if (status == 1) { 1033 //Write only if curr DMP state <> request 1034 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:cat %s (%lld)", 1035 mpu.dmp_on, getTimestamp()); 1036 if (read_sysfs_int(mpu.dmp_on, &status) < 0) { 1037 LOGE("HAL:ERR can't read DMP state"); 1038 } else if (status != en) { 1039 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1040 en, mpu.dmp_on, getTimestamp()); 1041 if (write_sysfs_int(mpu.dmp_on, en) < 0) { 1042 LOGE("HAL:ERR can't write dmp_on"); 1043 } else { 1044 mDmpOn = en; 1045 res = 0; //Indicate write successful 1046 if(!en) { 1047 setAccelBias(); 1048 } 1049 } 1050 //Enable DMP interrupt 1051 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1052 en, mpu.dmp_int_on, getTimestamp()); 1053 if (write_sysfs_int(mpu.dmp_int_on, en) < 0) { 1054 LOGE("HAL:ERR can't en/dis DMP interrupt"); 1055 } 1056 1057 // disable DMP event interrupt if needed 1058 if (!en) { 1059 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1060 en, mpu.dmp_event_int_on, getTimestamp()); 1061 if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) { 1062 res = -1; 1063 LOGE("HAL:ERR can't enable DMP event interrupt"); 1064 } 1065 } 1066 } else { 1067 mDmpOn = en; 1068 res = 0; //DMP already set as requested 1069 if(!en) { 1070 setAccelBias(); 1071 } 1072 } 1073 } else { 1074 LOGE("HAL:ERR No DMP image"); 1075 } 1076 return res; 1077} 1078 1079int MPLSensor::setDmpFeature(int en) 1080{ 1081 int res = 0; 1082 1083 // set sensor engine and fifo 1084 if ((mFeatureActiveMask & DMP_FEATURE_MASK) || en) { 1085 if ((mFeatureActiveMask & INV_DMP_6AXIS_QUATERNION) || 1086 (mFeatureActiveMask & INV_DMP_PED_QUATERNION) || 1087 (mFeatureActiveMask & INV_DMP_QUATERNION)) { 1088 res = enableGyro(1); 1089 if (res < 0) { 1090 return res; 1091 } 1092 if (!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_GYRO)) { 1093 res = turnOffGyroFifo(); 1094 if (res < 0) { 1095 return res; 1096 } 1097 } 1098 } 1099 res = enableAccel(1); 1100 if (res < 0) { 1101 return res; 1102 } 1103 if (!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_ACCEL)) { 1104 res = turnOffAccelFifo(); 1105 if (res < 0) { 1106 return res; 1107 } 1108 } 1109 } else { 1110 if (!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_GYRO)) { 1111 res = enableGyro(0); 1112 if (res < 0) { 1113 return res; 1114 } 1115 } 1116 if (!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_ACCEL)) { 1117 res = enableAccel(0); 1118 if (res < 0) { 1119 return res; 1120 } 1121 } 1122 } 1123 1124 // set sensor data interrupt 1125 uint32_t dataInterrupt = (mEnabled || (mFeatureActiveMask & INV_DMP_BATCH_MODE)); 1126 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1127 !dataInterrupt, mpu.dmp_event_int_on, getTimestamp()); 1128 if (write_sysfs_int(mpu.dmp_event_int_on, !dataInterrupt) < 0) { 1129 res = -1; 1130 LOGE("HAL:ERR can't enable DMP event interrupt"); 1131 } 1132 return res; 1133} 1134 1135int MPLSensor::computeAndSetDmpState() 1136{ 1137 int res = 0; 1138 bool dmpState = 0; 1139 1140 if (mFeatureActiveMask) { 1141 dmpState = 1; 1142 LOGV_IF(PROCESS_VERBOSE, "HAL:computeAndSetDmpState() mFeatureActiveMask = 1"); 1143 } else if ((mEnabled & VIRTUAL_SENSOR_9AXES_MASK) 1144 || (mEnabled & VIRTUAL_SENSOR_GYRO_6AXES_MASK)) { 1145 if (checkLPQuaternion() && checkLPQRateSupported()) { 1146 dmpState = 1; 1147 LOGV_IF(PROCESS_VERBOSE, "HAL:computeAndSetDmpState() Sensor Fusion = 1"); 1148 } 1149 } /*else { 1150 unsigned long sensor = mLocalSensorMask & mMasterSensorMask; 1151 if (sensor & (INV_THREE_AXIS_ACCEL & INV_THREE_AXIS_GYRO)) { 1152 dmpState = 1; 1153 LOGV_IF(PROCESS_VERBOSE, "HAL:computeAndSetDmpState() accel and gyro = 1"); 1154 } 1155 }*/ 1156 1157 // set Dmp state 1158 res = onDmp(dmpState); 1159 if (res < 0) 1160 return res; 1161 1162 if (dmpState) { 1163 // set DMP rate to 200Hz 1164 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1165 200, mpu.accel_fifo_rate, getTimestamp()); 1166 if (write_sysfs_int(mpu.accel_fifo_rate, 200) < 0) { 1167 res = -1; 1168 LOGE("HAL:ERR can't set rate to 200Hz"); 1169 return res; 1170 } 1171 } 1172 LOGV_IF(PROCESS_VERBOSE, "HAL:DMP is set %s", (dmpState ? "on" : "off")); 1173 return dmpState; 1174} 1175 1176/* called when batch and hw sensor enabled*/ 1177int MPLSensor::enablePedIndicator(int en) 1178{ 1179 VFUNC_LOG; 1180 1181 int res = 0; 1182 if (en) { 1183 if (!(mFeatureActiveMask & INV_DMP_PED_QUATERNION)) { 1184 //Disable DMP Pedometer Interrupt 1185 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1186 0, mpu.pedometer_int_on, getTimestamp()); 1187 if (write_sysfs_int(mpu.pedometer_int_on, 0) < 0) { 1188 LOGE("HAL:ERR can't enable Android Pedometer Interrupt"); 1189 res = -1; // indicate an err 1190 return res; 1191 } 1192 1193 LOGV_IF(ENG_VERBOSE, "HAL:Enabling ped standalone"); 1194 // enable accel engine 1195 res = enableAccel(1); 1196 if (res < 0) 1197 return res; 1198 LOGV_IF(EXTRA_VERBOSE, "mLocalSensorMask=0x%lx", mLocalSensorMask); 1199 // disable accel FIFO 1200 if (!((mLocalSensorMask & mMasterSensorMask) & INV_THREE_AXIS_ACCEL)) { 1201 res = turnOffAccelFifo(); 1202 if (res < 0) 1203 return res; 1204 } 1205 } 1206 } else { 1207 //Disable Accel if no sensor needs it 1208 if (!(mFeatureActiveMask & DMP_FEATURE_MASK) 1209 && (!(mLocalSensorMask & mMasterSensorMask 1210 & INV_THREE_AXIS_ACCEL))) { 1211 res = enableAccel(0); 1212 if (res < 0) 1213 return res; 1214 } 1215 } 1216 1217 LOGV_IF(ENG_VERBOSE, "HAL:Toggling step indicator to %d", en); 1218 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1219 en, mpu.step_indicator_on, getTimestamp()); 1220 if (write_sysfs_int(mpu.step_indicator_on, en) < 0) { 1221 res = -1; 1222 LOGE("HAL:ERR can't write to DMP step_indicator_on"); 1223 } 1224 return res; 1225} 1226 1227int MPLSensor::checkPedStandaloneBatched(void) 1228{ 1229 VFUNC_LOG; 1230 int res = 0; 1231 1232 if ((mFeatureActiveMask & INV_DMP_PEDOMETER) && 1233 (mBatchEnabled & (1 << StepDetector))) { 1234 res = 1; 1235 } else 1236 res = 0; 1237 1238 LOGV_IF(ENG_VERBOSE, "HAL:checkPedStandaloneBatched=%d", res); 1239 return res; 1240} 1241 1242int MPLSensor::checkPedStandaloneEnabled(void) 1243{ 1244 VFUNC_LOG; 1245 return ((mFeatureActiveMask & INV_DMP_PED_STANDALONE)? 1:0); 1246} 1247 1248/* This feature is only used in batch mode */ 1249/* Stand-alone Step Detector */ 1250int MPLSensor::enablePedStandalone(int en) 1251{ 1252 VFUNC_LOG; 1253 1254 if (!en) { 1255 enablePedStandaloneData(0); 1256 mFeatureActiveMask &= ~INV_DMP_PED_STANDALONE; 1257 if (mFeatureActiveMask == 0) { 1258 onDmp(0); 1259 } else if(mFeatureActiveMask & INV_DMP_PEDOMETER) { 1260 //Re-enable DMP Pedometer Interrupt 1261 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1262 1, mpu.pedometer_int_on, getTimestamp()); 1263 if (write_sysfs_int(mpu.pedometer_int_on, 1) < 0) { 1264 LOGE("HAL:ERR can't enable Android Pedometer Interrupt"); 1265 return (-1); 1266 } 1267 //Disable data interrupt if no continuous data 1268 if (mEnabled == 0) { 1269 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1270 1, mpu.dmp_event_int_on, getTimestamp()); 1271 if (write_sysfs_int(mpu.dmp_event_int_on, 1) < 0) { 1272 LOGE("HAL:ERR can't enable DMP event interrupt"); 1273 return (-1); 1274 } 1275 } 1276 } 1277 LOGV_IF(ENG_VERBOSE, "HAL:Ped Standalone disabled"); 1278 } else { 1279 if (enablePedStandaloneData(1) < 0 || onDmp(1) < 0) { 1280 LOGE("HAL:ERR can't enable Ped Standalone"); 1281 } else { 1282 mFeatureActiveMask |= INV_DMP_PED_STANDALONE; 1283 //Disable DMP Pedometer Interrupt 1284 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1285 0, mpu.pedometer_int_on, getTimestamp()); 1286 if (write_sysfs_int(mpu.pedometer_int_on, 0) < 0) { 1287 LOGE("HAL:ERR can't disable Android Pedometer Interrupt"); 1288 return (-1); 1289 } 1290 //Enable Data Interrupt 1291 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1292 0, mpu.dmp_event_int_on, getTimestamp()); 1293 if (write_sysfs_int(mpu.dmp_event_int_on, 0) < 0) { 1294 LOGE("HAL:ERR can't enable DMP event interrupt"); 1295 return (-1); 1296 } 1297 LOGV_IF(ENG_VERBOSE, "HAL:Ped Standalone enabled"); 1298 } 1299 } 1300 return 0; 1301} 1302 1303int MPLSensor:: enablePedStandaloneData(int en) 1304{ 1305 VFUNC_LOG; 1306 1307 int res = 0; 1308 1309 // Set DMP Ped standalone 1310 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1311 en, mpu.step_detector_on, getTimestamp()); 1312 if (write_sysfs_int(mpu.step_detector_on, en) < 0) { 1313 LOGE("HAL:ERR can't write DMP step_detector_on"); 1314 res = -1; //Indicate an err 1315 } 1316 1317 // Set DMP Step indicator 1318 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1319 en, mpu.step_indicator_on, getTimestamp()); 1320 if (write_sysfs_int(mpu.step_indicator_on, en) < 0) { 1321 LOGE("HAL:ERR can't write DMP step_indicator_on"); 1322 res = -1; //Indicate an err 1323 } 1324 1325 if (!en) { 1326 LOGV_IF(ENG_VERBOSE, "HAL:Disabling ped standalone"); 1327 //Disable Accel if no sensor needs it 1328 if (!(mFeatureActiveMask & DMP_FEATURE_MASK) 1329 && (!(mLocalSensorMask & mMasterSensorMask 1330 & INV_THREE_AXIS_ACCEL))) { 1331 res = enableAccel(0); 1332 if (res < 0) 1333 return res; 1334 } 1335 if (!(mFeatureActiveMask & DMP_FEATURE_MASK) 1336 && (!(mLocalSensorMask & mMasterSensorMask 1337 & INV_THREE_AXIS_GYRO))) { 1338 res = enableGyro(0); 1339 if (res < 0) 1340 return res; 1341 } 1342 } else { 1343 LOGV_IF(ENG_VERBOSE, "HAL:Enabling ped standalone"); 1344 // enable accel engine 1345 res = enableAccel(1); 1346 if (res < 0) 1347 return res; 1348 LOGV_IF(EXTRA_VERBOSE, "mLocalSensorMask=0x%lx", mLocalSensorMask); 1349 // disable accel FIFO 1350 if (!((mLocalSensorMask & mMasterSensorMask) & INV_THREE_AXIS_ACCEL)) { 1351 res = turnOffAccelFifo(); 1352 if (res < 0) 1353 return res; 1354 } 1355 } 1356 1357 return res; 1358} 1359 1360int MPLSensor::checkPedQuatEnabled(void) 1361{ 1362 VFUNC_LOG; 1363 return ((mFeatureActiveMask & INV_DMP_PED_QUATERNION)? 1:0); 1364} 1365 1366/* This feature is only used in batch mode */ 1367/* Step Detector && Game Rotation Vector */ 1368int MPLSensor::enablePedQuaternion(int en) 1369{ 1370 VFUNC_LOG; 1371 1372 if (!en) { 1373 enablePedQuaternionData(0); 1374 mFeatureActiveMask &= ~INV_DMP_PED_QUATERNION; 1375 if (mFeatureActiveMask == 0) { 1376 onDmp(0); 1377 } else if(mFeatureActiveMask & INV_DMP_PEDOMETER) { 1378 //Re-enable DMP Pedometer Interrupt 1379 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1380 1, mpu.pedometer_int_on, getTimestamp()); 1381 if (write_sysfs_int(mpu.pedometer_int_on, 1) < 0) { 1382 LOGE("HAL:ERR can't enable Android Pedometer Interrupt"); 1383 return (-1); 1384 } 1385 //Disable data interrupt if no continuous data 1386 if (mEnabled == 0) { 1387 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1388 1, mpu.dmp_event_int_on, getTimestamp()); 1389 if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) { 1390 LOGE("HAL:ERR can't enable DMP event interrupt"); 1391 return (-1); 1392 } 1393 } 1394 } 1395 LOGV_IF(ENG_VERBOSE, "HAL:Ped Quat disabled"); 1396 } else { 1397 if (enablePedQuaternionData(1) < 0 || onDmp(1) < 0) { 1398 LOGE("HAL:ERR can't enable Ped Quaternion"); 1399 } else { 1400 mFeatureActiveMask |= INV_DMP_PED_QUATERNION; 1401 //Disable DMP Pedometer Interrupt 1402 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1403 0, mpu.pedometer_int_on, getTimestamp()); 1404 if (write_sysfs_int(mpu.pedometer_int_on, 0) < 0) { 1405 LOGE("HAL:ERR can't disable Android Pedometer Interrupt"); 1406 return (-1); 1407 } 1408 //Enable Data Interrupt 1409 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1410 0, mpu.dmp_event_int_on, getTimestamp()); 1411 if (write_sysfs_int(mpu.dmp_event_int_on, 0) < 0) { 1412 LOGE("HAL:ERR can't enable DMP event interrupt"); 1413 return (-1); 1414 } 1415 LOGV_IF(ENG_VERBOSE, "HAL:Ped Quat enabled"); 1416 } 1417 } 1418 return 0; 1419} 1420 1421int MPLSensor::enablePedQuaternionData(int en) 1422{ 1423 VFUNC_LOG; 1424 1425 int res = 0; 1426 1427 // Enable DMP quaternion 1428 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1429 en, mpu.ped_q_on, getTimestamp()); 1430 if (write_sysfs_int(mpu.ped_q_on, en) < 0) { 1431 LOGE("HAL:ERR can't write DMP ped_q_on"); 1432 res = -1; //Indicate an err 1433 } 1434 1435 if (!en) { 1436 LOGV_IF(ENG_VERBOSE, "HAL:Disabling ped quat"); 1437 //Disable Accel if no sensor needs it 1438 if (!(mFeatureActiveMask & DMP_FEATURE_MASK) 1439 && (!(mLocalSensorMask & mMasterSensorMask 1440 & INV_THREE_AXIS_ACCEL))) { 1441 res = enableAccel(0); 1442 if (res < 0) 1443 return res; 1444 } 1445 if (!(mFeatureActiveMask & DMP_FEATURE_MASK) 1446 && (!(mLocalSensorMask & mMasterSensorMask 1447 & INV_THREE_AXIS_GYRO))) { 1448 res = enableGyro(0); 1449 if (res < 0) 1450 return res; 1451 } 1452 if (mFeatureActiveMask & INV_DMP_QUATERNION) { 1453 res = write_sysfs_int(mpu.gyro_fifo_enable, 1); 1454 res += write_sysfs_int(mpu.accel_fifo_enable, 1); 1455 if (res < 0) 1456 return res; 1457 } 1458 // LOGV_IF(ENG_VERBOSE, "before mLocalSensorMask=0x%lx", mLocalSensorMask); 1459 // reset global mask for buildMpuEvent() 1460 if (mEnabled & (1 << GameRotationVector)) { 1461 mLocalSensorMask |= INV_THREE_AXIS_GYRO; 1462 mLocalSensorMask |= INV_THREE_AXIS_ACCEL; 1463 } else if (mEnabled & (1 << Accelerometer)) { 1464 mLocalSensorMask |= INV_THREE_AXIS_ACCEL; 1465 } else if ((mEnabled & ( 1 << Gyro)) || 1466 (mEnabled & (1 << RawGyro))) { 1467 mLocalSensorMask |= INV_THREE_AXIS_GYRO; 1468 } 1469 //LOGV_IF(ENG_VERBOSE, "after mLocalSensorMask=0x%lx", mLocalSensorMask); 1470 } else { 1471 LOGV_IF(PROCESS_VERBOSE, "HAL:Enabling ped quat"); 1472 // enable accel engine 1473 res = enableAccel(1); 1474 if (res < 0) 1475 return res; 1476 1477 // enable gyro engine 1478 res = enableGyro(1); 1479 if (res < 0) 1480 return res; 1481 LOGV_IF(EXTRA_VERBOSE, "mLocalSensorMask=0x%lx", mLocalSensorMask); 1482 // disable accel FIFO 1483 if ((!((mLocalSensorMask & mMasterSensorMask) & INV_THREE_AXIS_ACCEL)) || 1484 !(mBatchEnabled & (1 << Accelerometer))) { 1485 res = turnOffAccelFifo(); 1486 if (res < 0) 1487 return res; 1488 mLocalSensorMask &= ~INV_THREE_AXIS_ACCEL; 1489 } 1490 1491 // disable gyro FIFO 1492 if ((!((mLocalSensorMask & mMasterSensorMask) & INV_THREE_AXIS_GYRO)) || 1493 !((mBatchEnabled & (1 << Gyro)) || (mBatchEnabled & (1 << RawGyro)))) { 1494 res = turnOffGyroFifo(); 1495 if (res < 0) 1496 return res; 1497 mLocalSensorMask &= ~INV_THREE_AXIS_GYRO; 1498 } 1499 } 1500 1501 return res; 1502} 1503 1504int MPLSensor::setPedQuaternionRate(int64_t wanted) 1505{ 1506 VFUNC_LOG; 1507 int res = 0; 1508 1509 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1510 int(1000000000.f / wanted), mpu.ped_q_rate, 1511 getTimestamp()); 1512 res = write_sysfs_int(mpu.ped_q_rate, 1000000000.f / wanted); 1513 LOGV_IF(PROCESS_VERBOSE, 1514 "HAL:DMP ped quaternion rate %.2f Hz", 1000000000.f / wanted); 1515 1516 return res; 1517} 1518 1519int MPLSensor::check6AxisQuatEnabled(void) 1520{ 1521 VFUNC_LOG; 1522 return ((mFeatureActiveMask & INV_DMP_6AXIS_QUATERNION)? 1:0); 1523} 1524 1525/* This is used for batch mode only */ 1526/* GRV is batched but not along with ped */ 1527int MPLSensor::enable6AxisQuaternion(int en) 1528{ 1529 VFUNC_LOG; 1530 1531 if (!en) { 1532 enable6AxisQuaternionData(0); 1533 mFeatureActiveMask &= ~INV_DMP_6AXIS_QUATERNION; 1534 if (mFeatureActiveMask == 0) { 1535 onDmp(0); 1536 } 1537 LOGV_IF(ENG_VERBOSE, "HAL:6 Axis Quat disabled"); 1538 } else { 1539 if (enable6AxisQuaternionData(1) < 0 || onDmp(1) < 0) { 1540 LOGE("HAL:ERR can't enable 6 Axis Quaternion"); 1541 } else { 1542 mFeatureActiveMask |= INV_DMP_6AXIS_QUATERNION; 1543 LOGV_IF(PROCESS_VERBOSE, "HAL:6 Axis Quat enabled"); 1544 } 1545 } 1546 return 0; 1547} 1548 1549int MPLSensor::enable6AxisQuaternionData(int en) 1550{ 1551 VFUNC_LOG; 1552 1553 int res = 0; 1554 1555 // Enable DMP quaternion 1556 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1557 en, mpu.six_axis_q_on, getTimestamp()); 1558 if (write_sysfs_int(mpu.six_axis_q_on, en) < 0) { 1559 LOGE("HAL:ERR can't write DMP six_axis_q_on"); 1560 res = -1; //Indicate an err 1561 } 1562 1563 if (!en) { 1564 LOGV_IF(EXTRA_VERBOSE, "HAL:DMP six axis quaternion data was turned off"); 1565 inv_quaternion_sensor_was_turned_off(); 1566 if (!(mFeatureActiveMask & DMP_FEATURE_MASK) 1567 && (!(mLocalSensorMask & mMasterSensorMask 1568 & INV_THREE_AXIS_ACCEL))) { 1569 res = enableAccel(0); 1570 if (res < 0) 1571 return res; 1572 } 1573 if (!(mFeatureActiveMask & DMP_FEATURE_MASK) 1574 && (!(mLocalSensorMask & mMasterSensorMask 1575 & INV_THREE_AXIS_GYRO))) { 1576 res = enableGyro(0); 1577 if (res < 0) 1578 return res; 1579 } 1580 if (mFeatureActiveMask & INV_DMP_QUATERNION) { 1581 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1582 1, mpu.gyro_fifo_enable, getTimestamp()); 1583 res = write_sysfs_int(mpu.gyro_fifo_enable, 1); 1584 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1585 1, mpu.accel_fifo_enable, getTimestamp()); 1586 res += write_sysfs_int(mpu.accel_fifo_enable, 1); 1587 if (res < 0) 1588 return res; 1589 } 1590 LOGV_IF(ENG_VERBOSE, " k=0x%lx", mLocalSensorMask); 1591 // reset global mask for buildMpuEvent() 1592 if (mEnabled & (1 << GameRotationVector)) { 1593 if (!(mFeatureActiveMask & INV_DMP_PED_QUATERNION)) { 1594 mLocalSensorMask |= INV_THREE_AXIS_GYRO; 1595 mLocalSensorMask |= INV_THREE_AXIS_ACCEL; 1596 res = write_sysfs_int(mpu.gyro_fifo_enable, 1); 1597 res += write_sysfs_int(mpu.accel_fifo_enable, 1); 1598 if (res < 0) 1599 return res; 1600 } 1601 } else if (mEnabled & (1 << Accelerometer)) { 1602 mLocalSensorMask |= INV_THREE_AXIS_ACCEL; 1603 } else if ((mEnabled & ( 1 << Gyro)) || 1604 (mEnabled & (1 << RawGyro))) { 1605 mLocalSensorMask |= INV_THREE_AXIS_GYRO; 1606 } 1607 LOGV_IF(ENG_VERBOSE, "after mLocalSensorMask=0x%lx", mLocalSensorMask); 1608 } else { 1609 LOGV_IF(PROCESS_VERBOSE, "HAL:Enabling six axis quat"); 1610 if (mEnabled & ( 1 << GameRotationVector)) { 1611 // enable accel engine 1612 res = enableAccel(1); 1613 if (res < 0) 1614 return res; 1615 1616 // enable gyro engine 1617 res = enableGyro(1); 1618 if (res < 0) 1619 return res; 1620 LOGV_IF(EXTRA_VERBOSE, "before: mLocalSensorMask=0x%lx", mLocalSensorMask); 1621 if ((!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_ACCEL)) || 1622 (!(mBatchEnabled & (1 << Accelerometer)) || 1623 (!(mEnabled & (1 << Accelerometer))))) { 1624 res = turnOffAccelFifo(); 1625 if (res < 0) 1626 return res; 1627 mLocalSensorMask &= ~INV_THREE_AXIS_ACCEL; 1628 } 1629 1630 if ((!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_GYRO)) || 1631 (!(mBatchEnabled & (1 << Gyro)) || 1632 (!(mEnabled & (1 << Gyro))))) { 1633 if (!(mBatchEnabled & (1 << RawGyro)) || 1634 (!(mEnabled & (1 << RawGyro)))) { 1635 res = turnOffGyroFifo(); 1636 if (res < 0) 1637 return res; 1638 mLocalSensorMask &= ~INV_THREE_AXIS_GYRO; 1639 } 1640 } 1641 LOGV_IF(ENG_VERBOSE, "after: mLocalSensorMask=0x%lx", mLocalSensorMask); 1642 } 1643 } 1644 1645 return res; 1646} 1647 1648int MPLSensor::set6AxisQuaternionRate(int64_t wanted) 1649{ 1650 VFUNC_LOG; 1651 int res = 0; 1652 1653 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1654 int(1000000000.f / wanted), mpu.six_axis_q_rate, 1655 getTimestamp()); 1656 res = write_sysfs_int(mpu.six_axis_q_rate, 1000000000.f / wanted); 1657 LOGV_IF(PROCESS_VERBOSE, 1658 "HAL:DMP six axis rate %.2f Hz", 1000000000.f / wanted); 1659 1660 return res; 1661} 1662 1663/* this is for batch mode only */ 1664int MPLSensor::checkLPQRateSupported(void) 1665{ 1666 VFUNC_LOG; 1667#ifndef USE_LPQ_AT_FASTEST 1668 return ((mDelays[GameRotationVector] <= RATE_200HZ) ? 0 :1); 1669#else 1670 return 1; 1671#endif 1672} 1673 1674int MPLSensor::checkLPQuaternion(void) 1675{ 1676 VFUNC_LOG; 1677 return ((mFeatureActiveMask & INV_DMP_QUATERNION)? 1:0); 1678} 1679 1680int MPLSensor::enableLPQuaternion(int en) 1681{ 1682 VFUNC_LOG; 1683 1684 if (!en) { 1685 enableQuaternionData(0); 1686 mFeatureActiveMask &= ~INV_DMP_QUATERNION; 1687 if (mFeatureActiveMask == 0) { 1688 onDmp(0); 1689 } 1690 LOGV_IF(ENG_VERBOSE, "HAL:LP Quat disabled"); 1691 } else { 1692 if (enableQuaternionData(1) < 0 || onDmp(1) < 0) { 1693 LOGE("HAL:ERR can't enable LP Quaternion"); 1694 } else { 1695 mFeatureActiveMask |= INV_DMP_QUATERNION; 1696 LOGV_IF(ENG_VERBOSE, "HAL:LP Quat enabled"); 1697 } 1698 } 1699 return 0; 1700} 1701 1702int MPLSensor::enableQuaternionData(int en) 1703{ 1704 VFUNC_LOG; 1705 1706 int res = 0; 1707 1708 // Enable DMP quaternion 1709 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1710 en, mpu.three_axis_q_on, getTimestamp()); 1711 if (write_sysfs_int(mpu.three_axis_q_on, en) < 0) { 1712 LOGE("HAL:ERR can't write DMP three_axis_q__on"); 1713 res = -1; //Indicates an err 1714 } 1715 1716 if (!en) { 1717 LOGV_IF(ENG_VERBOSE, "HAL:DMP quaternion data was turned off"); 1718 inv_quaternion_sensor_was_turned_off(); 1719 } else { 1720 LOGV_IF(ENG_VERBOSE, "HAL:Enabling three axis quat"); 1721 } 1722 1723 return res; 1724} 1725 1726int MPLSensor::setQuaternionRate(int64_t wanted) 1727{ 1728 VFUNC_LOG; 1729 int res = 0; 1730 1731 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1732 int(1000000000.f / wanted), mpu.three_axis_q_rate, 1733 getTimestamp()); 1734 res = write_sysfs_int(mpu.three_axis_q_rate, 1000000000.f / wanted); 1735 LOGV_IF(PROCESS_VERBOSE, 1736 "HAL:DMP three axis rate %.2f Hz", 1000000000.f / wanted); 1737 1738 return res; 1739} 1740 1741int MPLSensor::enableDmpPedometer(int en, int interruptMode) 1742{ 1743 VFUNC_LOG; 1744 int res = 0; 1745 int enabled_sensors = mEnabled; 1746 1747 if (isMpuNonDmp()) 1748 return res; 1749 1750 // reset master enable 1751 res = masterEnable(0); 1752 if (res < 0) { 1753 return res; 1754 } 1755 1756 if (en == 1) { 1757 //Enable DMP Pedometer Function 1758 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1759 en, mpu.pedometer_on, getTimestamp()); 1760 if (write_sysfs_int(mpu.pedometer_on, en) < 0) { 1761 LOGE("HAL:ERR can't enable Android Pedometer"); 1762 res = -1; // indicate an err 1763 return res; 1764 } 1765 1766 if (interruptMode) { 1767 if(!checkPedStandaloneBatched()) { 1768 //Enable DMP Pedometer Interrupt 1769 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1770 en, mpu.pedometer_int_on, getTimestamp()); 1771 if (write_sysfs_int(mpu.pedometer_int_on, en) < 0) { 1772 LOGE("HAL:ERR can't enable Android Pedometer Interrupt"); 1773 res = -1; // indicate an err 1774 return res; 1775 } 1776 } 1777 } 1778 1779 if (interruptMode) { 1780 mFeatureActiveMask |= INV_DMP_PEDOMETER; 1781 } 1782 else { 1783 mFeatureActiveMask |= INV_DMP_PEDOMETER_STEP; 1784 mStepCountPollTime = 100000000LL; 1785 } 1786 1787 clock_gettime(CLOCK_MONOTONIC, &mt_pre); 1788 } else { 1789 if (interruptMode) { 1790 mFeatureActiveMask &= ~INV_DMP_PEDOMETER; 1791 } 1792 else { 1793 mFeatureActiveMask &= ~INV_DMP_PEDOMETER_STEP; 1794 mStepCountPollTime = -1; 1795 } 1796 1797 /* if neither step detector or step count is on */ 1798 if (!(mFeatureActiveMask & (INV_DMP_PEDOMETER | INV_DMP_PEDOMETER_STEP))) { 1799 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1800 en, mpu.pedometer_on, getTimestamp()); 1801 if (write_sysfs_int(mpu.pedometer_on, en) < 0) { 1802 LOGE("HAL:ERR can't enable Android Pedometer"); 1803 res = -1; 1804 return res; 1805 } 1806 } 1807 1808 /* if feature is not step detector */ 1809 if (!(mFeatureActiveMask & INV_DMP_PEDOMETER)) { 1810 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1811 en, mpu.pedometer_int_on, getTimestamp()); 1812 if (write_sysfs_int(mpu.pedometer_int_on, en) < 0) { 1813 LOGE("HAL:ERR can't enable Android Pedometer Interrupt"); 1814 res = -1; 1815 return res; 1816 } 1817 } 1818 } 1819 1820 if ((res = setDmpFeature(en)) < 0) 1821 return res; 1822 1823 if ((res = computeAndSetDmpState()) < 0) 1824 return res; 1825 1826 if (!mBatchEnabled && (resetDataRates() < 0)) 1827 return res; 1828 1829 if(en || enabled_sensors || mFeatureActiveMask) { 1830 res = masterEnable(1); 1831 } 1832 return res; 1833} 1834 1835int MPLSensor::masterEnable(int en) 1836{ 1837 VFUNC_LOG; 1838 1839 int res = 0; 1840 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1841 en, mpu.master_enable, getTimestamp()); 1842 res = write_sysfs_int(mpu.master_enable, en); 1843 return res; 1844} 1845 1846int MPLSensor::enableGyro(int en) 1847{ 1848 VFUNC_LOG; 1849 1850 int res = 0; 1851 1852 /* need to also turn on/off the master enable */ 1853 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1854 en, mpu.gyro_enable, getTimestamp()); 1855 res = write_sysfs_int(mpu.gyro_enable, en); 1856 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1857 en, mpu.gyro_fifo_enable, getTimestamp()); 1858 res += write_sysfs_int(mpu.gyro_fifo_enable, en); 1859 1860 if (!en) { 1861 LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:inv_gyro_was_turned_off"); 1862 inv_gyro_was_turned_off(); 1863 } 1864 1865 return res; 1866} 1867 1868int MPLSensor::enableLowPowerAccel(int en) 1869{ 1870 VFUNC_LOG; 1871 1872 int res; 1873 1874 /* need to also turn on/off the master enable */ 1875 res = write_sysfs_int(mpu.motion_lpa_on, en); 1876 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1877 en, mpu.motion_lpa_on, getTimestamp()); 1878 return res; 1879} 1880 1881int MPLSensor::enableAccel(int en) 1882{ 1883 VFUNC_LOG; 1884 1885 int res; 1886 1887 /* need to also turn on/off the master enable */ 1888 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1889 en, mpu.accel_enable, getTimestamp()); 1890 res = write_sysfs_int(mpu.accel_enable, en); 1891 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 1892 en, mpu.accel_fifo_enable, getTimestamp()); 1893 res += write_sysfs_int(mpu.accel_fifo_enable, en); 1894 1895 if (!en) { 1896 LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:inv_accel_was_turned_off"); 1897 inv_accel_was_turned_off(); 1898 } 1899 1900 return res; 1901} 1902 1903int MPLSensor::enableCompass(int en, int rawSensorRequested) 1904{ 1905 VFUNC_LOG; 1906 1907 int res = 0; 1908 /* TODO: handle ID_RM if third party compass cal is used */ 1909 if (rawSensorRequested && mCompassSensor->providesCalibration()) { 1910 res = mCompassSensor->enable(ID_RM, en); 1911 } else { 1912 res = mCompassSensor->enable(ID_M, en); 1913 } 1914 if (en == 0 || res != 0) { 1915 LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:inv_compass_was_turned_off %d", res); 1916 inv_compass_was_turned_off(); 1917 } 1918 1919 return res; 1920} 1921 1922#ifdef ENABLE_PRESSURE 1923int MPLSensor::enablePressure(int en) 1924{ 1925 VFUNC_LOG; 1926 1927 int res = 0; 1928 1929 if (mPressureSensor) 1930 res = mPressureSensor->enable(ID_PS, en); 1931 1932 return res; 1933} 1934#endif 1935 1936/* use this function for initialization */ 1937int MPLSensor::enableBatch(int64_t timeout) 1938{ 1939 VFUNC_LOG; 1940 1941 int res = 0; 1942 1943 res = write_sysfs_int(mpu.batchmode_timeout, timeout); 1944 if (timeout == 0) { 1945 res = write_sysfs_int(mpu.six_axis_q_on, 0); 1946 res = write_sysfs_int(mpu.ped_q_on, 0); 1947 res = write_sysfs_int(mpu.step_detector_on, 0); 1948 res = write_sysfs_int(mpu.step_indicator_on, 0); 1949 } 1950 1951 if (timeout == 0) { 1952 LOGV_IF(EXTRA_VERBOSE, "HAL:MPL:batchmode timeout is zero"); 1953 } 1954 1955 return res; 1956} 1957 1958void MPLSensor::computeLocalSensorMask(int enabled_sensors) 1959{ 1960 VFUNC_LOG; 1961 1962 do { 1963#ifdef ENABLE_PRESSURE 1964 /* Invensense Pressure on secondary bus */ 1965 if (PS_ENABLED) { 1966 LOGV_IF(ENG_VERBOSE, "PS ENABLED"); 1967 mLocalSensorMask |= INV_ONE_AXIS_PRESSURE; 1968 } else { 1969 LOGV_IF(ENG_VERBOSE, "PS DISABLED"); 1970 mLocalSensorMask &= ~INV_ONE_AXIS_PRESSURE; 1971 } 1972#else 1973 LOGV_IF(ENG_VERBOSE, "PS DISABLED"); 1974 mLocalSensorMask &= ~INV_ONE_AXIS_PRESSURE; 1975#endif 1976 1977 if (LA_ENABLED || GR_ENABLED || RV_ENABLED || O_ENABLED 1978 || (GRV_ENABLED && GMRV_ENABLED)) { 1979 LOGV_IF(ENG_VERBOSE, "FUSION ENABLED"); 1980 mLocalSensorMask |= ALL_MPL_SENSORS_NP; 1981 break; 1982 } 1983 1984 if (GRV_ENABLED) { 1985 if (!(mFeatureActiveMask & INV_DMP_BATCH_MODE) || 1986 !(mBatchEnabled & (1 << GameRotationVector))) { 1987 LOGV_IF(ENG_VERBOSE, "6 Axis Fusion ENABLED"); 1988 mLocalSensorMask |= INV_THREE_AXIS_GYRO; 1989 mLocalSensorMask |= INV_THREE_AXIS_ACCEL; 1990 } else { 1991 if (GY_ENABLED || RGY_ENABLED) { 1992 LOGV_IF(ENG_VERBOSE, "G ENABLED"); 1993 mLocalSensorMask |= INV_THREE_AXIS_GYRO; 1994 } else { 1995 LOGV_IF(ENG_VERBOSE, "G DISABLED"); 1996 mLocalSensorMask &= ~INV_THREE_AXIS_GYRO; 1997 } 1998 if (A_ENABLED) { 1999 LOGV_IF(ENG_VERBOSE, "A ENABLED"); 2000 mLocalSensorMask |= INV_THREE_AXIS_ACCEL; 2001 } else { 2002 LOGV_IF(ENG_VERBOSE, "A DISABLED"); 2003 mLocalSensorMask &= ~INV_THREE_AXIS_ACCEL; 2004 } 2005 } 2006 /* takes care of MAG case */ 2007 if (M_ENABLED || RM_ENABLED) { 2008 LOGV_IF(1, "M ENABLED"); 2009 mLocalSensorMask |= INV_THREE_AXIS_COMPASS; 2010 } else { 2011 LOGV_IF(1, "M DISABLED"); 2012 mLocalSensorMask &= ~INV_THREE_AXIS_COMPASS; 2013 } 2014 break; 2015 } 2016 2017 if (GMRV_ENABLED) { 2018 LOGV_IF(ENG_VERBOSE, "6 Axis Geomagnetic Fusion ENABLED"); 2019 mLocalSensorMask |= INV_THREE_AXIS_ACCEL; 2020 mLocalSensorMask |= INV_THREE_AXIS_COMPASS; 2021 2022 /* takes care of Gyro case */ 2023 if (GY_ENABLED || RGY_ENABLED) { 2024 LOGV_IF(1, "G ENABLED"); 2025 mLocalSensorMask |= INV_THREE_AXIS_GYRO; 2026 } else { 2027 LOGV_IF(1, "G DISABLED"); 2028 mLocalSensorMask &= ~INV_THREE_AXIS_GYRO; 2029 } 2030 break; 2031 } 2032 2033#ifdef ENABLE_PRESSURE 2034 if(!A_ENABLED && !M_ENABLED && !RM_ENABLED && 2035 !GRV_ENABLED && !GMRV_ENABLED && !GY_ENABLED && !RGY_ENABLED && 2036 !PS_ENABLED) { 2037#else 2038 if(!A_ENABLED && !M_ENABLED && !RM_ENABLED && 2039 !GRV_ENABLED && !GMRV_ENABLED && !GY_ENABLED && !RGY_ENABLED) { 2040#endif 2041 /* Invensense compass cal */ 2042 LOGV_IF(ENG_VERBOSE, "ALL DISABLED"); 2043 mLocalSensorMask = 0; 2044 break; 2045 } 2046 2047 if (GY_ENABLED || RGY_ENABLED) { 2048 LOGV_IF(ENG_VERBOSE, "G ENABLED"); 2049 mLocalSensorMask |= INV_THREE_AXIS_GYRO; 2050 } else { 2051 LOGV_IF(ENG_VERBOSE, "G DISABLED"); 2052 mLocalSensorMask &= ~INV_THREE_AXIS_GYRO; 2053 } 2054 2055 if (A_ENABLED) { 2056 LOGV_IF(ENG_VERBOSE, "A ENABLED"); 2057 mLocalSensorMask |= INV_THREE_AXIS_ACCEL; 2058 } else { 2059 LOGV_IF(ENG_VERBOSE, "A DISABLED"); 2060 mLocalSensorMask &= ~INV_THREE_AXIS_ACCEL; 2061 } 2062 2063 /* Invensense compass calibration */ 2064 if (M_ENABLED || RM_ENABLED) { 2065 LOGV_IF(ENG_VERBOSE, "M ENABLED"); 2066 mLocalSensorMask |= INV_THREE_AXIS_COMPASS; 2067 } else { 2068 LOGV_IF(ENG_VERBOSE, "M DISABLED"); 2069 mLocalSensorMask &= ~INV_THREE_AXIS_COMPASS; 2070 } 2071 } while (0); 2072} 2073 2074int MPLSensor::enableSensors(unsigned long sensors, int en, uint32_t changed) 2075{ 2076 VFUNC_LOG; 2077 2078 inv_error_t res = -1; 2079 int on = 1; 2080 int off = 0; 2081 int cal_stored = 0; 2082 2083 // Sequence to enable or disable a sensor 2084 // 1. reset master enable (=0) 2085 // 2. enable or disable a sensor 2086 // 3. set master enable (=1) 2087 2088 if (isLowPowerQuatEnabled() || 2089 changed & ((1 << Gyro) | (1 << RawGyro) | (1 << Accelerometer) | 2090 (mCompassSensor->isIntegrated() << MagneticField) | 2091#ifdef ENABLE_PRESSURE 2092 (mPressureSensor->isIntegrated() << Pressure) | 2093#endif 2094 (mCompassSensor->isIntegrated() << RawMagneticField))) { 2095 2096 /* reset master enable */ 2097 res = masterEnable(0); 2098 if(res < 0) { 2099 return res; 2100 } 2101 } 2102 2103 LOGV_IF(ENG_VERBOSE, "HAL:enableSensors - sensors: 0x%0x", 2104 (unsigned int)sensors); 2105 2106 if (changed & ((1 << Gyro) | (1 << RawGyro))) { 2107 LOGV_IF(ENG_VERBOSE, "HAL:enableSensors - gyro %s", 2108 (sensors & INV_THREE_AXIS_GYRO? "enable": "disable")); 2109 res = enableGyro(!!(sensors & INV_THREE_AXIS_GYRO)); 2110 if(res < 0) { 2111 return res; 2112 } 2113 2114 if (!cal_stored && (!en && (changed & (1 << Gyro)))) { 2115 storeCalibration(); 2116 cal_stored = 1; 2117 } 2118 } 2119 2120 if (changed & (1 << Accelerometer)) { 2121 LOGV_IF(ENG_VERBOSE, "HAL:enableSensors - accel %s", 2122 (sensors & INV_THREE_AXIS_ACCEL? "enable": "disable")); 2123 res = enableAccel(!!(sensors & INV_THREE_AXIS_ACCEL)); 2124 if(res < 0) { 2125 return res; 2126 } 2127 2128 if (!(sensors & INV_THREE_AXIS_ACCEL) && !cal_stored) { 2129 storeCalibration(); 2130 cal_stored = 1; 2131 } 2132 } 2133 2134 if (changed & ((1 << MagneticField) | (1 << RawMagneticField))) { 2135 LOGV_IF(ENG_VERBOSE, "HAL:enableSensors - compass %s", 2136 (sensors & INV_THREE_AXIS_COMPASS? "enable": "disable")); 2137 res = enableCompass(!!(sensors & INV_THREE_AXIS_COMPASS), changed & (1 << RawMagneticField)); 2138 if(res < 0) { 2139 return res; 2140 } 2141 2142 if (!cal_stored && (!en && (changed & (1 << MagneticField)))) { 2143 storeCalibration(); 2144 cal_stored = 1; 2145 } 2146 } 2147 2148#ifdef ENABLE_PRESSURE 2149 if (changed & (1 << Pressure)) { 2150 LOGV_IF(ENG_VERBOSE, "HAL:enableSensors - pressure %s", 2151 (sensors & INV_ONE_AXIS_PRESSURE? "enable": "disable")); 2152 res = enablePressure(!!(sensors & INV_ONE_AXIS_PRESSURE)); 2153 if(res < 0) { 2154 return res; 2155 } 2156 } 2157#endif 2158 2159 if (isLowPowerQuatEnabled()) { 2160 // Enable LP Quat 2161 if ((mEnabled & VIRTUAL_SENSOR_9AXES_MASK) 2162 || (mEnabled & VIRTUAL_SENSOR_GYRO_6AXES_MASK)) { 2163 LOGV_IF(ENG_VERBOSE, "HAL: 9 axis or game rot enabled"); 2164 if (!(changed & ((1 << Gyro) 2165 | (1 << RawGyro) 2166 | (1 << Accelerometer) 2167 | (mCompassSensor->isIntegrated() << MagneticField) 2168 | (mCompassSensor->isIntegrated() << RawMagneticField))) 2169 ) { 2170 /* reset master enable */ 2171 res = masterEnable(0); 2172 if(res < 0) { 2173 return res; 2174 } 2175 } 2176 if (!checkLPQuaternion()) { 2177 enableLPQuaternion(1); 2178 } else { 2179 LOGV_IF(ENG_VERBOSE, "HAL:LP Quat already enabled"); 2180 } 2181 } else if (checkLPQuaternion()) { 2182 enableLPQuaternion(0); 2183 } 2184 } 2185 2186 /* apply accel/gyro bias to DMP bias */ 2187 /* precondition: masterEnable(0), mGyroBiasAvailable=true */ 2188 /* postcondition: bias is applied upon masterEnable(1) */ 2189 if(!(sensors & INV_THREE_AXIS_GYRO)) { 2190 setGyroBias(); 2191 } 2192 if(!(sensors & INV_THREE_AXIS_ACCEL)) { 2193 setAccelBias(); 2194 } 2195 2196 /* to batch or not to batch */ 2197 int batchMode = computeBatchSensorMask(mEnabled, mBatchEnabled); 2198 /* skip setBatch if there is no need to */ 2199 if(((int)mOldBatchEnabledMask != batchMode) || batchMode) { 2200 setBatch(batchMode,0); 2201 } 2202 mOldBatchEnabledMask = batchMode; 2203 2204 /* check for invn hardware sensors change */ 2205 if (changed & ((1 << Gyro) | (1 << RawGyro) | (1 << Accelerometer) | 2206 (mCompassSensor->isIntegrated() << MagneticField) | 2207#ifdef ENABLE_PRESSURE 2208 (mPressureSensor->isIntegrated() << Pressure) | 2209#endif 2210 (mCompassSensor->isIntegrated() << RawMagneticField))) { 2211 LOGV_IF(ENG_VERBOSE, 2212 "HAL DEBUG: Gyro, Accel, Compass, Pressure changes"); 2213 if ((checkSmdSupport() == 1) || (checkPedometerSupport() == 1) || (sensors & 2214 (INV_THREE_AXIS_GYRO 2215 | INV_THREE_AXIS_ACCEL 2216#ifdef ENABLE_PRESSURE 2217 | (INV_ONE_AXIS_PRESSURE * mPressureSensor->isIntegrated()) 2218#endif 2219 | (INV_THREE_AXIS_COMPASS * mCompassSensor->isIntegrated())))) { 2220 LOGV_IF(ENG_VERBOSE, "SMD or Hardware sensors enabled"); 2221 LOGV_IF(ENG_VERBOSE, 2222 "mFeatureActiveMask=0x%llx", mFeatureActiveMask); 2223 LOGV_IF(ENG_VERBOSE, "HAL DEBUG: LPQ, SMD, SO enabled"); 2224 // disable DMP event interrupt only (w/ data interrupt) 2225 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 2226 0, mpu.dmp_event_int_on, getTimestamp()); 2227 if (write_sysfs_int(mpu.dmp_event_int_on, 0) < 0) { 2228 res = -1; 2229 LOGE("HAL:ERR can't disable DMP event interrupt"); 2230 return res; 2231 } 2232 LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=0x%llx", mFeatureActiveMask); 2233 LOGV_IF(ENG_VERBOSE, "DMP_FEATURE_MASK=0x%x", DMP_FEATURE_MASK); 2234 if ((mFeatureActiveMask & (long long)DMP_FEATURE_MASK) && 2235 !((mFeatureActiveMask & INV_DMP_6AXIS_QUATERNION) || 2236 (mFeatureActiveMask & INV_DMP_PED_STANDALONE) || 2237 (mFeatureActiveMask & INV_DMP_PED_QUATERNION) || 2238 (mFeatureActiveMask & INV_DMP_BATCH_MODE))) { 2239 // enable DMP 2240 onDmp(1); 2241 res = enableAccel(on); 2242 if(res < 0) { 2243 return res; 2244 } 2245 LOGV_IF(ENG_VERBOSE, "mLocalSensorMask=0x%lx", mLocalSensorMask); 2246 if (((sensors | mLocalSensorMask) & INV_THREE_AXIS_ACCEL) == 0) { 2247 res = turnOffAccelFifo(); 2248 } 2249 if(res < 0) { 2250 return res; 2251 } 2252 } 2253 } else { // all sensors idle 2254 LOGV_IF(ENG_VERBOSE, "HAL DEBUG: not SMD or Hardware sensors"); 2255 if (isDmpDisplayOrientationOn() 2256 && (mDmpOrientationEnabled 2257 || !isDmpScreenAutoRotationEnabled())) { 2258 enableDmpOrientation(1); 2259 } 2260 2261 if (!cal_stored) { 2262 storeCalibration(); 2263 cal_stored = 1; 2264 } 2265 } 2266 } else if ((changed & 2267 ((!mCompassSensor->isIntegrated()) << MagneticField) || 2268 ((!mCompassSensor->isIntegrated()) << RawMagneticField)) 2269 && 2270 !(sensors & (INV_THREE_AXIS_GYRO | INV_THREE_AXIS_ACCEL 2271 | (INV_THREE_AXIS_COMPASS * (!mCompassSensor->isIntegrated())))) 2272 ) { 2273 LOGV_IF(ENG_VERBOSE, "HAL DEBUG: Gyro, Accel, Compass no change"); 2274 if (!cal_stored) { 2275 storeCalibration(); 2276 cal_stored = 1; 2277 } 2278 } /*else { 2279 LOGV_IF(ENG_VERBOSE, "HAL DEBUG: mEnabled"); 2280 if (sensors & 2281 (INV_THREE_AXIS_GYRO 2282 | INV_THREE_AXIS_ACCEL 2283 | (INV_THREE_AXIS_COMPASS * mCompassSensor->isIntegrated()))) { 2284 res = masterEnable(1); 2285 if(res < 0) 2286 return res; 2287 } 2288 }*/ 2289 2290 if (!batchMode && (resetDataRates() < 0)) { 2291 LOGE("HAL:ERR can't reset output rate back to original setting"); 2292 } 2293 2294 if(mFeatureActiveMask || sensors) { 2295 res = masterEnable(1); 2296 if(res < 0) 2297 return res; 2298 } 2299 return res; 2300} 2301 2302/* check if batch mode should be turned on or not */ 2303int MPLSensor::computeBatchSensorMask(int enableSensors, int tempBatchSensor) 2304{ 2305 VFUNC_LOG; 2306 int batchMode = 1; 2307 mFeatureActiveMask &= ~INV_DMP_BATCH_MODE; 2308 2309 LOGV_IF(ENG_VERBOSE, 2310 "HAL:computeBatchSensorMask: enableSensors=%d tempBatchSensor=%d", 2311 enableSensors, tempBatchSensor); 2312 2313 // handle initialization case 2314 if (enableSensors == 0 && tempBatchSensor == 0) 2315 return 0; 2316 2317 // check for possible continuous data mode 2318 for(int i = 0; i <= LAST_HW_SENSOR; i++) { 2319 // if any one of the hardware sensor is in continuous data mode 2320 // turn off batch mode. 2321 if ((enableSensors & (1 << i)) && !(tempBatchSensor & (1 << i))) { 2322 LOGV_IF(ENG_VERBOSE, "HAL:computeBatchSensorMask: " 2323 "hardware sensor on continuous mode:%d", i); 2324 return 0; 2325 } 2326 if ((enableSensors & (1 << i)) && (tempBatchSensor & (1 << i))) { 2327 LOGV_IF(ENG_VERBOSE, 2328 "HAL:computeBatchSensorMask: hardware sensor is batch:%d", 2329 i); 2330 // if hardware sensor is batched, check if virtual sensor is also batched 2331 if ((enableSensors & (1 << GameRotationVector)) 2332 && !(tempBatchSensor & (1 << GameRotationVector))) { 2333 LOGV_IF(ENG_VERBOSE, 2334 "HAL:computeBatchSensorMask: but virtual sensor is not:%d", 2335 i); 2336 return 0; 2337 } 2338 } 2339 } 2340 2341 // if virtual sensors are on but not batched, turn off batch mode. 2342 for(int i = Orientation; i <= GeomagneticRotationVector; i++) { 2343 if ((enableSensors & (1 << i)) && !(tempBatchSensor & (1 << i))) { 2344 LOGV_IF(ENG_VERBOSE, "HAL:computeBatchSensorMask: " 2345 "composite sensor on continuous mode:%d", i); 2346 return 0; 2347 } 2348 } 2349 2350 if ((mFeatureActiveMask & INV_DMP_PEDOMETER) && !(tempBatchSensor & (1 << StepDetector))) { 2351 LOGV("HAL:computeBatchSensorMask: step detector on continuous mode."); 2352 return 0; 2353 } 2354 2355 mFeatureActiveMask |= INV_DMP_BATCH_MODE; 2356 LOGV_IF(EXTRA_VERBOSE, 2357 "HAL:computeBatchSensorMask: batchMode=%d, mBatchEnabled=%0x", 2358 batchMode, tempBatchSensor); 2359 return (batchMode && tempBatchSensor); 2360} 2361 2362/* This function is called by enable() */ 2363int MPLSensor::setBatch(int en, int toggleEnable) 2364{ 2365 VFUNC_LOG; 2366 2367 int res = 0; 2368 int64_t wanted = 1000000000LL; 2369 int64_t timeout = 0; 2370 int timeoutInMs = 0; 2371 int featureMask = computeBatchDataOutput(); 2372 2373 // reset master enable 2374 if (toggleEnable == 1) { 2375 res = masterEnable(0); 2376 if (res < 0) { 2377 return res; 2378 } 2379 } 2380 2381 /* step detector is enabled and */ 2382 /* batch mode is standalone */ 2383 if (en && (mFeatureActiveMask & INV_DMP_PEDOMETER) && 2384 (featureMask & INV_DMP_PED_STANDALONE)) { 2385 LOGV_IF(ENG_VERBOSE, "setBatch: ID_P only = 0x%x", mBatchEnabled); 2386 enablePedStandalone(1); 2387 } else { 2388 enablePedStandalone(0); 2389 } 2390 2391 /* step detector and GRV are enabled and */ 2392 /* batch mode is ped q */ 2393 if (en && (mFeatureActiveMask & INV_DMP_PEDOMETER) && 2394 (mEnabled & (1 << GameRotationVector)) && 2395 (featureMask & INV_DMP_PED_QUATERNION)) { 2396 LOGV_IF(ENG_VERBOSE, "setBatch: ID_P and GRV or ALL = 0x%x", mBatchEnabled); 2397 LOGV_IF(ENG_VERBOSE, "setBatch: ID_P is enabled for batching, " 2398 "PED quat will be automatically enabled"); 2399 enableLPQuaternion(0); 2400 enablePedQuaternion(1); 2401 } else if (!(featureMask & INV_DMP_PED_STANDALONE)){ 2402 enablePedQuaternion(0); 2403 } else { 2404 enablePedQuaternion(0); 2405 } 2406 2407 /* step detector and hardware sensors enabled */ 2408 if (en && (featureMask & INV_DMP_PED_INDICATOR) && 2409 ((mEnabled) || 2410 (mFeatureActiveMask & INV_DMP_PED_STANDALONE))) { 2411 enablePedIndicator(1); 2412 } else { 2413 enablePedIndicator(0); 2414 } 2415 2416 /* GRV is enabled and */ 2417 /* batch mode is 6axis q */ 2418 if (en && (mEnabled & (1 << GameRotationVector)) && 2419 (featureMask & INV_DMP_6AXIS_QUATERNION)) { 2420 LOGV_IF(ENG_VERBOSE, "setBatch: GRV = 0x%x", mBatchEnabled); 2421 enableLPQuaternion(0); 2422 enable6AxisQuaternion(1); 2423 setInitial6QuatValue(); 2424 } else if (!(featureMask & INV_DMP_PED_QUATERNION)){ 2425 LOGV_IF(ENG_VERBOSE, "setBatch: Toggle back to normal 6 axis"); 2426 if (mEnabled & (1 << GameRotationVector)) { 2427 enableLPQuaternion(checkLPQRateSupported()); 2428 } 2429 enable6AxisQuaternion(0); 2430 } else { 2431 enable6AxisQuaternion(0); 2432 } 2433 2434 writeBatchTimeout(en); 2435 2436 if (en) { 2437 // enable DMP 2438 res = onDmp(1); 2439 if (res < 0) { 2440 return res; 2441 } 2442 2443 // set batch rates 2444 if (setBatchDataRates() < 0) { 2445 LOGE("HAL:ERR can't set batch data rates"); 2446 } 2447 2448 // default fifo rate to 200Hz 2449 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 2450 200, mpu.gyro_fifo_rate, getTimestamp()); 2451 if (write_sysfs_int(mpu.gyro_fifo_rate, 200) < 0) { 2452 res = -1; 2453 LOGE("HAL:ERR can't set rate to 200Hz"); 2454 return res; 2455 } 2456 } else { 2457 if (mFeatureActiveMask == 0) { 2458 // disable DMP 2459 res = onDmp(0); 2460 if (res < 0) { 2461 return res; 2462 } 2463 /* reset sensor rate */ 2464 if (resetDataRates() < 0) { 2465 LOGE("HAL:ERR can't reset output rate back to original setting"); 2466 } 2467 } 2468 } 2469 2470 // set sensor data interrupt 2471 uint32_t dataInterrupt = (mEnabled || (mFeatureActiveMask & INV_DMP_BATCH_MODE)); 2472 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 2473 !dataInterrupt, mpu.dmp_event_int_on, getTimestamp()); 2474 if (write_sysfs_int(mpu.dmp_event_int_on, !dataInterrupt) < 0) { 2475 res = -1; 2476 LOGE("HAL:ERR can't enable DMP event interrupt"); 2477 } 2478 2479 if (toggleEnable == 1) { 2480 if (mFeatureActiveMask || mEnabled) 2481 masterEnable(1); 2482 } 2483 return res; 2484} 2485 2486int MPLSensor::writeBatchTimeout(int en) 2487{ 2488 VFUNC_LOG; 2489 2490 int64_t timeoutInMs = 0; 2491 if (en) { 2492 /* take the minimum batchmode timeout */ 2493 int64_t timeout = 100000000000LL; 2494 int64_t ns = 0; 2495 for (int i = 0; i < NumSensors; i++) { 2496 LOGV_IF(1, "mFeatureActiveMask=0x%016llx, mEnabled=0x%01x, mBatchEnabled=0x%x", 2497 mFeatureActiveMask, mEnabled, mBatchEnabled); 2498 if (((mEnabled & (1 << i)) && (mBatchEnabled & (1 << i))) || 2499 (checkPedStandaloneBatched() && (i == StepDetector))) { 2500 LOGV_IF(ENG_VERBOSE, "sensor=%d, timeout=%lld", i, mBatchTimeouts[i]); 2501 ns = mBatchTimeouts[i]; 2502 timeout = (ns < timeout) ? ns : timeout; 2503 } 2504 } 2505 /* Convert ns to millisecond */ 2506 timeoutInMs = timeout / 1000000; 2507 } else { 2508 timeoutInMs = 0; 2509 } 2510 2511 LOGV_IF(PROCESS_VERBOSE, 2512 "HAL: batch timeout set to %lld ms", timeoutInMs); 2513 2514 if(mBatchTimeoutInMs != timeoutInMs) { 2515 /* write required timeout to sysfs */ 2516 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %lld > %s (%lld)", 2517 timeoutInMs, mpu.batchmode_timeout, getTimestamp()); 2518 if (write_sysfs_int(mpu.batchmode_timeout, timeoutInMs) < 0) { 2519 LOGE("HAL:ERR can't write batchmode_timeout"); 2520 } 2521 } 2522 /* remember last timeout value */ 2523 mBatchTimeoutInMs = timeoutInMs; 2524 2525 return 0; 2526} 2527 2528/* Store calibration file */ 2529void MPLSensor::storeCalibration(void) 2530{ 2531 VFUNC_LOG; 2532 2533 if(mHaveGoodMpuCal == true 2534 || mAccelAccuracy >= 2 2535 || mCompassAccuracy >= 3) { 2536 int res = inv_store_calibration(); 2537 if (res) { 2538 LOGE("HAL:Cannot store calibration on file"); 2539 } else { 2540 LOGV_IF(PROCESS_VERBOSE, "HAL:Cal file updated"); 2541 } 2542 } 2543} 2544 2545/* these handlers transform mpl data into one of the Android sensor types */ 2546int MPLSensor::gyroHandler(sensors_event_t* s) 2547{ 2548 VHANDLER_LOG; 2549 int update; 2550 update = inv_get_sensor_type_gyroscope(s->gyro.v, &s->gyro.status, 2551 &s->timestamp); 2552 LOGV_IF(HANDLER_DATA, "HAL:gyro data : %+f %+f %+f -- %lld - %d", 2553 s->gyro.v[0], s->gyro.v[1], s->gyro.v[2], s->timestamp, update); 2554 return update; 2555} 2556 2557int MPLSensor::rawGyroHandler(sensors_event_t* s) 2558{ 2559 VHANDLER_LOG; 2560 int update; 2561 update = inv_get_sensor_type_gyroscope_raw(s->uncalibrated_gyro.uncalib, 2562 &s->gyro.status, &s->timestamp); 2563 if(update) { 2564 memcpy(s->uncalibrated_gyro.bias, mGyroBias, sizeof(mGyroBias)); 2565 LOGV_IF(HANDLER_DATA,"HAL:gyro bias data : %+f %+f %+f -- %lld - %d", 2566 s->uncalibrated_gyro.bias[0], s->uncalibrated_gyro.bias[1], 2567 s->uncalibrated_gyro.bias[2], s->timestamp, update); 2568 } 2569 s->gyro.status = SENSOR_STATUS_UNRELIABLE; 2570 LOGV_IF(HANDLER_DATA, "HAL:raw gyro data : %+f %+f %+f -- %lld - %d", 2571 s->uncalibrated_gyro.uncalib[0], s->uncalibrated_gyro.uncalib[1], 2572 s->uncalibrated_gyro.uncalib[2], s->timestamp, update); 2573 return update; 2574} 2575 2576int MPLSensor::accelHandler(sensors_event_t* s) 2577{ 2578 VHANDLER_LOG; 2579 int update; 2580 update = inv_get_sensor_type_accelerometer( 2581 s->acceleration.v, &s->acceleration.status, &s->timestamp); 2582 LOGV_IF(HANDLER_DATA, "HAL:accel data : %+f %+f %+f -- %lld - %d", 2583 s->acceleration.v[0], s->acceleration.v[1], s->acceleration.v[2], 2584 s->timestamp, update); 2585 mAccelAccuracy = s->acceleration.status; 2586 return update; 2587} 2588 2589int MPLSensor::compassHandler(sensors_event_t* s) 2590{ 2591 VHANDLER_LOG; 2592 int update; 2593 update = inv_get_sensor_type_magnetic_field( 2594 s->magnetic.v, &s->magnetic.status, &s->timestamp); 2595 LOGV_IF(HANDLER_DATA, "HAL:compass data: %+f %+f %+f -- %lld - %d", 2596 s->magnetic.v[0], s->magnetic.v[1], s->magnetic.v[2], 2597 s->timestamp, update); 2598 mCompassAccuracy = s->magnetic.status; 2599 return update | mCompassOverFlow; 2600} 2601 2602int MPLSensor::rawCompassHandler(sensors_event_t* s) 2603{ 2604 VHANDLER_LOG; 2605 int update; 2606 //TODO: need to handle uncalib data and bias for 3rd party compass 2607 if(mCompassSensor->providesCalibration()) { 2608 update = mCompassSensor->readRawSample(s->uncalibrated_magnetic.uncalib, &s->timestamp); 2609 } 2610 else { 2611 update = inv_get_sensor_type_magnetic_field_raw(s->uncalibrated_magnetic.uncalib, 2612 &s->magnetic.status, &s->timestamp); 2613 } 2614 if(update) { 2615 memcpy(s->uncalibrated_magnetic.bias, mCompassBias, sizeof(mCompassBias)); 2616 LOGV_IF(HANDLER_DATA, "HAL:compass bias data: %+f %+f %+f -- %lld - %d", 2617 s->uncalibrated_magnetic.bias[0], s->uncalibrated_magnetic.bias[1], 2618 s->uncalibrated_magnetic.bias[2], s->timestamp, update); 2619 } 2620 s->magnetic.status = SENSOR_STATUS_UNRELIABLE; 2621 LOGV_IF(HANDLER_DATA, "HAL:compass raw data: %+f %+f %+f %d -- %lld - %d", 2622 s->uncalibrated_magnetic.uncalib[0], s->uncalibrated_magnetic.uncalib[1], 2623 s->uncalibrated_magnetic.uncalib[2], s->magnetic.status, s->timestamp, update); 2624 return update | mCompassOverFlow; 2625} 2626 2627/* 2628 Rotation Vector handler. 2629 NOTE: rotation vector does not have an accuracy or status 2630*/ 2631int MPLSensor::rvHandler(sensors_event_t* s) 2632{ 2633 VHANDLER_LOG; 2634 int8_t status; 2635 int update; 2636 update = inv_get_sensor_type_rotation_vector(s->data, &status, 2637 &s->timestamp); 2638 s->orientation.status = status; 2639 update |= isCompassDisabled(); 2640 LOGV_IF(HANDLER_DATA, "HAL:rv data: %+f %+f %+f %+f %+f %d- %+lld - %d", 2641 s->data[0], s->data[1], s->data[2], s->data[3], s->data[4], s->orientation.status, s->timestamp, 2642 update); 2643 2644 return update; 2645} 2646 2647/* 2648 Game Rotation Vector handler. 2649 NOTE: rotation vector does not have an accuracy or status 2650*/ 2651int MPLSensor::grvHandler(sensors_event_t* s) 2652{ 2653 VHANDLER_LOG; 2654 int8_t status; 2655 int update; 2656 update = inv_get_sensor_type_rotation_vector_6_axis(s->data, &status, 2657 &s->timestamp); 2658 s->orientation.status = status; 2659 2660 LOGV_IF(HANDLER_DATA, "HAL:grv data: %+f %+f %+f %+f %+f %d- %+lld - %d", 2661 s->data[0], s->data[1], s->data[2], s->data[3], s->data[4], s->orientation.status, s->timestamp, 2662 update); 2663 return update; 2664} 2665 2666int MPLSensor::laHandler(sensors_event_t* s) 2667{ 2668 VHANDLER_LOG; 2669 int update; 2670 update = inv_get_sensor_type_linear_acceleration( 2671 s->gyro.v, &s->gyro.status, &s->timestamp); 2672 update |= isCompassDisabled(); 2673 LOGV_IF(HANDLER_DATA, "HAL:la data: %+f %+f %+f - %lld - %d", 2674 s->gyro.v[0], s->gyro.v[1], s->gyro.v[2], s->timestamp, update); 2675 return update; 2676} 2677 2678int MPLSensor::gravHandler(sensors_event_t* s) 2679{ 2680 VHANDLER_LOG; 2681 int update; 2682 update = inv_get_sensor_type_gravity(s->gyro.v, &s->gyro.status, 2683 &s->timestamp); 2684 update |= isCompassDisabled(); 2685 LOGV_IF(HANDLER_DATA, "HAL:gr data: %+f %+f %+f - %lld - %d", 2686 s->gyro.v[0], s->gyro.v[1], s->gyro.v[2], s->timestamp, update); 2687 return update; 2688} 2689 2690int MPLSensor::orienHandler(sensors_event_t* s) 2691{ 2692 VHANDLER_LOG; 2693 int update; 2694 update = inv_get_sensor_type_orientation( 2695 s->orientation.v, &s->orientation.status, &s->timestamp); 2696 update |= isCompassDisabled(); 2697 LOGV_IF(HANDLER_DATA, "HAL:or data: %f %f %f - %lld - %d", 2698 s->orientation.v[0], s->orientation.v[1], s->orientation.v[2], 2699 s->timestamp, update); 2700 return update; 2701} 2702 2703int MPLSensor::smHandler(sensors_event_t* s) 2704{ 2705 VHANDLER_LOG; 2706 int update = 1; 2707 2708 /* When event is triggered, set data to 1 */ 2709 s->data[0] = 1.f; 2710 s->data[1] = 0.f; 2711 s->data[2] = 0.f; 2712 2713 /* Capture timestamp in HAL */ 2714 struct timespec ts; 2715 clock_gettime(CLOCK_MONOTONIC, &ts); 2716 s->timestamp = (int64_t) ts.tv_sec * 1000000000 + ts.tv_nsec; 2717 2718 LOGV_IF(HANDLER_DATA, "HAL:sm data: %f - %lld - %d", 2719 s->data[0], s->timestamp, update); 2720 return update; 2721} 2722 2723int MPLSensor::gmHandler(sensors_event_t* s) 2724{ 2725 VHANDLER_LOG; 2726 int8_t status; 2727 int update = 0; 2728 update = inv_get_sensor_type_geomagnetic_rotation_vector(s->data, &status, 2729 &s->timestamp); 2730 s->orientation.status = status; 2731 LOGV_IF(HANDLER_DATA, "HAL:gm data: %+f %+f %+f %+f %+f %d- %+lld - %d", 2732 s->data[0], s->data[1], s->data[2], s->data[3], s->data[4], s->orientation.status, s->timestamp, update); 2733 return update < 1 ? 0 :1; 2734 2735} 2736 2737int MPLSensor::psHandler(sensors_event_t* s) 2738{ 2739 VHANDLER_LOG; 2740 int8_t status; 2741 int update = 0; 2742 2743 s->pressure = mCachedPressureData / 100.f; //hpa (millibar) 2744 s->data[1] = 0; 2745 s->data[2] = 0; 2746 s->timestamp = mPressureTimestamp; 2747 s->magnetic.status = 0; 2748 update = mPressureUpdate; 2749 mPressureUpdate = 0; 2750 2751 LOGV_IF(HANDLER_DATA, "HAL:ps data: %+f %+f %+f %+f- %+lld - %d", 2752 s->data[0], s->data[1], s->data[2], s->data[3], s->timestamp, update); 2753 return update < 1 ? 0 :1; 2754 2755} 2756 2757int MPLSensor::sdHandler(sensors_event_t* s) 2758{ 2759 VHANDLER_LOG; 2760 int update = 1; 2761 2762 /* When event is triggered, set data to 1 */ 2763 s->data[0] = 1; 2764 s->data[1] = 0.f; 2765 s->data[2] = 0.f; 2766 2767 /* get current timestamp */ 2768 struct timespec ts; 2769 clock_gettime(CLOCK_MONOTONIC, &ts) ; 2770 s->timestamp = (int64_t)ts.tv_sec * 1000000000 + ts.tv_nsec; 2771 2772 LOGV_IF(HANDLER_DATA, "HAL:sd data: %f - %lld - %d", 2773 s->data[0], s->timestamp, update); 2774 return update; 2775} 2776 2777int MPLSensor::scHandler(sensors_event_t* s) 2778{ 2779 VHANDLER_LOG; 2780 int update = 1; 2781 2782 /* Set step count */ 2783#if defined ANDROID_KITKAT 2784 s->u64.step_counter = mLastStepCount; 2785 LOGV_IF(HANDLER_DATA, "HAL:sc data: %lld - %lld - %d", 2786 s->u64.step_counter, s->timestamp, update); 2787#else 2788 s->step_counter = mLastStepCount; 2789 LOGV_IF(HANDLER_DATA, "HAL:sc data: %lld - %lld - %d", 2790 s->step_counter, s->timestamp, update); 2791#endif 2792 return update; 2793} 2794 2795int MPLSensor::metaHandler(sensors_event_t* s, int flags) 2796{ 2797 VHANDLER_LOG; 2798 int update = 1; 2799 2800#if defined ANDROID_KITKAT 2801 /* initalize SENSOR_TYPE_META_DATA */ 2802 s->version = 0; 2803 s->sensor = 0; 2804 s->reserved0 = 0; 2805 s->timestamp = 0LL; 2806 2807 switch(flags) { 2808 case META_DATA_FLUSH_COMPLETE: 2809 s->type = SENSOR_TYPE_META_DATA; 2810 s->meta_data.what = flags; 2811 s->meta_data.sensor = mFlushSensorEnabledVector[0]; 2812 mFlushSensorEnabledVector.removeAt(0); 2813 mFlushBatchSet = 0; 2814 LOGV_IF(HANDLER_DATA, 2815 "HAL:flush complete data: type=%d what=%d, " 2816 "sensor=%d - %lld - %d", 2817 s->type, s->meta_data.what, s->meta_data.sensor, 2818 s->timestamp, update); 2819 break; 2820 2821 default: 2822 LOGW("HAL: Meta flags not supported"); 2823 break; 2824 } 2825#endif 2826 return 1; 2827} 2828 2829int MPLSensor::enable(int32_t handle, int en) 2830{ 2831 VFUNC_LOG; 2832 2833 android::String8 sname; 2834 int what = -1, err = 0; 2835 int batchMode = 0; 2836 2837 if (uint32_t(handle) >= NumSensors) 2838 return -EINVAL; 2839 2840 if (!en) 2841 mBatchEnabled &= ~(1 << handle); 2842 2843 LOGV_IF(ENG_VERBOSE, "HAL:handle = %d", handle); 2844 2845 switch (handle) { 2846 case ID_SC: 2847 what = StepCounter; 2848 sname = "Step Counter"; 2849 LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s", 2850 sname.string(), handle, 2851 (mDmpStepCountEnabled? "en": "dis"), 2852 (en? "en" : "dis")); 2853 enableDmpPedometer(en, 0); 2854 mDmpStepCountEnabled = !!en; 2855 return 0; 2856 case ID_P: 2857 sname = "StepDetector"; 2858 LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s", 2859 sname.string(), handle, 2860 (mDmpPedometerEnabled? "en": "dis"), 2861 (en? "en" : "dis")); 2862 enableDmpPedometer(en, 1); 2863 mDmpPedometerEnabled = !!en; 2864 batchMode = computeBatchSensorMask(mEnabled, mBatchEnabled); 2865 /* skip setBatch if there is no need to */ 2866 if(((int)mOldBatchEnabledMask != batchMode) || batchMode) { 2867 setBatch(batchMode,1); 2868 } 2869 mOldBatchEnabledMask = batchMode; 2870 return 0; 2871 case ID_SM: 2872 sname = "Significant Motion"; 2873 LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s", 2874 sname.string(), handle, 2875 (mDmpSignificantMotionEnabled? "en": "dis"), 2876 (en? "en" : "dis")); 2877 enableDmpSignificantMotion(en); 2878 mDmpSignificantMotionEnabled = !!en; 2879 return 0; 2880 case ID_SO: 2881 sname = "Screen Orientation"; 2882 LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s", 2883 sname.string(), handle, 2884 (mDmpOrientationEnabled? "en": "dis"), 2885 (en? "en" : "dis")); 2886 enableDmpOrientation(en && isDmpDisplayOrientationOn()); 2887 mDmpOrientationEnabled = !!en; 2888 return 0; 2889 case ID_A: 2890 what = Accelerometer; 2891 sname = "Accelerometer"; 2892 break; 2893 case ID_M: 2894 what = MagneticField; 2895 sname = "MagneticField"; 2896 break; 2897 case ID_RM: 2898 what = RawMagneticField; 2899 sname = "MagneticField Uncalibrated"; 2900 break; 2901 case ID_O: 2902 what = Orientation; 2903 sname = "Orientation"; 2904 break; 2905 case ID_GY: 2906 what = Gyro; 2907 sname = "Gyro"; 2908 break; 2909 case ID_RG: 2910 what = RawGyro; 2911 sname = "Gyro Uncalibrated"; 2912 break; 2913 case ID_GR: 2914 what = Gravity; 2915 sname = "Gravity"; 2916 break; 2917 case ID_RV: 2918 what = RotationVector; 2919 sname = "RotationVector"; 2920 break; 2921 case ID_GRV: 2922 what = GameRotationVector; 2923 sname = "GameRotationVector"; 2924 break; 2925 case ID_LA: 2926 what = LinearAccel; 2927 sname = "LinearAccel"; 2928 break; 2929 case ID_GMRV: 2930 what = GeomagneticRotationVector; 2931 sname = "GeomagneticRotationVector"; 2932 break; 2933#ifdef ENABLE_PRESSURE 2934 case ID_PS: 2935 what = Pressure; 2936 sname = "Pressure"; 2937 break; 2938#endif 2939 default: 2940 what = handle; 2941 sname = "Others"; 2942 break; 2943 } 2944 2945 int newState = en ? 1 : 0; 2946 unsigned long sen_mask; 2947 2948 LOGV_IF(PROCESS_VERBOSE, "HAL:enable - sensor %s (handle %d) %s -> %s", 2949 sname.string(), handle, 2950 ((mEnabled & (1 << what)) ? "en" : "dis"), 2951 ((uint32_t(newState) << what) ? "en" : "dis")); 2952 LOGV_IF(ENG_VERBOSE, 2953 "HAL:%s sensor state change what=%d", sname.string(), what); 2954 2955 // pthread_mutex_lock(&mMplMutex); 2956 // pthread_mutex_lock(&mHALMutex); 2957 2958 if ((uint32_t(newState) << what) != (mEnabled & (1 << what))) { 2959 uint32_t sensor_type; 2960 short flags = newState; 2961 uint32_t lastEnabled = mEnabled, changed = 0; 2962 2963 mEnabled &= ~(1 << what); 2964 mEnabled |= (uint32_t(flags) << what); 2965 2966 LOGV_IF(ENG_VERBOSE, "HAL:flags = %d", flags); 2967 computeLocalSensorMask(mEnabled); 2968 LOGV_IF(ENG_VERBOSE, "HAL:enable : mEnabled = %d", mEnabled); 2969 LOGV_IF(ENG_VERBOSE, "HAL:last enable : lastEnabled = %d", lastEnabled); 2970 sen_mask = mLocalSensorMask & mMasterSensorMask; 2971 mSensorMask = sen_mask; 2972 LOGV_IF(ENG_VERBOSE, "HAL:sen_mask= 0x%0lx", sen_mask); 2973 2974 switch (what) { 2975 case Gyro: 2976 case RawGyro: 2977 case Accelerometer: 2978 if ((!(mEnabled & VIRTUAL_SENSOR_GYRO_6AXES_MASK) && 2979 !(mEnabled & VIRTUAL_SENSOR_9AXES_MASK)) && 2980 ((lastEnabled & (1 << what)) != (mEnabled & (1 << what)))) { 2981 changed |= (1 << what); 2982 } 2983 if (mFeatureActiveMask & INV_DMP_6AXIS_QUATERNION) { 2984 changed |= (1 << what); 2985 } 2986 break; 2987 case MagneticField: 2988 case RawMagneticField: 2989 if (!(mEnabled & VIRTUAL_SENSOR_9AXES_MASK) && 2990 ((lastEnabled & (1 << what)) != (mEnabled & (1 << what)))) { 2991 changed |= (1 << what); 2992 } 2993 break; 2994#ifdef ENABLE_PRESSURE 2995 case Pressure: 2996 if ((lastEnabled & (1 << what)) != (mEnabled & (1 << what))) { 2997 changed |= (1 << what); 2998 } 2999 break; 3000#endif 3001 case GameRotationVector: 3002 if (!en) 3003 storeCalibration(); 3004 if ((en && !(lastEnabled & VIRTUAL_SENSOR_ALL_MASK)) 3005 || 3006 (en && !(lastEnabled & VIRTUAL_SENSOR_9AXES_MASK)) 3007 || 3008 (!en && !(mEnabled & VIRTUAL_SENSOR_ALL_MASK)) 3009 || 3010 (!en && (mEnabled & VIRTUAL_SENSOR_MAG_6AXES_MASK))) { 3011 for (int i = Gyro; i <= RawMagneticField; i++) { 3012 if (!(mEnabled & (1 << i))) { 3013 changed |= (1 << i); 3014 } 3015 } 3016 } 3017 break; 3018 3019 case Orientation: 3020 case RotationVector: 3021 case LinearAccel: 3022 case Gravity: 3023 if (!en) 3024 storeCalibration(); 3025 if ((en && !(lastEnabled & VIRTUAL_SENSOR_9AXES_MASK)) 3026 || 3027 (!en && !(mEnabled & VIRTUAL_SENSOR_9AXES_MASK))) { 3028 for (int i = Gyro; i <= RawMagneticField; i++) { 3029 if (!(mEnabled & (1 << i))) { 3030 changed |= (1 << i); 3031 } 3032 } 3033 } 3034 break; 3035 case GeomagneticRotationVector: 3036 if (!en) 3037 storeCalibration(); 3038 if ((en && !(lastEnabled & VIRTUAL_SENSOR_ALL_MASK)) 3039 || 3040 (en && !(lastEnabled & VIRTUAL_SENSOR_9AXES_MASK)) 3041 || 3042 (!en && !(mEnabled & VIRTUAL_SENSOR_ALL_MASK)) 3043 || 3044 (!en && (mEnabled & VIRTUAL_SENSOR_GYRO_6AXES_MASK))) { 3045 for (int i = Accelerometer; i <= RawMagneticField; i++) { 3046 if (!(mEnabled & (1<<i))) { 3047 changed |= (1 << i); 3048 } 3049 } 3050 } 3051 break; 3052 } 3053 LOGV_IF(ENG_VERBOSE, "HAL:changed = %d", changed); 3054 enableSensors(sen_mask, flags, changed); 3055 } 3056 3057 // pthread_mutex_unlock(&mMplMutex); 3058 // pthread_mutex_unlock(&mHALMutex); 3059 3060#ifdef INV_PLAYBACK_DBG 3061 /* apparently the logging needs to go through this sequence 3062 to properly flush the log file */ 3063 inv_turn_off_data_logging(); 3064 if (fclose(logfile) < 0) { 3065 LOGE("cannot close debug log file"); 3066 } 3067 logfile = fopen("/data/playback.bin", "ab"); 3068 if (logfile) 3069 inv_turn_on_data_logging(logfile); 3070#endif 3071 3072 return err; 3073} 3074 3075void MPLSensor::getHandle(int32_t handle, int &what, android::String8 &sname) 3076{ 3077 VFUNC_LOG; 3078 3079 what = -1; 3080 3081 switch (handle) { 3082 case ID_P: 3083 what = StepDetector; 3084 sname = "StepDetector"; 3085 break; 3086 case ID_SC: 3087 what = StepCounter; 3088 sname = "StepCounter"; 3089 break; 3090 case ID_SM: 3091 what = SignificantMotion; 3092 sname = "SignificantMotion"; 3093 break; 3094 case ID_SO: 3095 what = handle; 3096 sname = "ScreenOrienation"; 3097 break; 3098 case ID_A: 3099 what = Accelerometer; 3100 sname = "Accelerometer"; 3101 break; 3102 case ID_M: 3103 what = MagneticField; 3104 sname = "MagneticField"; 3105 break; 3106 case ID_RM: 3107 what = RawMagneticField; 3108 sname = "MagneticField Uncalibrated"; 3109 break; 3110 case ID_O: 3111 what = Orientation; 3112 sname = "Orientation"; 3113 break; 3114 case ID_GY: 3115 what = Gyro; 3116 sname = "Gyro"; 3117 break; 3118 case ID_RG: 3119 what = RawGyro; 3120 sname = "Gyro Uncalibrated"; 3121 break; 3122 case ID_GR: 3123 what = Gravity; 3124 sname = "Gravity"; 3125 break; 3126 case ID_RV: 3127 what = RotationVector; 3128 sname = "RotationVector"; 3129 break; 3130 case ID_GRV: 3131 what = GameRotationVector; 3132 sname = "GameRotationVector"; 3133 break; 3134 case ID_LA: 3135 what = LinearAccel; 3136 sname = "LinearAccel"; 3137 break; 3138#ifdef ENABLE_PRESSURE 3139 case ID_PS: 3140 what = Pressure; 3141 sname = "Pressure"; 3142 break; 3143#endif 3144 default: // this takes care of all the gestures 3145 what = handle; 3146 sname = "Others"; 3147 break; 3148 } 3149 3150 LOGI_IF(EXTRA_VERBOSE, "HAL:getHandle - what=%d, sname=%s", what, sname.string()); 3151 return; 3152} 3153 3154int MPLSensor::setDelay(int32_t handle, int64_t ns) 3155{ 3156 VFUNC_LOG; 3157 3158 android::String8 sname; 3159 int what = -1; 3160 3161#if 0 3162 // skip the 1st call for enalbing sensors called by ICS/JB sensor service 3163 static int counter_delay = 0; 3164 if (!(mEnabled & (1 << what))) { 3165 counter_delay = 0; 3166 } else { 3167 if (++counter_delay == 1) { 3168 return 0; 3169 } 3170 else { 3171 counter_delay = 0; 3172 } 3173 } 3174#endif 3175 3176 getHandle(handle, what, sname); 3177 if (uint32_t(what) >= NumSensors) 3178 return -EINVAL; 3179 3180 if (ns < 0) 3181 return -EINVAL; 3182 3183 LOGV_IF(PROCESS_VERBOSE, 3184 "setDelay : %llu ns, (%.2f Hz)", ns, 1000000000.f / ns); 3185 3186 // limit all rates to reasonable ones */ 3187 if (ns < 5000000LL) { 3188 ns = 5000000LL; 3189 } 3190 3191 /* store request rate to mDelays arrary for each sensor */ 3192 int64_t previousDelay = mDelays[what]; 3193 mDelays[what] = ns; 3194 LOGV_IF(ENG_VERBOSE, "storing mDelays[%d] = %lld, previousDelay = %lld", what, ns, previousDelay); 3195 3196 switch (what) { 3197 case StepCounter: 3198 /* set limits of delivery rate of events */ 3199 mStepCountPollTime = ns; 3200 LOGV_IF(ENG_VERBOSE, "step count rate =%lld ns", ns); 3201 break; 3202 case StepDetector: 3203 case SignificantMotion: 3204#ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION 3205 case ID_SO: 3206#endif 3207 LOGV_IF(ENG_VERBOSE, "Step Detect, SMD, SO rate=%lld ns", ns); 3208 break; 3209 case Gyro: 3210 case RawGyro: 3211 case Accelerometer: 3212 // need to update delay since they are different 3213 // resetDataRates was called earlier 3214 // LOGV("what=%d mEnabled=%d mDelays[%d]=%lld previousDelay=%lld", 3215 // what, mEnabled, what, mDelays[what], previousDelay); 3216 if ((mEnabled & (1 << what)) && (previousDelay != mDelays[what])) { 3217 LOGV_IF(ENG_VERBOSE, 3218 "HAL:need to update delay due to resetDataRates"); 3219 break; 3220 } 3221 for (int i = Gyro; 3222 i <= Accelerometer + mCompassSensor->isIntegrated(); 3223 i++) { 3224 if (i != what && (mEnabled & (1 << i)) && ns > mDelays[i]) { 3225 LOGV_IF(ENG_VERBOSE, 3226 "HAL:ignore delay set due to sensor %d", i); 3227 return 0; 3228 } 3229 } 3230 break; 3231 3232 case MagneticField: 3233 case RawMagneticField: 3234 // need to update delay since they are different 3235 // resetDataRates was called earlier 3236 if ((mEnabled & (1 << what)) && (previousDelay != mDelays[what])) { 3237 LOGV_IF(ENG_VERBOSE, 3238 "HAL:need to update delay due to resetDataRates"); 3239 break; 3240 } 3241 if (mCompassSensor->isIntegrated() && 3242 (((mEnabled & (1 << Gyro)) && ns > mDelays[Gyro]) || 3243 ((mEnabled & (1 << RawGyro)) && ns > mDelays[RawGyro]) || 3244 ((mEnabled & (1 << Accelerometer)) && 3245 ns > mDelays[Accelerometer])) && 3246 !checkBatchEnabled()) { 3247 /* if request is slower rate, ignore request */ 3248 LOGV_IF(ENG_VERBOSE, 3249 "HAL:ignore delay set due to gyro/accel"); 3250 return 0; 3251 } 3252 break; 3253 3254 case Orientation: 3255 case RotationVector: 3256 case GameRotationVector: 3257 case GeomagneticRotationVector: 3258 case LinearAccel: 3259 case Gravity: 3260 if (isLowPowerQuatEnabled()) { 3261 LOGV_IF(ENG_VERBOSE, 3262 "HAL:need to update delay due to LPQ"); 3263 break; 3264 } 3265 3266 for (int i = 0; i < NumSensors; i++) { 3267 if (i != what && (mEnabled & (1 << i)) && ns > mDelays[i]) { 3268 LOGV_IF(ENG_VERBOSE, 3269 "HAL:ignore delay set due to sensor %d", i); 3270 return 0; 3271 } 3272 } 3273 break; 3274 } 3275 3276 // pthread_mutex_lock(&mHALMutex); 3277 int res = update_delay(); 3278 // pthread_mutex_unlock(&mHALMutex); 3279 return res; 3280} 3281 3282int MPLSensor::update_delay(void) 3283{ 3284 VFUNC_LOG; 3285 3286 int res = 0; 3287 int64_t got; 3288 3289 if (mEnabled) { 3290 int64_t wanted = 1000000000LL; 3291 int64_t wanted_3rd_party_sensor = 1000000000LL; 3292 3293 // Sequence to change sensor's FIFO rate 3294 // 1. reset master enable 3295 // 2. Update delay 3296 // 3. set master enable 3297 3298 // reset master enable 3299 masterEnable(0); 3300 3301 int64_t gyroRate; 3302 int64_t accelRate; 3303 int64_t compassRate; 3304#ifdef ENABLE_PRESSURE 3305 int64_t pressureRate; 3306#endif 3307 3308 int rateInus; 3309 int mplGyroRate; 3310 int mplAccelRate; 3311 int mplCompassRate; 3312 int tempRate = wanted; 3313 3314 /* search the minimum delay requested across all enabled sensors */ 3315 for (int i = 0; i < NumSensors; i++) { 3316 if (mEnabled & (1 << i)) { 3317 int64_t ns = mDelays[i]; 3318 wanted = wanted < ns ? wanted : ns; 3319 } 3320 } 3321 3322 /* initialize rate for each sensor */ 3323 gyroRate = wanted; 3324 accelRate = wanted; 3325 compassRate = wanted; 3326#ifdef ENABLE_PRESSURE 3327 pressureRate = wanted; 3328#endif 3329 // same delay for 3rd party Accel or Compass 3330 wanted_3rd_party_sensor = wanted; 3331 3332 int enabled_sensors = mEnabled; 3333 int tempFd = -1; 3334 3335 if(mFeatureActiveMask & INV_DMP_BATCH_MODE) { 3336 // set batch rates 3337 LOGV_IF(ENG_VERBOSE, "HAL: mFeatureActiveMask=%016llx", mFeatureActiveMask); 3338 LOGV("HAL: batch mode is set, set batch data rates"); 3339 if (setBatchDataRates() < 0) { 3340 LOGE("HAL:ERR can't set batch data rates"); 3341 } 3342 } else { 3343 /* set master sampling frequency */ 3344 int64_t tempWanted = wanted; 3345 getDmpRate(&tempWanted); 3346 /* driver only looks at sampling frequency if DMP is off */ 3347 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)", 3348 1000000000.f / tempWanted, mpu.gyro_fifo_rate, getTimestamp()); 3349 tempFd = open(mpu.gyro_fifo_rate, O_RDWR); 3350 res = write_attribute_sensor(tempFd, 1000000000.f / tempWanted); 3351 LOGE_IF(res < 0, "HAL:sampling frequency update delay error"); 3352 3353 if (LA_ENABLED || GR_ENABLED || RV_ENABLED 3354 || GRV_ENABLED || O_ENABLED || GMRV_ENABLED) { 3355 rateInus = (int)wanted / 1000LL; 3356 3357 /* set rate in MPL */ 3358 /* compass can only do 100Hz max */ 3359 inv_set_gyro_sample_rate(rateInus); 3360 inv_set_accel_sample_rate(rateInus); 3361 inv_set_compass_sample_rate(rateInus); 3362 inv_set_linear_acceleration_sample_rate(rateInus); 3363 inv_set_orientation_sample_rate(rateInus); 3364 inv_set_rotation_vector_sample_rate(rateInus); 3365 inv_set_gravity_sample_rate(rateInus); 3366 inv_set_orientation_geomagnetic_sample_rate(rateInus); 3367 inv_set_rotation_vector_6_axis_sample_rate(rateInus); 3368 inv_set_geomagnetic_rotation_vector_sample_rate(rateInus); 3369 3370 LOGV_IF(ENG_VERBOSE, 3371 "HAL:MPL virtual sensor sample rate: (mpl)=%d us (mpu)=%.2f Hz", 3372 rateInus, 1000000000.f / wanted); 3373 LOGV_IF(ENG_VERBOSE, 3374 "HAL:MPL gyro sample rate: (mpl)=%d us (mpu)=%.2f Hz", 3375 rateInus, 1000000000.f / gyroRate); 3376 LOGV_IF(ENG_VERBOSE, 3377 "HAL:MPL accel sample rate: (mpl)=%d us (mpu)=%.2f Hz", 3378 rateInus, 1000000000.f / accelRate); 3379 LOGV_IF(ENG_VERBOSE, 3380 "HAL:MPL compass sample rate: (mpl)=%d us (mpu)=%.2f Hz", 3381 rateInus, 1000000000.f / compassRate); 3382 3383 LOGV_IF(ENG_VERBOSE, 3384 "mFeatureActiveMask=%016llx", mFeatureActiveMask); 3385 if(mFeatureActiveMask & DMP_FEATURE_MASK) { 3386 bool setDMPrate= 0; 3387 gyroRate = wanted; 3388 accelRate = wanted; 3389 compassRate = wanted; 3390 // same delay for 3rd party Accel or Compass 3391 wanted_3rd_party_sensor = wanted; 3392 rateInus = (int)wanted / 1000LL; 3393 // Set LP Quaternion sample rate if enabled 3394 if (checkLPQuaternion()) { 3395 if (wanted <= RATE_200HZ) { 3396#ifndef USE_LPQ_AT_FASTEST 3397 enableLPQuaternion(0); 3398#endif 3399 } else { 3400 inv_set_quat_sample_rate(rateInus); 3401 LOGV_IF(ENG_VERBOSE, "HAL:MPL quat sample rate: " 3402 "(mpl)=%d us (mpu)=%.2f Hz", 3403 rateInus, 1000000000.f / wanted); 3404 setDMPrate= 1; 3405 } 3406 } 3407 } 3408 3409 LOGV_IF(EXTRA_VERBOSE, "HAL:setDelay - Fusion"); 3410 //nsToHz 3411 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)", 3412 1000000000.f / gyroRate, mpu.gyro_rate, 3413 getTimestamp()); 3414 tempFd = open(mpu.gyro_rate, O_RDWR); 3415 res = write_attribute_sensor(tempFd, 1000000000.f / gyroRate); 3416 if(res < 0) { 3417 LOGE("HAL:GYRO update delay error"); 3418 } 3419 3420 if(USE_THIRD_PARTY_ACCEL == 1) { 3421 // 3rd party accelerometer - if applicable 3422 // nsToHz (BMA250) 3423 LOGV_IF(SYSFS_VERBOSE, "echo %lld > %s (%lld)", 3424 wanted_3rd_party_sensor / 1000000L, mpu.accel_rate, 3425 getTimestamp()); 3426 tempFd = open(mpu.accel_rate, O_RDWR); 3427 res = write_attribute_sensor(tempFd, 3428 wanted_3rd_party_sensor / 1000000L); 3429 LOGE_IF(res < 0, "HAL:ACCEL update delay error"); 3430 } else { 3431 // mpu accel 3432 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)", 3433 1000000000.f / accelRate, mpu.accel_rate, 3434 getTimestamp()); 3435 tempFd = open(mpu.accel_rate, O_RDWR); 3436 res = write_attribute_sensor(tempFd, 1000000000.f / accelRate); 3437 LOGE_IF(res < 0, "HAL:ACCEL update delay error"); 3438 } 3439 3440 if (!mCompassSensor->isIntegrated()) { 3441 // stand-alone compass - if applicable 3442 LOGV_IF(ENG_VERBOSE, 3443 "HAL:Ext compass delay %lld", wanted_3rd_party_sensor); 3444 LOGV_IF(ENG_VERBOSE, "HAL:Ext compass rate %.2f Hz", 3445 1000000000.f / wanted_3rd_party_sensor); 3446 if (wanted_3rd_party_sensor < 3447 mCompassSensor->getMinDelay() * 1000LL) { 3448 wanted_3rd_party_sensor = 3449 mCompassSensor->getMinDelay() * 1000LL; 3450 } 3451 LOGV_IF(ENG_VERBOSE, 3452 "HAL:Ext compass delay %lld", wanted_3rd_party_sensor); 3453 LOGV_IF(ENG_VERBOSE, "HAL:Ext compass rate %.2f Hz", 3454 1000000000.f / wanted_3rd_party_sensor); 3455 mCompassSensor->setDelay(ID_M, wanted_3rd_party_sensor); 3456 got = mCompassSensor->getDelay(ID_M); 3457 inv_set_compass_sample_rate(got / 1000); 3458 } else { 3459 // compass on secondary bus 3460 if (compassRate < mCompassSensor->getMinDelay() * 1000LL) { 3461 compassRate = mCompassSensor->getMinDelay() * 1000LL; 3462 } 3463 mCompassSensor->setDelay(ID_M, compassRate); 3464 } 3465 } else { 3466 3467 if (GY_ENABLED || RGY_ENABLED) { 3468 wanted = (mDelays[Gyro] <= mDelays[RawGyro]? 3469 (mEnabled & (1 << Gyro)? mDelays[Gyro]: mDelays[RawGyro]): 3470 (mEnabled & (1 << RawGyro)? mDelays[RawGyro]: mDelays[Gyro])); 3471 LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask); 3472 inv_set_gyro_sample_rate((int)wanted/1000LL); 3473 LOGV_IF(ENG_VERBOSE, 3474 "HAL:MPL gyro sample rate: (mpl)=%d us", int(wanted/1000LL)); 3475 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)", 3476 1000000000.f / wanted, mpu.gyro_rate, getTimestamp()); 3477 tempFd = open(mpu.gyro_rate, O_RDWR); 3478 res = write_attribute_sensor(tempFd, 1000000000.f / wanted); 3479 LOGE_IF(res < 0, "HAL:GYRO update delay error"); 3480 } 3481 3482 if (A_ENABLED) { /* there is only 1 fifo rate for MPUxxxx */ 3483 if (GY_ENABLED && mDelays[Gyro] < mDelays[Accelerometer]) { 3484 wanted = mDelays[Gyro]; 3485 } else if (RGY_ENABLED && mDelays[RawGyro] 3486 < mDelays[Accelerometer]) { 3487 wanted = mDelays[RawGyro]; 3488 } else { 3489 wanted = mDelays[Accelerometer]; 3490 } 3491 LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask); 3492 inv_set_accel_sample_rate((int)wanted/1000LL); 3493 LOGV_IF(ENG_VERBOSE, "HAL:MPL accel sample rate: (mpl)=%d us", 3494 int(wanted/1000LL)); 3495 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)", 3496 1000000000.f / wanted, mpu.accel_rate, 3497 getTimestamp()); 3498 tempFd = open(mpu.accel_rate, O_RDWR); 3499 if(USE_THIRD_PARTY_ACCEL == 1) { 3500 //BMA250 in ms 3501 res = write_attribute_sensor(tempFd, wanted / 1000000L); 3502 } 3503 else { 3504 //MPUxxxx in hz 3505 res = write_attribute_sensor(tempFd, 1000000000.f/wanted); 3506 } 3507 LOGE_IF(res < 0, "HAL:ACCEL update delay error"); 3508 } 3509 3510 /* Invensense compass calibration */ 3511 if (M_ENABLED || RM_ENABLED) { 3512 int64_t compassWanted = (mDelays[MagneticField] <= mDelays[RawMagneticField]? 3513 (mEnabled & (1 << MagneticField)? mDelays[MagneticField]: mDelays[RawMagneticField]): 3514 (mEnabled & (1 << RawMagneticField)? mDelays[RawMagneticField]: mDelays[MagneticField])); 3515 if (!mCompassSensor->isIntegrated()) { 3516 wanted = compassWanted; 3517 } else { 3518 if (GY_ENABLED 3519 && (mDelays[Gyro] < compassWanted)) { 3520 wanted = mDelays[Gyro]; 3521 } else if (RGY_ENABLED 3522 && mDelays[RawGyro] < compassWanted) { 3523 wanted = mDelays[RawGyro]; 3524 } else if (A_ENABLED && mDelays[Accelerometer] 3525 < compassWanted) { 3526 wanted = mDelays[Accelerometer]; 3527 } else { 3528 wanted = compassWanted; 3529 } 3530 LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask); 3531 } 3532 3533 mCompassSensor->setDelay(ID_M, wanted); 3534 got = mCompassSensor->getDelay(ID_M); 3535 inv_set_compass_sample_rate(got / 1000); 3536 LOGV_IF(ENG_VERBOSE, "HAL:MPL compass sample rate: (mpl)=%d us", 3537 int(got/1000LL)); 3538 } 3539#ifdef ENABLE_PRESSURE 3540 if (PS_ENABLED) { 3541 int64_t pressureRate = mDelays[Pressure]; 3542 LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask); 3543 mPressureSensor->setDelay(ID_PS, pressureRate); 3544 LOGE_IF(res < 0, "HAL:PRESSURE update delay error"); 3545 } 3546#endif 3547 } 3548 3549 } //end of non batch mode 3550 3551 unsigned long sensors = mLocalSensorMask & mMasterSensorMask; 3552 if (sensors & 3553 (INV_THREE_AXIS_GYRO 3554 | INV_THREE_AXIS_ACCEL 3555#ifdef ENABLE_PRESSURE 3556 | (INV_ONE_AXIS_PRESSURE * mPressureSensor->isIntegrated()) 3557#endif 3558 | (INV_THREE_AXIS_COMPASS * mCompassSensor->isIntegrated()))) { 3559 LOGV_IF(ENG_VERBOSE, "sensors=%lu", sensors); 3560 res = masterEnable(1); 3561 if(res < 0) 3562 return res; 3563 } else { // all sensors idle -> reduce power, unless DMP is needed 3564 LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask); 3565 if(mFeatureActiveMask & DMP_FEATURE_MASK) { 3566 res = masterEnable(1); 3567 if(res < 0) 3568 return res; 3569 } 3570 } 3571 } 3572 3573 return res; 3574} 3575 3576/** 3577 * Should be called after reading at least one of gyro 3578 * compass or accel data. (Also okay for handling all of them). 3579 * @returns 0, if successful, error number if not. 3580 */ 3581int MPLSensor::readEvents(sensors_event_t* data, int count) 3582{ 3583 VHANDLER_LOG; 3584 3585 inv_execute_on_data(); 3586 3587 int numEventReceived = 0; 3588 3589 long msg; 3590 msg = inv_get_message_level_0(1); 3591 if (msg) { 3592 if (msg & INV_MSG_MOTION_EVENT) { 3593 LOGV_IF(PROCESS_VERBOSE, "HAL:**** Motion ****\n"); 3594 } 3595 if (msg & INV_MSG_NO_MOTION_EVENT) { 3596 LOGV_IF(PROCESS_VERBOSE, "HAL:***** No Motion *****\n"); 3597 /* after the first no motion, the gyro should be 3598 calibrated well */ 3599 mGyroAccuracy = SENSOR_STATUS_ACCURACY_HIGH; 3600 /* if gyros are on and we got a no motion, set a flag 3601 indicating that the cal file can be written. */ 3602 mHaveGoodMpuCal = true; 3603 } 3604 if(msg & INV_MSG_NEW_AB_EVENT) { 3605 LOGV_IF(EXTRA_VERBOSE, "HAL:***** New Accel Bias *****\n"); 3606 getAccelBias(); 3607 mAccelAccuracy = inv_get_accel_accuracy(); 3608 } 3609 if(msg & INV_MSG_NEW_GB_EVENT) { 3610 LOGV_IF(EXTRA_VERBOSE, "HAL:***** New Gyro Bias *****\n"); 3611 getGyroBias(); 3612 setGyroBias(); 3613 } 3614 if(msg & INV_MSG_NEW_FGB_EVENT) { 3615 LOGV_IF(EXTRA_VERBOSE, "HAL:***** New Factory Gyro Bias *****\n"); 3616 getFactoryGyroBias(); 3617 } 3618 if(msg & INV_MSG_NEW_FAB_EVENT) { 3619 LOGV_IF(EXTRA_VERBOSE, "HAL:***** New Factory Accel Bias *****\n"); 3620 getFactoryAccelBias(); 3621 } 3622 if(msg & INV_MSG_NEW_CB_EVENT) { 3623 LOGV_IF(EXTRA_VERBOSE, "HAL:***** New Compass Bias *****\n"); 3624 getCompassBias(); 3625 mCompassAccuracy = inv_get_mag_accuracy(); 3626 } 3627 } 3628 3629 // handle partial packet read and end marker 3630 // skip readEvents from hal_outputs 3631 if (!mFlushSensorEnabledVector.isEmpty()) { 3632 if (!mEmptyDataMarkerDetected) { 3633 // turn off sensors in data_builder 3634 resetMplStates(); 3635 } 3636 mEmptyDataMarkerDetected = 0; 3637 mDataMarkerDetected = 0; 3638 3639 // handle flush complete event 3640 for(int k = 0; k < mFlushSensorEnabledVector.size(); k++) { 3641 int sendEvent = metaHandler(&mPendingFlushEvents[k], META_DATA_FLUSH_COMPLETE); 3642 if(sendEvent && count > 0) { 3643 *data++ = mPendingFlushEvents[k]; 3644 count--; 3645 numEventReceived++; 3646 } 3647 } 3648 return numEventReceived; 3649 } 3650 3651 if (mSkipReadEvents) { 3652 return numEventReceived; 3653 } 3654 3655 for (int i = 0; i < NumSensors; i++) { 3656 int update = 0; 3657 3658 // handle step detector when ped_q is enabled 3659 if(mPedUpdate) { 3660 if (i == StepDetector) { 3661 update = readDmpPedometerEvents(data, count, ID_P, 1); 3662 mPedUpdate = 0; 3663 if(update == 1 && count > 0) { 3664 data->timestamp = mStepSensorTimestamp; 3665 count--; 3666 numEventReceived++; 3667 continue; 3668 } 3669 } else { 3670 if (mPedUpdate == DATA_FORMAT_STEP) { 3671 continue; 3672 } 3673 } 3674 } 3675 3676 // load up virtual sensors 3677 if (mEnabled & (1 << i)) { 3678 update = CALL_MEMBER_FN(this, mHandlers[i])(mPendingEvents + i); 3679 mPendingMask |= (1 << i); 3680 3681 if (update && (count > 0)) { 3682 *data++ = mPendingEvents[i]; 3683 count--; 3684 numEventReceived++; 3685 } 3686 } 3687 } 3688 mCompassOverFlow = 0; 3689 3690 return numEventReceived; 3691} 3692 3693// collect data for MPL (but NOT sensor service currently), from driver layer 3694void MPLSensor::buildMpuEvent(void) 3695{ 3696 VHANDLER_LOG; 3697 3698 mSkipReadEvents = 0; 3699 int64_t mGyroSensorTimestamp=0, mAccelSensorTimestamp=0, latestTimestamp=0; 3700 int lp_quaternion_on = 0, sixAxis_quaternion_on = 0, 3701 ped_quaternion_on = 0, ped_standalone_on = 0; 3702 size_t nbyte; 3703 unsigned short data_format = 0; 3704 int i, nb, mask = 0, 3705 sensors = ((mLocalSensorMask & INV_THREE_AXIS_GYRO)? 1 : 0) + 3706 ((mLocalSensorMask & INV_THREE_AXIS_ACCEL)? 1 : 0) + 3707 (((mLocalSensorMask & INV_THREE_AXIS_COMPASS) 3708 && mCompassSensor->isIntegrated())? 1 : 0) + 3709 ((mLocalSensorMask & INV_ONE_AXIS_PRESSURE)? 1 : 0); 3710 3711 char *rdata = mIIOBuffer; 3712 ssize_t rsize = 0; 3713 ssize_t readCounter = 0; 3714 char *rdataP = NULL; 3715 bool doneFlag = 0; 3716 3717 lp_quaternion_on = isLowPowerQuatEnabled() && checkLPQuaternion(); 3718 sixAxis_quaternion_on = check6AxisQuatEnabled(); 3719 ped_quaternion_on = checkPedQuatEnabled(); 3720 ped_standalone_on = checkPedStandaloneEnabled(); 3721 3722 nbyte = MAX_READ_SIZE - mLeftOverBufferSize; 3723 3724 /* check previous copied buffer */ 3725 /* append with just read data */ 3726 if (mLeftOverBufferSize > 0) { 3727 LOGV_IF(0, "append old buffer size=%d", mLeftOverBufferSize); 3728 memset(rdata, 0, sizeof(rdata)); 3729 memcpy(rdata, mLeftOverBuffer, mLeftOverBufferSize); 3730 LOGV_IF(0, 3731 "HAL:input retrieve old buffer data=:%d, %d, %d, %d,%d, %d, %d, %d,%d, %d, " 3732 "%d, %d,%d, %d, %d, %d\n", 3733 rdata[0], rdata[1], rdata[2], rdata[3], 3734 rdata[4], rdata[5], rdata[6], rdata[7], 3735 rdata[8], rdata[9], rdata[10], rdata[11], 3736 rdata[12], rdata[13], rdata[14], rdata[15]); 3737 } 3738 rdataP = rdata + mLeftOverBufferSize; 3739 3740 /* read expected number of bytes */ 3741 rsize = read(iio_fd, rdataP, nbyte); 3742 if(rsize < 0) { 3743 /* IIO buffer might have old data. 3744 Need to flush it if no sensor is on, to avoid infinite 3745 read loop.*/ 3746 LOGE("HAL:input data file descriptor not available - (%s)", 3747 strerror(errno)); 3748 if (sensors == 0) { 3749 rsize = read(iio_fd, rdata, MAX_SUSPEND_BATCH_PACKET_SIZE); 3750 if(rsize > 0) { 3751 LOGV_IF(ENG_VERBOSE, "HAL:input data flush rsize=%d", (int)rsize); 3752#ifdef TESTING 3753 LOGV_IF(INPUT_DATA, 3754 "HAL:input rdata:r=%d, n=%d," 3755 "%d, %d, %d, %d, %d, %d, %d, %d", 3756 (int)rsize, nbyte, 3757 rdataP[0], rdataP[1], rdataP[2], rdataP[3], 3758 rdataP[4], rdataP[5], rdataP[6], rdataP[7]); 3759#endif 3760 mLeftOverBufferSize = 0; 3761 } 3762 } 3763 return; 3764 } 3765 3766#ifdef TESTING 3767LOGV_IF(INPUT_DATA, 3768 "HAL:input just read rdataP:r=%d, n=%d," 3769 "%d, %d, %d, %d,%d, %d, %d, %d,%d, %d, %d, %d,%d, %d, %d, %d," 3770 "%d, %d, %d, %d,%d, %d, %d, %d\n", 3771 (int)rsize, nbyte, 3772 rdataP[0], rdataP[1], rdataP[2], rdataP[3], 3773 rdataP[4], rdataP[5], rdataP[6], rdataP[7], 3774 rdataP[8], rdataP[9], rdataP[10], rdataP[11], 3775 rdataP[12], rdataP[13], rdataP[14], rdataP[15], 3776 rdataP[16], rdataP[17], rdataP[18], rdataP[19], 3777 rdataP[20], rdataP[21], rdataP[22], rdataP[23]); 3778 3779 LOGV_IF(INPUT_DATA, 3780 "HAL:input rdata:r=%d, n=%d," 3781 "%d, %d, %d, %d,%d, %d, %d, %d,%d, %d, %d, %d,%d, %d, %d, %d," 3782 "%d, %d, %d, %d,%d, %d, %d, %d\n", 3783 (int)rsize, nbyte, 3784 rdata[0], rdata[1], rdata[2], rdata[3], 3785 rdata[4], rdata[5], rdata[6], rdata[7], 3786 rdata[8], rdata[9], rdata[10], rdata[11], 3787 rdata[12], rdata[13], rdata[14], rdata[15], 3788 rdata[16], rdata[17], rdata[18], rdata[19], 3789 rdata[20], rdata[21], rdata[22], rdata[23]); 3790#endif 3791 /* reset data and count pointer */ 3792 rdataP = rdata; 3793 readCounter = rsize + mLeftOverBufferSize; 3794 LOGV_IF(0, "HAL:input readCounter set=%d", (int)readCounter); 3795 3796 if(readCounter < MAX_READ_SIZE) { 3797 // Handle standalone MARKER packet 3798 if (readCounter >= BYTES_PER_SENSOR) { 3799 data_format = *((short *)(rdata)); 3800 if (data_format == DATA_FORMAT_MARKER) { 3801 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "MARKER DETECTED:0x%x", data_format); 3802 readCounter -= BYTES_PER_SENSOR; 3803 rdata += BYTES_PER_SENSOR; 3804 if (!mFlushSensorEnabledVector.isEmpty()) { 3805 mFlushBatchSet = 1; 3806 } 3807 mDataMarkerDetected = 1; 3808 } 3809 else if (data_format == DATA_FORMAT_EMPTY_MARKER) { 3810 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "EMPTY MARKER DETECTED:0x%x", data_format); 3811 readCounter -= BYTES_PER_SENSOR; 3812 rdata += BYTES_PER_SENSOR; 3813 if (!mFlushSensorEnabledVector.isEmpty()) { 3814 mFlushBatchSet = 1; 3815 } 3816 mEmptyDataMarkerDetected = 1; 3817 } 3818 } 3819 3820 /* store packet then return */ 3821 mLeftOverBufferSize = readCounter; 3822 memcpy(mLeftOverBuffer, rdata, mLeftOverBufferSize); 3823 3824#ifdef TESTING 3825 LOGV_IF(1, "HAL:input data has batched partial packet"); 3826 LOGV_IF(1, "HAL:input data batched mLeftOverBufferSize=%d", mLeftOverBufferSize); 3827 LOGV_IF(1, 3828 "HAL:input catch up batched retrieve buffer=:%d, %d, %d, %d, %d, %d, %d, %d," 3829 "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", 3830 mLeftOverBuffer[0], mLeftOverBuffer[1], mLeftOverBuffer[2], mLeftOverBuffer[3], 3831 mLeftOverBuffer[4], mLeftOverBuffer[5], mLeftOverBuffer[6], mLeftOverBuffer[7], 3832 mLeftOverBuffer[8], mLeftOverBuffer[9], mLeftOverBuffer[10], mLeftOverBuffer[11], 3833 mLeftOverBuffer[12], mLeftOverBuffer[13], mLeftOverBuffer[14], mLeftOverBuffer[15]); 3834#endif 3835 mSkipReadEvents = 1; 3836 return; 3837 } 3838 3839 LOGV_IF(INPUT_DATA && ENG_VERBOSE, 3840 "HAL:input b=%d rdata= %d nbyte= %d rsize= %d readCounter= %d", 3841 checkBatchEnabled(), *((short *) rdata), nbyte, (int)rsize, (int)readCounter); 3842 LOGV_IF(INPUT_DATA && ENG_VERBOSE, 3843 "HAL:input sensors= %d, lp_q_on= %d, 6axis_q_on= %d, " 3844 "ped_q_on= %d, ped_standalone_on= %d", 3845 sensors, lp_quaternion_on, sixAxis_quaternion_on, ped_quaternion_on, 3846 ped_standalone_on); 3847 3848 while (readCounter > 0) { 3849 // since copied buffer is already accounted for, reset left over size 3850 mLeftOverBufferSize = 0; 3851 // clear data format mask for parsing the next set of data 3852 mask = 0; 3853 data_format = *((short *)(rdata)); 3854 LOGV_IF(INPUT_DATA && ENG_VERBOSE, 3855 "HAL:input data_format=%x", data_format); 3856 3857 if(checkValidHeader(data_format) == 0) { 3858 LOGE("HAL:input invalid data_format 0x%02X", data_format); 3859 return; 3860 } 3861 3862 if (data_format & DATA_FORMAT_STEP) { 3863 if (data_format == DATA_FORMAT_STEP) { 3864 rdata += BYTES_PER_SENSOR; 3865 latestTimestamp = *((long long*) (rdata)); 3866 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "STEP DETECTED:0x%x - ts: %lld", data_format, latestTimestamp); 3867 // readCounter is decrement by 24 because DATA_FORMAT_STEP only applies in batch mode 3868 readCounter -= BYTES_PER_SENSOR_PACKET; 3869 } else { 3870 LOGV_IF(0, "STEP DETECTED:0x%x", data_format); 3871 } 3872 mPedUpdate |= data_format; 3873 mask |= DATA_FORMAT_STEP; 3874 // cancels step bit 3875 data_format &= (~DATA_FORMAT_STEP); 3876 } 3877 3878 if (data_format == DATA_FORMAT_MARKER) { 3879 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "MARKER DETECTED:0x%x", data_format); 3880 readCounter -= BYTES_PER_SENSOR; 3881 if (!mFlushSensorEnabledVector.isEmpty()) { 3882 mFlushBatchSet = 1; 3883 } 3884 mDataMarkerDetected = 1; 3885 mSkipReadEvents = 1; 3886 } 3887 else if (data_format == DATA_FORMAT_EMPTY_MARKER) { 3888 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "EMPTY MARKER DETECTED:0x%x", data_format); 3889 readCounter -= BYTES_PER_SENSOR; 3890 if (!mFlushSensorEnabledVector.isEmpty()) { 3891 mFlushBatchSet = 1; 3892 } 3893 mEmptyDataMarkerDetected = 1; 3894 mSkipReadEvents = 1; 3895 } 3896 else if (data_format == DATA_FORMAT_QUAT) { 3897 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "QUAT DETECTED:0x%x", data_format); 3898 if (readCounter >= BYTES_QUAT_DATA) { 3899 mCachedQuaternionData[0] = *((int *) (rdata + 4)); 3900 mCachedQuaternionData[1] = *((int *) (rdata + 8)); 3901 mCachedQuaternionData[2] = *((int *) (rdata + 12)); 3902 rdata += QUAT_ONLY_LAST_PACKET_OFFSET; 3903 mQuatSensorTimestamp = *((long long*) (rdata)); 3904 mask |= DATA_FORMAT_QUAT; 3905 readCounter -= BYTES_QUAT_DATA; 3906 } 3907 else { 3908 doneFlag = 1; 3909 } 3910 } 3911 else if (data_format == DATA_FORMAT_6_AXIS) { 3912 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "6AXIS DETECTED:0x%x", data_format); 3913 if (readCounter >= BYTES_QUAT_DATA) { 3914 mCached6AxisQuaternionData[0] = *((int *) (rdata + 4)); 3915 mCached6AxisQuaternionData[1] = *((int *) (rdata + 8)); 3916 mCached6AxisQuaternionData[2] = *((int *) (rdata + 12)); 3917 rdata += QUAT_ONLY_LAST_PACKET_OFFSET; 3918 mQuatSensorTimestamp = *((long long*) (rdata)); 3919 mask |= DATA_FORMAT_6_AXIS; 3920 readCounter -= BYTES_QUAT_DATA; 3921 } 3922 else { 3923 doneFlag = 1; 3924 } 3925 } 3926 else if (data_format == DATA_FORMAT_PED_QUAT) { 3927 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "PED QUAT DETECTED:0x%x", data_format); 3928 if (readCounter >= BYTES_PER_SENSOR_PACKET) { 3929 mCachedPedQuaternionData[0] = *((short *) (rdata + 2)); 3930 mCachedPedQuaternionData[1] = *((short *) (rdata + 4)); 3931 mCachedPedQuaternionData[2] = *((short *) (rdata + 6)); 3932 rdata += BYTES_PER_SENSOR; 3933 mQuatSensorTimestamp = *((long long*) (rdata)); 3934 mask |= DATA_FORMAT_PED_QUAT; 3935 readCounter -= BYTES_PER_SENSOR_PACKET; 3936 } 3937 else { 3938 doneFlag = 1; 3939 } 3940 } 3941 else if (data_format == DATA_FORMAT_PED_STANDALONE) { 3942 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "STANDALONE STEP DETECTED:0x%x", data_format); 3943 if (readCounter >= BYTES_PER_SENSOR_PACKET) { 3944 rdata += BYTES_PER_SENSOR; 3945 mStepSensorTimestamp = *((long long*) (rdata)); 3946 mask |= DATA_FORMAT_PED_STANDALONE; 3947 readCounter -= BYTES_PER_SENSOR_PACKET; 3948 mPedUpdate |= data_format; 3949 } 3950 else { 3951 doneFlag = 1; 3952 } 3953 } 3954 else if (data_format == DATA_FORMAT_GYRO) { 3955 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "GYRO DETECTED:0x%x", data_format); 3956 if (readCounter >= BYTES_PER_SENSOR_PACKET) { 3957 mCachedGyroData[0] = *((short *) (rdata + 2)); 3958 mCachedGyroData[1] = *((short *) (rdata + 4)); 3959 mCachedGyroData[2] = *((short *) (rdata + 6)); 3960 rdata += BYTES_PER_SENSOR; 3961 mGyroSensorTimestamp = *((long long*) (rdata)); 3962 mask |= DATA_FORMAT_GYRO; 3963 readCounter -= BYTES_PER_SENSOR_PACKET; 3964 } else { 3965 doneFlag = 1; 3966 } 3967 } 3968 else if (data_format == DATA_FORMAT_ACCEL) { 3969 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "ACCEL DETECTED:0x%x", data_format); 3970 if (readCounter >= BYTES_PER_SENSOR_PACKET) { 3971 mCachedAccelData[0] = *((short *) (rdata + 2)); 3972 mCachedAccelData[1] = *((short *) (rdata + 4)); 3973 mCachedAccelData[2] = *((short *) (rdata + 6)); 3974 rdata += BYTES_PER_SENSOR; 3975 mAccelSensorTimestamp = *((long long*) (rdata)); 3976 mask |= DATA_FORMAT_ACCEL; 3977 readCounter -= BYTES_PER_SENSOR_PACKET; 3978 } 3979 else { 3980 doneFlag = 1; 3981 } 3982 } 3983 else if (data_format == DATA_FORMAT_COMPASS) { 3984 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "COMPASS DETECTED:0x%x", data_format); 3985 if (readCounter >= BYTES_PER_SENSOR_PACKET) { 3986 if (mCompassSensor->isIntegrated()) { 3987 mCachedCompassData[0] = *((short *) (rdata + 2)); 3988 mCachedCompassData[1] = *((short *) (rdata + 4)); 3989 mCachedCompassData[2] = *((short *) (rdata + 6)); 3990 rdata += BYTES_PER_SENSOR; 3991 mCompassTimestamp = *((long long*) (rdata)); 3992 mask |= DATA_FORMAT_COMPASS; 3993 readCounter -= BYTES_PER_SENSOR_PACKET; 3994 } 3995 } 3996 else { 3997 doneFlag = 1; 3998 } 3999 } 4000 else if (data_format == DATA_FORMAT_COMPASS_OF) { 4001 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "COMPASS OF DETECTED:0x%x", data_format); 4002 mask |= DATA_FORMAT_COMPASS_OF; 4003 mCompassOverFlow = 1; 4004#ifdef INV_PLAYBACK_DBG 4005 if (readCounter >= BYTES_PER_SENSOR_PACKET) { 4006 if (mCompassSensor->isIntegrated()) { 4007 mCachedCompassData[0] = *((short *) (rdata + 2)); 4008 mCachedCompassData[1] = *((short *) (rdata + 4)); 4009 mCachedCompassData[2] = *((short *) (rdata + 6)); 4010 rdata += BYTES_PER_SENSOR; 4011 mCompassTimestamp = *((long long*) (rdata)); 4012 readCounter -= BYTES_PER_SENSOR_PACKET; 4013 } 4014 } 4015#else 4016 readCounter -= BYTES_PER_SENSOR; 4017#endif 4018 } 4019#ifdef ENABLE_PRESSURE 4020 else if (data_format == DATA_FORMAT_PRESSURE) { 4021 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "PRESSURE DETECTED:0x%x", data_format); 4022 if (readCounter >= BYTES_QUAT_DATA) { 4023 if (mPressureSensor->isIntegrated()) { 4024 mCachedPressureData = 4025 ((*((short *)(rdata + 4))) << 16) + 4026 (*((unsigned short *) (rdata + 6))); 4027 rdata += BYTES_PER_SENSOR; 4028 mPressureTimestamp = *((long long*) (rdata)); 4029 if (mCachedPressureData != 0) { 4030 mask |= DATA_FORMAT_PRESSURE; 4031 } 4032 readCounter -= BYTES_PER_SENSOR_PACKET; 4033 } 4034 } else{ 4035 doneFlag = 1; 4036 } 4037 } 4038#endif 4039 4040 if(doneFlag == 0) { 4041 rdata += BYTES_PER_SENSOR; 4042 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "HAL: input data doneFlag is zero, readCounter=%d", (int)readCounter); 4043 } 4044 else { 4045 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "HAL: input data doneFlag is set, readCounter=%d", (int)readCounter); 4046 } 4047 4048 /* read ahead and store left over data if any */ 4049 if (readCounter != 0) { 4050 int currentBufferCounter = 0; 4051 LOGV_IF(0, "Not enough data readCounter=%d, expected nbyte=%d, rsize=%d", (int)readCounter, nbyte, (int)rsize); 4052 memset(mLeftOverBuffer, 0, sizeof(mLeftOverBuffer)); 4053 /* check for end markers, don't save */ 4054 data_format = *((short *) (rdata)); 4055 if ((data_format == DATA_FORMAT_MARKER) || (data_format == DATA_FORMAT_EMPTY_MARKER)) { 4056 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "s MARKER DETECTED:0x%x", data_format); 4057 rdata += BYTES_PER_SENSOR; 4058 readCounter -= BYTES_PER_SENSOR; 4059 if (!mFlushSensorEnabledVector.isEmpty()) { 4060 mFlushBatchSet = 1; 4061 } 4062 mDataMarkerDetected = 1; 4063 mSkipReadEvents = 1; 4064 if (readCounter == 0) { 4065 mLeftOverBufferSize = 0; 4066 if(doneFlag != 0) { 4067 return; 4068 } 4069 } 4070 } 4071 memcpy(mLeftOverBuffer, rdata, readCounter); 4072 LOGV_IF(0, 4073 "HAL:input store rdata=:%d, %d, %d, %d,%d, %d, %d, %d,%d, " 4074 "%d, %d, %d,%d, %d, %d, %d\n", 4075 mLeftOverBuffer[0], mLeftOverBuffer[1], mLeftOverBuffer[2], mLeftOverBuffer[3], 4076 mLeftOverBuffer[4], mLeftOverBuffer[5], mLeftOverBuffer[6], mLeftOverBuffer[7], 4077 mLeftOverBuffer[8], mLeftOverBuffer[9], mLeftOverBuffer[10], mLeftOverBuffer[11], 4078 mLeftOverBuffer[12],mLeftOverBuffer[13],mLeftOverBuffer[14], mLeftOverBuffer[15]); 4079 4080 mLeftOverBufferSize = readCounter; 4081 readCounter = 0; 4082 LOGV_IF(0, "Stored number of bytes:%d", mLeftOverBufferSize); 4083 } else { 4084 /* reset count since this is the last packet for the data set */ 4085 readCounter = 0; 4086 mLeftOverBufferSize = 0; 4087 } 4088 4089 /* take the latest timestamp */ 4090 if (mask & DATA_FORMAT_STEP) { 4091 /* work around driver output duplicate step detector bit */ 4092 if (latestTimestamp > mStepSensorTimestamp) { 4093 mStepSensorTimestamp = latestTimestamp; 4094 LOGV_IF(INPUT_DATA, 4095 "HAL:input build step: 1 - %lld", mStepSensorTimestamp); 4096 } else { 4097 mPedUpdate = 0; 4098 } 4099 // cancels step bit 4100 mask &= (~DATA_FORMAT_STEP); 4101 } 4102 4103 /* handle data read */ 4104 if (mask == DATA_FORMAT_GYRO) { 4105 /* batch mode does not batch temperature */ 4106 /* disable temperature read */ 4107 if (!(mFeatureActiveMask & INV_DMP_BATCH_MODE)) { 4108 // send down temperature every 0.5 seconds 4109 // with timestamp measured in "driver" layer 4110 if(mGyroSensorTimestamp - mTempCurrentTime >= 500000000LL) { 4111 mTempCurrentTime = mGyroSensorTimestamp; 4112 long long temperature[2]; 4113 if(inv_read_temperature(temperature) == 0) { 4114 LOGV_IF(INPUT_DATA, 4115 "HAL:input inv_read_temperature = %lld, timestamp= %lld", 4116 temperature[0], temperature[1]); 4117 inv_build_temp(temperature[0], temperature[1]); 4118 } 4119#ifdef TESTING 4120 long bias[3], temp, temp_slope[3]; 4121 inv_get_mpl_gyro_bias(bias, &temp); 4122 inv_get_gyro_ts(temp_slope); 4123 LOGI("T: %.3f " 4124 "GB: %+13f %+13f %+13f " 4125 "TS: %+13f %+13f %+13f " 4126 "\n", 4127 (float)temperature[0] / 65536.f, 4128 (float)bias[0] / 65536.f / 16.384f, 4129 (float)bias[1] / 65536.f / 16.384f, 4130 (float)bias[2] / 65536.f / 16.384f, 4131 temp_slope[0] / 65536.f, 4132 temp_slope[1] / 65536.f, 4133 temp_slope[2] / 65536.f); 4134#endif 4135 } 4136 } 4137 mPendingMask |= 1 << Gyro; 4138 mPendingMask |= 1 << RawGyro; 4139 4140 inv_build_gyro(mCachedGyroData, mGyroSensorTimestamp); 4141 LOGV_IF(INPUT_DATA, 4142 "HAL:input inv_build_gyro: %+8d %+8d %+8d - %lld", 4143 mCachedGyroData[0], mCachedGyroData[1], 4144 mCachedGyroData[2], mGyroSensorTimestamp); 4145 latestTimestamp = mGyroSensorTimestamp; 4146 } 4147 4148 if (mask == DATA_FORMAT_ACCEL) { 4149 mPendingMask |= 1 << Accelerometer; 4150 inv_build_accel(mCachedAccelData, 0, mAccelSensorTimestamp); 4151 LOGV_IF(INPUT_DATA, 4152 "HAL:input inv_build_accel: %+8ld %+8ld %+8ld - %lld", 4153 mCachedAccelData[0], mCachedAccelData[1], 4154 mCachedAccelData[2], mAccelSensorTimestamp); 4155 /* remember inital 6 axis quaternion */ 4156 inv_time_t tempTimestamp; 4157 inv_get_6axis_quaternion(mInitial6QuatValue, &tempTimestamp); 4158 if (mInitial6QuatValue[0] != 0 && mInitial6QuatValue[1] != 0 && 4159 mInitial6QuatValue[2] != 0 && mInitial6QuatValue[3] != 0) { 4160 mInitial6QuatValueAvailable = 1; 4161 LOGV_IF(INPUT_DATA && ENG_VERBOSE, 4162 "HAL:input build 6q init: %+8ld %+8ld %+8ld %+8ld", 4163 mInitial6QuatValue[0], mInitial6QuatValue[1], 4164 mInitial6QuatValue[2], mInitial6QuatValue[3]); 4165 } 4166 latestTimestamp = mAccelSensorTimestamp; 4167 } 4168 4169 if (mask == DATA_FORMAT_COMPASS_OF) { 4170 /* compass overflow detected */ 4171 /* reset compass algorithm */ 4172 int status = 0; 4173 inv_build_compass(mCachedCompassData, status, 4174 mCompassTimestamp); 4175 LOGV_IF(INPUT_DATA, 4176 "HAL:input inv_build_compass_of: %+8ld %+8ld %+8ld - %lld", 4177 mCachedCompassData[0], mCachedCompassData[1], 4178 mCachedCompassData[2], mCompassTimestamp); 4179 resetCompass(); 4180 } 4181 4182 if ((mask == DATA_FORMAT_COMPASS) && mCompassSensor->isIntegrated()) { 4183 int status = 0; 4184 if (mCompassSensor->providesCalibration()) { 4185 status = mCompassSensor->getAccuracy(); 4186 status |= INV_CALIBRATED; 4187 } 4188 inv_build_compass(mCachedCompassData, status, 4189 mCompassTimestamp); 4190 LOGV_IF(INPUT_DATA, 4191 "HAL:input inv_build_compass: %+8ld %+8ld %+8ld - %lld", 4192 mCachedCompassData[0], mCachedCompassData[1], 4193 mCachedCompassData[2], mCompassTimestamp); 4194 latestTimestamp = mCompassTimestamp; 4195 } 4196 4197 if (mask == DATA_FORMAT_QUAT) { 4198 /* if bias was applied to DMP bias, 4199 set status bits to disable gyro bias cal */ 4200 int status = 0; 4201 if (mGyroBiasApplied == true) { 4202 LOGV_IF(INPUT_DATA && ENG_VERBOSE, "HAL:input dmp bias is used"); 4203 status |= INV_BIAS_APPLIED; 4204 } 4205 status |= INV_CALIBRATED | INV_QUAT_3AXIS | INV_QUAT_3ELEMENT; /* default 32 (16/32bits) */ 4206 inv_build_quat(mCachedQuaternionData, 4207 status, 4208 mQuatSensorTimestamp); 4209 LOGV_IF(INPUT_DATA, 4210 "HAL:input inv_build_quat-3x: %+8ld %+8ld %+8ld - %lld", 4211 mCachedQuaternionData[0], mCachedQuaternionData[1], 4212 mCachedQuaternionData[2], 4213 mQuatSensorTimestamp); 4214 latestTimestamp = mQuatSensorTimestamp; 4215 } 4216 4217 if (mask == DATA_FORMAT_6_AXIS) { 4218 /* if bias was applied to DMP bias, 4219 set status bits to disable gyro bias cal */ 4220 int status = 0; 4221 if (mGyroBiasApplied == true) { 4222 LOGV_IF(INPUT_DATA && ENG_VERBOSE, "HAL:input dmp bias is used"); 4223 status |= INV_QUAT_6AXIS; 4224 } 4225 status |= INV_CALIBRATED | INV_QUAT_6AXIS | INV_QUAT_3ELEMENT; /* default 32 (16/32bits) */ 4226 inv_build_quat(mCached6AxisQuaternionData, 4227 status, 4228 mQuatSensorTimestamp); 4229 LOGV_IF(INPUT_DATA, 4230 "HAL:input inv_build_quat-6x: %+8ld %+8ld %+8ld - %lld", 4231 mCached6AxisQuaternionData[0], mCached6AxisQuaternionData[1], 4232 mCached6AxisQuaternionData[2], mQuatSensorTimestamp); 4233 latestTimestamp = mQuatSensorTimestamp; 4234 } 4235 4236 if (mask == DATA_FORMAT_PED_QUAT) { 4237 /* if bias was applied to DMP bias, 4238 set status bits to disable gyro bias cal */ 4239 int status = 0; 4240 if (mGyroBiasApplied == true) { 4241 LOGV_IF(INPUT_DATA && ENG_VERBOSE, 4242 "HAL:input dmp bias is used"); 4243 status |= INV_QUAT_6AXIS; 4244 } 4245 status |= INV_CALIBRATED | INV_QUAT_6AXIS | INV_QUAT_3ELEMENT; /* default 32 (16/32bits) */ 4246 mCachedPedQuaternionData[0] = mCachedPedQuaternionData[0] << 16; 4247 mCachedPedQuaternionData[1] = mCachedPedQuaternionData[1] << 16; 4248 mCachedPedQuaternionData[2] = mCachedPedQuaternionData[2] << 16; 4249 inv_build_quat(mCachedPedQuaternionData, 4250 status, 4251 mQuatSensorTimestamp); 4252 4253 LOGV_IF(INPUT_DATA, 4254 "HAL:HAL:input inv_build_quat-ped_6x: %+8ld %+8ld %+8ld - %lld", 4255 mCachedPedQuaternionData[0], mCachedPedQuaternionData[1], 4256 mCachedPedQuaternionData[2], mQuatSensorTimestamp); 4257 latestTimestamp = mQuatSensorTimestamp; 4258 } 4259 4260#ifdef ENABLE_PRESSURE 4261 if ((mask ==DATA_FORMAT_PRESSURE) && mPressureSensor->isIntegrated()) { 4262 int status = 0; 4263 if (mLocalSensorMask & INV_ONE_AXIS_PRESSURE) { 4264 latestTimestamp = mPressureTimestamp; 4265 mPressureUpdate = 1; 4266 inv_build_pressure(mCachedPressureData, 4267 status, 4268 mPressureTimestamp); 4269 LOGV_IF(INPUT_DATA, 4270 "HAL:input inv_build_pressure: %+8ld - %lld", 4271 mCachedPressureData, mPressureTimestamp); 4272 } 4273 } 4274#endif 4275 } //while end 4276} 4277 4278int MPLSensor::checkValidHeader(unsigned short data_format) 4279{ 4280 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "check data_format=%x", data_format); 4281 4282 if(data_format == DATA_FORMAT_STEP) 4283 return 1; 4284 4285 if(data_format & DATA_FORMAT_STEP) { 4286 data_format &= (~DATA_FORMAT_STEP); 4287 } 4288 4289 if ((data_format == DATA_FORMAT_PED_STANDALONE) || 4290 (data_format == DATA_FORMAT_PED_QUAT) || 4291 (data_format == DATA_FORMAT_6_AXIS) || 4292 (data_format == DATA_FORMAT_QUAT) || 4293 (data_format == DATA_FORMAT_COMPASS) || 4294 (data_format == DATA_FORMAT_GYRO) || 4295 (data_format == DATA_FORMAT_ACCEL) || 4296 (data_format == DATA_FORMAT_PRESSURE) || 4297 (data_format == DATA_FORMAT_EMPTY_MARKER) || 4298 (data_format == DATA_FORMAT_MARKER) || 4299 (data_format == DATA_FORMAT_COMPASS_OF)) 4300 return 1; 4301 else { 4302 LOGV_IF(ENG_VERBOSE, "bad data_format = %x", data_format); 4303 return 0; 4304 } 4305} 4306 4307/* use for both MPUxxxx and third party compass */ 4308void MPLSensor::buildCompassEvent(void) 4309{ 4310 VHANDLER_LOG; 4311 4312 int done = 0; 4313 4314 // pthread_mutex_lock(&mMplMutex); 4315 // pthread_mutex_lock(&mHALMutex); 4316 4317 done = mCompassSensor->readSample(mCachedCompassData, &mCompassTimestamp); 4318 if(mCompassSensor->isYasCompass()) { 4319 if (mCompassSensor->checkCoilsReset() == 1) { 4320 //Reset relevant compass settings 4321 resetCompass(); 4322 } 4323 } 4324 if (done > 0) { 4325 int status = 0; 4326 if (mCompassSensor->providesCalibration()) { 4327 status = mCompassSensor->getAccuracy(); 4328 status |= INV_CALIBRATED; 4329 } 4330 if (mLocalSensorMask & INV_THREE_AXIS_COMPASS) { 4331 inv_build_compass(mCachedCompassData, status, 4332 mCompassTimestamp); 4333 LOGV_IF(INPUT_DATA, 4334 "HAL:input inv_build_compass: %+8ld %+8ld %+8ld - %lld", 4335 mCachedCompassData[0], mCachedCompassData[1], 4336 mCachedCompassData[2], mCompassTimestamp); 4337 mSkipReadEvents = 0; 4338 } 4339 } 4340 4341 // pthread_mutex_unlock(&mMplMutex); 4342 // pthread_mutex_unlock(&mHALMutex); 4343} 4344 4345int MPLSensor::resetCompass(void) 4346{ 4347 VFUNC_LOG; 4348 4349 //Reset compass cal if enabled 4350 if (mMplFeatureActiveMask & INV_COMPASS_CAL) { 4351 LOGV_IF(EXTRA_VERBOSE, "HAL:Reset compass cal"); 4352 inv_init_vector_compass_cal(); 4353 inv_init_magnetic_disturbance(); 4354 inv_vector_compass_cal_sensitivity(3); 4355 } 4356 4357 //Reset compass fit if enabled 4358 if (mMplFeatureActiveMask & INV_COMPASS_FIT) { 4359 LOGV_IF(EXTRA_VERBOSE, "HAL:Reset compass fit"); 4360 inv_init_compass_fit(); 4361 } 4362 4363 return 0; 4364} 4365 4366int MPLSensor::getFd(void) const 4367{ 4368 VFUNC_LOG; 4369 LOGV_IF(EXTRA_VERBOSE, "getFd returning %d", iio_fd); 4370 return iio_fd; 4371} 4372 4373int MPLSensor::getAccelFd(void) const 4374{ 4375 VFUNC_LOG; 4376 LOGV_IF(EXTRA_VERBOSE, "getAccelFd returning %d", accel_fd); 4377 return accel_fd; 4378} 4379 4380int MPLSensor::getCompassFd(void) const 4381{ 4382 VFUNC_LOG; 4383 int fd = mCompassSensor->getFd(); 4384 LOGV_IF(EXTRA_VERBOSE, "getCompassFd returning %d", fd); 4385 return fd; 4386} 4387 4388int MPLSensor::turnOffAccelFifo(void) 4389{ 4390 VFUNC_LOG; 4391 int i, res = 0, tempFd; 4392 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 4393 0, mpu.accel_fifo_enable, getTimestamp()); 4394 res += write_sysfs_int(mpu.accel_fifo_enable, 0); 4395 return res; 4396} 4397 4398int MPLSensor::turnOffGyroFifo(void) 4399{ 4400 VFUNC_LOG; 4401 int i, res = 0, tempFd; 4402 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 4403 0, mpu.gyro_fifo_enable, getTimestamp()); 4404 res += write_sysfs_int(mpu.gyro_fifo_enable, 0); 4405 return res; 4406} 4407 4408int MPLSensor::enableDmpOrientation(int en) 4409{ 4410 VFUNC_LOG; 4411 int res = 0; 4412 int enabled_sensors = mEnabled; 4413 4414 if (isMpuNonDmp()) 4415 return res; 4416 4417 // reset master enable 4418 res = masterEnable(0); 4419 if (res < 0) 4420 return res; 4421 4422 if (en == 1) { 4423 // Enable DMP orientation 4424 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 4425 en, mpu.display_orientation_on, getTimestamp()); 4426 if (write_sysfs_int(mpu.display_orientation_on, en) < 0) { 4427 LOGE("HAL:ERR can't enable Android orientation"); 4428 res = -1; // indicate an err 4429 return res; 4430 } 4431 4432 // enable accel engine 4433 res = enableAccel(1); 4434 if (res < 0) 4435 return res; 4436 4437 // disable accel FIFO 4438 if (!(mLocalSensorMask & mMasterSensorMask & INV_THREE_AXIS_ACCEL)) { 4439 res = turnOffAccelFifo(); 4440 if (res < 0) 4441 return res; 4442 } 4443 4444 if (!mEnabled){ 4445 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 4446 1, mpu.dmp_event_int_on, getTimestamp()); 4447 if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) { 4448 res = -1; 4449 LOGE("HAL:ERR can't enable DMP event interrupt"); 4450 } 4451 } 4452 4453 mFeatureActiveMask |= INV_DMP_DISPL_ORIENTATION; 4454 LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask); 4455 } else { 4456 mFeatureActiveMask &= ~INV_DMP_DISPL_ORIENTATION; 4457 4458 if (mFeatureActiveMask == 0) { 4459 // disable accel engine 4460 if (!(mLocalSensorMask & mMasterSensorMask 4461 & INV_THREE_AXIS_ACCEL)) { 4462 res = enableAccel(0); 4463 if (res < 0) 4464 return res; 4465 } 4466 } 4467 4468 if (mEnabled){ 4469 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 4470 en, mpu.dmp_event_int_on, getTimestamp()); 4471 if (write_sysfs_int(mpu.dmp_event_int_on, en) < 0) { 4472 res = -1; 4473 LOGE("HAL:ERR can't enable DMP event interrupt"); 4474 } 4475 } 4476 LOGV_IF(ENG_VERBOSE, "mFeatureActiveMask=%016llx", mFeatureActiveMask); 4477 } 4478 4479 if ((res = computeAndSetDmpState()) < 0) 4480 return res; 4481 4482 if (en || mEnabled || mFeatureActiveMask) { 4483 res = masterEnable(1); 4484 } 4485 return res; 4486} 4487 4488int MPLSensor::openDmpOrientFd(void) 4489{ 4490 VFUNC_LOG; 4491 4492 if (!isDmpDisplayOrientationOn() || dmp_orient_fd >= 0) { 4493 LOGV_IF(PROCESS_VERBOSE, 4494 "HAL:DMP display orientation disabled or file desc opened"); 4495 return 0; 4496 } 4497 4498 dmp_orient_fd = open(mpu.event_display_orientation, O_RDONLY| O_NONBLOCK); 4499 if (dmp_orient_fd < 0) { 4500 LOGE("HAL:ERR couldn't open dmpOrient node"); 4501 return -1; 4502 } else { 4503 LOGV_IF(PROCESS_VERBOSE, 4504 "HAL:dmp_orient_fd opened : %d", dmp_orient_fd); 4505 return 0; 4506 } 4507} 4508 4509int MPLSensor::closeDmpOrientFd(void) 4510{ 4511 VFUNC_LOG; 4512 if (dmp_orient_fd >= 0) 4513 close(dmp_orient_fd); 4514 return 0; 4515} 4516 4517int MPLSensor::dmpOrientHandler(int orient) 4518{ 4519 VFUNC_LOG; 4520 LOGV_IF(PROCESS_VERBOSE, "HAL:orient %x", orient); 4521 return 0; 4522} 4523 4524int MPLSensor::readDmpOrientEvents(sensors_event_t* data, int count) 4525{ 4526 VFUNC_LOG; 4527 4528 char dummy[4]; 4529 int screen_orientation = 0; 4530 FILE *fp; 4531 4532 fp = fopen(mpu.event_display_orientation, "r"); 4533 if (fp == NULL) { 4534 LOGE("HAL:cannot open event_display_orientation"); 4535 return 0; 4536 } else { 4537 if (fscanf(fp, "%d\n", &screen_orientation) < 0 || fclose(fp) < 0) 4538 { 4539 LOGE("HAL:cannot write event_display_orientation"); 4540 } 4541 } 4542 4543 int numEventReceived = 0; 4544 4545 if (mDmpOrientationEnabled && count > 0) { 4546 sensors_event_t temp; 4547 4548 temp.acceleration.x = 0; 4549 temp.acceleration.y = 0; 4550 temp.acceleration.z = 0; 4551 temp.version = sizeof(sensors_event_t); 4552 temp.sensor = ID_SO; 4553 temp.acceleration.status 4554 = SENSOR_STATUS_UNRELIABLE; 4555#ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION 4556 temp.type = SENSOR_TYPE_SCREEN_ORIENTATION; 4557 temp.screen_orientation = screen_orientation; 4558#endif 4559 struct timespec ts; 4560 clock_gettime(CLOCK_MONOTONIC, &ts); 4561 temp.timestamp = (int64_t) ts.tv_sec * 1000000000 + ts.tv_nsec; 4562 4563 *data++ = temp; 4564 count--; 4565 numEventReceived++; 4566 } 4567 4568 // read dummy data per driver's request 4569 dmpOrientHandler(screen_orientation); 4570 read(dmp_orient_fd, dummy, 4); 4571 4572 return numEventReceived; 4573} 4574 4575int MPLSensor::getDmpOrientFd(void) 4576{ 4577 VFUNC_LOG; 4578 4579 LOGV_IF(EXTRA_VERBOSE, "getDmpOrientFd returning %d", dmp_orient_fd); 4580 return dmp_orient_fd; 4581 4582} 4583 4584int MPLSensor::checkDMPOrientation(void) 4585{ 4586 VFUNC_LOG; 4587 return ((mFeatureActiveMask & INV_DMP_DISPL_ORIENTATION) ? 1 : 0); 4588} 4589 4590int MPLSensor::getDmpRate(int64_t *wanted) 4591{ 4592 VFUNC_LOG; 4593 4594 // set DMP output rate to FIFO 4595 if(mDmpOn == 1) { 4596 setQuaternionRate(*wanted); 4597 if (mFeatureActiveMask & INV_DMP_BATCH_MODE) { 4598 set6AxisQuaternionRate(*wanted); 4599 setPedQuaternionRate(*wanted); 4600 } 4601 // DMP running rate must be @ 200Hz 4602 *wanted= RATE_200HZ; 4603 LOGV_IF(PROCESS_VERBOSE, 4604 "HAL:DMP rate= %.2f Hz", 1000000000.f / *wanted); 4605 } 4606 return 0; 4607} 4608 4609int MPLSensor::getPollTime(void) 4610{ 4611 VFUNC_LOG; 4612 return mPollTime; 4613} 4614 4615int MPLSensor::getStepCountPollTime(void) 4616{ 4617 VFUNC_LOG; 4618 /* clamped to 1ms? as spec, still rather large */ 4619 return 100; 4620} 4621 4622bool MPLSensor::hasStepCountPendingEvents(void) 4623{ 4624 VFUNC_LOG; 4625 if (mDmpStepCountEnabled) { 4626 struct timespec t_now; 4627 int64_t interval = 0; 4628 4629 clock_gettime(CLOCK_MONOTONIC, &t_now); 4630 interval = ((int64_t(t_now.tv_sec) * 1000000000LL + t_now.tv_nsec) - 4631 (int64_t(mt_pre.tv_sec) * 1000000000LL + mt_pre.tv_nsec)); 4632 4633 if (interval < mStepCountPollTime) { 4634 LOGV_IF(0, 4635 "Step Count interval elapsed: %lld, triggered: %lld", 4636 interval, mStepCountPollTime); 4637 return false; 4638 } else { 4639 clock_gettime(CLOCK_MONOTONIC, &mt_pre); 4640 LOGV_IF(0, "Step Count previous time: %ld ms", 4641 mt_pre.tv_nsec / 1000); 4642 return true; 4643 } 4644 } 4645 return false; 4646} 4647 4648bool MPLSensor::hasPendingEvents(void) const 4649{ 4650 VFUNC_LOG; 4651 // if we are using the polling workaround, force the main 4652 // loop to check for data every time 4653 return (mPollTime != -1); 4654} 4655 4656int MPLSensor::inv_read_temperature(long long *data) 4657{ 4658 VHANDLER_LOG; 4659 4660 int count = 0; 4661 char raw_buf[40]; 4662 long raw = 0; 4663 4664 long long timestamp = 0; 4665 4666 memset(raw_buf, 0, sizeof(raw_buf)); 4667 count = read_attribute_sensor(gyro_temperature_fd, raw_buf, 4668 sizeof(raw_buf)); 4669 if(count < 1) { 4670 LOGE("HAL:error reading gyro temperature"); 4671 return -1; 4672 } 4673 4674 count = sscanf(raw_buf, "%ld%lld", &raw, ×tamp); 4675 4676 if(count < 0) { 4677 return -1; 4678 } 4679 4680 LOGV_IF(ENG_VERBOSE && INPUT_DATA, 4681 "HAL:temperature raw = %ld, timestamp = %lld, count = %d", 4682 raw, timestamp, count); 4683 data[0] = raw; 4684 data[1] = timestamp; 4685 4686 return 0; 4687} 4688 4689int MPLSensor::inv_read_dmp_state(int fd) 4690{ 4691 VFUNC_LOG; 4692 4693 if(fd < 0) 4694 return -1; 4695 4696 int count = 0; 4697 char raw_buf[10]; 4698 short raw = 0; 4699 4700 memset(raw_buf, 0, sizeof(raw_buf)); 4701 count = read_attribute_sensor(fd, raw_buf, sizeof(raw_buf)); 4702 if(count < 1) { 4703 LOGE("HAL:error reading dmp state"); 4704 close(fd); 4705 return -1; 4706 } 4707 count = sscanf(raw_buf, "%hd", &raw); 4708 if(count < 0) { 4709 LOGE("HAL:dmp state data is invalid"); 4710 close(fd); 4711 return -1; 4712 } 4713 LOGV_IF(EXTRA_VERBOSE, "HAL:dmp state = %d, count = %d", raw, count); 4714 close(fd); 4715 return (int)raw; 4716} 4717 4718int MPLSensor::inv_read_sensor_bias(int fd, long *data) 4719{ 4720 VFUNC_LOG; 4721 4722 if(fd == -1) { 4723 return -1; 4724 } 4725 4726 char buf[50]; 4727 char x[15], y[15], z[15]; 4728 4729 memset(buf, 0, sizeof(buf)); 4730 int count = read_attribute_sensor(fd, buf, sizeof(buf)); 4731 if(count < 1) { 4732 LOGE("HAL:Error reading gyro bias"); 4733 return -1; 4734 } 4735 count = sscanf(buf, "%[^','],%[^','],%[^',']", x, y, z); 4736 if(count) { 4737 /* scale appropriately for MPL */ 4738 LOGV_IF(ENG_VERBOSE, 4739 "HAL:pre-scaled bias: X:Y:Z (%ld, %ld, %ld)", 4740 atol(x), atol(y), atol(z)); 4741 4742 data[0] = (long)(atol(x) / 10000 * (1L << 16)); 4743 data[1] = (long)(atol(y) / 10000 * (1L << 16)); 4744 data[2] = (long)(atol(z) / 10000 * (1L << 16)); 4745 4746 LOGV_IF(ENG_VERBOSE, 4747 "HAL:scaled bias: X:Y:Z (%ld, %ld, %ld)", 4748 data[0], data[1], data[2]); 4749 } 4750 return 0; 4751} 4752 4753/** fill in the sensor list based on which sensors are configured. 4754 * return the number of configured sensors. 4755 * parameter list must point to a memory region of at least 7*sizeof(sensor_t) 4756 * parameter len gives the length of the buffer pointed to by list 4757 */ 4758int MPLSensor::populateSensorList(struct sensor_t *list, int len) 4759{ 4760 VFUNC_LOG; 4761 4762 int numsensors; 4763 4764 if(len < 4765 (int)((sizeof(sBaseSensorList) / sizeof(sensor_t)) * sizeof(sensor_t))) { 4766 LOGE("HAL:sensor list too small, not populating."); 4767 return -(sizeof(sBaseSensorList) / sizeof(sensor_t)); 4768 } 4769 4770 /* fill in the base values */ 4771 memcpy(list, sBaseSensorList, 4772 sizeof (struct sensor_t) * (sizeof(sBaseSensorList) / sizeof(sensor_t))); 4773 4774 /* first add gyro, accel and compass to the list */ 4775 4776 /* fill in gyro/accel values */ 4777 if(chip_ID == NULL) { 4778 LOGE("HAL:Can not get gyro/accel id"); 4779 } 4780 fillGyro(chip_ID, list); 4781 fillAccel(chip_ID, list); 4782 4783 // TODO: need fixes for unified HAL and 3rd-party solution 4784 mCompassSensor->fillList(&list[MagneticField]); 4785 mCompassSensor->fillList(&list[RawMagneticField]); 4786#ifdef ENABLE_PRESSURE 4787 if (mPressureSensor != NULL) { 4788 mPressureSensor->fillList(&list[Pressure]); 4789 } 4790#endif 4791 4792 if(1) { 4793 numsensors = (sizeof(sBaseSensorList) / sizeof(sensor_t)); 4794 /* all sensors will be added to the list 4795 fill in orientation values */ 4796 fillOrientation(list); 4797 /* fill in rotation vector values */ 4798 fillRV(list); 4799 /* fill in game rotation vector values */ 4800 fillGRV(list); 4801 /* fill in gravity values */ 4802 fillGravity(list); 4803 /* fill in Linear accel values */ 4804 fillLinearAccel(list); 4805 /* fill in Significant motion values */ 4806 fillSignificantMotion(list); 4807#ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION 4808 /* fill in screen orientation values */ 4809 fillScreenOrientation(list); 4810#endif 4811 } else { 4812 /* no 9-axis sensors, zero fill that part of the list */ 4813 numsensors = 3; 4814 memset(list + 3, 0, 4 * sizeof(struct sensor_t)); 4815 } 4816 4817 return numsensors; 4818} 4819 4820void MPLSensor::fillAccel(const char* accel, struct sensor_t *list) 4821{ 4822 VFUNC_LOG; 4823 4824 if (accel) { 4825 if(accel != NULL && strcmp(accel, "BMA250") == 0) { 4826 list[Accelerometer].maxRange = ACCEL_BMA250_RANGE; 4827 list[Accelerometer].resolution = ACCEL_BMA250_RESOLUTION; 4828 list[Accelerometer].power = ACCEL_BMA250_POWER; 4829 list[Accelerometer].minDelay = ACCEL_BMA250_MINDELAY; 4830 return; 4831 } else if (accel != NULL && strcmp(accel, "MPU6050") == 0) { 4832 list[Accelerometer].maxRange = ACCEL_MPU6050_RANGE; 4833 list[Accelerometer].resolution = ACCEL_MPU6050_RESOLUTION; 4834 list[Accelerometer].power = ACCEL_MPU6050_POWER; 4835 list[Accelerometer].minDelay = ACCEL_MPU6050_MINDELAY; 4836 return; 4837 } else if (accel != NULL && strcmp(accel, "MPU6500") == 0) { 4838 list[Accelerometer].maxRange = ACCEL_MPU6500_RANGE; 4839 list[Accelerometer].resolution = ACCEL_MPU6500_RESOLUTION; 4840 list[Accelerometer].power = ACCEL_MPU6500_POWER; 4841 list[Accelerometer].minDelay = ACCEL_MPU6500_MINDELAY; 4842 return; 4843 } else if (accel != NULL && strcmp(accel, "MPU6515") == 0) { 4844 list[Accelerometer].maxRange = ACCEL_MPU6500_RANGE; 4845 list[Accelerometer].resolution = ACCEL_MPU6500_RESOLUTION; 4846 list[Accelerometer].power = ACCEL_MPU6500_POWER; 4847 list[Accelerometer].minDelay = ACCEL_MPU6500_MINDELAY; 4848 return; 4849 } else if (accel != NULL && strcmp(accel, "MPU6500") == 0) { 4850 list[Accelerometer].maxRange = ACCEL_MPU6500_RANGE; 4851 list[Accelerometer].resolution = ACCEL_MPU6500_RESOLUTION; 4852 list[Accelerometer].power = ACCEL_MPU6500_POWER; 4853 list[Accelerometer].minDelay = ACCEL_MPU6500_MINDELAY; 4854 return; 4855 } else if (accel != NULL && strcmp(accel, "MPU6500") == 0) { 4856 list[Accelerometer].maxRange = ACCEL_MPU6500_RANGE; 4857 list[Accelerometer].resolution = ACCEL_MPU6500_RESOLUTION; 4858 list[Accelerometer].power = ACCEL_MPU6500_POWER; 4859 list[Accelerometer].minDelay = ACCEL_MPU6500_MINDELAY; 4860 return; 4861 } else if (accel != NULL && strcmp(accel, "MPU9150") == 0) { 4862 list[Accelerometer].maxRange = ACCEL_MPU9150_RANGE; 4863 list[Accelerometer].resolution = ACCEL_MPU9150_RESOLUTION; 4864 list[Accelerometer].power = ACCEL_MPU9150_POWER; 4865 list[Accelerometer].minDelay = ACCEL_MPU9150_MINDELAY; 4866 return; 4867 } else if (accel != NULL && strcmp(accel, "MPU9250") == 0) { 4868 list[Accelerometer].maxRange = ACCEL_MPU9250_RANGE; 4869 list[Accelerometer].resolution = ACCEL_MPU9250_RESOLUTION; 4870 list[Accelerometer].power = ACCEL_MPU9250_POWER; 4871 list[Accelerometer].minDelay = ACCEL_MPU9250_MINDELAY; 4872 return; 4873 } else if (accel != NULL && strcmp(accel, "MPU9350") == 0) { 4874 list[Accelerometer].maxRange = ACCEL_MPU9350_RANGE; 4875 list[Accelerometer].resolution = ACCEL_MPU9350_RESOLUTION; 4876 list[Accelerometer].power = ACCEL_MPU9350_POWER; 4877 list[Accelerometer].minDelay = ACCEL_MPU9350_MINDELAY; 4878 return; 4879 } else if (accel != NULL && strcmp(accel, "MPU3050") == 0) { 4880 list[Accelerometer].maxRange = ACCEL_BMA250_RANGE; 4881 list[Accelerometer].resolution = ACCEL_BMA250_RESOLUTION; 4882 list[Accelerometer].power = ACCEL_BMA250_POWER; 4883 list[Accelerometer].minDelay = ACCEL_BMA250_MINDELAY; 4884 return; 4885 } 4886 } 4887 4888 LOGE("HAL:unknown accel id %s -- " 4889 "params default to mpu6515 and might be wrong.", 4890 accel); 4891 list[Accelerometer].maxRange = ACCEL_MPU6500_RANGE; 4892 list[Accelerometer].resolution = ACCEL_MPU6500_RESOLUTION; 4893 list[Accelerometer].power = ACCEL_MPU6500_POWER; 4894 list[Accelerometer].minDelay = ACCEL_MPU6500_MINDELAY; 4895} 4896 4897void MPLSensor::fillGyro(const char* gyro, struct sensor_t *list) 4898{ 4899 VFUNC_LOG; 4900 4901 if ( gyro != NULL && strcmp(gyro, "MPU3050") == 0) { 4902 list[Gyro].maxRange = GYRO_MPU3050_RANGE; 4903 list[Gyro].resolution = GYRO_MPU3050_RESOLUTION; 4904 list[Gyro].power = GYRO_MPU3050_POWER; 4905 list[Gyro].minDelay = GYRO_MPU3050_MINDELAY; 4906 } else if( gyro != NULL && strcmp(gyro, "MPU6050") == 0) { 4907 list[Gyro].maxRange = GYRO_MPU6050_RANGE; 4908 list[Gyro].resolution = GYRO_MPU6050_RESOLUTION; 4909 list[Gyro].power = GYRO_MPU6050_POWER; 4910 list[Gyro].minDelay = GYRO_MPU6050_MINDELAY; 4911 } else if( gyro != NULL && strcmp(gyro, "MPU6500") == 0) { 4912 list[Gyro].maxRange = GYRO_MPU6500_RANGE; 4913 list[Gyro].resolution = GYRO_MPU6500_RESOLUTION; 4914 list[Gyro].power = GYRO_MPU6500_POWER; 4915 list[Gyro].minDelay = GYRO_MPU6500_MINDELAY; 4916 } else if( gyro != NULL && strcmp(gyro, "MPU6515") == 0) { 4917 list[Gyro].maxRange = GYRO_MPU6500_RANGE; 4918 list[Gyro].resolution = GYRO_MPU6500_RESOLUTION; 4919 list[Gyro].power = GYRO_MPU6500_POWER; 4920 list[Gyro].minDelay = GYRO_MPU6500_MINDELAY; 4921 } else if( gyro != NULL && strcmp(gyro, "MPU9150") == 0) { 4922 list[Gyro].maxRange = GYRO_MPU9150_RANGE; 4923 list[Gyro].resolution = GYRO_MPU9150_RESOLUTION; 4924 list[Gyro].power = GYRO_MPU9150_POWER; 4925 list[Gyro].minDelay = GYRO_MPU9150_MINDELAY; 4926 } else if( gyro != NULL && strcmp(gyro, "MPU9250") == 0) { 4927 list[Gyro].maxRange = GYRO_MPU9250_RANGE; 4928 list[Gyro].resolution = GYRO_MPU9250_RESOLUTION; 4929 list[Gyro].power = GYRO_MPU9250_POWER; 4930 list[Gyro].minDelay = GYRO_MPU9250_MINDELAY; 4931 } else if( gyro != NULL && strcmp(gyro, "MPU9350") == 0) { 4932 list[Gyro].maxRange = GYRO_MPU9350_RANGE; 4933 list[Gyro].resolution = GYRO_MPU9350_RESOLUTION; 4934 list[Gyro].power = GYRO_MPU9350_POWER; 4935 list[Gyro].minDelay = GYRO_MPU9350_MINDELAY; 4936 } else { 4937 LOGE("HAL:unknown gyro id -- gyro params will be wrong."); 4938 LOGE("HAL:default to use mpu6515 params"); 4939 list[Gyro].maxRange = GYRO_MPU6500_RANGE; 4940 list[Gyro].resolution = GYRO_MPU6500_RESOLUTION; 4941 list[Gyro].power = GYRO_MPU6500_POWER; 4942 list[Gyro].minDelay = GYRO_MPU6500_MINDELAY; 4943 } 4944 4945 list[RawGyro].maxRange = list[Gyro].maxRange; 4946 list[RawGyro].resolution = list[Gyro].resolution; 4947 list[RawGyro].power = list[Gyro].power; 4948 list[RawGyro].minDelay = list[Gyro].minDelay; 4949 4950 return; 4951} 4952 4953/* fillRV depends on values of gyro, accel and compass in the list */ 4954void MPLSensor::fillRV(struct sensor_t *list) 4955{ 4956 VFUNC_LOG; 4957 4958 /* compute power on the fly */ 4959 list[RotationVector].power = list[Gyro].power + 4960 list[Accelerometer].power + 4961 list[MagneticField].power; 4962 list[RotationVector].resolution = .00001; 4963 list[RotationVector].maxRange = 1.0; 4964 list[RotationVector].minDelay = 5000; 4965 4966 return; 4967} 4968 4969/* fillGMRV depends on values of accel and mag in the list */ 4970void MPLSensor::fillGMRV(struct sensor_t *list) 4971{ 4972 VFUNC_LOG; 4973 4974 /* compute power on the fly */ 4975 list[GeomagneticRotationVector].power = list[Accelerometer].power + 4976 list[MagneticField].power; 4977 list[GeomagneticRotationVector].resolution = .00001; 4978 list[GeomagneticRotationVector].maxRange = 1.0; 4979 list[GeomagneticRotationVector].minDelay = 5000; 4980 4981 return; 4982} 4983 4984/* fillGRV depends on values of gyro and accel in the list */ 4985void MPLSensor::fillGRV(struct sensor_t *list) 4986{ 4987 VFUNC_LOG; 4988 4989 /* compute power on the fly */ 4990 list[GameRotationVector].power = list[Gyro].power + 4991 list[Accelerometer].power; 4992 list[GameRotationVector].resolution = .00001; 4993 list[GameRotationVector].maxRange = 1.0; 4994 list[GameRotationVector].minDelay = 5000; 4995 4996 return; 4997} 4998 4999void MPLSensor::fillOrientation(struct sensor_t *list) 5000{ 5001 VFUNC_LOG; 5002 5003 list[Orientation].power = list[Gyro].power + 5004 list[Accelerometer].power + 5005 list[MagneticField].power; 5006 list[Orientation].resolution = .00001; 5007 list[Orientation].maxRange = 360.0; 5008 list[Orientation].minDelay = 5000; 5009 5010 return; 5011} 5012 5013void MPLSensor::fillGravity( struct sensor_t *list) 5014{ 5015 VFUNC_LOG; 5016 5017 list[Gravity].power = list[Gyro].power + 5018 list[Accelerometer].power + 5019 list[MagneticField].power; 5020 list[Gravity].resolution = .00001; 5021 list[Gravity].maxRange = 9.81; 5022 list[Gravity].minDelay = 5000; 5023 5024 return; 5025} 5026 5027void MPLSensor::fillLinearAccel(struct sensor_t *list) 5028{ 5029 VFUNC_LOG; 5030 5031 list[LinearAccel].power = list[Gyro].power + 5032 list[Accelerometer].power + 5033 list[MagneticField].power; 5034 list[LinearAccel].resolution = list[Accelerometer].resolution; 5035 list[LinearAccel].maxRange = list[Accelerometer].maxRange; 5036 list[LinearAccel].minDelay = 5000; 5037 5038 return; 5039} 5040 5041void MPLSensor::fillSignificantMotion(struct sensor_t *list) 5042{ 5043 VFUNC_LOG; 5044 5045 list[SignificantMotion].power = list[Accelerometer].power; 5046 list[SignificantMotion].resolution = 1; 5047 list[SignificantMotion].maxRange = 1; 5048 list[SignificantMotion].minDelay = -1; 5049} 5050 5051#ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION 5052void MPLSensor::fillScreenOrientation(struct sensor_t *list) 5053{ 5054 VFUNC_LOG; 5055 5056 list[NumSensors].power = list[Accelerometer].power; 5057 list[NumSensors].resolution = 1; 5058 list[NumSensors].maxRange = 3; 5059 list[NumSensors].minDelay = 0; 5060} 5061#endif 5062 5063int MPLSensor::inv_init_sysfs_attributes(void) 5064{ 5065 VFUNC_LOG; 5066 5067 unsigned char i = 0; 5068 char sysfs_path[MAX_SYSFS_NAME_LEN]; 5069 char tbuf[2]; 5070 char *sptr; 5071 char **dptr; 5072 int num; 5073 5074 memset(sysfs_path, 0, sizeof(sysfs_path)); 5075 5076 sysfs_names_ptr = 5077 (char*)malloc(sizeof(char[MAX_SYSFS_ATTRB][MAX_SYSFS_NAME_LEN])); 5078 sptr = sysfs_names_ptr; 5079 if (sptr != NULL) { 5080 dptr = (char**)&mpu; 5081 do { 5082 *dptr++ = sptr; 5083 memset(sptr, 0, sizeof(sptr)); 5084 sptr += sizeof(char[MAX_SYSFS_NAME_LEN]); 5085 } while (++i < MAX_SYSFS_ATTRB); 5086 } else { 5087 LOGE("HAL:couldn't alloc mem for sysfs paths"); 5088 return -1; 5089 } 5090 5091 // get proper (in absolute) IIO path & build MPU's sysfs paths 5092 inv_get_sysfs_path(sysfs_path); 5093 5094 memcpy(mSysfsPath, sysfs_path, sizeof(sysfs_path)); 5095 sprintf(mpu.key, "%s%s", sysfs_path, "/key"); 5096 sprintf(mpu.chip_enable, "%s%s", sysfs_path, "/buffer/enable"); 5097 sprintf(mpu.buffer_length, "%s%s", sysfs_path, "/buffer/length"); 5098 sprintf(mpu.master_enable, "%s%s", sysfs_path, "/master_enable"); 5099 sprintf(mpu.power_state, "%s%s", sysfs_path, "/power_state"); 5100 5101 sprintf(mpu.in_timestamp_en, "%s%s", sysfs_path, 5102 "/scan_elements/in_timestamp_en"); 5103 sprintf(mpu.in_timestamp_index, "%s%s", sysfs_path, 5104 "/scan_elements/in_timestamp_index"); 5105 sprintf(mpu.in_timestamp_type, "%s%s", sysfs_path, 5106 "/scan_elements/in_timestamp_type"); 5107 5108 sprintf(mpu.dmp_firmware, "%s%s", sysfs_path, "/dmp_firmware"); 5109 sprintf(mpu.firmware_loaded, "%s%s", sysfs_path, "/firmware_loaded"); 5110 sprintf(mpu.dmp_on, "%s%s", sysfs_path, "/dmp_on"); 5111 sprintf(mpu.dmp_int_on, "%s%s", sysfs_path, "/dmp_int_on"); 5112 sprintf(mpu.dmp_event_int_on, "%s%s", sysfs_path, "/dmp_event_int_on"); 5113 sprintf(mpu.tap_on, "%s%s", sysfs_path, "/tap_on"); 5114 5115 sprintf(mpu.self_test, "%s%s", sysfs_path, "/self_test"); 5116 5117 sprintf(mpu.temperature, "%s%s", sysfs_path, "/temperature"); 5118 sprintf(mpu.gyro_enable, "%s%s", sysfs_path, "/gyro_enable"); 5119 sprintf(mpu.gyro_fifo_rate, "%s%s", sysfs_path, "/sampling_frequency"); 5120 sprintf(mpu.gyro_orient, "%s%s", sysfs_path, "/gyro_matrix"); 5121 sprintf(mpu.gyro_fifo_enable, "%s%s", sysfs_path, "/gyro_fifo_enable"); 5122 sprintf(mpu.gyro_fsr, "%s%s", sysfs_path, "/in_anglvel_scale"); 5123 sprintf(mpu.gyro_fifo_enable, "%s%s", sysfs_path, "/gyro_fifo_enable"); 5124 sprintf(mpu.gyro_rate, "%s%s", sysfs_path, "/gyro_rate"); 5125 5126 sprintf(mpu.accel_enable, "%s%s", sysfs_path, "/accel_enable"); 5127 sprintf(mpu.accel_fifo_rate, "%s%s", sysfs_path, "/sampling_frequency"); 5128 sprintf(mpu.accel_orient, "%s%s", sysfs_path, "/accel_matrix"); 5129 sprintf(mpu.accel_fifo_enable, "%s%s", sysfs_path, "/accel_fifo_enable"); 5130 sprintf(mpu.accel_rate, "%s%s", sysfs_path, "/accel_rate"); 5131 5132#ifndef THIRD_PARTY_ACCEL //MPU3050 5133 sprintf(mpu.accel_fsr, "%s%s", sysfs_path, "/in_accel_scale"); 5134 5135 // DMP uses these values 5136 sprintf(mpu.in_accel_x_dmp_bias, "%s%s", sysfs_path, "/in_accel_x_dmp_bias"); 5137 sprintf(mpu.in_accel_y_dmp_bias, "%s%s", sysfs_path, "/in_accel_y_dmp_bias"); 5138 sprintf(mpu.in_accel_z_dmp_bias, "%s%s", sysfs_path, "/in_accel_z_dmp_bias"); 5139 5140 // MPU uses these values 5141 sprintf(mpu.in_accel_x_offset, "%s%s", sysfs_path, "/in_accel_x_offset"); 5142 sprintf(mpu.in_accel_y_offset, "%s%s", sysfs_path, "/in_accel_y_offset"); 5143 sprintf(mpu.in_accel_z_offset, "%s%s", sysfs_path, "/in_accel_z_offset"); 5144 sprintf(mpu.in_accel_self_test_scale, "%s%s", sysfs_path, "/in_accel_self_test_scale"); 5145#endif 5146 5147 // DMP uses these bias values 5148 sprintf(mpu.in_gyro_x_dmp_bias, "%s%s", sysfs_path, "/in_anglvel_x_dmp_bias"); 5149 sprintf(mpu.in_gyro_y_dmp_bias, "%s%s", sysfs_path, "/in_anglvel_y_dmp_bias"); 5150 sprintf(mpu.in_gyro_z_dmp_bias, "%s%s", sysfs_path, "/in_anglvel_z_dmp_bias"); 5151 5152 // MPU uses these bias values 5153 sprintf(mpu.in_gyro_x_offset, "%s%s", sysfs_path, "/in_anglvel_x_offset"); 5154 sprintf(mpu.in_gyro_y_offset, "%s%s", sysfs_path, "/in_anglvel_y_offset"); 5155 sprintf(mpu.in_gyro_z_offset, "%s%s", sysfs_path, "/in_anglvel_z_offset"); 5156 sprintf(mpu.in_gyro_self_test_scale, "%s%s", sysfs_path, "/in_anglvel_self_test_scale"); 5157 5158 sprintf(mpu.three_axis_q_on, "%s%s", sysfs_path, "/three_axes_q_on"); //formerly quaternion_on 5159 sprintf(mpu.three_axis_q_rate, "%s%s", sysfs_path, "/three_axes_q_rate"); 5160 5161 sprintf(mpu.ped_q_on, "%s%s", sysfs_path, "/ped_q_on"); 5162 sprintf(mpu.ped_q_rate, "%s%s", sysfs_path, "/ped_q_rate"); 5163 5164 sprintf(mpu.six_axis_q_on, "%s%s", sysfs_path, "/six_axes_q_on"); 5165 sprintf(mpu.six_axis_q_rate, "%s%s", sysfs_path, "/six_axes_q_rate"); 5166 5167 sprintf(mpu.six_axis_q_value, "%s%s", sysfs_path, "/six_axes_q_value"); 5168 5169 sprintf(mpu.step_detector_on, "%s%s", sysfs_path, "/step_detector_on"); 5170 sprintf(mpu.step_indicator_on, "%s%s", sysfs_path, "/step_indicator_on"); 5171 5172 sprintf(mpu.display_orientation_on, "%s%s", sysfs_path, 5173 "/display_orientation_on"); 5174 sprintf(mpu.event_display_orientation, "%s%s", sysfs_path, 5175 "/event_display_orientation"); 5176 5177 sprintf(mpu.event_smd, "%s%s", sysfs_path, 5178 "/event_smd"); 5179 sprintf(mpu.smd_enable, "%s%s", sysfs_path, 5180 "/smd_enable"); 5181 sprintf(mpu.smd_delay_threshold, "%s%s", sysfs_path, 5182 "/smd_delay_threshold"); 5183 sprintf(mpu.smd_delay_threshold2, "%s%s", sysfs_path, 5184 "/smd_delay_threshold2"); 5185 sprintf(mpu.smd_threshold, "%s%s", sysfs_path, 5186 "/smd_threshold"); 5187 sprintf(mpu.batchmode_timeout, "%s%s", sysfs_path, 5188 "/batchmode_timeout"); 5189 sprintf(mpu.batchmode_wake_fifo_full_on, "%s%s", sysfs_path, 5190 "/batchmode_wake_fifo_full_on"); 5191 sprintf(mpu.flush_batch, "%s%s", sysfs_path, 5192 "/flush_batch"); 5193 sprintf(mpu.pedometer_on, "%s%s", sysfs_path, 5194 "/pedometer_on"); 5195 sprintf(mpu.pedometer_int_on, "%s%s", sysfs_path, 5196 "/pedometer_int_on"); 5197 sprintf(mpu.event_pedometer, "%s%s", sysfs_path, 5198 "/event_pedometer"); 5199 sprintf(mpu.pedometer_steps, "%s%s", sysfs_path, 5200 "/pedometer_steps"); 5201 sprintf(mpu.pedometer_step_thresh, "%s%s", sysfs_path, 5202 "/pedometer_step_thresh"); 5203 sprintf(mpu.pedometer_counter, "%s%s", sysfs_path, 5204 "/pedometer_counter"); 5205 sprintf(mpu.motion_lpa_on, "%s%s", sysfs_path, 5206 "/motion_lpa_on"); 5207 return 0; 5208} 5209 5210//DMP support only for MPU6xxx/9xxx 5211bool MPLSensor::isMpuNonDmp(void) 5212{ 5213 VFUNC_LOG; 5214 if (!strcmp(chip_ID, "mpu3050") || !strcmp(chip_ID, "MPU3050")) 5215 return true; 5216 else 5217 return false; 5218} 5219 5220int MPLSensor::isLowPowerQuatEnabled(void) 5221{ 5222 VFUNC_LOG; 5223#ifdef ENABLE_LP_QUAT_FEAT 5224 return !isMpuNonDmp(); 5225#else 5226 return 0; 5227#endif 5228} 5229 5230int MPLSensor::isDmpDisplayOrientationOn(void) 5231{ 5232 VFUNC_LOG; 5233#ifdef ENABLE_DMP_DISPL_ORIENT_FEAT 5234 if (isMpuNonDmp()) 5235 return 0; 5236 return 1; 5237#else 5238 return 0; 5239#endif 5240} 5241 5242/* these functions can be consolidated 5243with inv_convert_to_body_with_scale */ 5244void MPLSensor::getCompassBias() 5245{ 5246 VFUNC_LOG; 5247 5248 5249 long bias[3]; 5250 long compassBias[3]; 5251 unsigned short orient; 5252 signed char orientMtx[9]; 5253 mCompassSensor->getOrientationMatrix(orientMtx); 5254 orient = inv_orientation_matrix_to_scalar(orientMtx); 5255 5256 /* Get Values from MPL */ 5257 inv_get_compass_bias(bias); 5258 inv_convert_to_body(orient, bias, compassBias); 5259 LOGV_IF(HANDLER_DATA, "Mpl Compass Bias (HW unit) %ld %ld %ld", bias[0], bias[1], bias[2]); 5260 LOGV_IF(HANDLER_DATA, "Mpl Compass Bias (HW unit) (body) %ld %ld %ld", compassBias[0], compassBias[1], compassBias[2]); 5261 long compassSensitivity = inv_get_compass_sensitivity(); 5262 if (compassSensitivity == 0) { 5263 compassSensitivity = mCompassScale; 5264 } 5265 for(int i=0; i<3; i++) { 5266 /* convert to uT */ 5267 float temp = (float) compassSensitivity / (1L << 30); 5268 mCompassBias[i] =(float) (compassBias[i] * temp / 65536.f); 5269 } 5270 5271 return; 5272} 5273 5274void MPLSensor::getFactoryGyroBias() 5275{ 5276 VFUNC_LOG; 5277 5278 /* Get Values from MPL */ 5279 inv_get_gyro_bias(mFactoryGyroBias); 5280 LOGV_IF(ENG_VERBOSE, "Factory Gyro Bias %ld %ld %ld", mFactoryGyroBias[0], mFactoryGyroBias[1], mFactoryGyroBias[2]); 5281 mFactoryGyroBiasAvailable = true; 5282 5283 return; 5284} 5285 5286/* set bias from factory cal file to MPU offset (in chip frame) 5287 x = values store in cal file --> (v/1000 * 2^16 / (2000/250)) 5288 offset = x/2^16 * (Gyro scale / self test scale used) * (-1) / offset scale 5289 i.e. self test default scale = 250 5290 gyro scale default to = 2000 5291 offset scale = 4 //as spec by hardware 5292 offset = x/2^16 * (8) * (-1) / (4) 5293*/ 5294void MPLSensor::setFactoryGyroBias() 5295{ 5296 VFUNC_LOG; 5297 int scaleRatio = mGyroScale / mGyroSelfTestScale; 5298 int offsetScale = 4; 5299 LOGV_IF(ENG_VERBOSE, "HAL: scaleRatio used =%d", scaleRatio); 5300 LOGV_IF(ENG_VERBOSE, "HAL: offsetScale used =%d", offsetScale); 5301 5302 /* Write to Driver */ 5303 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 5304 (((int) (((float) mFactoryGyroBias[0]) / 65536.f * scaleRatio)) * -1 / offsetScale), 5305 mpu.in_gyro_x_offset, getTimestamp()); 5306 if(write_attribute_sensor_continuous(gyro_x_offset_fd, 5307 (((int) (((float) mFactoryGyroBias[0]) / 65536.f * scaleRatio)) * -1 / offsetScale)) < 0) 5308 { 5309 LOGE("HAL:Error writing to gyro_x_offset"); 5310 return; 5311 } 5312 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 5313 (((int) (((float) mFactoryGyroBias[1]) / 65536.f * scaleRatio)) * -1 / offsetScale), 5314 mpu.in_gyro_y_offset, getTimestamp()); 5315 if(write_attribute_sensor_continuous(gyro_y_offset_fd, 5316 (((int) (((float) mFactoryGyroBias[1]) / 65536.f * scaleRatio)) * -1 / offsetScale)) < 0) 5317 { 5318 LOGE("HAL:Error writing to gyro_y_offset"); 5319 return; 5320 } 5321 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 5322 (((int) (((float) mFactoryGyroBias[2]) / 65536.f * scaleRatio)) * -1 / offsetScale), 5323 mpu.in_gyro_z_offset, getTimestamp()); 5324 if(write_attribute_sensor_continuous(gyro_z_offset_fd, 5325 (((int) (((float) mFactoryGyroBias[2]) / 65536.f * scaleRatio)) * -1 / offsetScale)) < 0) 5326 { 5327 LOGE("HAL:Error writing to gyro_z_offset"); 5328 return; 5329 } 5330 mFactoryGyroBiasAvailable = false; 5331 LOGV_IF(EXTRA_VERBOSE, "HAL:Factory Gyro Calibrated Bias Applied"); 5332 5333 return; 5334} 5335 5336/* these functions can be consolidated 5337with inv_convert_to_body_with_scale */ 5338void MPLSensor::getGyroBias() 5339{ 5340 VFUNC_LOG; 5341 5342 long *temp = NULL; 5343 long chipBias[3]; 5344 long bias[3]; 5345 unsigned short orient; 5346 5347 /* Get Values from MPL */ 5348 inv_get_mpl_gyro_bias(mGyroChipBias, temp); 5349 orient = inv_orientation_matrix_to_scalar(mGyroOrientation); 5350 inv_convert_to_body(orient, mGyroChipBias, bias); 5351 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "Mpl Gyro Bias (HW unit) %ld %ld %ld", mGyroChipBias[0], mGyroChipBias[1], mGyroChipBias[2]); 5352 LOGV_IF(ENG_VERBOSE && INPUT_DATA, "Mpl Gyro Bias (HW unit) (body) %ld %ld %ld", bias[0], bias[1], bias[2]); 5353 long gyroSensitivity = inv_get_gyro_sensitivity(); 5354 if(gyroSensitivity == 0) { 5355 gyroSensitivity = mGyroScale; 5356 } 5357 5358 /* scale and convert to rad */ 5359 for(int i=0; i<3; i++) { 5360 float temp = (float) gyroSensitivity / (1L << 30); 5361 mGyroBias[i] = (float) (bias[i] * temp / (1<<16) / 180 * M_PI); 5362 if (mGyroBias[i] != 0) 5363 mGyroBiasAvailable = true; 5364 } 5365 5366 return; 5367} 5368 5369void MPLSensor::setGyroZeroBias() 5370{ 5371 VFUNC_LOG; 5372 5373 /* Write to Driver */ 5374 LOGV_IF(SYSFS_VERBOSE && INPUT_DATA, "HAL:sysfs:echo %d > %s (%lld)", 5375 0, mpu.in_gyro_x_dmp_bias, getTimestamp()); 5376 if(write_attribute_sensor_continuous(gyro_x_dmp_bias_fd, 0) < 0) { 5377 LOGE("HAL:Error writing to gyro_x_dmp_bias"); 5378 return; 5379 } 5380 LOGV_IF(SYSFS_VERBOSE && INPUT_DATA, "HAL:sysfs:echo %d > %s (%lld)", 5381 0, mpu.in_gyro_y_dmp_bias, getTimestamp()); 5382 if(write_attribute_sensor_continuous(gyro_y_dmp_bias_fd, 0) < 0) { 5383 LOGE("HAL:Error writing to gyro_y_dmp_bias"); 5384 return; 5385 } 5386 LOGV_IF(SYSFS_VERBOSE && INPUT_DATA, "HAL:sysfs:echo %d > %s (%lld)", 5387 0, mpu.in_gyro_z_dmp_bias, getTimestamp()); 5388 if(write_attribute_sensor_continuous(gyro_z_dmp_bias_fd, 0) < 0) { 5389 LOGE("HAL:Error writing to gyro_z_dmp_bias"); 5390 return; 5391 } 5392 LOGV_IF(EXTRA_VERBOSE, "HAL:Zero Gyro DMP Calibrated Bias Applied"); 5393 5394 return; 5395} 5396 5397void MPLSensor::setGyroBias() 5398{ 5399 VFUNC_LOG; 5400 5401 if(mGyroBiasAvailable == false) 5402 return; 5403 5404 long bias[3]; 5405 long gyroSensitivity = inv_get_gyro_sensitivity(); 5406 5407 if(gyroSensitivity == 0) { 5408 gyroSensitivity = mGyroScale; 5409 } 5410 5411 inv_get_gyro_bias_dmp_units(bias); 5412 5413 /* Write to Driver */ 5414 LOGV_IF(SYSFS_VERBOSE && INPUT_DATA, "HAL:sysfs:echo %ld > %s (%lld)", 5415 bias[0], mpu.in_gyro_x_dmp_bias, getTimestamp()); 5416 if(write_attribute_sensor_continuous(gyro_x_dmp_bias_fd, bias[0]) < 0) { 5417 LOGE("HAL:Error writing to gyro_x_dmp_bias"); 5418 return; 5419 } 5420 LOGV_IF(SYSFS_VERBOSE && INPUT_DATA, "HAL:sysfs:echo %ld > %s (%lld)", 5421 bias[1], mpu.in_gyro_y_dmp_bias, getTimestamp()); 5422 if(write_attribute_sensor_continuous(gyro_y_dmp_bias_fd, bias[1]) < 0) { 5423 LOGE("HAL:Error writing to gyro_y_dmp_bias"); 5424 return; 5425 } 5426 LOGV_IF(SYSFS_VERBOSE && INPUT_DATA, "HAL:sysfs:echo %ld > %s (%lld)", 5427 bias[2], mpu.in_gyro_z_dmp_bias, getTimestamp()); 5428 if(write_attribute_sensor_continuous(gyro_z_dmp_bias_fd, bias[2]) < 0) { 5429 LOGE("HAL:Error writing to gyro_z_dmp_bias"); 5430 return; 5431 } 5432 mGyroBiasApplied = true; 5433 mGyroBiasAvailable = false; 5434 LOGV_IF(EXTRA_VERBOSE, "HAL:Gyro DMP Calibrated Bias Applied"); 5435 5436 return; 5437} 5438 5439void MPLSensor::getFactoryAccelBias() 5440{ 5441 VFUNC_LOG; 5442 5443 long temp; 5444 5445 /* Get Values from MPL */ 5446 inv_get_accel_bias(mFactoryAccelBias); 5447 LOGV_IF(ENG_VERBOSE, "Factory Accel Bias (mg) %ld %ld %ld", mFactoryAccelBias[0], mFactoryAccelBias[1], mFactoryAccelBias[2]); 5448 mFactoryAccelBiasAvailable = true; 5449 5450 return; 5451} 5452 5453void MPLSensor::setFactoryAccelBias() 5454{ 5455 VFUNC_LOG; 5456 5457 if(mFactoryAccelBiasAvailable == false) 5458 return; 5459 5460 /* add scaling here - depends on self test parameters */ 5461 int scaleRatio = mAccelScale / mAccelSelfTestScale; 5462 int offsetScale = 16; 5463 long tempBias; 5464 5465 LOGV_IF(ENG_VERBOSE, "HAL: scaleRatio used =%d", scaleRatio); 5466 LOGV_IF(ENG_VERBOSE, "HAL: offsetScale used =%d", offsetScale); 5467 5468 /* Write to Driver */ 5469 tempBias = -mFactoryAccelBias[0] / 65536.f * scaleRatio / offsetScale; 5470 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)", 5471 tempBias, mpu.in_accel_x_offset, getTimestamp()); 5472 if(write_attribute_sensor_continuous(accel_x_offset_fd, tempBias) < 0) { 5473 LOGE("HAL:Error writing to accel_x_offset"); 5474 return; 5475 } 5476 tempBias = -mFactoryAccelBias[1] / 65536.f * scaleRatio / offsetScale; 5477 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)", 5478 tempBias, mpu.in_accel_y_offset, getTimestamp()); 5479 if(write_attribute_sensor_continuous(accel_y_offset_fd, tempBias) < 0) { 5480 LOGE("HAL:Error writing to accel_y_offset"); 5481 return; 5482 } 5483 tempBias = -mFactoryAccelBias[2] / 65536.f * scaleRatio / offsetScale; 5484 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %ld > %s (%lld)", 5485 tempBias, mpu.in_accel_z_offset, getTimestamp()); 5486 if(write_attribute_sensor_continuous(accel_z_offset_fd, tempBias) < 0) { 5487 LOGE("HAL:Error writing to accel_z_offset"); 5488 return; 5489 } 5490 mFactoryAccelBiasAvailable = false; 5491 LOGV_IF(EXTRA_VERBOSE, "HAL:Factory Accel Calibrated Bias Applied"); 5492 5493 return; 5494} 5495 5496void MPLSensor::getAccelBias() 5497{ 5498 VFUNC_LOG; 5499 long temp; 5500 5501 /* Get Values from MPL */ 5502 inv_get_mpl_accel_bias(mAccelBias, &temp); 5503 LOGV_IF(ENG_VERBOSE, "Accel Bias (mg) %ld %ld %ld", 5504 mAccelBias[0], mAccelBias[1], mAccelBias[2]); 5505 mAccelBiasAvailable = true; 5506 5507 return; 5508} 5509 5510/* set accel bias obtained from MPL 5511 bias is scaled by 65536 from MPL 5512 DMP expects: bias * 536870912 / 2^30 = bias / 2 (in body frame) 5513*/ 5514void MPLSensor::setAccelBias() 5515{ 5516 VFUNC_LOG; 5517 5518 if(mAccelBiasAvailable == false) { 5519 LOGV_IF(ENG_VERBOSE, "HAL: setAccelBias - accel bias not available"); 5520 return; 5521 } 5522 5523 /* write to driver */ 5524 LOGV_IF(SYSFS_VERBOSE && INPUT_DATA, "HAL:sysfs:echo %ld > %s (%lld)", 5525 (long) (mAccelBias[0] / 65536.f / 2), 5526 mpu.in_accel_x_dmp_bias, getTimestamp()); 5527 if(write_attribute_sensor_continuous( 5528 accel_x_dmp_bias_fd, (long)(mAccelBias[0] / 65536.f / 2)) < 0) { 5529 LOGE("HAL:Error writing to accel_x_dmp_bias"); 5530 return; 5531 } 5532 LOGV_IF(SYSFS_VERBOSE && INPUT_DATA, "HAL:sysfs:echo %ld > %s (%lld)", 5533 (long)(mAccelBias[1] / 65536.f / 2), 5534 mpu.in_accel_y_dmp_bias, getTimestamp()); 5535 if(write_attribute_sensor_continuous( 5536 accel_y_dmp_bias_fd, (long)(mAccelBias[1] / 65536.f / 2)) < 0) { 5537 LOGE("HAL:Error writing to accel_y_dmp_bias"); 5538 return; 5539 } 5540 LOGV_IF(SYSFS_VERBOSE && INPUT_DATA, "HAL:sysfs:echo %ld > %s (%lld)", 5541 (long)(mAccelBias[2] / 65536 / 2), 5542 mpu.in_accel_z_dmp_bias, getTimestamp()); 5543 if(write_attribute_sensor_continuous( 5544 accel_z_dmp_bias_fd, (long)(mAccelBias[2] / 65536 / 2)) < 0) { 5545 LOGE("HAL:Error writing to accel_z_dmp_bias"); 5546 return; 5547 } 5548 5549 mAccelBiasAvailable = false; 5550 mAccelBiasApplied = true; 5551 LOGV_IF(EXTRA_VERBOSE, "HAL:Accel DMP Calibrated Bias Applied"); 5552 5553 return; 5554} 5555 5556int MPLSensor::isCompassDisabled(void) 5557{ 5558 VFUNC_LOG; 5559 if(mCompassSensor->getFd() < 0 && !mCompassSensor->isIntegrated()) { 5560 LOGI_IF(EXTRA_VERBOSE, "HAL: Compass is disabled, Six-axis Sensor Fusion is used."); 5561 return 1; 5562 } 5563 return 0; 5564} 5565 5566int MPLSensor::checkBatchEnabled(void) 5567{ 5568 VFUNC_LOG; 5569 return ((mFeatureActiveMask & INV_DMP_BATCH_MODE)? 1:0); 5570} 5571 5572/* precondition: framework disallows this case, ie enable continuous sensor, */ 5573/* and enable batch sensor */ 5574/* if one sensor is in continuous mode, HAL disallows enabling batch for this sensor */ 5575/* or any other sensors */ 5576int MPLSensor::batch(int handle, int flags, int64_t period_ns, int64_t timeout) 5577{ 5578 VFUNC_LOG; 5579 5580 int res = 0; 5581 5582 if (isMpuNonDmp()) 5583 return res; 5584 5585 /* Enables batch mode and sets timeout for the given sensor */ 5586 /* enum SENSORS_BATCH_DRY_RUN, SENSORS_BATCH_WAKE_UPON_FIFO_FULL */ 5587 bool dryRun = false; 5588 android::String8 sname; 5589 int what = -1; 5590 int enabled_sensors = mEnabled; 5591 int batchMode = timeout > 0 ? 1 : 0; 5592 5593 LOGI_IF(DEBUG_BATCHING || ENG_VERBOSE, 5594 "HAL:batch called - handle=%d, flags=%d, period=%lld, timeout=%lld", 5595 handle, flags, period_ns, timeout); 5596 5597 if(flags & SENSORS_BATCH_DRY_RUN) { 5598 dryRun = true; 5599 LOGI_IF(PROCESS_VERBOSE, 5600 "HAL:batch - dry run mode is set (%d)", SENSORS_BATCH_DRY_RUN); 5601 } 5602 5603 /* check if we can support issuing interrupt before FIFO fills-up */ 5604 /* in a given timeout. */ 5605 if (flags & SENSORS_BATCH_WAKE_UPON_FIFO_FULL) { 5606 LOGE("HAL: batch SENSORS_BATCH_WAKE_UPON_FIFO_FULL is not supported"); 5607 return -EINVAL; 5608 } 5609 5610 getHandle(handle, what, sname); 5611 if(uint32_t(what) >= NumSensors) { 5612 LOGE("HAL:batch sensors %d not found", what); 5613 return -EINVAL; 5614 } 5615 5616 LOGV_IF(PROCESS_VERBOSE, 5617 "HAL:batch : %llu ns, (%.2f Hz)", period_ns, 1000000000.f / period_ns); 5618 5619 // limit all rates to reasonable ones */ 5620 if (period_ns < 5000000LL) { 5621 period_ns = 5000000LL; 5622 } 5623 5624 switch (what) { 5625 case Gyro: 5626 case RawGyro: 5627 case Accelerometer: 5628#ifdef ENABLE_PRESSURE 5629 case Pressure: 5630#endif 5631 case GameRotationVector: 5632 case StepDetector: 5633 LOGV_IF(PROCESS_VERBOSE, "HAL: batch - select sensor (handle %d)", handle); 5634 break; 5635 case MagneticField: 5636 case RawMagneticField: 5637 if(timeout > 0 && !mCompassSensor->isIntegrated()) 5638 return -EINVAL; 5639 else 5640 LOGV_IF(PROCESS_VERBOSE, "HAL: batch - select sensor (handle %d)", handle); 5641 break; 5642 default: 5643 if (timeout > 0) { 5644 LOGE("sensor (handle %d) is not supported in batch mode", handle); 5645 return -EINVAL; 5646 } 5647 } 5648 5649 if(dryRun == true) { 5650 LOGI("HAL: batch Dry Run is complete"); 5651 return 0; 5652 } 5653 5654 int tempBatch = 0; 5655 if (timeout > 0) { 5656 tempBatch = mBatchEnabled | (1 << what); 5657 } else { 5658 tempBatch = mBatchEnabled & ~(1 << what); 5659 } 5660 5661 if (!computeBatchSensorMask(mEnabled, tempBatch)) { 5662 batchMode = 0; 5663 } else { 5664 batchMode = 1; 5665 } 5666 5667 /* get maximum possible bytes to batch per sample */ 5668 /* get minimum delay for each requested sensor */ 5669 ssize_t nBytes = 0; 5670 int64_t wanted = 1000000000LL, ns = 0; 5671 int64_t timeoutInMs = 0; 5672 for (int i = 0; i < NumSensors; i++) { 5673 if (batchMode == 1) { 5674 ns = mBatchDelays[i]; 5675 LOGV_IF(DEBUG_BATCHING && EXTRA_VERBOSE, 5676 "HAL:batch - requested sensor=0x%01x, batch delay=%lld", mEnabled & (1 << i), ns); 5677 // take the min delay ==> max rate 5678 wanted = (ns < wanted) ? ns : wanted; 5679 if (i <= RawMagneticField) { 5680 nBytes += 8; 5681 } 5682#ifdef ENABLE_PRESSURE 5683 if (i == Pressure) { 5684 nBytes += 6; 5685 } 5686#endif 5687 if ((i == StepDetector) || (i == GameRotationVector)) { 5688 nBytes += 16; 5689 } 5690 } 5691 } 5692 5693 /* starting from code below, we will modify hardware */ 5694 /* first edit global batch mode mask */ 5695 5696 if (!timeout) { 5697 mBatchEnabled &= ~(1 << what); 5698 mBatchDelays[what] = 1000000000L; 5699 mDelays[what] = period_ns; 5700 mBatchTimeouts[what] = 100000000000LL; 5701 } else { 5702 mBatchEnabled |= (1 << what); 5703 mBatchDelays[what] = period_ns; 5704 mDelays[what] = period_ns; 5705 mBatchTimeouts[what] = timeout; 5706 } 5707 5708 // reset master enable 5709 res = masterEnable(0); 5710 if (res < 0) { 5711 return res; 5712 } 5713 5714 if(((int)mOldBatchEnabledMask != batchMode) || batchMode) { 5715 5716 /* remember batch mode that is set */ 5717 mOldBatchEnabledMask = batchMode; 5718 5719 /* For these sensors, switch to different data output */ 5720 int featureMask = computeBatchDataOutput(); 5721 5722 LOGV_IF(ENG_VERBOSE, "batchMode =%d, featureMask=0x%x, mEnabled=%d", 5723 batchMode, featureMask, mEnabled); 5724 if (DEBUG_BATCHING && EXTRA_VERBOSE) { 5725 LOGV("HAL:batch - sensor=0x%01x", mBatchEnabled); 5726 for (int d = 0; d < NumSensors; d++) { 5727 LOGV("HAL:batch - sensor status=0x%01x batch status=0x%01x timeout=%lld delay=%lld", 5728 mEnabled & (1 << d), (mBatchEnabled & (1 << d)), mBatchTimeouts[d], 5729 mBatchDelays[d]); 5730 } 5731 } 5732 5733 /* case for Ped standalone */ 5734 if ((batchMode == 1) && (featureMask & INV_DMP_PED_STANDALONE) && 5735 (mFeatureActiveMask & INV_DMP_PEDOMETER)) { 5736 LOGI_IF(ENG_VERBOSE, "batch - ID_P only = 0x%x", mBatchEnabled); 5737 enablePedQuaternion(0); 5738 enablePedStandalone(1); 5739 } else { 5740 enablePedStandalone(0); 5741 if (featureMask & INV_DMP_PED_QUATERNION) { 5742 enableLPQuaternion(0); 5743 enablePedQuaternion(1); 5744 } 5745 } 5746 5747 /* case for Ped Quaternion */ 5748 if ((batchMode == 1) && (featureMask & INV_DMP_PED_QUATERNION) && 5749 (mEnabled & (1 << GameRotationVector)) && 5750 (mFeatureActiveMask & INV_DMP_PEDOMETER)) { 5751 LOGI_IF(ENG_VERBOSE, "batch - ID_P and GRV or ALL = 0x%x", mBatchEnabled); 5752 LOGI_IF(ENG_VERBOSE, "batch - ID_P is enabled for batching, PED quat will be automatically enabled"); 5753 enableLPQuaternion(0); 5754 enablePedQuaternion(1); 5755 5756 /* set pedq rate */ 5757 wanted = mBatchDelays[GameRotationVector]; 5758 setPedQuaternionRate(wanted); 5759 } else if (!(featureMask & INV_DMP_PED_STANDALONE)){ 5760 LOGV_IF(ENG_VERBOSE, "batch - PedQ Toggle back to normal 6 axis"); 5761 if (mEnabled & (1 << GameRotationVector)) { 5762 enableLPQuaternion(checkLPQRateSupported()); 5763 } 5764 enablePedQuaternion(0); 5765 } else { 5766 enablePedQuaternion(0); 5767 } 5768 5769 /* case for Ped indicator */ 5770 if ((batchMode == 1) && ((featureMask & INV_DMP_PED_INDICATOR))) { 5771 enablePedIndicator(1); 5772 } else { 5773 enablePedIndicator(0); 5774 } 5775 5776 /* case for Six Axis Quaternion */ 5777 if ((batchMode == 1) && (featureMask & INV_DMP_6AXIS_QUATERNION) && 5778 (mEnabled & (1 << GameRotationVector))) { 5779 LOGI_IF(ENG_VERBOSE, "batch - GRV = 0x%x", mBatchEnabled); 5780 enableLPQuaternion(0); 5781 enable6AxisQuaternion(1); 5782 if (what == GameRotationVector) { 5783 setInitial6QuatValue(); 5784 } 5785 5786 /* set sixaxis rate */ 5787 wanted = mBatchDelays[GameRotationVector]; 5788 set6AxisQuaternionRate(wanted); 5789 } else if (!(featureMask & INV_DMP_PED_QUATERNION)){ 5790 LOGV_IF(ENG_VERBOSE, "batch - 6Axis Toggle back to normal 6 axis"); 5791 if (mEnabled & (1 << GameRotationVector)) { 5792 enableLPQuaternion(checkLPQRateSupported()); 5793 } 5794 enable6AxisQuaternion(0); 5795 } else { 5796 enable6AxisQuaternion(0); 5797 } 5798 5799 /* TODO: This may make a come back some day */ 5800 /* Not to overflow hardware FIFO if flag is set */ 5801 /*if (flags & (1 << SENSORS_BATCH_WAKE_UPON_FIFO_FULL)) { 5802 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 5803 0, mpu.batchmode_wake_fifo_full_on, getTimestamp()); 5804 if (write_sysfs_int(mpu.batchmode_wake_fifo_full_on, 0) < 0) { 5805 LOGE("HAL:ERR can't write batchmode_wake_fifo_full_on"); 5806 } 5807 }*/ 5808 5809 writeBatchTimeout(batchMode); 5810 5811 if (computeAndSetDmpState() < 0) { 5812 LOGE("HAL:ERR can't compute dmp state"); 5813 } 5814 5815}//end of batch mode modify 5816 5817 if (batchMode == 1) { 5818 /* set batch rates */ 5819 if (setBatchDataRates() < 0) { 5820 LOGE("HAL:ERR can't set batch data rates"); 5821 } 5822 } else { 5823 /* reset sensor rate */ 5824 if (resetDataRates() < 0) { 5825 LOGE("HAL:ERR can't reset output rate back to original setting"); 5826 } 5827 } 5828 5829 // set sensor data interrupt 5830 uint32_t dataInterrupt = (mEnabled || (mFeatureActiveMask & INV_DMP_BATCH_MODE)); 5831 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 5832 !dataInterrupt, mpu.dmp_event_int_on, getTimestamp()); 5833 if (write_sysfs_int(mpu.dmp_event_int_on, !dataInterrupt) < 0) { 5834 res = -1; 5835 LOGE("HAL:ERR can't enable DMP event interrupt"); 5836 } 5837 5838 if (enabled_sensors || mFeatureActiveMask) { 5839 masterEnable(1); 5840 } 5841 return res; 5842} 5843 5844/* Send empty event when: */ 5845/* 1. batch mode is not enabled */ 5846/* 2. no data in HW FIFO */ 5847/* return status zero if (2) */ 5848int MPLSensor::flush(int handle) 5849{ 5850 VFUNC_LOG; 5851 5852 int res = 0; 5853 int status = 0; 5854 android::String8 sname; 5855 int what = -1; 5856 5857 getHandle(handle, what, sname); 5858 if (uint32_t(what) >= NumSensors) { 5859 LOGE("HAL:flush - what=%d is invalid", what); 5860 return -EINVAL; 5861 } 5862 5863 LOGV_IF(PROCESS_VERBOSE, "HAL: flush - select sensor %s (handle %d)", sname.string(), handle); 5864 5865 if (((what != StepDetector) && (!(mEnabled & (1 << what)))) || 5866 ((what == StepDetector) && !(mFeatureActiveMask & INV_DMP_PEDOMETER))) { 5867 LOGV_IF(ENG_VERBOSE, "HAL: flush - sensor %s not enabled", sname.string()); 5868 return -EINVAL; 5869 } 5870 5871 if(!(mBatchEnabled & (1 << what))) { 5872 LOGV_IF(PROCESS_VERBOSE, "HAL:flush - batch mode not enabled for sensor %s (handle %d)", sname.string(), handle); 5873 } 5874 5875 mFlushSensorEnabledVector.push_back(handle); 5876 5877 /*write sysfs */ 5878 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:cat %s (%lld)", 5879 mpu.flush_batch, getTimestamp()); 5880 5881 status = read_sysfs_int(mpu.flush_batch, &res); 5882 5883 if (status < 0) 5884 LOGE("HAL: flush - error invoking flush_batch"); 5885 5886 /* driver returns 0 if FIFO is empty */ 5887 if (res == 0) { 5888 LOGI("HAL: flush - no data in FIFO"); 5889 } 5890 5891 LOGV_IF(ENG_VERBOSE, "HAl:flush - mFlushSensorEnabledVector=%d res=%d status=%d", handle, res, status); 5892 5893 mFlushBatchSet = 0; 5894 return 0; 5895} 5896 5897int MPLSensor::selectAndSetQuaternion(int batchMode, int mEnabled, long long featureMask) 5898{ 5899 VFUNC_LOG; 5900 int res = 0; 5901 5902 int64_t wanted; 5903 5904 /* case for Ped Quaternion */ 5905 if (batchMode == 1) { 5906 if ((featureMask & INV_DMP_PED_QUATERNION) && 5907 (mEnabled & (1 << GameRotationVector)) && 5908 (mFeatureActiveMask & INV_DMP_PEDOMETER)) { 5909 enableLPQuaternion(0); 5910 enable6AxisQuaternion(0); 5911 setInitial6QuatValue(); 5912 enablePedQuaternion(1); 5913 5914 /* set pedq rate */ 5915 wanted = mBatchDelays[GameRotationVector]; 5916 setPedQuaternionRate(wanted); 5917 } else if ((featureMask & INV_DMP_6AXIS_QUATERNION) && 5918 (mEnabled & (1 << GameRotationVector))) { 5919 enableLPQuaternion(0); 5920 enablePedQuaternion(0); 5921 setInitial6QuatValue(); 5922 enable6AxisQuaternion(1); 5923 5924 /* set sixaxis rate */ 5925 wanted = mBatchDelays[GameRotationVector]; 5926 set6AxisQuaternionRate(wanted); 5927 } else { 5928 enablePedQuaternion(0); 5929 enable6AxisQuaternion(0); 5930 } 5931 } else { 5932 if(mEnabled & (1 << GameRotationVector)) { 5933 enablePedQuaternion(0); 5934 enable6AxisQuaternion(0); 5935 enableLPQuaternion(checkLPQRateSupported()); 5936 } 5937 else { 5938 enablePedQuaternion(0); 5939 enable6AxisQuaternion(0); 5940 } 5941 } 5942 5943 return res; 5944} 5945 5946/* 5947Select Quaternion and Options for Batching 5948 5949 ID_P ID_GRV HW Batch Type 5950a 1 1 1 PedQ, Ped Indicator, HW 5951b 1 1 0 PedQ 5952c 1 0 1 Ped Indicator, HW 5953d 1 0 0 Ped Standalone, Ped Indicator 5954e 0 1 1 6Q, HW 5955f 0 1 0 6Q 5956g 0 0 1 HW 5957h 0 0 0 LPQ <defualt> 5958*/ 5959int MPLSensor::computeBatchDataOutput() 5960{ 5961 VFUNC_LOG; 5962 5963 int featureMask = 0; 5964 if (mBatchEnabled == 0) 5965 return 0;//h 5966 5967 uint32_t hardwareSensorMask = (1 << Gyro) 5968 | (1 << RawGyro) 5969 | (1 << Accelerometer) 5970 | (1 << MagneticField) 5971#ifdef ENABLE_PRESSURE 5972 | (1 << Pressure) 5973#endif 5974 | (1 << RawMagneticField); 5975 5976 LOGV_IF(ENG_VERBOSE, "hardwareSensorMask = 0x%0x, mBatchEnabled = 0x%0x", 5977 hardwareSensorMask, mBatchEnabled); 5978 5979 if (mBatchEnabled & (1 << StepDetector)) { 5980 if (mBatchEnabled & (1 << GameRotationVector)) { 5981 if ((mBatchEnabled & hardwareSensorMask)) { 5982 featureMask |= INV_DMP_6AXIS_QUATERNION;//a 5983 featureMask |= INV_DMP_PED_INDICATOR; 5984//LOGE("batch output: a"); 5985 } else { 5986 featureMask |= INV_DMP_PED_QUATERNION; //b 5987 featureMask |= INV_DMP_PED_INDICATOR; //always piggy back a bit 5988//LOGE("batch output: b"); 5989 } 5990 } else { 5991 if (mBatchEnabled & hardwareSensorMask) { 5992 featureMask |= INV_DMP_PED_INDICATOR; //c 5993//LOGE("batch output: c"); 5994 } else { 5995 featureMask |= INV_DMP_PED_STANDALONE; //d 5996 featureMask |= INV_DMP_PED_INDICATOR; //required for standalone 5997//LOGE("batch output: d"); 5998 } 5999 } 6000 } else if (mBatchEnabled & (1 << GameRotationVector)) { 6001 featureMask |= INV_DMP_6AXIS_QUATERNION; //e,f 6002//LOGE("batch output: e,f"); 6003 } else { 6004 LOGV_IF(ENG_VERBOSE, 6005 "HAL:computeBatchDataOutput: featuerMask=0x%x", featureMask); 6006//LOGE("batch output: g"); 6007 return 0; //g 6008 } 6009 6010 LOGV_IF(ENG_VERBOSE, 6011 "HAL:computeBatchDataOutput: featuerMask=0x%x", featureMask); 6012 return featureMask; 6013} 6014 6015int MPLSensor::getDmpPedometerFd() 6016{ 6017 VFUNC_LOG; 6018 LOGV_IF(EXTRA_VERBOSE, "getDmpPedometerFd returning %d", dmp_pedometer_fd); 6019 return dmp_pedometer_fd; 6020} 6021 6022/* @param [in] : outputType = 1 --event is from PED_Q */ 6023/* outputType = 0 --event is from ID_SC, ID_P */ 6024int MPLSensor::readDmpPedometerEvents(sensors_event_t* data, int count, 6025 int32_t id, int outputType) 6026{ 6027 VFUNC_LOG; 6028 6029 int res = 0; 6030 char dummy[4]; 6031 6032 int numEventReceived = 0; 6033 int update = 0; 6034 6035 LOGI_IF(0, "HAL: Read Pedometer Event ID=%d", id); 6036 switch (id) { 6037 case ID_P: 6038 if (mDmpPedometerEnabled && count > 0) { 6039 /* Handles return event */ 6040 LOGI("HAL: Step detected"); 6041 update = sdHandler(&mSdEvents); 6042 } 6043 6044 if (update && count > 0) { 6045 *data++ = mSdEvents; 6046 count--; 6047 numEventReceived++; 6048 } 6049 break; 6050 case ID_SC: 6051 FILE *fp; 6052 uint64_t stepCount; 6053 uint64_t stepCountTs; 6054 6055 if (mDmpStepCountEnabled && count > 0) { 6056 fp = fopen(mpu.pedometer_steps, "r"); 6057 if (fp == NULL) { 6058 LOGE("HAL:cannot open pedometer_steps"); 6059 } else { 6060 if (fscanf(fp, "%lld\n", &stepCount) < 0) { 6061 LOGW("HAL:cannot read pedometer_steps"); 6062 if (fclose(fp) < 0) { 6063 LOGW("HAL:cannot close pedometer_steps"); 6064 } 6065 return 0; 6066 } 6067 if (fclose(fp) < 0) { 6068 LOGW("HAL:cannot close pedometer_steps"); 6069 } 6070 } 6071 6072 /* return event onChange only */ 6073 if (stepCount == mLastStepCount) { 6074 return 0; 6075 } 6076 6077 mLastStepCount = stepCount; 6078 6079 /* Read step count timestamp */ 6080 fp = fopen(mpu.pedometer_counter, "r"); 6081 if (fp == NULL) { 6082 LOGE("HAL:cannot open pedometer_counter"); 6083 } else{ 6084 if (fscanf(fp, "%lld\n", &stepCountTs) < 0) { 6085 LOGE("HAL:cannot read pedometer_counter"); 6086 if (fclose(fp) < 0) { 6087 LOGE("HAL:cannot close pedometer_counter"); 6088 } 6089 return 0; 6090 } 6091 if (fclose(fp) < 0) { 6092 LOGE("HAL:cannot close pedometer_counter"); 6093 return 0; 6094 } 6095 } 6096 mScEvents.timestamp = stepCountTs; 6097 6098 /* Handles return event */ 6099 update = scHandler(&mScEvents); 6100 } 6101 6102 if (update && count > 0) { 6103 *data++ = mScEvents; 6104 count--; 6105 numEventReceived++; 6106 } 6107 break; 6108 } 6109 6110 if (!outputType) { 6111 // read dummy data per driver's request 6112 // only required if actual irq is issued 6113 read(dmp_pedometer_fd, dummy, 4); 6114 } else { 6115 return 1; 6116 } 6117 6118 return numEventReceived; 6119} 6120 6121int MPLSensor::getDmpSignificantMotionFd() 6122{ 6123 VFUNC_LOG; 6124 6125 LOGV_IF(EXTRA_VERBOSE, "getDmpSignificantMotionFd returning %d", 6126 dmp_sign_motion_fd); 6127 return dmp_sign_motion_fd; 6128} 6129 6130int MPLSensor::readDmpSignificantMotionEvents(sensors_event_t* data, int count) 6131{ 6132 VFUNC_LOG; 6133 6134 int res = 0; 6135 char dummy[4]; 6136 int significantMotion; 6137 FILE *fp; 6138 int sensors = mEnabled; 6139 int numEventReceived = 0; 6140 int update = 0; 6141 6142 /* Technically this step is not necessary for now */ 6143 /* In the future, we may have meaningful values */ 6144 fp = fopen(mpu.event_smd, "r"); 6145 if (fp == NULL) { 6146 LOGE("HAL:cannot open event_smd"); 6147 return 0; 6148 } else { 6149 if (fscanf(fp, "%d\n", &significantMotion) < 0) { 6150 LOGE("HAL:cannot read event_smd"); 6151 } 6152 if (fclose(fp) < 0) { 6153 LOGE("HAL:cannot close event_smd"); 6154 } 6155 } 6156 6157 if(mDmpSignificantMotionEnabled && count > 0) { 6158 /* By implementation, smd is disabled once an event is triggered */ 6159 sensors_event_t temp; 6160 6161 /* Handles return event */ 6162 LOGI("HAL: SMD detected"); 6163 int update = smHandler(&mSmEvents); 6164 if (update && count > 0) { 6165 *data++ = mSmEvents; 6166 count--; 6167 numEventReceived++; 6168 6169 /* reset smd state */ 6170 mDmpSignificantMotionEnabled = 0; 6171 mFeatureActiveMask &= ~INV_DMP_SIGNIFICANT_MOTION; 6172 6173 /* auto disable this sensor */ 6174 enableDmpSignificantMotion(0); 6175 } 6176 } 6177 6178 // read dummy data per driver's request 6179 read(dmp_sign_motion_fd, dummy, 4); 6180 6181 return numEventReceived; 6182} 6183 6184int MPLSensor::enableDmpSignificantMotion(int en) 6185{ 6186 VFUNC_LOG; 6187 6188 int res = 0; 6189 int enabled_sensors = mEnabled; 6190 6191 if (isMpuNonDmp()) 6192 return res; 6193 6194 // reset master enable 6195 res = masterEnable(0); 6196 if (res < 0) 6197 return res; 6198 6199 //Toggle significant montion detection 6200 if(en) { 6201 LOGV_IF(ENG_VERBOSE, "HAL:Enabling Significant Motion"); 6202 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 6203 1, mpu.smd_enable, getTimestamp()); 6204 if (write_sysfs_int(mpu.smd_enable, 1) < 0) { 6205 LOGE("HAL:ERR can't write DMP smd_enable"); 6206 res = -1; //Indicate an err 6207 } 6208 mFeatureActiveMask |= INV_DMP_SIGNIFICANT_MOTION; 6209 } 6210 else { 6211 LOGV_IF(ENG_VERBOSE, "HAL:Disabling Significant Motion"); 6212 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 6213 0, mpu.smd_enable, getTimestamp()); 6214 if (write_sysfs_int(mpu.smd_enable, 0) < 0) { 6215 LOGE("HAL:ERR write DMP smd_enable"); 6216 } 6217 mFeatureActiveMask &= ~INV_DMP_SIGNIFICANT_MOTION; 6218 } 6219 6220 if ((res = setDmpFeature(en)) < 0) 6221 return res; 6222 6223 if ((res = computeAndSetDmpState()) < 0) 6224 return res; 6225 6226 if (!mBatchEnabled && (resetDataRates() < 0)) 6227 return res; 6228 6229 if(en || enabled_sensors || mFeatureActiveMask) { 6230 res = masterEnable(1); 6231 } 6232 return res; 6233} 6234 6235void MPLSensor::setInitial6QuatValue() 6236{ 6237 VFUNC_LOG; 6238 6239 if (!mInitial6QuatValueAvailable) 6240 return; 6241 6242 /* convert to unsigned char array */ 6243 size_t length = 16; 6244 unsigned char quat[16]; 6245 convert_long_to_hex_char(mInitial6QuatValue, quat, 4); 6246 6247 /* write to sysfs */ 6248 LOGV_IF(EXTRA_VERBOSE, "HAL:sysfs:echo quat value > %s", mpu.six_axis_q_value); 6249 LOGV_IF(EXTRA_VERBOSE && ENG_VERBOSE, "quat=%ld,%ld,%ld,%ld", mInitial6QuatValue[0], 6250 mInitial6QuatValue[1], 6251 mInitial6QuatValue[2], 6252 mInitial6QuatValue[3]); 6253 FILE* fptr = fopen(mpu.six_axis_q_value, "w"); 6254 if(fptr == NULL) { 6255 LOGE("HAL:could not open six_axis_q_value"); 6256 } else { 6257 if (fwrite(quat, 1, length, fptr) != length) { 6258 LOGE("HAL:write six axis q value failed"); 6259 } else { 6260 mInitial6QuatValueAvailable = 0; 6261 } 6262 if (fclose(fptr) < 0) { 6263 LOGE("HAL:could not close six_axis_q_value"); 6264 } 6265 } 6266 6267 return; 6268} 6269int MPLSensor::writeSignificantMotionParams(bool toggleEnable, 6270 uint32_t delayThreshold1, 6271 uint32_t delayThreshold2, 6272 uint32_t motionThreshold) 6273{ 6274 VFUNC_LOG; 6275 6276 int res = 0; 6277 6278 // Turn off enable 6279 if (toggleEnable) { 6280 masterEnable(0); 6281 } 6282 6283 // Write supplied values 6284 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 6285 delayThreshold1, mpu.smd_delay_threshold, getTimestamp()); 6286 res = write_sysfs_int(mpu.smd_delay_threshold, delayThreshold1); 6287 if (res == 0) { 6288 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 6289 delayThreshold2, mpu.smd_delay_threshold2, getTimestamp()); 6290 res = write_sysfs_int(mpu.smd_delay_threshold2, delayThreshold2); 6291 } 6292 if (res == 0) { 6293 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 6294 motionThreshold, mpu.smd_threshold, getTimestamp()); 6295 res = write_sysfs_int(mpu.smd_threshold, motionThreshold); 6296 } 6297 6298 // Turn on enable 6299 if (toggleEnable) { 6300 masterEnable(1); 6301 } 6302 return res; 6303} 6304 6305/* set batch data rate */ 6306/* this function should be optimized */ 6307int MPLSensor::setBatchDataRates() 6308{ 6309 VFUNC_LOG; 6310 6311 int res = 0; 6312 int tempFd = -1; 6313 6314 int64_t gyroRate; 6315 int64_t accelRate; 6316 int64_t compassRate; 6317#ifdef ENABLE_PRESSURE 6318 int64_t pressureRate; 6319#endif 6320 int64_t quatRate; 6321 6322 int mplGyroRate; 6323 int mplAccelRate; 6324 int mplCompassRate; 6325 int mplQuatRate; 6326 6327#ifdef ENABLE_MULTI_RATE 6328 gyroRate = mBatchDelays[Gyro]; 6329 /* take care of case where only one type of gyro sensors or 6330 compass sensors is turned on */ 6331 if (mBatchEnabled & (1 << Gyro) || mBatchEnabled & (1 << RawGyro)) { 6332 gyroRate = (mBatchDelays[Gyro] <= mBatchDelays[RawGyro]) ? 6333 (mBatchEnabled & (1 << Gyro) ? mBatchDelays[Gyro] : mBatchDelays[RawGyro]): 6334 (mBatchEnabled & (1 << RawGyro) ? mBatchDelays[RawGyro] : mBatchDelays[Gyro]); 6335 } 6336 compassRate = mBatchDelays[MagneticField]; 6337 if (mBatchEnabled & (1 << MagneticField) || mBatchEnabled & (1 << RawMagneticField)) { 6338 compassRate = (mBatchDelays[MagneticField] <= mBatchDelays[RawMagneticField]) ? 6339 (mBatchEnabled & (1 << MagneticField) ? mBatchDelays[MagneticField] : 6340 mBatchDelays[RawMagneticField]) : 6341 (mBatchEnabled & (1 << RawMagneticField) ? mBatchDelays[RawMagneticField] : 6342 mBatchDelays[MagneticField]); 6343 } 6344 accelRate = mBatchDelays[Accelerometer]; 6345#ifdef ENABLE_PRESSURE 6346 pressureRate = mBatchDelays[Pressure]; 6347#endif //ENABLE_PRESSURE 6348 6349 if ((mFeatureActiveMask & INV_DMP_PED_QUATERNION) || 6350 (mFeatureActiveMask & INV_DMP_6AXIS_QUATERNION)) { 6351 quatRate = mBatchDelays[GameRotationVector]; 6352 mplQuatRate = (int) quatRate / 1000LL; 6353 inv_set_quat_sample_rate(mplQuatRate); 6354 inv_set_rotation_vector_6_axis_sample_rate(mplQuatRate); 6355 LOGV_IF(PROCESS_VERBOSE, 6356 "HAL:MPL rv 6 axis sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplQuatRate, 6357 1000000000.f / quatRate ); 6358 LOGV_IF(PROCESS_VERBOSE, 6359 "HAL:MPL quat sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplQuatRate, 6360 1000000000.f / quatRate ); 6361 getDmpRate(&quatRate); 6362 } 6363 6364 mplGyroRate = (int) gyroRate / 1000LL; 6365 mplAccelRate = (int) accelRate / 1000LL; 6366 mplCompassRate = (int) compassRate / 1000LL; 6367 6368 /* set rate in MPL */ 6369 /* compass can only do 100Hz max */ 6370 inv_set_gyro_sample_rate(mplGyroRate); 6371 inv_set_accel_sample_rate(mplAccelRate); 6372 inv_set_compass_sample_rate(mplCompassRate); 6373 6374 LOGV_IF(PROCESS_VERBOSE, 6375 "HAL:MPL gyro sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplGyroRate, 1000000000.f / gyroRate); 6376 LOGV_IF(PROCESS_VERBOSE, 6377 "HAL:MPL accel sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplAccelRate, 1000000000.f / accelRate); 6378 LOGV_IF(PROCESS_VERBOSE, 6379 "HAL:MPL compass sample rate: (mpl)=%d us (mpu)=%.2f Hz", mplCompassRate, 1000000000.f / compassRate); 6380 6381#else 6382 /* search the minimum delay requested across all enabled sensors */ 6383 int64_t wanted = 1000000000LL; 6384 for (int i = 0; i < NumSensors; i++) { 6385 if (mBatchEnabled & (1 << i)) { 6386 int64_t ns = mBatchDelays[i]; 6387 wanted = wanted < ns ? wanted : ns; 6388 } 6389 } 6390 gyroRate = wanted; 6391 accelRate = wanted; 6392 compassRate = wanted; 6393#ifdef ENABLE_PRESSURE 6394 pressureRate = wanted; 6395#endif 6396#endif 6397 6398 /* takes care of gyro rate */ 6399 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)", 6400 1000000000.f / gyroRate, mpu.gyro_rate, 6401 getTimestamp()); 6402 tempFd = open(mpu.gyro_rate, O_RDWR); 6403 res = write_attribute_sensor(tempFd, 1000000000.f / gyroRate); 6404 if(res < 0) { 6405 LOGE("HAL:GYRO update delay error"); 6406 } 6407 6408 /* takes care of accel rate */ 6409 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)", 6410 1000000000.f / accelRate, mpu.accel_rate, 6411 getTimestamp()); 6412 tempFd = open(mpu.accel_rate, O_RDWR); 6413 res = write_attribute_sensor(tempFd, 1000000000.f / accelRate); 6414 LOGE_IF(res < 0, "HAL:ACCEL update delay error"); 6415 6416 /* takes care of compass rate */ 6417 if (compassRate < mCompassSensor->getMinDelay() * 1000LL) { 6418 compassRate = mCompassSensor->getMinDelay() * 1000LL; 6419 } 6420 mCompassSensor->setDelay(ID_M, compassRate); 6421 6422#ifdef ENABLE_PRESSURE 6423 /* takes care of pressure rate */ 6424 mPressureSensor->setDelay(ID_PS, pressureRate); 6425#endif 6426 6427 return res; 6428} 6429 6430/* Set sensor rate */ 6431/* this function should be optimized */ 6432int MPLSensor::resetDataRates() 6433{ 6434 VFUNC_LOG; 6435 6436 int res = 0; 6437 int tempFd = -1; 6438 int64_t wanted = 1000000000LL; 6439 6440 int64_t resetRate; 6441 int64_t gyroRate; 6442 int64_t accelRate; 6443 int64_t compassRate; 6444#ifdef ENABLE_PRESSURE 6445 int64_t pressureRate; 6446#endif 6447 6448 if (!mEnabled) { 6449 LOGV_IF(ENG_VERBOSE, "skip resetDataRates"); 6450 return 0; 6451 } 6452 LOGI("HAL:resetDataRates mEnabled=%d", mEnabled); 6453 /* search the minimum delay requested across all enabled sensors */ 6454 /* skip setting rates if it is not changed */ 6455 for (int i = 0; i < NumSensors; i++) { 6456 if (mEnabled & (1 << i)) { 6457 int64_t ns = mDelays[i]; 6458#ifdef ENABLE_PRESSURE 6459 if ((wanted == ns) && (i != Pressure)) { 6460 LOGV_IF(ENG_VERBOSE, "skip resetDataRates : same delay mDelays[%d]=%lld", i,mDelays[i]); 6461 //return 0; 6462 } 6463#endif 6464 LOGV_IF(ENG_VERBOSE, "resetDataRates - mDelays[%d]=%lld", i, mDelays[i]); 6465 wanted = wanted < ns ? wanted : ns; 6466 } 6467 } 6468 6469 resetRate = wanted; 6470 gyroRate = wanted; 6471 accelRate = wanted; 6472 compassRate = wanted; 6473#ifdef ENABLE_PRESSURE 6474 pressureRate = wanted; 6475#endif 6476 6477 /* set mpl data rate */ 6478 inv_set_gyro_sample_rate((int)gyroRate/1000LL); 6479 inv_set_accel_sample_rate((int)accelRate/1000LL); 6480 inv_set_compass_sample_rate((int)compassRate/1000LL); 6481 inv_set_linear_acceleration_sample_rate((int)resetRate/1000LL); 6482 inv_set_orientation_sample_rate((int)resetRate/1000LL); 6483 inv_set_rotation_vector_sample_rate((int)resetRate/1000LL); 6484 inv_set_gravity_sample_rate((int)resetRate/1000LL); 6485 inv_set_orientation_geomagnetic_sample_rate((int)resetRate/1000LL); 6486 inv_set_rotation_vector_6_axis_sample_rate((int)resetRate/1000LL); 6487 inv_set_geomagnetic_rotation_vector_sample_rate((int)resetRate/1000LL); 6488 6489 LOGV_IF(PROCESS_VERBOSE, 6490 "HAL:MPL gyro sample rate: (mpl)=%lld us (mpu)=%.2f Hz", 6491 gyroRate/1000LL, 1000000000.f / gyroRate); 6492 LOGV_IF(PROCESS_VERBOSE, 6493 "HAL:MPL accel sample rate: (mpl)=%lld us (mpu)=%.2f Hz", 6494 accelRate/1000LL, 1000000000.f / accelRate); 6495 LOGV_IF(PROCESS_VERBOSE, 6496 "HAL:MPL compass sample rate: (mpl)=%lld us (mpu)=%.2f Hz", 6497 compassRate/1000LL, 1000000000.f / compassRate); 6498 6499 /* reset dmp rate */ 6500 getDmpRate (&wanted); 6501 6502 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)", 6503 1000000000.f / wanted, mpu.gyro_fifo_rate, 6504 getTimestamp()); 6505 tempFd = open(mpu.gyro_fifo_rate, O_RDWR); 6506 res = write_attribute_sensor(tempFd, 1000000000.f / wanted); 6507 LOGE_IF(res < 0, "HAL:sampling frequency update delay error"); 6508 6509 /* takes care of gyro rate */ 6510 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)", 6511 1000000000.f / gyroRate, mpu.gyro_rate, 6512 getTimestamp()); 6513 tempFd = open(mpu.gyro_rate, O_RDWR); 6514 res = write_attribute_sensor(tempFd, 1000000000.f / gyroRate); 6515 if(res < 0) { 6516 LOGE("HAL:GYRO update delay error"); 6517 } 6518 6519 /* takes care of accel rate */ 6520 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %.0f > %s (%lld)", 6521 1000000000.f / accelRate, mpu.accel_rate, 6522 getTimestamp()); 6523 tempFd = open(mpu.accel_rate, O_RDWR); 6524 res = write_attribute_sensor(tempFd, 1000000000.f / accelRate); 6525 LOGE_IF(res < 0, "HAL:ACCEL update delay error"); 6526 6527 /* takes care of compass rate */ 6528 if (compassRate < mCompassSensor->getMinDelay() * 1000LL) { 6529 compassRate = mCompassSensor->getMinDelay() * 1000LL; 6530 } 6531 mCompassSensor->setDelay(ID_M, compassRate); 6532 6533#ifdef ENABLE_PRESSURE 6534 /* takes care of pressure rate */ 6535 mPressureSensor->setDelay(ID_PS, pressureRate); 6536#endif 6537 6538 /* takes care of lpq case for data rate at 200Hz */ 6539 if (checkLPQuaternion()) { 6540 if (resetRate <= RATE_200HZ) { 6541#ifndef USE_LPQ_AT_FASTEST 6542 enableLPQuaternion(0); 6543#endif 6544 } 6545 } 6546 6547 return res; 6548} 6549 6550void MPLSensor::resetMplStates() 6551{ 6552 VFUNC_LOG; 6553 LOGV_IF(ENG_VERBOSE, "HAL:resetMplStates()"); 6554 6555 inv_gyro_was_turned_off(); 6556 inv_accel_was_turned_off(); 6557 inv_compass_was_turned_off(); 6558 inv_quaternion_sensor_was_turned_off(); 6559 6560 return; 6561} 6562 6563void MPLSensor::initBias() 6564{ 6565 VFUNC_LOG; 6566 6567 LOGV_IF(ENG_VERBOSE, "HAL:inititalize dmp and device offsets to 0"); 6568 if(write_attribute_sensor_continuous(accel_x_dmp_bias_fd, 0) < 0) { 6569 LOGE("HAL:Error writing to accel_x_dmp_bias"); 6570 } 6571 if(write_attribute_sensor_continuous(accel_y_dmp_bias_fd, 0) < 0) { 6572 LOGE("HAL:Error writing to accel_y_dmp_bias"); 6573 } 6574 if(write_attribute_sensor_continuous(accel_z_dmp_bias_fd, 0) < 0) { 6575 LOGE("HAL:Error writing to accel_z_dmp_bias"); 6576 } 6577 6578 if(write_attribute_sensor_continuous(accel_x_offset_fd, 0) < 0) { 6579 LOGE("HAL:Error writing to accel_x_offset"); 6580 } 6581 if(write_attribute_sensor_continuous(accel_y_offset_fd, 0) < 0) { 6582 LOGE("HAL:Error writing to accel_y_offset"); 6583 } 6584 if(write_attribute_sensor_continuous(accel_z_offset_fd, 0) < 0) { 6585 LOGE("HAL:Error writing to accel_z_offset"); 6586 } 6587 6588 if(write_attribute_sensor_continuous(gyro_x_dmp_bias_fd, 0) < 0) { 6589 LOGE("HAL:Error writing to gyro_x_dmp_bias"); 6590 } 6591 if(write_attribute_sensor_continuous(gyro_y_dmp_bias_fd, 0) < 0) { 6592 LOGE("HAL:Error writing to gyro_y_dmp_bias"); 6593 } 6594 if(write_attribute_sensor_continuous(gyro_z_dmp_bias_fd, 0) < 0) { 6595 LOGE("HAL:Error writing to gyro_z_dmp_bias"); 6596 } 6597 6598 if(write_attribute_sensor_continuous(gyro_x_offset_fd, 0) < 0) { 6599 LOGE("HAL:Error writing to gyro_x_offset"); 6600 } 6601 if(write_attribute_sensor_continuous(gyro_y_offset_fd, 0) < 0) { 6602 LOGE("HAL:Error writing to gyro_y_offset"); 6603 } 6604 if(write_attribute_sensor_continuous(gyro_z_offset_fd, 0) < 0) { 6605 LOGE("HAL:Error writing to gyro_z_offset"); 6606 } 6607 return; 6608} 6609 6610/*TODO: reg_dump in a separate file*/ 6611void MPLSensor::sys_dump(bool fileMode) 6612{ 6613 VFUNC_LOG; 6614 6615 char sysfs_path[MAX_SYSFS_NAME_LEN]; 6616 char scan_element_path[MAX_SYSFS_NAME_LEN]; 6617 6618 memset(sysfs_path, 0, sizeof(sysfs_path)); 6619 memset(scan_element_path, 0, sizeof(scan_element_path)); 6620 inv_get_sysfs_path(sysfs_path); 6621 sprintf(scan_element_path, "%s%s", sysfs_path, "/scan_elements"); 6622 6623 read_sysfs_dir(fileMode, sysfs_path); 6624 read_sysfs_dir(fileMode, scan_element_path); 6625 6626 dump_dmp_img("/data/local/read_img.h"); 6627 return; 6628} 6629