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
46class 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
157int isDmpScreenAutoRotationEnabled()
158{
159#ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
160    return 1;
161#else
162    return 0;
163#endif
164}
165
166int (*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
173class MPLSensor: public SensorBase
174{
175    typedef int (MPLSensor::*hfunc_t)(sensors_event_t*);
176
177public:
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);
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);
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();
251    bool checkPedometerSupport() {return (mDmpPedometerEnabled || mDmpStepCountEnabled);};
252    bool checkOrientationSupport() {return ((isDmpDisplayOrientationOn()
253                                       && (mDmpOrientationEnabled
254                                       || !isDmpScreenAutoRotationEnabled())));};
255
256protected:
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
540private:
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
575extern "C" {
576    void setCallbackObject(MPLSensor*);
577    MPLSensor *getCallbackObject();
578}
579
580#endif  // ANDROID_MPL_SENSOR_H
581