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