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