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