1/*
2 $License:
3   Copyright 2011 InvenSense, Inc.
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16  $
17 */
18/******************************************************************************
19 *
20 * $Id: mlarray_legacy.c $
21 *
22 *****************************************************************************/
23
24/**
25 *  @defgroup MLArray_Legacy
26 *  @brief  Legacy Motion Library Array APIs.
27 *          The Motion Library Array APIs provide the user access to the
28 *          Motion Library state. These Legacy APIs provide access to
29 *          individual state arrays using a data set name as the first
30 *          argument to the API. This format has been replaced by unique
31 *          named APIs for each data set, found in the MLArray group.
32 *
33 *  @{
34 *      @file   mlarray_legacy.c
35 *      @brief  The Legacy Motion Library Array APIs.
36 */
37
38#include "ml.h"
39#include "mltypes.h"
40#include "mlinclude.h"
41#include "mlFIFO.h"
42#include "mldl_cfg.h"
43
44/**
45 *  @brief  inv_get_array is used to get an array of processed motion sensor data.
46 *          inv_get_array can be used to retrieve various data sets. Certain data
47 *          sets require functions to be enabled using MLEnable in order to be
48 *          valid.
49 *
50 *          The available data sets are:
51 *
52 *          - INV_ROTATION_MATRIX
53 *          - INV_QUATERNION
54 *          - INV_EULER_ANGLES_X
55 *          - INV_EULER_ANGLES_Y
56 *          - INV_EULER_ANGLES_Z
57 *          - INV_EULER_ANGLES
58 *          - INV_LINEAR_ACCELERATION
59 *          - INV_LINEAR_ACCELERATION_WORLD
60 *          - INV_GRAVITY
61 *          - INV_ANGULAR_VELOCITY
62 *          - INV_RAW_DATA
63 *          - INV_GYROS
64 *          - INV_ACCELS
65 *          - INV_MAGNETOMETER
66 *          - INV_GYRO_BIAS
67 *          - INV_ACCEL_BIAS
68 *          - INV_MAG_BIAS
69 *          - INV_HEADING
70 *          - INV_MAG_BIAS_ERROR
71 *          - INV_PRESSURE
72 *
73 *          Please refer to the documentation of inv_get_float_array() for a
74 *          description of these data sets.
75 *
76 *  @pre    MLDmpOpen() or MLDmpPedometerStandAloneOpen()
77 *          must have been called.
78 *
79 *  @param  dataSet
80 *              A constant specifying an array of data processed by the
81 *              motion processor.
82 *  @param  data
83 *              A pointer to an array to be passed back to the user.
84 *              <b>Must be 9 cells long at least</b>.
85 *
86 *  @return Zero if the command is successful; an ML error code otherwise.
87 */
88inv_error_t inv_get_array(int dataSet, long *data)
89{
90    inv_error_t result;
91    switch (dataSet) {
92    case INV_GYROS:
93        result = inv_get_gyro(data);
94        break;
95    case INV_ACCELS:
96        result = inv_get_accel(data);
97        break;
98    case INV_TEMPERATURE:
99        result = inv_get_temperature(data);
100        break;
101    case INV_ROTATION_MATRIX:
102        result = inv_get_rot_mat(data);
103        break;
104    case INV_QUATERNION:
105        result = inv_get_quaternion(data);
106        break;
107    case INV_LINEAR_ACCELERATION:
108        result = inv_get_linear_accel(data);
109        break;
110    case INV_LINEAR_ACCELERATION_WORLD:
111        result = inv_get_linear_accel_in_world(data);
112        break;
113    case INV_GRAVITY:
114        result = inv_get_gravity(data);
115        break;
116    case INV_ANGULAR_VELOCITY:
117        result = inv_get_angular_velocity(data);
118        break;
119    case INV_EULER_ANGLES:
120        result = inv_get_euler_angles(data);
121        break;
122    case INV_EULER_ANGLES_X:
123        result = inv_get_euler_angles_x(data);
124        break;
125    case INV_EULER_ANGLES_Y:
126        result = inv_get_euler_angles_y(data);
127        break;
128    case INV_EULER_ANGLES_Z:
129        result = inv_get_euler_angles_z(data);
130        break;
131    case INV_GYRO_TEMP_SLOPE:
132        result = inv_get_gyro_temp_slope(data);
133        break;
134    case INV_GYRO_BIAS:
135        result = inv_get_gyro_bias(data);
136        break;
137    case INV_ACCEL_BIAS:
138        result = inv_get_accel_bias(data);
139        break;
140    case INV_MAG_BIAS:
141        result = inv_get_mag_bias(data);
142        break;
143    case INV_RAW_DATA:
144        result = inv_get_gyro_and_accel_sensor(data);
145        break;
146    case INV_MAG_RAW_DATA:
147        result = inv_get_mag_raw_data(data);
148        break;
149    case INV_MAGNETOMETER:
150        result = inv_get_magnetometer(data);
151        break;
152    case INV_PRESSURE:
153        result = inv_get_pressure(data);
154        break;
155    case INV_HEADING:
156        result = inv_get_heading(data);
157        break;
158    case INV_GYRO_CALIBRATION_MATRIX:
159        result = inv_get_gyro_cal_matrix(data);
160        break;
161    case INV_ACCEL_CALIBRATION_MATRIX:
162        result = inv_get_accel_cal_matrix(data);
163        break;
164    case INV_MAG_CALIBRATION_MATRIX:
165        result = inv_get_mag_cal_matrix(data);
166        break;
167    case INV_MAG_BIAS_ERROR:
168        result = inv_get_mag_bias_error(data);
169        break;
170    case INV_MAG_SCALE:
171        result = inv_get_mag_scale(data);
172        break;
173    case INV_LOCAL_FIELD:
174        result = inv_get_local_field(data);
175        break;
176    case INV_RELATIVE_QUATERNION:
177        result = inv_get_relative_quaternion(data);
178        break;
179    default:
180        return INV_ERROR_INVALID_PARAMETER;
181        break;
182    }
183    return result;
184}
185
186/**
187 *  @brief  inv_get_float_array is used to get an array of processed motion sensor
188 *          data. inv_get_array can be used to retrieve various data sets.
189 *          Certain data sets require functions to be enabled using MLEnable
190 *          in order to be valid.
191 *
192 *          The available data sets are:
193 *
194 *          - INV_ROTATION_MATRIX :
195 *          Returns an array of nine data points representing the rotation
196 *          matrix generated from all available sensors.
197 *          This requires that ML_SENSOR_FUSION be enabled.
198 *          The array format will be R11, R12, R13, R21, R22, R23, R31, R32,
199 *          R33, representing the matrix:
200 *          <center>R11 R12 R13</center>
201 *          <center>R21 R22 R23</center>
202 *          <center>R31 R32 R33</center>
203 *          <b>Please refer to the "9-Axis Sensor Fusion Application Note" document,
204 *          section 7 "Sensor Fusion Output", for details regarding rotation
205 *          matrix output</b>.
206 *
207 *          - INV_QUATERNION :
208 *          Returns an array of four data points representing the quaternion
209 *          generated from all available sensors.
210 *          This requires that ML_SENSOR_FUSION be enabled.
211 *
212 *          - INV_EULER_ANGLES_X :
213 *          Returns an array of three data points representing roll, pitch, and
214 *          yaw using the X axis of the gyroscope, accelerometer, and compass as
215 *          reference axis.
216 *          This is typically the convention used for mobile devices where the X
217 *          axis is the width of the screen, Y axis is the height, and Z the
218 *          depth. In this case roll is defined as the rotation around the X
219 *          axis of the device.
220 *          The euler angles convention for this output is the following:
221 *          <TABLE>
222 *          <TR><TD><b>EULER ANGLE</b></TD><TD><b>ROTATION AROUND</b></TD></TR>
223 *          <TR><TD>roll              </TD><TD>X axis                </TD></TR>
224 *          <TR><TD>pitch             </TD><TD>Y axis                </TD></TR>
225 *          <TR><TD>yaw               </TD><TD>Z axis                </TD></TR>
226 *          </TABLE>
227 *          INV_EULER_ANGLES_X corresponds to the INV_EULER_ANGLES output and is
228 *          therefore the default convention.
229 *
230 *          - INV_EULER_ANGLES_Y :
231 *          Returns an array of three data points representing roll, pitch, and
232 *          yaw using the Y axis of the gyroscope, accelerometer, and compass as
233 *          reference axis.
234 *          This convention is typically used in augmented reality applications,
235 *          where roll is defined as the rotation around the axis along the
236 *          height of the screen of a mobile device, namely the Y axis.
237 *          The euler angles convention for this output is the following:
238 *          <TABLE>
239 *          <TR><TD><b>EULER ANGLE</b></TD><TD><b>ROTATION AROUND</b></TD></TR>
240 *          <TR><TD>roll              </TD><TD>Y axis                </TD></TR>
241 *          <TR><TD>pitch             </TD><TD>X axis                </TD></TR>
242 *          <TR><TD>yaw               </TD><TD>Z axis                </TD></TR>
243 *          </TABLE>
244 *
245 *          - INV_EULER_ANGLES_Z :
246 *          Returns an array of three data points representing roll, pitch, and
247 *          yaw using the Z axis of the gyroscope, accelerometer, and compass as
248 *          reference axis.
249 *          This convention is mostly used in application involving the use
250 *          of a camera, typically placed on the back of a mobile device, that
251 *          is along the Z axis.  In this convention roll is defined as the
252 *          rotation around the Z axis.
253 *          The euler angles convention for this output is the following:
254 *          <TABLE>
255 *          <TR><TD><b>EULER ANGLE</b></TD><TD><b>ROTATION AROUND</b></TD></TR>
256 *          <TR><TD>roll              </TD><TD>Z axis                </TD></TR>
257 *          <TR><TD>pitch             </TD><TD>X axis                </TD></TR>
258 *          <TR><TD>yaw               </TD><TD>Y axis                </TD></TR>
259 *          </TABLE>
260 *
261 *          - INV_EULER_ANGLES :
262 *          Returns an array of three data points representing roll, pitch, and
263 *          yaw corresponding to the INV_EULER_ANGLES_X output and it is
264 *          therefore the default convention for Euler angles.
265 *          Please refer to the INV_EULER_ANGLES_X for a detailed description.
266 *
267 *          - INV_LINEAR_ACCELERATION :
268 *          Returns an array of three data points representing the linear
269 *          acceleration as derived from both gyroscopes and accelerometers.
270 *          This requires that ML_SENSOR_FUSION be enabled.
271 *
272 *          - INV_LINEAR_ACCELERATION_WORLD :
273 *          Returns an array of three data points representing the linear
274 *          acceleration in world coordinates, as derived from both gyroscopes
275 *          and accelerometers.
276 *          This requires that ML_SENSOR_FUSION be enabled.
277 *
278 *          - INV_GRAVITY :
279 *          Returns an array of three data points representing the direction
280 *          of gravity in body coordinates, as derived from both gyroscopes
281 *          and accelerometers.
282 *          This requires that ML_SENSOR_FUSION be enabled.
283 *
284 *          - INV_ANGULAR_VELOCITY :
285 *          Returns an array of three data points representing the angular
286 *          velocity as derived from <b>both</b> gyroscopes and accelerometers.
287 *          This requires that ML_SENSOR_FUSION be enabled, to fuse data from
288 *          the gyroscope and accelerometer device, appropriately scaled and
289 *          oriented according to the respective mounting matrices.
290 *
291 *          - INV_RAW_DATA :
292 *          Returns an array of nine data points representing raw sensor data
293 *          of the gyroscope X, Y, Z, accelerometer X, Y, Z, and
294 *          compass X, Y, Z values.
295 *          These values are not scaled and come out directly from the devices'
296 *          sensor data output. In case of accelerometers with lower output
297 *          resolution, e.g 8-bit, the sensor data is scaled up to match the
298 *          2^14 = 1 gee typical representation for a +/- 2 gee full scale
299 *          range.
300 *
301 *          - INV_GYROS :
302 *          Returns an array of three data points representing the X gyroscope,
303 *          Y gyroscope, and Z gyroscope values.
304 *          The values are not sensor fused with other sensor types data but
305 *          reflect the orientation from the mounting matrices in use.
306 *          The INV_GYROS values are scaled to ensure 1 dps corresponds to 2^16
307 *          codes.
308 *
309 *          - INV_ACCELS :
310 *          Returns an array of three data points representing the X
311 *          accelerometer, Y accelerometer, and Z accelerometer values.
312 *          The values are not sensor fused with other sensor types data but
313 *          reflect the orientation from the mounting matrices in use.
314 *          The INV_ACCELS values are scaled to ensure 1 gee corresponds to 2^16
315 *          codes.
316 *
317 *          - INV_MAGNETOMETER :
318 *          Returns an array of three data points representing the compass
319 *          X, Y, and Z values.
320 *          The values are not sensor fused with other sensor types data but
321 *          reflect the orientation from the mounting matrices in use.
322 *          The INV_MAGNETOMETER values are scaled to ensure 1 micro Tesla (uT)
323 *          corresponds to 2^16 codes.
324 *
325 *          - INV_GYRO_BIAS :
326 *          Returns an array of three data points representing the gyroscope
327 *          biases.
328 *
329 *          - INV_ACCEL_BIAS :
330 *          Returns an array of three data points representing the
331 *          accelerometer biases.
332 *
333 *          - INV_MAG_BIAS :
334 *          Returns an array of three data points representing the compass
335 *          biases.
336 *
337 *          - INV_GYRO_CALIBRATION_MATRIX :
338 *          Returns an array of nine data points representing the calibration
339 *          matrix for the gyroscopes:
340 *          <center>C11 C12 C13</center>
341 *          <center>C21 C22 C23</center>
342 *          <center>C31 C32 C33</center>
343 *
344 *          - INV_ACCEL_CALIBRATION_MATRIX :
345 *          Returns an array of nine data points representing the calibration
346 *          matrix for the accelerometers:
347 *          <center>C11 C12 C13</center>
348 *          <center>C21 C22 C23</center>
349 *          <center>C31 C32 C33</center>
350 *
351 *          - INV_MAG_CALIBRATION_MATRIX :
352 *          Returns an array of nine data points representing the calibration
353 *          matrix for the compass:
354 *          <center>C11 C12 C13</center>
355 *          <center>C21 C22 C23</center>
356 *          <center>C31 C32 C33</center>
357 *
358 *          - INV_PRESSURE :
359 *          Returns a single value representing the pressure in Pascal
360 *
361 *          - INV_HEADING :
362 *          Returns a single number representing the heading of the device
363 *          relative to the Earth, in which 0 represents North, 90 degrees
364 *          represents East, and so on.
365 *          The heading is defined as the direction of the +Y axis if the Y
366 *          axis is horizontal, and otherwise the direction of the -Z axis.
367 *
368 *          - INV_MAG_BIAS_ERROR :
369 *          Returns an array of three numbers representing the current estimated
370 *          error in the compass biases. These numbers are unitless and serve
371 *          as rough estimates in which numbers less than 100 typically represent
372 *          reasonably well calibrated compass axes.
373 *
374 *  @pre    MLDmpOpen() or MLDmpPedometerStandAloneOpen()
375 *          must have been called.
376 *
377 *  @param  dataSet
378 *              A constant specifying an array of data processed by
379 *              the motion processor.
380 *  @param  data
381 *              A pointer to an array to be passed back to the user.
382 *              <b>Must be 9 cells long at least</b>.
383 *
384 *  @return INV_SUCCESS if the command is successful; an error code otherwise.
385 */
386inv_error_t inv_get_float_array(int dataSet, float *data)
387{
388    inv_error_t result;
389    switch (dataSet) {
390    case INV_GYROS:
391        result = inv_get_gyro_float(data);
392        break;
393    case INV_ACCELS:
394        result = inv_get_accel_float(data);
395        break;
396    case INV_TEMPERATURE:
397        result = inv_get_temperature_float(data);
398        break;
399    case INV_ROTATION_MATRIX:
400        result = inv_get_rot_mat_float(data);
401        break;
402    case INV_QUATERNION:
403        result = inv_get_quaternion_float(data);
404        break;
405    case INV_LINEAR_ACCELERATION:
406        result = inv_get_linear_accel_float(data);
407        break;
408    case INV_LINEAR_ACCELERATION_WORLD:
409        result = inv_get_linear_accel_in_world_float(data);
410        break;
411    case INV_GRAVITY:
412        result = inv_get_gravity_float(data);
413        break;
414    case INV_ANGULAR_VELOCITY:
415        result = inv_get_angular_velocity_float(data);
416        break;
417    case INV_EULER_ANGLES:
418        result = inv_get_euler_angles_float(data);
419        break;
420    case INV_EULER_ANGLES_X:
421        result = inv_get_euler_angles_x_float(data);
422        break;
423    case INV_EULER_ANGLES_Y:
424        result = inv_get_euler_angles_y_float(data);
425        break;
426    case INV_EULER_ANGLES_Z:
427        result = inv_get_euler_angles_z_float(data);
428        break;
429    case INV_GYRO_TEMP_SLOPE:
430        result = inv_get_gyro_temp_slope_float(data);
431        break;
432    case INV_GYRO_BIAS:
433        result = inv_get_gyro_bias_float(data);
434        break;
435    case INV_ACCEL_BIAS:
436        result = inv_get_accel_bias_float(data);
437        break;
438    case INV_MAG_BIAS:
439        result = inv_get_mag_bias_float(data);
440        break;
441    case INV_RAW_DATA:
442        result = inv_get_gyro_and_accel_sensor_float(data);
443        break;
444    case INV_MAG_RAW_DATA:
445        result = inv_get_mag_raw_data_float(data);
446        break;
447    case INV_MAGNETOMETER:
448        result = inv_get_magnetometer_float(data);
449        break;
450    case INV_PRESSURE:
451        result = inv_get_pressure_float(data);
452        break;
453    case INV_HEADING:
454        result = inv_get_heading_float(data);
455        break;
456    case INV_GYRO_CALIBRATION_MATRIX:
457        result = inv_get_gyro_cal_matrix_float(data);
458        break;
459    case INV_ACCEL_CALIBRATION_MATRIX:
460        result = inv_get_accel_cal_matrix_float(data);
461        break;
462    case INV_MAG_CALIBRATION_MATRIX:
463        result = inv_get_mag_cal_matrix_float(data);
464        break;
465    case INV_MAG_BIAS_ERROR:
466        result = inv_get_mag_bias_error_float(data);
467        break;
468    case INV_MAG_SCALE:
469        result = inv_get_mag_scale_float(data);
470        break;
471    case INV_LOCAL_FIELD:
472        result = inv_get_local_field_float(data);
473        break;
474    case INV_RELATIVE_QUATERNION:
475        result = inv_get_relative_quaternion_float(data);
476        break;
477    default:
478        return INV_ERROR_INVALID_PARAMETER;
479        break;
480    }
481    return result;
482}
483
484/**
485 *  @brief  used to set an array of motion sensor data.
486 *          Handles the following data sets:
487 *          - INV_GYRO_BIAS
488 *          - INV_ACCEL_BIAS
489 *          - INV_MAG_BIAS
490 *          - INV_GYRO_TEMP_SLOPE
491 *
492 *          For more details about the use of the data sets
493 *          please refer to the documentation of inv_set_float_array().
494 *
495 *          Please also refer to the provided "9-Axis Sensor Fusion
496 *          Application Note" document provided.
497 *
498 *  @pre    MLDmpOpen() or
499 *          MLDmpPedometerStandAloneOpen()
500 *  @pre    MLDmpStart() must <b>NOT</b> have been called.
501 *
502 *  @param  dataSet     A constant specifying an array of data.
503 *  @param  data        A pointer to an array to be copied from the user.
504 *
505 *  @return INV_SUCCESS if successful; a non-zero error code otherwise.
506 */
507inv_error_t inv_set_array(int dataSet, long *data)
508{
509    INVENSENSE_FUNC_START;
510    inv_error_t result;
511    switch (dataSet) {
512    case INV_GYRO_BIAS:
513        result = inv_set_gyro_bias(data);
514        break;
515    case INV_ACCEL_BIAS:
516        result = inv_set_accel_bias(data);
517        break;
518    case INV_MAG_BIAS:
519        result = inv_set_mag_bias(data);
520        break;
521    case INV_GYRO_TEMP_SLOPE:
522        result = inv_set_gyro_temp_slope(data);
523        break;
524    case INV_LOCAL_FIELD:
525        result = inv_set_local_field(data);
526        break;
527    case INV_MAG_SCALE:
528        result = inv_set_mag_scale(data);
529        break;
530    default:
531        return INV_ERROR_INVALID_PARAMETER;
532        break;
533    }
534    return result;
535}
536
537/**
538 *  @brief  used to set an array of motion sensor data.
539 *          Handles various data sets:
540 *          - INV_GYRO_BIAS
541 *          - INV_ACCEL_BIAS
542 *          - INV_MAG_BIAS
543 *          - INV_GYRO_TEMP_SLOPE
544 *
545 *          Please refer to the provided "9-Axis Sensor Fusion Application
546 *          Note" document provided.
547 *
548 *  @pre    MLDmpOpen() or
549 *          MLDmpPedometerStandAloneOpen()
550 *  @pre    MLDmpStart() must <b>NOT</b> have been called.
551 *
552 *  @param  dataSet     A constant specifying an array of data.
553 *  @param  data        A pointer to an array to be copied from the user.
554 *
555 *  @return INV_SUCCESS if successful; a non-zero error code otherwise.
556 */
557inv_error_t inv_set_float_array(int dataSet, float *data)
558{
559    INVENSENSE_FUNC_START;
560    inv_error_t result;
561
562    switch (dataSet) {
563    case INV_GYRO_TEMP_SLOPE:  // internal
564        result = inv_set_gyro_temp_slope_float(data);
565        break;
566    case INV_GYRO_BIAS:        // internal
567        result = inv_set_gyro_bias_float(data);
568        break;
569    case INV_ACCEL_BIAS:       // internal
570        result = inv_set_accel_bias_float(data);
571        break;
572    case INV_MAG_BIAS:         // internal
573        result = inv_set_mag_bias_float(data);
574        break;
575    case INV_LOCAL_FIELD:      // internal
576        result = inv_set_local_field_float(data);
577        break;
578    case INV_MAG_SCALE:        // internal
579        result = inv_set_mag_scale_float(data);
580        break;
581    default:
582        result = INV_ERROR_INVALID_PARAMETER;
583        break;
584    }
585
586    return result;
587}
588