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 #ifndef ANDROID_MPL_SENSOR_H
18 #define ANDROID_MPL_SENSOR_H
19 
20 #include <stdint.h>
21 #include <errno.h>
22 #include <sys/cdefs.h>
23 #include <sys/types.h>
24 #include <poll.h>
25 #include <time.h>
26 #include <utils/Vector.h>
27 #include <utils/KeyedVector.h>
28 #include <utils/String8.h>
29 #include "sensors.h"
30 #include "SensorBase.h"
31 #include "InputEventReader.h"
32 
33 #ifndef INVENSENSE_COMPASS_CAL
34 #pragma message("unified HAL for AKM")
35 #include "CompassSensor.AKM.h"
36 #endif
37 
38 #ifdef SENSOR_ON_PRIMARY_BUS
39 #pragma message("Sensor on Primary Bus")
40 #include "CompassSensor.IIO.primary.h"
41 #else
42 #pragma message("Sensor on Secondary Bus")
43 #include "CompassSensor.IIO.9150.h"
44 #endif
45 
46 class PressureSensor;
47 
48 /*****************************************************************************/
49 /* Sensors Enable/Disable Mask
50  *****************************************************************************/
51 #define MAX_CHIP_ID_LEN             (20)
52 
53 #define INV_THREE_AXIS_GYRO         (0x000F)
54 #define INV_THREE_AXIS_ACCEL        (0x0070)
55 #define INV_THREE_AXIS_COMPASS      (0x0380)
56 #define INV_ONE_AXIS_PRESSURE       (0x0400)
57 #define INV_ALL_SENSORS             (0x7FFF)
58 
59 #ifdef INVENSENSE_COMPASS_CAL
60 #define ALL_MPL_SENSORS_NP          (INV_THREE_AXIS_ACCEL \
61                                       | INV_THREE_AXIS_COMPASS \
62                                       | INV_THREE_AXIS_GYRO)
63 #else
64 #define ALL_MPL_SENSORS_NP          (INV_THREE_AXIS_ACCEL \
65                                       | INV_THREE_AXIS_COMPASS \
66                                       | INV_THREE_AXIS_GYRO)
67 #endif
68 
69 // bit mask of current active features (mMplFeatureActiveMask)
70 #define INV_COMPASS_CAL              0x01
71 #define INV_COMPASS_FIT              0x02
72 // bit mask of current active features (mFeatureActiveMask)
73 #define INV_DMP_QUATERNION           0x001 //3 elements without real part, 32 bit each
74 #define INV_DMP_DISPL_ORIENTATION    0x002
75 #define INV_DMP_SIGNIFICANT_MOTION   0x004
76 #define INV_DMP_PEDOMETER            0x008
77 #define INV_DMP_PEDOMETER_STEP       0x010
78 #define INV_DMP_PED_STANDALONE       0x020 //timestamps only
79 #define INV_DMP_6AXIS_QUATERNION     0x040 //3 elements without real part, 32 bit each
80 #define INV_DMP_PED_QUATERNION       0x080 //3 elements without real part, 16 bit each
81 #define INV_DMP_PED_INDICATOR        0x100 //tag along header with step indciator
82 #define INV_DMP_BATCH_MODE           0x200
83 #define INV_DMP_ACCEL_PED (0xffff)
84 
85 // bit mask of whether screen orientation is on
86 /*#define SCREEN_ORIENTATION_MASK (                         \
87         (isDmpDisplayOrientationOn()                      \
88         && ((1 << INV_DMP_DISPL_ORIENTATION)              \
89              || !isDmpScreenAutoRotationEnabled()))       \
90 )*/
91 // bit mask of whether DMP should be turned on
92 #define DMP_FEATURE_MASK (                           \
93         (INV_DMP_QUATERNION)                         \
94         | (INV_DMP_DISPL_ORIENTATION)                \
95         | (INV_DMP_SIGNIFICANT_MOTION)               \
96         | (INV_DMP_PEDOMETER)                        \
97         | (INV_DMP_PEDOMETER_STEP)                   \
98         | (INV_DMP_6AXIS_QUATERNION)                 \
99         | (INV_DMP_PED_QUATERNION)                   \
100         | (INV_DMP_BATCH_MODE)                       \
101 )
102 // bit mask of DMP features as sensors
103 #define DMP_SENSOR_MASK (                            \
104         (INV_DMP_DISPL_ORIENTATION)                  \
105         | (INV_DMP_SIGNIFICANT_MOTION)               \
106         | (INV_DMP_PEDOMETER)                        \
107         | (INV_DMP_PEDOMETER_STEP)                   \
108         | (INV_DMP_6AXIS_QUATERNION)                 \
109 )
110 // data header format used by kernel driver.
111 #define DATA_FORMAT_STEP           0x0001
112 #define DATA_FORMAT_MARKER         0x0010
113 #define DATA_FORMAT_PED_STANDALONE 0x0100
114 #define DATA_FORMAT_PED_QUAT       0x0200
115 #define DATA_FORMAT_6_AXIS         0x0400
116 #define DATA_FORMAT_QUAT           0x0800
117 #define DATA_FORMAT_COMPASS        0x1000
118 #define DATA_FORMAT_GYRO           0x2000
119 #define DATA_FORMAT_ACCEL          0x4000
120 #define DATA_FORMAT_PRESSURE       0x8000
121 #define DATA_FORMAT_MASK           0xffff
122 
123 #define BYTES_PER_SENSOR                8
124 #define BYTES_PER_SENSOR_PACKET         16
125 #define QUAT_ONLY_LAST_PACKET_OFFSET    16
126 #define BYTES_QUAT_DATA                 24
127 #define MAX_SUSPEND_BATCH_PACKET_SIZE   1024
128 #define MAX_PACKET_SIZE                 80 //8 * 4 + (2 * 24)
129 
130 /* Uncomment to enable Low Power Quaternion */
131 #define ENABLE_LP_QUAT_FEAT
132 
133 /* Uncomment to enable DMP display orientation
134    (within the HAL, see below for Java framework) */
135 //#define ENABLE_DMP_DISPL_ORIENT_FEAT
136 
137 #ifdef ENABLE_DMP_DISPL_ORIENT_FEAT
138 /* Uncomment following to expose the SENSOR_TYPE_SCREEN_ORIENTATION
139    sensor type (DMP screen orientation) to the Java framework.
140    NOTE:
141        need Invensense customized
142        'hardware/libhardware/include/hardware/sensors.h' to compile correctly.
143    NOTE:
144        need Invensense java framework changes to:
145        'frameworks/base/core/java/android/view/WindowOrientationListener.java'
146        'frameworks/base/core/java/android/hardware/Sensor.java'
147        'frameworks/base/core/java/android/hardware/SensorEvent.java'
148        for the 'Auto-rotate screen' to use this feature.
149 */
150 #define ENABLE_DMP_SCREEN_AUTO_ROTATION
151 #pragma message("ENABLE_DMP_DISPL_ORIENT_FEAT is defined, framework changes are necessary for HAL to work properly")
152 #endif
153 
154 /* Enable Pressure sensor support */
155 #define ENABLE_PRESSURE
156 
isDmpScreenAutoRotationEnabled()157 int isDmpScreenAutoRotationEnabled()
158 {
159 #ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
160     return 1;
161 #else
162     return 0;
163 #endif
164 }
165 
166 int (*m_pt2AccelCalLoadFunc)(long *bias) = NULL;
167 /*****************************************************************************/
168 /** MPLSensor implementation which fits into the HAL example for crespo provided
169  *  by Google.
170  *  WARNING: there may only be one instance of MPLSensor, ever.
171  */
172 
173 class MPLSensor: public SensorBase
174 {
175     typedef int (MPLSensor::*hfunc_t)(sensors_event_t*);
176 
177 public:
178 
179     enum {
180         Gyro = 0,
181         RawGyro,
182         Accelerometer,
183         MagneticField,
184         RawMagneticField,
185         Pressure,
186         Orientation,
187         RotationVector,
188         GameRotationVector,
189         LinearAccel,
190         Gravity,
191         SignificantMotion,
192         StepDetector,
193         StepCounter,
194         GeomagneticRotationVector,
195         NumSensors
196     };
197 
198     MPLSensor(CompassSensor *, int (*m_pt2AccelCalLoadFunc)(long*) = 0);
199     virtual ~MPLSensor();
200 
201     virtual int setDelay(int32_t handle, int64_t ns);
202     virtual int enable(int32_t handle, int enabled);
203     virtual int batch(int handle, int flags, int64_t period_ns, int64_t timeout);
204     virtual int flush(int handle);
205     int checkBatchEnabled();
206     int setBatch(int en, int toggleEnable);
getEnableMask()207     int32_t getEnableMask() { return mEnabled; }
208     void getHandle(int32_t handle, int &what, android::String8 &sname);
209 
210     virtual int readEvents(sensors_event_t *data, int count);
211     virtual int getFd() const;
212     virtual int getAccelFd() const;
213     virtual int getCompassFd() const;
214     virtual int getPollTime();
215     virtual int getStepCountPollTime();
216     virtual bool hasPendingEvents() const;
217     virtual bool hasStepCountPendingEvents();
218     virtual void sleepEvent();
219     virtual void wakeEvent();
220     int populateSensorList(struct sensor_t *list, int len);
221     void cbProcData();
222 
223     //static pointer to the object that will handle callbacks
224     static MPLSensor* gMPLSensor;
225 
226     int readAccelEvents(sensors_event_t* data, int count);
227     void buildCompassEvent();
228     void buildMpuEvent();
229 
230     int turnOffAccelFifo();
231     int turnOffGyroFifo();
232     int enableDmpOrientation(int);
233     int dmpOrientHandler(int);
234     int readDmpOrientEvents(sensors_event_t* data, int count);
235     int getDmpOrientFd();
236     int openDmpOrientFd();
237     int closeDmpOrientFd();
238 
239     int getDmpRate(int64_t *);
240     int checkDMPOrientation();
241 
242     int getDmpSignificantMotionFd();
243     int readDmpSignificantMotionEvents(sensors_event_t* data, int count);
244     int enableDmpSignificantMotion(int);
245     int significantMotionHandler(sensors_event_t* data);
checkSmdSupport()246     bool checkSmdSupport(){return (mDmpSignificantMotionEnabled);};
247 
248     int enableDmpPedometer(int, int);
249     int readDmpPedometerEvents(sensors_event_t* data, int count, int32_t id, int32_t type, int outputType);
250     int getDmpPedometerFd();
checkPedometerSupport()251     bool checkPedometerSupport() {return (mDmpPedometerEnabled || mDmpStepCountEnabled);};
checkOrientationSupport()252     bool checkOrientationSupport() {return ((isDmpDisplayOrientationOn()
253                                        && (mDmpOrientationEnabled
254                                        || !isDmpScreenAutoRotationEnabled())));};
255 
256 protected:
257     CompassSensor *mCompassSensor;
258     PressureSensor *mPressureSensor;
259 
260     int gyroHandler(sensors_event_t *data);
261     int rawGyroHandler(sensors_event_t *data);
262     int accelHandler(sensors_event_t *data);
263     int compassHandler(sensors_event_t *data);
264     int rawCompassHandler(sensors_event_t *data);
265     int rvHandler(sensors_event_t *data);
266     int grvHandler(sensors_event_t *data);
267     int laHandler(sensors_event_t *data);
268     int gravHandler(sensors_event_t *data);
269     int orienHandler(sensors_event_t *data);
270     int smHandler(sensors_event_t *data);
271     int pHandler(sensors_event_t *data);
272     int scHandler(sensors_event_t *data);
273     int gmHandler(sensors_event_t *data);
274     int psHandler(sensors_event_t *data);
275     int metaHandler(sensors_event_t *data, int flags);
276     void calcOrientationSensor(float *Rx, float *Val);
277     virtual int update_delay();
278 
279     void inv_set_device_properties();
280     int inv_constructor_init();
281     int inv_constructor_default_enable();
282     int setGyroInitialState();
283     int setAccelInitialState();
284     int masterEnable(int en);
285     int enablePedStandalone(int en);
286     int enablePedStandaloneData(int en);
287     int enablePedQuaternion(int);
288     int enablePedQuaternionData(int);
289     int enable6AxisQuaternion(int);
290     int enable6AxisQuaternionData(int);
291     int enableLPQuaternion(int);
292     int enableQuaternionData(int);
293     int enableAccelPedometer(int);
294     int enableAccelPedData(int);
295     int onDmp(int);
296     int enableGyro(int en);
297     int enableLowPowerAccel(int en);
298     int enableAccel(int en);
299     int enableCompass(int en, int rawSensorOn);
300     int enablePressure(int en);
301     int enableBatch(int64_t timeout);
302     void computeLocalSensorMask(int enabled_sensors);
303     int computeBatchSensorMask(int enableSensor, int checkNewBatchSensor);
304     int computeBatchDataOutput();
305     int enableSensors(unsigned long sensors, int en, uint32_t changed);
306     int inv_read_gyro_buffer(int fd, short *data, long long *timestamp);
307     int inv_float_to_q16(float *fdata, long *ldata);
308     int inv_long_to_q16(long *fdata, long *ldata);
309     int inv_float_to_round(float *fdata, long *ldata);
310     int inv_float_to_round2(float *fdata, short *sdata);
311     int inv_long_to_float(long *ldata, float *fdata);
312     int inv_read_temperature(long long *data);
313     int inv_read_dmp_state(int fd);
314     int inv_read_sensor_bias(int fd, long *data);
315     void inv_get_sensors_orientation(void);
316     int inv_init_sysfs_attributes(void);
317     int resetCompass(void);
318     void setCompassDelay(int64_t ns);
319     void enable_iio_sysfs(void);
320     int enablePedometer(int);
321     int enablePedIndicator(int en);
322     int checkPedStandaloneEnabled(void);
323     int checkPedQuatEnabled();
324     int check6AxisQuatEnabled();
325     int checkLPQRateSupported();
326     int checkLPQuaternion();
327     int checkAccelPed();
328     void setInitial6QuatValue();
329     int writeSignificantMotionParams(bool toggleEnable,
330                                      uint32_t delayThreshold1, uint32_t delayThreshold2,
331                                      uint32_t motionThreshold);
332 
333     int mNewData;   // flag indicating that the MPL calculated new output values
334     int mDmpStarted;
335     long mMasterSensorMask;
336     long mLocalSensorMask;
337     int mPollTime;
338     int mStepCountPollTime;
339     bool mHaveGoodMpuCal;   // flag indicating that the cal file can be written
340     int mGyroAccuracy;      // value indicating the quality of the gyro calibr.
341     int mAccelAccuracy;     // value indicating the quality of the accel calibr.
342     int mCompassAccuracy;     // value indicating the quality of the compass calibr.
343     struct pollfd mPollFds[5];
344     int mSampleCount;
345     pthread_mutex_t mMplMutex;
346     pthread_mutex_t mHALMutex;
347 
348     char mIIOBuffer[(16 + 8 * 3 + 8) * IIO_BUFFER_LENGTH];
349 
350     int iio_fd;
351     int accel_fd;
352     int mpufifo_fd;
353     int gyro_temperature_fd;
354     int accel_x_offset_fd;
355     int accel_y_offset_fd;
356     int accel_z_offset_fd;
357 
358     int accel_x_dmp_bias_fd;
359     int accel_y_dmp_bias_fd;
360     int accel_z_dmp_bias_fd;
361 
362     int gyro_x_offset_fd;
363     int gyro_y_offset_fd;
364     int gyro_z_offset_fd;
365 
366     int gyro_x_dmp_bias_fd;
367     int gyro_y_dmp_bias_fd;
368     int gyro_z_dmp_bias_fd;
369 
370     int dmp_orient_fd;
371     int mDmpOrientationEnabled;
372 
373     int dmp_sign_motion_fd;
374     int mDmpSignificantMotionEnabled;
375 
376     int dmp_pedometer_fd;
377     int mDmpPedometerEnabled;
378     int mDmpStepCountEnabled;
379 
380     uint32_t mEnabled;
381     uint32_t mBatchEnabled;
382     int32_t mFlushEnabled;
383     uint32_t mOldBatchEnabledMask;
384     int64_t mBatchTimeoutInMs;
385     sensors_event_t mPendingEvents[NumSensors];
386     int64_t mDelays[NumSensors];
387     int64_t mBatchDelays[NumSensors];
388     int64_t mBatchTimeouts[NumSensors];
389     hfunc_t mHandlers[NumSensors];
390     short mCachedGyroData[3];
391     long mCachedAccelData[3];
392     long mCachedCompassData[3];
393     long mCachedQuaternionData[3];
394     long mCached6AxisQuaternionData[3];
395     long mCachedPedQuaternionData[3];
396     long mCachedPressureData;
397     android::KeyedVector<int, int> mIrqFds;
398 
399     InputEventCircularReader mAccelInputReader;
400     InputEventCircularReader mGyroInputReader;
401 
402     bool mFirstRead;
403     short mTempScale;
404     short mTempOffset;
405     int64_t mTempCurrentTime;
406     int mAccelScale;
407     long mAccelSelfTestScale;
408     long mGyroScale;
409     long mGyroSelfTestScale;
410     long mCompassScale;
411     float mCompassBias[3];
412     bool mFactoryGyroBiasAvailable;
413     long mFactoryGyroBias[3];
414     bool mGyroBiasAvailable;
415     bool mGyroBiasApplied;
416     float mGyroBias[3];    //in body frame
417     long mGyroChipBias[3]; //in chip frame
418     bool mFactoryAccelBiasAvailable;
419     long mFactoryAccelBias[3];
420     bool mAccelBiasAvailable;
421     bool mAccelBiasApplied;
422     long mAccelBias[3];    //in chip frame
423 
424     uint32_t mPendingMask;
425     unsigned long mSensorMask;
426 
427     char chip_ID[MAX_CHIP_ID_LEN];
428     char mSysfsPath[MAX_SYSFS_NAME_LEN];
429 
430     signed char mGyroOrientation[9];
431     signed char mAccelOrientation[9];
432 
433     int64_t mSensorTimestamp;
434     int64_t mCompassTimestamp;
435     int64_t mPressureTimestamp;
436 
437     struct sysfs_attrbs {
438        char *chip_enable;
439        char *power_state;
440        char *master_enable;
441        char *dmp_firmware;
442        char *firmware_loaded;
443        char *dmp_on;
444        char *dmp_int_on;
445        char *dmp_event_int_on;
446        char *tap_on;
447        char *key;
448        char *self_test;
449        char *temperature;
450 
451        char *gyro_enable;
452        char *gyro_fifo_rate;
453        char *gyro_fsr;
454        char *gyro_orient;
455        char *gyro_fifo_enable;
456        char *gyro_rate;
457 
458        char *accel_enable;
459        char *accel_fifo_rate;
460        char *accel_fsr;
461        char *accel_bias;
462        char *accel_orient;
463        char *accel_fifo_enable;
464        char *accel_rate;
465 
466        char *three_axis_q_on; //formerly quaternion_on
467        char *three_axis_q_rate;
468 
469        char *six_axis_q_on;
470        char *six_axis_q_rate;
471 
472        char *six_axis_q_value;
473 
474        char *ped_q_on;
475        char *ped_q_rate;
476 
477        char *step_detector_on;
478        char *step_indicator_on;
479 
480        char *in_timestamp_en;
481        char *in_timestamp_index;
482        char *in_timestamp_type;
483 
484        char *buffer_length;
485 
486        char *display_orientation_on;
487        char *event_display_orientation;
488 
489        char *in_accel_x_offset;
490        char *in_accel_y_offset;
491        char *in_accel_z_offset;
492        char *in_accel_self_test_scale;
493 
494        char *in_accel_x_dmp_bias;
495        char *in_accel_y_dmp_bias;
496        char *in_accel_z_dmp_bias;
497 
498        char *in_gyro_x_offset;
499        char *in_gyro_y_offset;
500        char *in_gyro_z_offset;
501        char *in_gyro_self_test_scale;
502 
503        char *in_gyro_x_dmp_bias;
504        char *in_gyro_y_dmp_bias;
505        char *in_gyro_z_dmp_bias;
506 
507        char *event_smd;
508        char *smd_enable;
509        char *smd_delay_threshold;
510        char *smd_delay_threshold2;
511        char *smd_threshold;
512        char *batchmode_timeout;
513        char *batchmode_wake_fifo_full_on;
514        char *flush_batch;
515 
516        char *pedometer_on;
517        char *pedometer_int_on;
518        char *event_pedometer;
519        char *pedometer_steps;
520 
521        char *motion_lpa_on;
522     } mpu;
523 
524     char *sysfs_names_ptr;
525     int mMplFeatureActiveMask;
526     uint64_t mFeatureActiveMask;
527     bool mDmpOn;
528     int mPedUpdate;
529     int mPressureUpdate;
530     int64_t mQuatSensorTimestamp;
531     int64_t mStepSensorTimestamp;
532     uint64_t mLastStepCount;
533     int mLeftOverBufferSize;
534     char mLeftOverBuffer[24];
535     bool mInitial6QuatValueAvailable;
536     long mInitial6QuatValue[4];
537     bool mFlushBatchSet;
538     uint32_t mSkipReadEvents;
539 
540 private:
541     /* added for dynamic get sensor list */
542     void fillAccel(const char* accel, struct sensor_t *list);
543     void fillGyro(const char* gyro, struct sensor_t *list);
544     void fillRV(struct sensor_t *list);
545     void fillGMRV(struct sensor_t *list);
546     void fillGRV(struct sensor_t *list);
547     void fillOrientation(struct sensor_t *list);
548     void fillGravity(struct sensor_t *list);
549     void fillLinearAccel(struct sensor_t *list);
550     void fillSignificantMotion(struct sensor_t *list);
551 #ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
552     void fillScreenOrientation(struct sensor_t *list);
553 #endif
554     void storeCalibration();
555     void loadDMP();
556     bool isMpuNonDmp();
557     int isLowPowerQuatEnabled();
558     int isDmpDisplayOrientationOn();
559     void getCompassBias();
560     void getFactoryGyroBias();
561     void setFactoryGyroBias();
562     void getGyroBias();
563     void setGyroBias();
564     void getFactoryAccelBias();
565     void setFactoryAccelBias();
566     void getAccelBias();
567     void setAccelBias();
568     int isCompassDisabled();
569     int setBatchDataRates();
570     int resetDataRates();
571     void initBias();
572     void sys_dump(bool fileMode);
573 };
574 
575 extern "C" {
576     void setCallbackObject(MPLSensor*);
577     MPLSensor *getCallbackObject();
578 }
579 
580 #endif  // ANDROID_MPL_SENSOR_H
581