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