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 <utils/Vector.h>
26#include <utils/KeyedVector.h>
27#include "sensors.h"
28#include "SensorBase.h"
29#include "InputEventReader.h"
30
31#ifdef INVENSENSE_COMPASS_CAL
32
33#ifdef COMPASS_YAS530
34#warning "unified HAL for YAS530"
35#include "CompassSensor.IIO.primary.h"
36#elif COMPASS_AMI306
37#warning "unified HAL for AMI306"
38#include "CompassSensor.IIO.primary.h"
39#else
40#warning "unified HAL for MPU9150"
41#include "CompassSensor.IIO.9150.h"
42#endif
43#else
44#warning "unified HAL for AKM"
45#include "CompassSensor.AKM.h"
46#endif
47
48/*****************************************************************************/
49/* Sensors Enable/Disable Mask
50 *****************************************************************************/
51#define MAX_CHIP_ID_LEN             (20)
52#define IIO_BUFFER_LENGTH           (100 * 2)
53
54#define INV_THREE_AXIS_GYRO         (0x000F)
55#define INV_THREE_AXIS_ACCEL        (0x0070)
56#define INV_THREE_AXIS_COMPASS      (0x0380)
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 (mFeatureActiveMask)
70#define INV_COMPASS_CAL              0x01
71#define INV_COMPASS_FIT              0x02
72#define INV_DMP_QUATERNION           0x04
73#define INV_DMP_DISPL_ORIENTATION    0x08
74
75// #define ENABLE_LP_QUAT_FEAT /* Uncomment to enable Low Power Quaternion */
76// #define ENABLE_DMP_DISPL_ORIENT_FEAT /* Uncomment to enable DMP display orientation */
77
78#ifdef ENABLE_DMP_DISPL_ORIENT_FEAT
79/* Uncomment followings to enable screen auto-rotation by DMP (need the latest Android source tree update) */
80// #define ENABLE_DMP_SCREEN_AUTO_ROTATION
81#endif
82
83int isLowPowerQuatEnabled() {
84#ifdef ENABLE_LP_QUAT_FEAT
85    return 1;
86#else
87    return 0;
88#endif
89}
90
91int isDmpDisplayOrientationOn() {
92#ifdef ENABLE_DMP_DISPL_ORIENT_FEAT
93    return 1;
94#else
95    return 0;
96#endif
97}
98
99int isDmpScreenAutoRotationOn() {
100#ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
101    return 1;
102#else
103    return 0;
104#endif
105}
106
107/*****************************************************************************/
108/** MPLSensor implementation which fits into the HAL example for crespo provided
109 *  by Google.
110 *  WARNING: there may only be one instance of MPLSensor, ever.
111 */
112
113class MPLSensor: public SensorBase
114{
115    typedef int (MPLSensor::*hfunc_t)(sensors_event_t*);
116
117public:
118    enum {
119        Gyro = 0,
120        RawGyro,
121        Accelerometer,
122        MagneticField,
123        Orientation,
124        RotationVector,
125        LinearAccel,
126        Gravity,
127        numSensors
128    };
129
130    MPLSensor(CompassSensor *);
131    virtual ~MPLSensor();
132
133    virtual int setDelay(int32_t handle, int64_t ns);
134    virtual int enable(int32_t handle, int enabled);
135    int32_t getEnableMask() { return mEnabled; }
136
137    virtual int readEvents(sensors_event_t *data, int count);
138    virtual int getFd() const;
139    virtual int getAccelFd() const;
140    virtual int getCompassFd() const;
141    virtual int getPollTime();
142    virtual bool hasPendingEvents() const;
143    virtual void sleepEvent();
144    virtual void wakeEvent();
145    int populateSensorList(struct sensor_t *list, int len);
146    void cbProcData();
147
148    // Do not work with this object unless it is initialized
149    bool isValid() { return mMplSensorInitialized; };
150
151    //static pointer to the object that will handle callbacks
152    static MPLSensor* gMPLSensor;
153
154    //AKM HAL Integration
155    //void set_compass(long ready, long x, long y, long z, long accuracy);
156    int executeOnData(sensors_event_t* data, int count);
157    int readAccelEvents(sensors_event_t* data, int count);
158    int readCompassEvents(sensors_event_t* data, int count);
159
160    int turnOffAccelFifo();
161    int enableDmpOrientation(int);
162    int dmpOrientHandler(int);
163    int readDmpOrientEvents(sensors_event_t* data, int count);
164    int getDmpOrientFd();
165    int openDmpOrientFd();
166    int closeDmpOrientFd();
167
168    int getDmpRate(int64_t *);
169    int checkDMPOrientation();
170
171protected:
172    // Lets us know if the constructor was actually able to finish its job.
173    // E.g. false if init sysfs failed.
174    bool mMplSensorInitialized;
175    CompassSensor *mCompassSensor;
176
177    int gyroHandler(sensors_event_t *data);
178    int rawGyroHandler(sensors_event_t *data);
179    int accelHandler(sensors_event_t *data);
180    int compassHandler(sensors_event_t *data);
181    int rvHandler(sensors_event_t *data);
182    int laHandler(sensors_event_t *data);
183    int gravHandler(sensors_event_t *data);
184    int orienHandler(sensors_event_t *data);
185    void calcOrientationSensor(float *Rx, float *Val);
186    virtual int update_delay();
187
188    void inv_set_device_properties();
189    int inv_constructor_init();
190    int inv_constructor_default_enable();
191    int setGyroInitialState();
192    int setAccelInitialState();
193    int masterEnable(int en);
194    int onPower(int en);
195    int enableLPQuaternion(int);
196    int enableQuaternionData(int);
197    int onDMP(int);
198    int enableGyro(int en);
199    int enableAccel(int en);
200    int enableCompass(int en);
201    void computeLocalSensorMask(int enabled_sensors);
202    int enableSensors(unsigned long sensors, int en, uint32_t changed);
203    int inv_read_gyro_buffer(int fd, short *data, long long *timestamp);
204    int inv_float_to_q16(float *fdata, long *ldata);
205    int inv_long_to_q16(long *fdata, long *ldata);
206    int inv_float_to_round(float *fdata, long *ldata);
207    int inv_float_to_round2(float *fdata, short *sdata);
208    int inv_read_temperature(long long *data);
209    int inv_read_dmp_state(int fd);
210    int inv_read_sensor_bias(int fd, long *data);
211    void inv_get_sensors_orientation(void);
212    int inv_init_sysfs_attributes(void);
213#ifdef COMPASS_YAS530
214    int resetCompass(void);
215#endif
216    void setCompassDelay(int64_t ns);
217    void enable_iio_sysfs(void);
218    int enableTap(int);
219    int enableFlick(int);
220    int enablePedometer(int);
221    int checkLPQuaternion();
222
223    int mNewData;   // flag indicating that the MPL calculated new output values
224    int mDmpStarted;
225    long mMasterSensorMask;
226    long mLocalSensorMask;
227    int mPollTime;
228    bool mHaveGoodMpuCal;   // flag indicating that the cal file can be written
229    int mGyroAccuracy;      // value indicating the quality of the gyro calibr.
230    int mAccelAccuracy;     // value indicating the quality of the accel calibr.
231    struct pollfd mPollFds[5];
232    int mSampleCount;
233    pthread_mutex_t mMplMutex;
234    pthread_mutex_t mHALMutex;
235
236    char mIIOBuffer[(16 + 8 * 3 + 8) * IIO_BUFFER_LENGTH];
237
238    int iio_fd;
239    int accel_fd;
240    int mpufifo_fd;
241    int gyro_temperature_fd;
242    int dmp_orient_fd;
243
244    int mDmpOrientationEnabled;
245
246    uint32_t mEnabled;
247    uint32_t mOldEnabledMask;
248    sensors_event_t mPendingEvents[numSensors];
249    int64_t mDelays[numSensors];
250    hfunc_t mHandlers[numSensors];
251    short mCachedGyroData[3];
252    long mCachedAccelData[3];
253    long mCachedCompassData[3];
254    long mCachedQuaternionData[4];
255    android::KeyedVector<int, int> mIrqFds;
256
257    InputEventCircularReader mAccelInputReader;
258    InputEventCircularReader mGyroInputReader;
259
260    bool mFirstRead;
261    short mTempScale;
262    short mTempOffset;
263    int64_t mTempCurrentTime;
264    int mAccelScale;
265
266    uint32_t mPendingMask;
267    unsigned long mSensorMask;
268
269    char chip_ID[MAX_CHIP_ID_LEN];
270
271    signed char mGyroOrientation[9];
272    signed char mAccelOrientation[9];
273
274    int64_t mSensorTimestamp;
275    int64_t mCompassTimestamp;
276
277    struct sysfs_attrbs {
278       char *chip_enable;
279       char *power_state;
280       char *dmp_firmware;
281       char *firmware_loaded;
282       char *dmp_on;
283       char *dmp_int_on;
284       char *dmp_event_int_on;
285       char *dmp_output_rate;
286       char *tap_on;
287       char *key;
288       char *self_test;
289       char *temperature;
290
291       char *gyro_enable;
292       char *gyro_fifo_rate;
293       char *gyro_orient;
294       char *gyro_x_fifo_enable;
295       char *gyro_y_fifo_enable;
296       char *gyro_z_fifo_enable;
297
298       char *accel_enable;
299       char *accel_fifo_rate;
300       char *accel_fsr;
301       char *accel_bias;
302       char *accel_orient;
303       char *accel_x_fifo_enable;
304       char *accel_y_fifo_enable;
305       char *accel_z_fifo_enable;
306
307       char *quaternion_on;
308       char *in_quat_r_en;
309       char *in_quat_x_en;
310       char *in_quat_y_en;
311       char *in_quat_z_en;
312
313       char *in_timestamp_en;
314       char *trigger_name;
315       char *current_trigger;
316       char *buffer_length;
317
318       char *display_orientation_on;
319       char *event_display_orientation;
320    } mpu;
321
322    char *sysfs_names_ptr;
323    int mFeatureActiveMask;
324
325private:
326    /* added for dynamic get sensor list */
327    void fillAccel(const char* accel, struct sensor_t *list);
328    void fillGyro(const char* gyro, struct sensor_t *list);
329    void fillRV(struct sensor_t *list);
330    void fillOrientation(struct sensor_t *list);
331    void fillGravity(struct sensor_t *list);
332    void fillLinearAccel(struct sensor_t *list);
333    void storeCalibration();
334    void loadDMP();
335};
336
337extern "C" {
338    void setCallbackObject(MPLSensor*);
339    MPLSensor *getCallbackObject();
340}
341
342#endif  // ANDROID_MPL_SENSOR_H
343