Home | History | Annotate | Download | only in mllite
      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.c 5085 2011-04-08 22:25:14Z phickey $
     21  *
     22  *****************************************************************************/
     23 
     24 /**
     25  *  @defgroup ML
     26  *  @{
     27  *      @file   mlarray.c
     28  *      @brief  APIs to read different data sets from FIFO.
     29  */
     30 
     31 /* ------------------ */
     32 /* - Include Files. - */
     33 /* ------------------ */
     34 #include "ml.h"
     35 #include "mltypes.h"
     36 #include "mlinclude.h"
     37 #include "mlMathFunc.h"
     38 #include "mlmath.h"
     39 #include "mlstates.h"
     40 #include "mlFIFO.h"
     41 #include "mlsupervisor.h"
     42 #include "mldl.h"
     43 #include "dmpKey.h"
     44 #include "compass.h"
     45 
     46 /**
     47  *  @brief  inv_get_gyro is used to get the most recent gyroscope measurement.
     48  *          The argument array elements are ordered X,Y,Z.
     49  *          The values are scaled at 1 dps = 2^16 LSBs.
     50  *
     51  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
     52  *          must have been called.
     53  *
     54  *  @param  data
     55  *              A pointer to an array to be passed back to the user.
     56  *              <b>Must be 3 cells long </b>.
     57  *
     58  *  @return Zero if the command is successful; an ML error code otherwise.
     59  */
     60 
     61  /* inv_get_gyro implemented in mlFIFO.c */
     62 
     63 /**
     64  *  @brief  inv_get_accel is used to get the most recent
     65  *          accelerometer measurement.
     66  *          The argument array elements are ordered X,Y,Z.
     67  *          The values are scaled in units of g (gravity),
     68  *          where 1 g = 2^16 LSBs.
     69  *
     70  *
     71  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
     72  *          must have been called.
     73  *
     74  *  @param  data
     75  *              A pointer to an array to be passed back to the user.
     76  *              <b>Must be 3 cells long </b>.
     77  *
     78  *  @return Zero if the command is successful; an ML error code otherwise.
     79  */
     80  /* inv_get_accel implemented in mlFIFO.c */
     81 
     82 /**
     83  *  @brief  inv_get_temperature is used to get the most recent
     84  *          temperature measurement.
     85  *          The argument array should only have one element.
     86  *          The value is in units of deg C (degrees Celsius), where
     87  *          2^16 LSBs = 1 deg C.
     88  *
     89  *
     90  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
     91  *          must have been called.
     92  *
     93  *  @param  data
     94  *              A pointer to the data to be passed back to the user.
     95  *
     96  *  @return Zero if the command is successful; an ML error code otherwise.
     97  */
     98  /* inv_get_temperature implemented in mlFIFO.c */
     99 
    100 /**
    101  *  @brief  inv_get_rot_mat is used to get the rotation matrix
    102  *          representation of the current sensor fusion solution.
    103  *          The array format will be R11, R12, R13, R21, R22, R23, R31, R32,
    104  *          R33, representing the matrix:
    105  *          <center>R11 R12 R13</center>
    106  *          <center>R21 R22 R23</center>
    107  *          <center>R31 R32 R33</center>
    108  *          Values are scaled, where 1.0 = 2^30 LSBs.
    109  *
    110  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    111  *          must have been called.
    112  *
    113  *  @param  data
    114  *              A pointer to an array to be passed back to the user.
    115  *              <b>Must be 9 cells long</b>.
    116  *
    117  *  @return Zero if the command is successful; an ML error code otherwise.
    118  */
    119 inv_error_t inv_get_rot_mat(long *data)
    120 {
    121     inv_error_t result = INV_SUCCESS;
    122     long qdata[4];
    123     if (inv_get_state() < INV_STATE_DMP_OPENED)
    124         return INV_ERROR_SM_IMPROPER_STATE;
    125 
    126     if (NULL == data) {
    127         return INV_ERROR_INVALID_PARAMETER;
    128     }
    129 
    130     inv_get_quaternion(qdata);
    131     inv_quaternion_to_rotation(qdata, data);
    132 
    133     return result;
    134 }
    135 
    136 /**
    137  *  @brief  inv_get_quaternion is used to get the quaternion representation
    138  *          of the current sensor fusion solution.
    139  *          The values are scaled where 1.0 = 2^30 LSBs.
    140  *
    141  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    142  *          must have been called.
    143  *
    144  *  @param  data
    145  *              A pointer to an array to be passed back to the user.
    146  *              <b>Must be 4 cells long </b>.
    147  *
    148  *  @return INV_SUCCESS if the command is successful; an ML error code otherwise.
    149  */
    150  /* inv_get_quaternion implemented in mlFIFO.c */
    151 
    152 /**
    153  *  @brief  inv_get_linear_accel is used to get an estimate of linear
    154  *          acceleration, based on the most recent accelerometer measurement
    155  *          and sensor fusion solution.
    156  *          The values are scaled where 1 g (gravity) = 2^16 LSBs.
    157  *
    158  *
    159  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    160  *          must have been called.
    161  *
    162  *  @param  data
    163  *              A pointer to an array to be passed back to the user.
    164  *              <b>Must be 3 cells long </b>.
    165  *
    166  *  @return Zero if the command is successful; an ML error code otherwise.
    167  */
    168  /* inv_get_linear_accel implemented in mlFIFO.c */
    169 
    170 /**
    171  *  @brief  inv_get_linear_accel_in_world is used to get an estimate of
    172  *          linear acceleration, in the world frame,  based on the most
    173  *          recent accelerometer measurement and sensor fusion solution.
    174  *          The values are scaled where 1 g (gravity) = 2^16 LSBs.
    175  *
    176  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    177  *          must have been called.
    178  *
    179  *  @param  data
    180  *              A pointer to an array to be passed back to the user.
    181  *              <b>Must be 3 cells long</b>.
    182  *
    183  *  @return Zero if the command is successful; an ML error code otherwise.
    184  */
    185  /* inv_get_linear_accel_in_world implemented in mlFIFO.c */
    186 
    187 /**
    188  *  @brief  inv_get_gravity is used to get an estimate of the body frame
    189  *          gravity vector, based on the most recent sensor fusion solution.
    190  *
    191  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    192  *          must have been called.
    193  *
    194  *  @param  data
    195  *              A pointer to an array to be passed back to the user.
    196  *              <b>Must be 3 cells long</b>.
    197  *
    198  *  @return Zero if the command is successful; an ML error code otherwise.
    199  */
    200  /* inv_get_gravity implemented in mlFIFO.c */
    201 
    202 /**
    203  *  @internal
    204  *  @brief  inv_get_angular_velocity is used to get an estimate of the body
    205  *          frame angular velocity, which is computed from the current and
    206  *          previous sensor fusion solutions.
    207  *
    208  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    209  *          must have been called.
    210  *
    211  *  @param  data
    212  *              A pointer to an array to be passed back to the user.
    213  *              <b>Must be 3 cells long </b>.
    214  *
    215  *  @return Zero if the command is successful; an ML error code otherwise.
    216  */
    217 inv_error_t inv_get_angular_velocity(long *data)
    218 {
    219 
    220     return INV_ERROR_FEATURE_NOT_IMPLEMENTED;
    221     /* not implemented. old (invalid) implementation:
    222        if ( inv_get_state() < INV_STATE_DMP_OPENED )
    223        return INV_ERROR_SM_IMPROPER_STATE;
    224 
    225        if (NULL == data) {
    226        return INV_ERROR_INVALID_PARAMETER;
    227        }
    228        data[0] = inv_obj.ang_v_body[0];
    229        data[1] = inv_obj.ang_v_body[1];
    230        data[2] = inv_obj.ang_v_body[2];
    231 
    232        return result;
    233      */
    234 }
    235 
    236 /**
    237  *  @brief  inv_get_euler_angles is used to get the Euler angle representation
    238  *          of the current sensor fusion solution.
    239  *          Euler angles may follow various conventions. This function is equivelant
    240  *          to inv_get_euler_angles_x, refer to inv_get_euler_angles_x for more
    241  *          information.
    242  *
    243  *
    244  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    245  *          must have been called.
    246  *
    247  *  @param  data
    248  *              A pointer to an array to be passed back to the user.
    249  *              <b>Must be 3 cells long </b>.
    250  *
    251  *  @return Zero if the command is successful; an ML error code otherwise.
    252  */
    253 inv_error_t inv_get_euler_angles(long *data)
    254 {
    255     return inv_get_euler_angles_x(data);
    256 }
    257 
    258 /**
    259  *  @brief  inv_get_euler_angles_x is used to get the Euler angle representation
    260  *          of the current sensor fusion solution.
    261  *          Euler angles are returned according to the X convention.
    262  *          This is typically the convention used for mobile devices where the X
    263  *          axis is the width of the screen, Y axis is the height, and Z the
    264  *          depth. In this case roll is defined as the rotation around the X
    265  *          axis of the device.
    266  *          <TABLE>
    267  *          <TR><TD>Element </TD><TD><b>Euler angle</b></TD><TD><b>Rotation about </b></TD></TR>
    268  *          <TR><TD> 0      </TD><TD>Roll              </TD><TD>X axis                </TD></TR>
    269  *          <TR><TD> 1      </TD><TD>Pitch             </TD><TD>Y axis                </TD></TR>
    270  *          <TR><TD> 2      </TD><TD>Yaw               </TD><TD>Z axis                </TD></TR>
    271  *          </TABLE>
    272  *
    273  *          Values are scaled where 1.0 = 2^16.
    274  *
    275  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    276  *          must have been called.
    277  *
    278  *  @param  data
    279  *              A pointer to an array to be passed back to the user.
    280  *              <b>Must be 3 cells long </b>.
    281  *
    282  *  @return Zero if the command is successful; an ML error code otherwise.
    283  */
    284 inv_error_t inv_get_euler_angles_x(long *data)
    285 {
    286     inv_error_t result = INV_SUCCESS;
    287     float rotMatrix[9];
    288     float tmp;
    289     if (inv_get_state() < INV_STATE_DMP_OPENED)
    290         return INV_ERROR_SM_IMPROPER_STATE;
    291 
    292     if (NULL == data) {
    293         return INV_ERROR_INVALID_PARAMETER;
    294     }
    295 
    296     result = inv_get_rot_mat_float(rotMatrix);
    297     tmp = rotMatrix[6];
    298     if (tmp > 1.0f) {
    299         tmp = 1.0f;
    300     }
    301     if (tmp < -1.0f) {
    302         tmp = -1.0f;
    303     }
    304     data[0] =
    305         (long)((float)
    306                (atan2f(rotMatrix[7], rotMatrix[8]) * 57.29577951308) *
    307                65536L);
    308     data[1] = (long)((float)((double)asin(tmp) * 57.29577951308) * 65536L);
    309     data[2] =
    310         (long)((float)
    311                (atan2f(rotMatrix[3], rotMatrix[0]) * 57.29577951308) *
    312                65536L);
    313     return result;
    314 }
    315 
    316 /**
    317  *  @brief  inv_get_euler_angles_y is used to get the Euler angle representation
    318  *          of the current sensor fusion solution.
    319  *          Euler angles are returned according to the Y convention.
    320  *          This convention is typically used in augmented reality applications,
    321  *          where roll is defined as the rotation around the axis along the
    322  *          height of the screen of a mobile device, namely the Y axis.
    323  *          <TABLE>
    324  *          <TR><TD>Element </TD><TD><b>Euler angle</b></TD><TD><b>Rotation about </b></TD></TR>
    325  *          <TR><TD> 0      </TD><TD>Roll              </TD><TD>Y axis                </TD></TR>
    326  *          <TR><TD> 1      </TD><TD>Pitch             </TD><TD>X axis                </TD></TR>
    327  *          <TR><TD> 2      </TD><TD>Yaw               </TD><TD>Z axis                </TD></TR>
    328  *          </TABLE>
    329  *
    330  *          Values are scaled where 1.0 = 2^16.
    331  *
    332  *
    333  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    334  *          must have been called.
    335  *
    336  *  @param  data
    337  *              A pointer to an array to be passed back to the user.
    338  *              <b>Must be 3 cells long</b>.
    339  *
    340  *  @return Zero if the command is successful; an ML error code otherwise.
    341  */
    342 inv_error_t inv_get_euler_angles_y(long *data)
    343 {
    344     inv_error_t result = INV_SUCCESS;
    345     float rotMatrix[9];
    346     float tmp;
    347     if (inv_get_state() < INV_STATE_DMP_OPENED)
    348         return INV_ERROR_SM_IMPROPER_STATE;
    349 
    350     if (NULL == data) {
    351         return INV_ERROR_INVALID_PARAMETER;
    352     }
    353 
    354     result = inv_get_rot_mat_float(rotMatrix);
    355     tmp = rotMatrix[7];
    356     if (tmp > 1.0f) {
    357         tmp = 1.0f;
    358     }
    359     if (tmp < -1.0f) {
    360         tmp = -1.0f;
    361     }
    362     data[0] =
    363         (long)((float)
    364                (atan2f(rotMatrix[8], rotMatrix[6]) * 57.29577951308f) *
    365                65536L);
    366     data[1] = (long)((float)((double)asin(tmp) * 57.29577951308) * 65536L);
    367     data[2] =
    368         (long)((float)
    369                (atan2f(rotMatrix[4], rotMatrix[1]) * 57.29577951308f) *
    370                65536L);
    371     return result;
    372 }
    373 
    374 /**  @brief  inv_get_euler_angles_z is used to get the Euler angle representation
    375  *          of the current sensor fusion solution.
    376  *          This convention is mostly used in application involving the use
    377  *          of a camera, typically placed on the back of a mobile device, that
    378  *          is along the Z axis.  In this convention roll is defined as the
    379  *          rotation around the Z axis.
    380  *          Euler angles are returned according to the Y convention.
    381  *          <TABLE>
    382  *          <TR><TD>Element </TD><TD><b>Euler angle</b></TD><TD><b>Rotation about </b></TD></TR>
    383  *          <TR><TD> 0      </TD><TD>Roll              </TD><TD>Z axis                </TD></TR>
    384  *          <TR><TD> 1      </TD><TD>Pitch             </TD><TD>X axis                </TD></TR>
    385  *          <TR><TD> 2      </TD><TD>Yaw               </TD><TD>Y axis                </TD></TR>
    386  *          </TABLE>
    387  *
    388  *          Values are scaled where 1.0 = 2^16.
    389  *
    390  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    391  *          must have been called.
    392  *
    393  *  @param  data
    394  *              A pointer to an array to be passed back to the user.
    395  *              <b>Must be 3 cells long</b>.
    396  *
    397  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
    398  */
    399 
    400 inv_error_t inv_get_euler_angles_z(long *data)
    401 {
    402     inv_error_t result = INV_SUCCESS;
    403     float rotMatrix[9];
    404     float tmp;
    405     if (inv_get_state() < INV_STATE_DMP_OPENED)
    406         return INV_ERROR_SM_IMPROPER_STATE;
    407 
    408     if (NULL == data) {
    409         return INV_ERROR_INVALID_PARAMETER;
    410     }
    411 
    412     result = inv_get_rot_mat_float(rotMatrix);
    413     tmp = rotMatrix[8];
    414     if (tmp > 1.0f) {
    415         tmp = 1.0f;
    416     }
    417     if (tmp < -1.0f) {
    418         tmp = -1.0f;
    419     }
    420     data[0] =
    421         (long)((float)
    422                (atan2f(rotMatrix[6], rotMatrix[7]) * 57.29577951308) *
    423                65536L);
    424     data[1] = (long)((float)((double)asin(tmp) * 57.29577951308) * 65536L);
    425     data[2] =
    426         (long)((float)
    427                (atan2f(rotMatrix[5], rotMatrix[2]) * 57.29577951308) *
    428                65536L);
    429     return result;
    430 }
    431 
    432 /**
    433  *  @brief  inv_get_gyro_temp_slope is used to get is used to get the temperature
    434  *          compensation algorithm's estimate of the gyroscope bias temperature
    435  *          coefficient.
    436  *          The argument array elements are ordered X,Y,Z.
    437  *          Values are in units of dps per deg C (degrees per second per degree
    438  *          Celcius). Values are scaled so that 1 dps per deg C = 2^16 LSBs.
    439  *          Please refer to the provided "9-Axis Sensor Fusion
    440  *          Application Note" document.
    441  *
    442  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    443  *          must have been called.
    444  *
    445  *  @param  data
    446  *              A pointer to an array to be passed back to the user.
    447  *              <b>Must be 3 cells long </b>.
    448  *
    449  *  @return Zero if the command is successful; an ML error code otherwise.
    450  */
    451 inv_error_t inv_get_gyro_temp_slope(long *data)
    452 {
    453     inv_error_t result = INV_SUCCESS;
    454     if (inv_get_state() < INV_STATE_DMP_OPENED)
    455         return INV_ERROR_SM_IMPROPER_STATE;
    456 
    457     if (NULL == data) {
    458         return INV_ERROR_INVALID_PARAMETER;
    459     }
    460     if (inv_params_obj.bias_mode & INV_LEARN_BIAS_FROM_TEMPERATURE) {
    461         data[0] = (long)(inv_obj.x_gyro_coef[1] * 65536.0f);
    462         data[1] = (long)(inv_obj.y_gyro_coef[1] * 65536.0f);
    463         data[2] = (long)(inv_obj.z_gyro_coef[1] * 65536.0f);
    464     } else {
    465         data[0] = inv_obj.temp_slope[0];
    466         data[1] = inv_obj.temp_slope[1];
    467         data[2] = inv_obj.temp_slope[2];
    468     }
    469     return result;
    470 }
    471 
    472 /**
    473  *  @brief  inv_get_gyro_bias is used to get the gyroscope biases.
    474  *          The argument array elements are ordered X,Y,Z.
    475  *          The values are scaled such that 1 dps = 2^16 LSBs.
    476  *
    477  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    478  *          must have been called.
    479  *
    480  *  @param  data
    481  *              A pointer to an array to be passed back to the user.
    482  *              <b>Must be 3 cells long</b>.
    483  *
    484  *  @return Zero if the command is successful; an ML error code otherwise.
    485  */
    486 inv_error_t inv_get_gyro_bias(long *data)
    487 {
    488     inv_error_t result = INV_SUCCESS;
    489     if (inv_get_state() < INV_STATE_DMP_OPENED)
    490         return INV_ERROR_SM_IMPROPER_STATE;
    491 
    492     if (NULL == data) {
    493         return INV_ERROR_INVALID_PARAMETER;
    494     }
    495     data[0] = inv_obj.gyro_bias[0];
    496     data[1] = inv_obj.gyro_bias[1];
    497     data[2] = inv_obj.gyro_bias[2];
    498 
    499     return result;
    500 }
    501 
    502 /**
    503  *  @brief  inv_get_accel_bias is used to get the accelerometer baises.
    504  *          The argument array elements are ordered X,Y,Z.
    505  *          The values are scaled such that 1 g (gravity) = 2^16 LSBs.
    506  *
    507  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    508  *          must have been called.
    509  *
    510  *  @param  data
    511  *              A pointer to an array to be passed back to the user.
    512  *              <b>Must be 3 cells long </b>.
    513  *
    514  *  @return Zero if the command is successful; an ML error code otherwise.
    515  */
    516 inv_error_t inv_get_accel_bias(long *data)
    517 {
    518     inv_error_t result = INV_SUCCESS;
    519     if (inv_get_state() < INV_STATE_DMP_OPENED)
    520         return INV_ERROR_SM_IMPROPER_STATE;
    521 
    522     if (NULL == data) {
    523         return INV_ERROR_INVALID_PARAMETER;
    524     }
    525     data[0] = inv_obj.accel_bias[0];
    526     data[1] = inv_obj.accel_bias[1];
    527     data[2] = inv_obj.accel_bias[2];
    528 
    529     return result;
    530 }
    531 
    532 /**
    533  *  @cond MPL
    534  *  @brief  inv_get_mag_bias is used to get Magnetometer Bias
    535  *
    536  *
    537  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    538  *          must have been called.
    539  *
    540  *  @param  data
    541  *              A pointer to an array to be passed back to the user.
    542  *              <b>Must be 3 cells long </b>.
    543  *
    544  *  @return Zero if the command is successful; an ML error code otherwise.
    545  *  @endcond
    546  */
    547 inv_error_t inv_get_mag_bias(long *data)
    548 {
    549     inv_error_t result = INV_SUCCESS;
    550     if (inv_get_state() < INV_STATE_DMP_OPENED)
    551         return INV_ERROR_SM_IMPROPER_STATE;
    552 
    553     if (NULL == data) {
    554         return INV_ERROR_INVALID_PARAMETER;
    555     }
    556     data[0] =
    557         inv_obj.compass_bias[0] +
    558         (long)((long long)inv_obj.init_compass_bias[0] * inv_obj.compass_sens /
    559                16384);
    560     data[1] =
    561         inv_obj.compass_bias[1] +
    562         (long)((long long)inv_obj.init_compass_bias[1] * inv_obj.compass_sens /
    563                16384);
    564     data[2] =
    565         inv_obj.compass_bias[2] +
    566         (long)((long long)inv_obj.init_compass_bias[2] * inv_obj.compass_sens /
    567                16384);
    568 
    569     return result;
    570 }
    571 
    572 /**
    573  *  @brief  inv_get_gyro_and_accel_sensor is used to get the most recent set of all sensor data.
    574  *          The argument array elements are ordered gyroscope X,Y, and Z,
    575  *          accelerometer X, Y, and Z, and magnetometer X,Y, and Z.
    576  *          \if UMPL The magnetometer elements are not populated in UMPL. \endif
    577  *          The gyroscope and accelerometer data is not scaled or offset, it is
    578  *          copied directly from the sensor registers.
    579  *          In the case of accelerometers with 8-bit output resolution, the data
    580  *          is scaled up to match the 2^14 = 1 g typical represntation of +/- 2 g
    581  *          full scale range
    582  *
    583  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    584  *          must have been called.
    585  *
    586  *  @param  data
    587  *              A pointer to an array to be passed back to the user.
    588  *              <b>Must be 9 cells long</b>.
    589  *
    590  *  @return Zero if the command is successful; an ML error code otherwise.
    591  */
    592  /* inv_get_gyro_and_accel_sensor implemented in mlFIFO.c */
    593 
    594 /**
    595  *  @cond MPL
    596  *  @brief  inv_get_mag_raw_data is used to get Raw magnetometer data.
    597  *
    598  *
    599  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    600  *          must have been called.
    601  *
    602  *  @param  data
    603  *              A pointer to an array to be passed back to the user.
    604  *              <b>Must be 3 cells long </b>.
    605  *
    606  *  @return Zero if the command is successful; an ML error code otherwise.
    607  *  @endcond
    608  */
    609 inv_error_t inv_get_mag_raw_data(long *data)
    610 {
    611     inv_error_t result = INV_SUCCESS;
    612     if (inv_get_state() < INV_STATE_DMP_OPENED)
    613         return INV_ERROR_SM_IMPROPER_STATE;
    614 
    615     if (NULL == data) {
    616         return INV_ERROR_INVALID_PARAMETER;
    617     }
    618 
    619     data[0] = inv_obj.compass_sensor_data[0];
    620     data[1] = inv_obj.compass_sensor_data[1];
    621     data[2] = inv_obj.compass_sensor_data[2];
    622 
    623     return result;
    624 }
    625 
    626 /**
    627  *  @cond MPL
    628  *  @brief  inv_get_magnetometer is used to get magnetometer data.
    629  *
    630  *
    631  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    632  *          must have been called.
    633  *
    634  *  @param  data
    635  *              A pointer to an array to be passed back to the user.
    636  *              <b>Must be 3 cells long</b>.
    637  *
    638  *  @return Zero if the command is successful; an ML error code otherwise.
    639  *  @endcond
    640  */
    641 inv_error_t inv_get_magnetometer(long *data)
    642 {
    643     inv_error_t result = INV_SUCCESS;
    644     if (inv_get_state() < INV_STATE_DMP_OPENED)
    645         return INV_ERROR_SM_IMPROPER_STATE;
    646 
    647     if (NULL == data) {
    648         return INV_ERROR_INVALID_PARAMETER;
    649     }
    650 
    651     data[0] = inv_obj.compass_sensor_data[0] + inv_obj.init_compass_bias[0];
    652     data[1] = inv_obj.compass_sensor_data[1] + inv_obj.init_compass_bias[1];
    653     data[2] = inv_obj.compass_sensor_data[2] + inv_obj.init_compass_bias[2];
    654 
    655     return result;
    656 }
    657 
    658 /**
    659  *  @cond MPL
    660  *  @brief  inv_get_pressure is used to get Pressure data.
    661  *
    662  *
    663  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    664  *          must have been called.
    665  *
    666  *  @param  data
    667  *              A pointer to data to be passed back to the user.
    668  *
    669  *  @return Zero if the command is successful; an ML error code otherwise.
    670  *  @endcond
    671  */
    672 inv_error_t inv_get_pressure(long *data)
    673 {
    674     inv_error_t result = INV_SUCCESS;
    675     if (inv_get_state() < INV_STATE_DMP_OPENED)
    676         return INV_ERROR_SM_IMPROPER_STATE;
    677 
    678     if (NULL == data) {
    679         return INV_ERROR_INVALID_PARAMETER;
    680     }
    681 
    682     data[0] = inv_obj.pressure;
    683 
    684     return result;
    685 }
    686 
    687 /**
    688  *  @cond MPL
    689  *  @brief  inv_get_heading is used to get heading from Rotation Matrix.
    690  *
    691  *
    692  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    693  *          must have been called.
    694  *
    695  *  @param  data
    696  *              A pointer to data to be passed back to the user.
    697  *
    698  *  @return Zero if the command is successful; an ML error code otherwise.
    699  *  @endcond
    700  */
    701 
    702 inv_error_t inv_get_heading(long *data)
    703 {
    704     inv_error_t result = INV_SUCCESS;
    705     float rotMatrix[9];
    706     float tmp;
    707     if (inv_get_state() < INV_STATE_DMP_OPENED)
    708         return INV_ERROR_SM_IMPROPER_STATE;
    709 
    710     if (NULL == data) {
    711         return INV_ERROR_INVALID_PARAMETER;
    712     }
    713     result = inv_get_rot_mat_float(rotMatrix);
    714     if ((rotMatrix[7] < 0.707) && (rotMatrix[7] > -0.707)) {
    715         tmp =
    716             (float)(atan2f(rotMatrix[4], rotMatrix[1]) * 57.29577951308 -
    717                     90.0f);
    718     } else {
    719         tmp =
    720             (float)(atan2f(rotMatrix[5], rotMatrix[2]) * 57.29577951308 +
    721                     90.0f);
    722     }
    723     if (tmp < 0) {
    724         tmp += 360.0f;
    725     }
    726     data[0] = (long)((360 - tmp) * 65536.0f);
    727 
    728     return result;
    729 }
    730 
    731 /**
    732  *  @brief  inv_get_gyro_cal_matrix is used to get the gyroscope
    733  *          calibration matrix. The gyroscope calibration matrix defines the relationship
    734  *          between the gyroscope sensor axes and the sensor fusion solution axes.
    735  *          Calibration matrix data members will have a value of 1, 0, or -1.
    736  *          The matrix has members
    737  *          <center>C11 C12 C13</center>
    738  *          <center>C21 C22 C23</center>
    739  *          <center>C31 C32 C33</center>
    740  *          The argument array elements are ordered C11, C12, C13, C21, C22, C23, C31, C32, C33.
    741  *
    742  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    743  *          must have been called.
    744  *
    745  *  @param  data
    746  *              A pointer to an array to be passed back to the user.
    747  *              <b>Must be 9 cells long</b>.
    748  *
    749  *  @return Zero if the command is successful; an ML error code otherwise.
    750  */
    751 inv_error_t inv_get_gyro_cal_matrix(long *data)
    752 {
    753     inv_error_t result = INV_SUCCESS;
    754     if (inv_get_state() < INV_STATE_DMP_OPENED)
    755         return INV_ERROR_SM_IMPROPER_STATE;
    756 
    757     if (NULL == data) {
    758         return INV_ERROR_INVALID_PARAMETER;
    759     }
    760 
    761     data[0] = inv_obj.gyro_cal[0];
    762     data[1] = inv_obj.gyro_cal[1];
    763     data[2] = inv_obj.gyro_cal[2];
    764     data[3] = inv_obj.gyro_cal[3];
    765     data[4] = inv_obj.gyro_cal[4];
    766     data[5] = inv_obj.gyro_cal[5];
    767     data[6] = inv_obj.gyro_cal[6];
    768     data[7] = inv_obj.gyro_cal[7];
    769     data[8] = inv_obj.gyro_cal[8];
    770 
    771     return result;
    772 }
    773 
    774 /**
    775  *  @brief  inv_get_accel_cal_matrix is used to get the accelerometer
    776  *          calibration matrix.
    777  *          Calibration matrix data members will have a value of 1, 0, or -1.
    778  *          The matrix has members
    779  *          <center>C11 C12 C13</center>
    780  *          <center>C21 C22 C23</center>
    781  *          <center>C31 C32 C33</center>
    782  *          The argument array elements are ordered C11, C12, C13, C21, C22, C23, C31, C32, C33.
    783  *
    784  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    785  *
    786  *
    787  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    788  *          must have been called.
    789  *
    790  *  @param  data
    791  *              A pointer to an array to be passed back to the user.
    792  *              <b>Must be 9 cells long</b>.
    793  *
    794  *  @return Zero if the command is successful; an ML error code otherwise.
    795  */
    796 inv_error_t inv_get_accel_cal_matrix(long *data)
    797 {
    798     inv_error_t result = INV_SUCCESS;
    799     if (inv_get_state() < INV_STATE_DMP_OPENED)
    800         return INV_ERROR_SM_IMPROPER_STATE;
    801 
    802     if (NULL == data) {
    803         return INV_ERROR_INVALID_PARAMETER;
    804     }
    805 
    806     data[0] = inv_obj.accel_cal[0];
    807     data[1] = inv_obj.accel_cal[1];
    808     data[2] = inv_obj.accel_cal[2];
    809     data[3] = inv_obj.accel_cal[3];
    810     data[4] = inv_obj.accel_cal[4];
    811     data[5] = inv_obj.accel_cal[5];
    812     data[6] = inv_obj.accel_cal[6];
    813     data[7] = inv_obj.accel_cal[7];
    814     data[8] = inv_obj.accel_cal[8];
    815 
    816     return result;
    817 }
    818 
    819 /**
    820  *  @cond MPL
    821  *  @brief  inv_get_mag_cal_matrix is used to get magnetometer calibration matrix.
    822  *
    823  *
    824  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    825  *          must have been called.
    826  *
    827  *  @param  data
    828  *              A pointer to an array to be passed back to the user.
    829  *              <b>Must be 9 cells long at least</b>.
    830  *
    831  *  @return Zero if the command is successful; an ML error code otherwise.
    832  *  @endcond
    833  */
    834 inv_error_t inv_get_mag_cal_matrix(long *data)
    835 {
    836     inv_error_t result = INV_SUCCESS;
    837     if (inv_get_state() < INV_STATE_DMP_OPENED)
    838         return INV_ERROR_SM_IMPROPER_STATE;
    839 
    840     if (NULL == data) {
    841         return INV_ERROR_INVALID_PARAMETER;
    842     }
    843 
    844     data[0] = inv_obj.compass_cal[0];
    845     data[1] = inv_obj.compass_cal[1];
    846     data[2] = inv_obj.compass_cal[2];
    847     data[3] = inv_obj.compass_cal[3];
    848     data[4] = inv_obj.compass_cal[4];
    849     data[5] = inv_obj.compass_cal[5];
    850     data[6] = inv_obj.compass_cal[6];
    851     data[7] = inv_obj.compass_cal[7];
    852     data[8] = inv_obj.compass_cal[8];
    853 
    854     return result;
    855 }
    856 
    857 /**
    858  *  @cond MPL
    859  *  @brief  inv_get_mag_bias_error is used to get magnetometer Bias error.
    860  *
    861  *
    862  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    863  *          must have been called.
    864  *
    865  *  @param  data
    866  *              A pointer to an array to be passed back to the user.
    867  *              <b>Must be 3 cells long at least</b>.
    868  *
    869  *  @return Zero if the command is successful; an ML error code otherwise.
    870  *  @endcond
    871  */
    872 inv_error_t inv_get_mag_bias_error(long *data)
    873 {
    874     inv_error_t result = INV_SUCCESS;
    875     if (inv_get_state() < INV_STATE_DMP_OPENED)
    876         return INV_ERROR_SM_IMPROPER_STATE;
    877 
    878     if (NULL == data) {
    879         return INV_ERROR_INVALID_PARAMETER;
    880     }
    881     if (inv_obj.large_field == 0) {
    882         data[0] = inv_obj.compass_bias_error[0];
    883         data[1] = inv_obj.compass_bias_error[1];
    884         data[2] = inv_obj.compass_bias_error[2];
    885     } else {
    886         data[0] = P_INIT;
    887         data[1] = P_INIT;
    888         data[2] = P_INIT;
    889     }
    890 
    891     return result;
    892 }
    893 
    894 /**
    895  *  @cond MPL
    896  *  @brief  inv_get_mag_scale is used to get magnetometer scale.
    897  *
    898  *
    899  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    900  *          must have been called.
    901  *
    902  *  @param  data
    903  *              A pointer to an array to be passed back to the user.
    904  *              <b>Must be 3 cells long at least</b>.
    905  *
    906  *  @return Zero if the command is successful; an ML error code otherwise.
    907  *  @endcond
    908  */
    909 inv_error_t inv_get_mag_scale(long *data)
    910 {
    911     inv_error_t result = INV_SUCCESS;
    912     if (inv_get_state() < INV_STATE_DMP_OPENED)
    913         return INV_ERROR_SM_IMPROPER_STATE;
    914 
    915     if (NULL == data) {
    916         return INV_ERROR_INVALID_PARAMETER;
    917     }
    918 
    919     data[0] = inv_obj.compass_scale[0];
    920     data[1] = inv_obj.compass_scale[1];
    921     data[2] = inv_obj.compass_scale[2];
    922 
    923     return result;
    924 }
    925 
    926 /**
    927  *  @cond MPL
    928  *  @brief  inv_get_local_field is used to get local magnetic field data.
    929  *
    930  *
    931  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    932  *          must have been called.
    933  *
    934  *  @param  data
    935  *              A pointer to an array to be passed back to the user.
    936  *              <b>Must be 3 cells long at least</b>.
    937  *
    938  *  @return Zero if the command is successful; an ML error code otherwise.
    939  *  @endcond
    940  */
    941 inv_error_t inv_get_local_field(long *data)
    942 {
    943     inv_error_t result = INV_SUCCESS;
    944     if (inv_get_state() < INV_STATE_DMP_OPENED)
    945         return INV_ERROR_SM_IMPROPER_STATE;
    946 
    947     if (NULL == data) {
    948         return INV_ERROR_INVALID_PARAMETER;
    949     }
    950 
    951     data[0] = inv_obj.local_field[0];
    952     data[1] = inv_obj.local_field[1];
    953     data[2] = inv_obj.local_field[2];
    954 
    955     return result;
    956 }
    957 
    958 /**
    959  *  @cond MPL
    960  *  @brief  inv_get_relative_quaternion is used to get relative quaternion.
    961  *
    962  *
    963  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    964  *          must have been called.
    965  *
    966  *  @param  data
    967  *              A pointer to an array to be passed back to the user.
    968  *              <b>Must be 4 cells long at least</b>.
    969  *
    970  *  @return Zero if the command is successful; an ML error code otherwise.
    971  *  @endcond
    972  */
    973 /* inv_get_relative_quaternion implemented in mlFIFO.c */
    974 
    975 /**
    976  *  @brief  inv_get_gyro_float is used to get the most recent gyroscope measurement.
    977  *          The argument array elements are ordered X,Y,Z.
    978  *          The values are in units of dps (degrees per second).
    979  *
    980  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
    981  *          must have been called.
    982  *
    983  *  @param  data
    984  *              A pointer to an array to be passed back to the user.
    985  *              <b>Must be 3 cells long</b>.
    986  *
    987  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
    988  */
    989 inv_error_t inv_get_gyro_float(float *data)
    990 {
    991     INVENSENSE_FUNC_START;
    992 
    993     inv_error_t result = INV_SUCCESS;
    994     long ldata[3];
    995 
    996     if (inv_get_state() < INV_STATE_DMP_OPENED)
    997         return INV_ERROR_SM_IMPROPER_STATE;
    998 
    999     if (NULL == data) {
   1000         return INV_ERROR_INVALID_PARAMETER;
   1001     }
   1002     result = inv_get_gyro(ldata);
   1003     data[0] = (float)ldata[0] / 65536.0f;
   1004     data[1] = (float)ldata[1] / 65536.0f;
   1005     data[2] = (float)ldata[2] / 65536.0f;
   1006 
   1007     return result;
   1008 }
   1009 
   1010 /**
   1011  *  @internal
   1012  *  @brief  inv_get_angular_velocity_float is used to get an array of three data points representing the angular
   1013  *          velocity as derived from <b>both</b> gyroscopes and accelerometers.
   1014  *          This requires that ML_SENSOR_FUSION be enabled, to fuse data from
   1015  *          the gyroscope and accelerometer device, appropriately scaled and
   1016  *          oriented according to the respective mounting matrices.
   1017  *
   1018  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1019  *          must have been called.
   1020  *  @param  data
   1021  *              A pointer to an array to be passed back to the user.
   1022  *              <b>Must be 3 cells long</b>.
   1023  *
   1024  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1025  */
   1026 inv_error_t inv_get_angular_velocity_float(float *data)
   1027 {
   1028     return INV_ERROR_FEATURE_NOT_IMPLEMENTED;
   1029     /* not implemented. old (invalid) implementation:
   1030        return inv_get_gyro_float(data);
   1031      */
   1032 }
   1033 
   1034 /**
   1035  *  @brief  inv_get_accel_float is used to get the most recent accelerometer measurement.
   1036  *          The argument array elements are ordered X,Y,Z.
   1037  *          The values are in units of g (gravity).
   1038  *
   1039  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1040  *          must have been called.
   1041  *
   1042  *  @param  data
   1043  *              A pointer to an array to be passed back to the user.
   1044  *              <b>Must be 3 cells long</b>.
   1045  *
   1046  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1047  */
   1048  /* inv_get_accel_float implemented in mlFIFO.c */
   1049 
   1050 /**
   1051  *  @brief  inv_get_temperature_float is used to get the most recent
   1052  *          temperature measurement.
   1053  *          The argument array should only have one element.
   1054  *          The value is in units of deg C (degrees Celsius).
   1055  *
   1056  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1057  *          must have been called.
   1058  *
   1059  *  @param  data
   1060  *              A pointer to data to be passed back to the user.
   1061  *
   1062  *  @return Zero if the command is successful; an ML error code otherwise.
   1063  */
   1064 inv_error_t inv_get_temperature_float(float *data)
   1065 {
   1066     INVENSENSE_FUNC_START;
   1067 
   1068     inv_error_t result = INV_SUCCESS;
   1069     long ldata[1];
   1070 
   1071     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1072         return INV_ERROR_SM_IMPROPER_STATE;
   1073 
   1074     if (NULL == data) {
   1075         return INV_ERROR_INVALID_PARAMETER;
   1076     }
   1077 
   1078     result = inv_get_temperature(ldata);
   1079     data[0] = (float)ldata[0] / 65536.0f;
   1080 
   1081     return result;
   1082 }
   1083 
   1084 /**
   1085  *  @brief  inv_get_rot_mat_float is used to get an array of nine data points representing the rotation
   1086  *          matrix generated from all available sensors.
   1087  *          The array format will be R11, R12, R13, R21, R22, R23, R31, R32,
   1088  *          R33, representing the matrix:
   1089  *          <center>R11 R12 R13</center>
   1090  *          <center>R21 R22 R23</center>
   1091  *          <center>R31 R32 R33</center>
   1092  *          <b>Please refer to the "9-Axis Sensor Fusion Application Note" document,
   1093  *          section 7 "Sensor Fusion Output", for details regarding rotation
   1094  *          matrix output</b>.
   1095  *
   1096  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1097  *          must have been called.
   1098  *
   1099  *  @param  data
   1100  *              A pointer to an array to be passed back to the user.
   1101  *              <b>Must be 9 cells long at least</b>.
   1102  *
   1103  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1104  */
   1105 inv_error_t inv_get_rot_mat_float(float *data)
   1106 {
   1107     INVENSENSE_FUNC_START;
   1108 
   1109     inv_error_t result = INV_SUCCESS;
   1110 
   1111     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1112         return INV_ERROR_SM_IMPROPER_STATE;
   1113 
   1114     if (NULL == data) {
   1115         return INV_ERROR_INVALID_PARAMETER;
   1116     }
   1117     {
   1118         long qdata[4], rdata[9];
   1119         inv_get_quaternion(qdata);
   1120         inv_quaternion_to_rotation(qdata, rdata);
   1121         data[0] = (float)rdata[0] / 1073741824.0f;
   1122         data[1] = (float)rdata[1] / 1073741824.0f;
   1123         data[2] = (float)rdata[2] / 1073741824.0f;
   1124         data[3] = (float)rdata[3] / 1073741824.0f;
   1125         data[4] = (float)rdata[4] / 1073741824.0f;
   1126         data[5] = (float)rdata[5] / 1073741824.0f;
   1127         data[6] = (float)rdata[6] / 1073741824.0f;
   1128         data[7] = (float)rdata[7] / 1073741824.0f;
   1129         data[8] = (float)rdata[8] / 1073741824.0f;
   1130     }
   1131 
   1132     return result;
   1133 }
   1134 
   1135 /**
   1136  *  @brief  inv_get_quaternion_float is used to get the quaternion representation
   1137  *          of the current sensor fusion solution.
   1138  *
   1139  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1140  *          must have been called.
   1141  *
   1142  *  @param  data
   1143  *              A pointer to an array to be passed back to the user.
   1144  *              <b>Must be 4 cells long</b>.
   1145  *
   1146  *  @return INV_SUCCESS if the command is successful; an ML error code otherwise.
   1147  */
   1148  /* inv_get_quaternion_float implemented in mlFIFO.c */
   1149 
   1150 /**
   1151  *  @brief  inv_get_linear_accel_float is used to get an estimate of linear
   1152  *          acceleration, based on the most recent accelerometer measurement
   1153  *          and sensor fusion solution.
   1154  *          The values are in units of g (gravity).
   1155  *
   1156  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1157  *          must have been called.
   1158  *
   1159  *  @param  data
   1160  *              A pointer to an array to be passed back to the user.
   1161  *              <b>Must be 3 cells long</b>.
   1162  *
   1163  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1164  */
   1165 inv_error_t inv_get_linear_accel_float(float *data)
   1166 {
   1167     INVENSENSE_FUNC_START;
   1168 
   1169     inv_error_t result = INV_SUCCESS;
   1170     long ldata[3];
   1171 
   1172     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1173         return INV_ERROR_SM_IMPROPER_STATE;
   1174 
   1175     if (NULL == data) {
   1176         return INV_ERROR_INVALID_PARAMETER;
   1177     }
   1178 
   1179     result = inv_get_linear_accel(ldata);
   1180     data[0] = (float)ldata[0] / 65536.0f;
   1181     data[1] = (float)ldata[1] / 65536.0f;
   1182     data[2] = (float)ldata[2] / 65536.0f;
   1183 
   1184     return result;
   1185 }
   1186 
   1187 /**
   1188  *  @brief  inv_get_linear_accel_in_world_float is used to get an estimate of
   1189  *          linear acceleration, in the world frame,  based on the most
   1190  *          recent accelerometer measurement and sensor fusion solution.
   1191  *          The values are in units of g (gravity).
   1192  *
   1193  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1194  *          must have been called.
   1195  *
   1196  *  @param  data
   1197  *              A pointer to an array to be passed back to the user.
   1198  *              <b>Must be 3 cells long</b>.
   1199  *
   1200  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1201  */
   1202 inv_error_t inv_get_linear_accel_in_world_float(float *data)
   1203 {
   1204     INVENSENSE_FUNC_START;
   1205 
   1206     inv_error_t result = INV_SUCCESS;
   1207     long ldata[3];
   1208 
   1209     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1210         return INV_ERROR_SM_IMPROPER_STATE;
   1211 
   1212     if (NULL == data) {
   1213         return INV_ERROR_INVALID_PARAMETER;
   1214     }
   1215 
   1216     result = inv_get_linear_accel_in_world(ldata);
   1217     data[0] = (float)ldata[0] / 65536.0f;
   1218     data[1] = (float)ldata[1] / 65536.0f;
   1219     data[2] = (float)ldata[2] / 65536.0f;
   1220 
   1221     return result;
   1222 }
   1223 
   1224 /**
   1225  *  @brief  inv_get_gravity_float is used to get an estimate of the body frame
   1226  *          gravity vector, based on the most recent sensor fusion solution.
   1227  *
   1228  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1229  *          must have been called.
   1230  *
   1231  *  @param  data
   1232  *              A pointer to an array to be passed back to the user.
   1233  *              <b>Must be 3 cells long at least</b>.
   1234  *
   1235  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1236  */
   1237 inv_error_t inv_get_gravity_float(float *data)
   1238 {
   1239     INVENSENSE_FUNC_START;
   1240 
   1241     inv_error_t result = INV_SUCCESS;
   1242     long ldata[3];
   1243 
   1244     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1245         return INV_ERROR_SM_IMPROPER_STATE;
   1246 
   1247     if (NULL == data) {
   1248         return INV_ERROR_INVALID_PARAMETER;
   1249     }
   1250     result = inv_get_gravity(ldata);
   1251     data[0] = (float)ldata[0] / 65536.0f;
   1252     data[1] = (float)ldata[1] / 65536.0f;
   1253     data[2] = (float)ldata[2] / 65536.0f;
   1254 
   1255     return result;
   1256 }
   1257 
   1258 /**
   1259  *  @brief  inv_get_gyro_cal_matrix_float is used to get the gyroscope
   1260  *          calibration matrix. The gyroscope calibration matrix defines the relationship
   1261  *          between the gyroscope sensor axes and the sensor fusion solution axes.
   1262  *          Calibration matrix data members will have a value of 1.0, 0, or -1.0.
   1263  *          The matrix has members
   1264  *          <center>C11 C12 C13</center>
   1265  *          <center>C21 C22 C23</center>
   1266  *          <center>C31 C32 C33</center>
   1267  *          The argument array elements are ordered C11, C12, C13, C21, C22, C23, C31, C32, C33.
   1268  *
   1269  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1270  *          must have been called.
   1271  *
   1272  *  @param  data
   1273  *              A pointer to an array to be passed back to the user.
   1274  *              <b>Must be 9 cells long</b>.
   1275  *
   1276  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1277  */
   1278 inv_error_t inv_get_gyro_cal_matrix_float(float *data)
   1279 {
   1280     INVENSENSE_FUNC_START;
   1281 
   1282     inv_error_t result = INV_SUCCESS;
   1283 
   1284     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1285         return INV_ERROR_SM_IMPROPER_STATE;
   1286 
   1287     if (NULL == data) {
   1288         return INV_ERROR_INVALID_PARAMETER;
   1289     }
   1290 
   1291     data[0] = (float)inv_obj.gyro_cal[0] / 1073741824.0f;
   1292     data[1] = (float)inv_obj.gyro_cal[1] / 1073741824.0f;
   1293     data[2] = (float)inv_obj.gyro_cal[2] / 1073741824.0f;
   1294     data[3] = (float)inv_obj.gyro_cal[3] / 1073741824.0f;
   1295     data[4] = (float)inv_obj.gyro_cal[4] / 1073741824.0f;
   1296     data[5] = (float)inv_obj.gyro_cal[5] / 1073741824.0f;
   1297     data[6] = (float)inv_obj.gyro_cal[6] / 1073741824.0f;
   1298     data[7] = (float)inv_obj.gyro_cal[7] / 1073741824.0f;
   1299     data[8] = (float)inv_obj.gyro_cal[8] / 1073741824.0f;
   1300 
   1301     return result;
   1302 }
   1303 
   1304 /**
   1305  *  @brief  inv_get_accel_cal_matrix_float is used to get the accelerometer
   1306  *          calibration matrix.
   1307  *          Calibration matrix data members will have a value of 1.0, 0, or -1.0.
   1308  *          The matrix has members
   1309  *          <center>C11 C12 C13</center>
   1310  *          <center>C21 C22 C23</center>
   1311  *          <center>C31 C32 C33</center>
   1312  *          The argument array elements are ordered C11, C12, C13, C21, C22, C23, C31, C32, C33.
   1313  *
   1314  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1315  *          must have been called.
   1316  *
   1317  *  @param  data
   1318  *              A pointer to an array to be passed back to the user.
   1319  *              <b>Must be 9 cells long</b>.
   1320  *
   1321  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1322  */
   1323 
   1324 inv_error_t inv_get_accel_cal_matrix_float(float *data)
   1325 {
   1326     INVENSENSE_FUNC_START;
   1327 
   1328     inv_error_t result = INV_SUCCESS;
   1329 
   1330     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1331         return INV_ERROR_SM_IMPROPER_STATE;
   1332 
   1333     if (NULL == data) {
   1334         return INV_ERROR_INVALID_PARAMETER;
   1335     }
   1336 
   1337     data[0] = (float)inv_obj.accel_cal[0] / 1073741824.0f;
   1338     data[1] = (float)inv_obj.accel_cal[1] / 1073741824.0f;
   1339     data[2] = (float)inv_obj.accel_cal[2] / 1073741824.0f;
   1340     data[3] = (float)inv_obj.accel_cal[3] / 1073741824.0f;
   1341     data[4] = (float)inv_obj.accel_cal[4] / 1073741824.0f;
   1342     data[5] = (float)inv_obj.accel_cal[5] / 1073741824.0f;
   1343     data[6] = (float)inv_obj.accel_cal[6] / 1073741824.0f;
   1344     data[7] = (float)inv_obj.accel_cal[7] / 1073741824.0f;
   1345     data[8] = (float)inv_obj.accel_cal[8] / 1073741824.0f;
   1346 
   1347     return result;
   1348 }
   1349 
   1350 /**
   1351  *  @cond MPL
   1352  *  @brief  inv_get_mag_cal_matrix_float is used to get an array of nine data points
   1353  *			representing the calibration matrix for the compass:
   1354  *          <center>C11 C12 C13</center>
   1355  *          <center>C21 C22 C23</center>
   1356  *          <center>C31 C32 C33</center>
   1357  *
   1358  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1359  *          must have been called.
   1360  *
   1361  *  @param  data
   1362  *              A pointer to an array to be passed back to the user.
   1363  *              <b>Must be 9 cells long at least</b>.
   1364  *
   1365  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1366  *  @endcond
   1367  */
   1368 inv_error_t inv_get_mag_cal_matrix_float(float *data)
   1369 {
   1370     INVENSENSE_FUNC_START;
   1371 
   1372     inv_error_t result = INV_SUCCESS;
   1373 
   1374     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1375         return INV_ERROR_SM_IMPROPER_STATE;
   1376 
   1377     if (NULL == data) {
   1378         return INV_ERROR_INVALID_PARAMETER;
   1379     }
   1380 
   1381     data[0] = (float)inv_obj.compass_cal[0] / 1073741824.0f;
   1382     data[1] = (float)inv_obj.compass_cal[1] / 1073741824.0f;
   1383     data[2] = (float)inv_obj.compass_cal[2] / 1073741824.0f;
   1384     data[3] = (float)inv_obj.compass_cal[3] / 1073741824.0f;
   1385     data[4] = (float)inv_obj.compass_cal[4] / 1073741824.0f;
   1386     data[5] = (float)inv_obj.compass_cal[5] / 1073741824.0f;
   1387     data[6] = (float)inv_obj.compass_cal[6] / 1073741824.0f;
   1388     data[7] = (float)inv_obj.compass_cal[7] / 1073741824.0f;
   1389     data[8] = (float)inv_obj.compass_cal[8] / 1073741824.0f;
   1390     return result;
   1391 }
   1392 
   1393 /**
   1394  *  @brief  inv_get_gyro_temp_slope_float is used to get the temperature
   1395  *          compensation algorithm's estimate of the gyroscope bias temperature
   1396  *          coefficient.
   1397  *          The argument array elements are ordered X,Y,Z.
   1398  *          Values are in units of dps per deg C (degrees per second per degree
   1399  *          Celcius)
   1400  *          Please refer to the provided "9-Axis Sensor Fusion
   1401  *          Application Note" document.
   1402  *
   1403  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1404  *          must have been called.
   1405  *
   1406  *  @param  data
   1407  *              A pointer to an array to be passed back to the user.
   1408  *              <b>Must be 3 cells long </b>.
   1409  *
   1410  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1411  */
   1412 inv_error_t inv_get_gyro_temp_slope_float(float *data)
   1413 {
   1414     INVENSENSE_FUNC_START;
   1415 
   1416     inv_error_t result = INV_SUCCESS;
   1417 
   1418     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1419         return INV_ERROR_SM_IMPROPER_STATE;
   1420 
   1421     if (NULL == data) {
   1422         return INV_ERROR_INVALID_PARAMETER;
   1423     }
   1424 
   1425     if (inv_params_obj.bias_mode & INV_LEARN_BIAS_FROM_TEMPERATURE) {
   1426         data[0] = inv_obj.x_gyro_coef[1];
   1427         data[1] = inv_obj.y_gyro_coef[1];
   1428         data[2] = inv_obj.z_gyro_coef[1];
   1429     } else {
   1430         data[0] = (float)inv_obj.temp_slope[0] / 65536.0f;
   1431         data[1] = (float)inv_obj.temp_slope[1] / 65536.0f;
   1432         data[2] = (float)inv_obj.temp_slope[2] / 65536.0f;
   1433     }
   1434 
   1435     return result;
   1436 }
   1437 
   1438 /**
   1439  *  @brief  inv_get_gyro_bias_float is used to get the gyroscope biases.
   1440  *          The argument array elements are ordered X,Y,Z.
   1441  *          The values are in units of dps (degrees per second).
   1442 
   1443  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1444  *          must have been called.
   1445  *
   1446  *  @param  data
   1447  *              A pointer to an array to be passed back to the user.
   1448  *              <b>Must be 3 cells long</b>.
   1449  *
   1450  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1451  */
   1452 inv_error_t inv_get_gyro_bias_float(float *data)
   1453 {
   1454     INVENSENSE_FUNC_START;
   1455 
   1456     inv_error_t result = INV_SUCCESS;
   1457 
   1458     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1459         return INV_ERROR_SM_IMPROPER_STATE;
   1460 
   1461     if (NULL == data) {
   1462         return INV_ERROR_INVALID_PARAMETER;
   1463     }
   1464 
   1465     data[0] = (float)inv_obj.gyro_bias[0] / 65536.0f;
   1466     data[1] = (float)inv_obj.gyro_bias[1] / 65536.0f;
   1467     data[2] = (float)inv_obj.gyro_bias[2] / 65536.0f;
   1468 
   1469     return result;
   1470 }
   1471 
   1472 /**
   1473  *  @brief  inv_get_accel_bias_float is used to get the accelerometer baises.
   1474  *          The argument array elements are ordered X,Y,Z.
   1475  *          The values are in units of g (gravity).
   1476  *
   1477  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1478  *          must have been called.
   1479  *
   1480  *  @param  data
   1481  *              A pointer to an array to be passed back to the user.
   1482  *              <b>Must be 3 cells long</b>.
   1483  *
   1484  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1485  */
   1486 inv_error_t inv_get_accel_bias_float(float *data)
   1487 {
   1488     INVENSENSE_FUNC_START;
   1489 
   1490     inv_error_t result = INV_SUCCESS;
   1491 
   1492     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1493         return INV_ERROR_SM_IMPROPER_STATE;
   1494 
   1495     if (NULL == data) {
   1496         return INV_ERROR_INVALID_PARAMETER;
   1497     }
   1498 
   1499     data[0] = (float)inv_obj.accel_bias[0] / 65536.0f;
   1500     data[1] = (float)inv_obj.accel_bias[1] / 65536.0f;
   1501     data[2] = (float)inv_obj.accel_bias[2] / 65536.0f;
   1502 
   1503     return result;
   1504 }
   1505 
   1506 /**
   1507  *  @cond MPL
   1508  *  @brief  inv_get_mag_bias_float is used to get an array of three data points representing
   1509  *			the compass biases.
   1510  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1511  *          must have been called.
   1512  *
   1513  *  @param  data
   1514  *              A pointer to an array to be passed back to the user.
   1515  *              <b>Must be 3 cells long</b>.
   1516  *
   1517  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1518  *  @endcond
   1519  */
   1520 inv_error_t inv_get_mag_bias_float(float *data)
   1521 {
   1522     INVENSENSE_FUNC_START;
   1523 
   1524     inv_error_t result = INV_SUCCESS;
   1525 
   1526     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1527         return INV_ERROR_SM_IMPROPER_STATE;
   1528 
   1529     if (NULL == data) {
   1530         return INV_ERROR_INVALID_PARAMETER;
   1531     }
   1532 
   1533     data[0] =
   1534         ((float)
   1535          (inv_obj.compass_bias[0] +
   1536           (long)((long long)inv_obj.init_compass_bias[0] *
   1537                  inv_obj.compass_sens / 16384))) / 65536.0f;
   1538     data[1] =
   1539         ((float)
   1540          (inv_obj.compass_bias[1] +
   1541           (long)((long long)inv_obj.init_compass_bias[1] *
   1542                  inv_obj.compass_sens / 16384))) / 65536.0f;
   1543     data[2] =
   1544         ((float)
   1545          (inv_obj.compass_bias[2] +
   1546           (long)((long long)inv_obj.init_compass_bias[2] *
   1547                  inv_obj.compass_sens / 16384))) / 65536.0f;
   1548 
   1549     return result;
   1550 }
   1551 
   1552 /**
   1553  *  @brief  inv_get_gyro_and_accel_sensor_float is used to get the most recent set of all sensor data.
   1554  *          The argument array elements are ordered gyroscope X,Y, and Z,
   1555  *          accelerometer X, Y, and Z, and magnetometer X,Y, and Z.
   1556  *          \if UMPL The magnetometer elements are not populated in UMPL. \endif
   1557  *          The gyroscope and accelerometer data is not scaled or offset, it is
   1558  *          copied directly from the sensor registers, and cast as a float.
   1559  *          In the case of accelerometers with 8-bit output resolution, the data
   1560  *          is scaled up to match the 2^14 = 1 g typical represntation of +/- 2 g
   1561  *          full scale range
   1562 
   1563  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1564  *          must have been called.
   1565  *
   1566  *  @param  data
   1567  *              A pointer to an array to be passed back to the user.
   1568  *              <b>Must be 9 cells long</b>.
   1569  *
   1570  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1571  */
   1572 inv_error_t inv_get_gyro_and_accel_sensor_float(float *data)
   1573 {
   1574     INVENSENSE_FUNC_START;
   1575 
   1576     inv_error_t result = INV_SUCCESS;
   1577     long ldata[6];
   1578 
   1579     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1580         return INV_ERROR_SM_IMPROPER_STATE;
   1581 
   1582     if (NULL == data) {
   1583         return INV_ERROR_INVALID_PARAMETER;
   1584     }
   1585 
   1586     result = inv_get_gyro_and_accel_sensor(ldata);
   1587     data[0] = (float)ldata[0];
   1588     data[1] = (float)ldata[1];
   1589     data[2] = (float)ldata[2];
   1590     data[3] = (float)ldata[3];
   1591     data[4] = (float)ldata[4];
   1592     data[5] = (float)ldata[5];
   1593     data[6] = (float)inv_obj.compass_sensor_data[0];
   1594     data[7] = (float)inv_obj.compass_sensor_data[1];
   1595     data[8] = (float)inv_obj.compass_sensor_data[2];
   1596 
   1597     return result;
   1598 }
   1599 
   1600 /**
   1601  *  @brief  inv_get_euler_angles_x is used to get the Euler angle representation
   1602  *          of the current sensor fusion solution.
   1603  *          Euler angles are returned according to the X convention.
   1604  *          This is typically the convention used for mobile devices where the X
   1605  *          axis is the width of the screen, Y axis is the height, and Z the
   1606  *          depth. In this case roll is defined as the rotation around the X
   1607  *          axis of the device.
   1608  *          <TABLE>
   1609  *          <TR><TD>Element </TD><TD><b>Euler angle</b></TD><TD><b>Rotation about </b></TD></TR>
   1610  *          <TR><TD> 0      </TD><TD>Roll              </TD><TD>X axis                </TD></TR>
   1611  *          <TR><TD> 1      </TD><TD>Pitch             </TD><TD>Y axis                </TD></TR>
   1612  *          <TR><TD> 2      </TD><TD>Yaw               </TD><TD>Z axis                </TD></TR>
   1613  *
   1614            </TABLE>
   1615  *
   1616  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1617  *          must have been called.
   1618  *
   1619  *  @param  data
   1620  *              A pointer to an array to be passed back to the user.
   1621  *              <b>Must be 3 cells long</b>.
   1622  *
   1623  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1624  */
   1625 inv_error_t inv_get_euler_angles_x_float(float *data)
   1626 {
   1627     INVENSENSE_FUNC_START;
   1628 
   1629     inv_error_t result = INV_SUCCESS;
   1630     float rotMatrix[9];
   1631     float tmp;
   1632 
   1633     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1634         return INV_ERROR_SM_IMPROPER_STATE;
   1635 
   1636     if (NULL == data) {
   1637         return INV_ERROR_INVALID_PARAMETER;
   1638     }
   1639 
   1640     result = inv_get_rot_mat_float(rotMatrix);
   1641     tmp = rotMatrix[6];
   1642     if (tmp > 1.0f) {
   1643         tmp = 1.0f;
   1644     }
   1645     if (tmp < -1.0f) {
   1646         tmp = -1.0f;
   1647     }
   1648     data[0] =
   1649         (float)(atan2f(rotMatrix[7],
   1650                        rotMatrix[8]) * 57.29577951308);
   1651     data[1] = (float)((double)asin(tmp) * 57.29577951308);
   1652     data[2] =
   1653         (float)(atan2f(rotMatrix[3], rotMatrix[0]) * 57.29577951308);
   1654 
   1655     return result;
   1656 }
   1657 
   1658 /**
   1659  *  @brief  inv_get_euler_angles_float is used to get an array of three data points three data points
   1660  *			representing roll, pitch, and yaw corresponding to the INV_EULER_ANGLES_X output and it is
   1661  *          therefore the default convention for Euler angles.
   1662  *          Please refer to the INV_EULER_ANGLES_X for a detailed description.
   1663  *
   1664  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1665  *          must have been called.
   1666  *
   1667  *  @param  data
   1668  *              A pointer to an array to be passed back to the user.
   1669  *              <b>Must be 3 cells long</b>.
   1670  *
   1671  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1672  */
   1673 inv_error_t inv_get_euler_angles_float(float *data)
   1674 {
   1675     return inv_get_euler_angles_x_float(data);
   1676 }
   1677 
   1678 /**  @brief  inv_get_euler_angles_y_float is used to get the Euler angle representation
   1679  *          of the current sensor fusion solution.
   1680  *          Euler angles are returned according to the Y convention.
   1681  *          This convention is typically used in augmented reality applications,
   1682  *          where roll is defined as the rotation around the axis along the
   1683  *          height of the screen of a mobile device, namely the Y axis.
   1684  *          <TABLE>
   1685  *          <TR><TD>Element </TD><TD><b>Euler angle</b></TD><TD><b>Rotation about </b></TD></TR>
   1686  *          <TR><TD> 0      </TD><TD>Roll              </TD><TD>Y axis                </TD></TR>
   1687  *          <TR><TD> 1      </TD><TD>Pitch             </TD><TD>X axis                </TD></TR>
   1688  *          <TR><TD> 2      </TD><TD>Yaw               </TD><TD>Z axis                </TD></TR>
   1689  *          </TABLE>
   1690  *
   1691  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1692  *          must have been called.
   1693  *
   1694  *  @param  data
   1695  *              A pointer to an array to be passed back to the user.
   1696  *              <b>Must be 3 cells long</b>.
   1697  *
   1698  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1699  */
   1700 inv_error_t inv_get_euler_angles_y_float(float *data)
   1701 {
   1702     INVENSENSE_FUNC_START;
   1703 
   1704     inv_error_t result = INV_SUCCESS;
   1705     float rotMatrix[9];
   1706     float tmp;
   1707 
   1708     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1709         return INV_ERROR_SM_IMPROPER_STATE;
   1710 
   1711     if (NULL == data) {
   1712         return INV_ERROR_INVALID_PARAMETER;
   1713     }
   1714 
   1715     result = inv_get_rot_mat_float(rotMatrix);
   1716     tmp = rotMatrix[7];
   1717     if (tmp > 1.0f) {
   1718         tmp = 1.0f;
   1719     }
   1720     if (tmp < -1.0f) {
   1721         tmp = -1.0f;
   1722     }
   1723     data[0] =
   1724         (float)(atan2f(rotMatrix[8], rotMatrix[6]) * 57.29577951308);
   1725     data[1] = (float)((double)asin(tmp) * 57.29577951308);
   1726     data[2] =
   1727         (float)(atan2f(rotMatrix[4], rotMatrix[1]) * 57.29577951308);
   1728 
   1729     return result;
   1730 }
   1731 
   1732 /**  @brief  inv_get_euler_angles_z_float is used to get the Euler angle representation
   1733  *          of the current sensor fusion solution.
   1734  *          This convention is mostly used in application involving the use
   1735  *          of a camera, typically placed on the back of a mobile device, that
   1736  *          is along the Z axis.  In this convention roll is defined as the
   1737  *          rotation around the Z axis.
   1738  *          Euler angles are returned according to the Y convention.
   1739  *          <TABLE>
   1740  *          <TR><TD>Element </TD><TD><b>Euler angle</b></TD><TD><b>Rotation about </b></TD></TR>
   1741  *          <TR><TD> 0      </TD><TD>Roll              </TD><TD>Z axis                </TD></TR>
   1742  *          <TR><TD> 1      </TD><TD>Pitch             </TD><TD>X axis                </TD></TR>
   1743  *          <TR><TD> 2      </TD><TD>Yaw               </TD><TD>Y axis                </TD></TR>
   1744  *          </TABLE>
   1745  *
   1746  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1747  *          must have been called.
   1748  *
   1749  *  @param  data
   1750  *              A pointer to an array to be passed back to the user.
   1751  *              <b>Must be 3 cells long</b>.
   1752  *
   1753  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1754  *          must have been called.
   1755  *
   1756  *  @param  data
   1757  *              A pointer to an array to be passed back to the user.
   1758  *              <b>Must be 3 cells long</b>.
   1759  *
   1760  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1761  */
   1762 inv_error_t inv_get_euler_angles_z_float(float *data)
   1763 {
   1764     INVENSENSE_FUNC_START;
   1765 
   1766     inv_error_t result = INV_SUCCESS;
   1767     float rotMatrix[9];
   1768     float tmp;
   1769 
   1770     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1771         return INV_ERROR_SM_IMPROPER_STATE;
   1772 
   1773     if (NULL == data) {
   1774         return INV_ERROR_INVALID_PARAMETER;
   1775     }
   1776 
   1777     result = inv_get_rot_mat_float(rotMatrix);
   1778     tmp = rotMatrix[8];
   1779     if (tmp > 1.0f) {
   1780         tmp = 1.0f;
   1781     }
   1782     if (tmp < -1.0f) {
   1783         tmp = -1.0f;
   1784     }
   1785     data[0] =
   1786         (float)(atan2f(rotMatrix[6], rotMatrix[7]) * 57.29577951308);
   1787     data[1] = (float)((double)asin(tmp) * 57.29577951308);
   1788     data[2] =
   1789         (float)(atan2f(rotMatrix[5], rotMatrix[2]) * 57.29577951308);
   1790 
   1791     return result;
   1792 }
   1793 
   1794 /**
   1795  *  @cond MPL
   1796  *  @brief  inv_get_mag_raw_data_float is used to get Raw magnetometer data
   1797  *
   1798  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1799  *          must have been called.
   1800  *
   1801  *  @param  data
   1802  *              A pointer to an array to be passed back to the user.
   1803  *              <b>Must be 3 cells long</b>.
   1804  *
   1805  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1806  *  @endcond
   1807  */
   1808 inv_error_t inv_get_mag_raw_data_float(float *data)
   1809 {
   1810     INVENSENSE_FUNC_START;
   1811 
   1812     inv_error_t result = INV_SUCCESS;
   1813 
   1814     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1815         return INV_ERROR_SM_IMPROPER_STATE;
   1816 
   1817     if (NULL == data) {
   1818         return INV_ERROR_INVALID_PARAMETER;
   1819     }
   1820 
   1821     data[0] =
   1822         (float)(inv_obj.compass_sensor_data[0] + inv_obj.init_compass_bias[0]);
   1823     data[1] =
   1824         (float)(inv_obj.compass_sensor_data[1] + inv_obj.init_compass_bias[1]);
   1825     data[2] =
   1826         (float)(inv_obj.compass_sensor_data[2] + inv_obj.init_compass_bias[2]);
   1827 
   1828     return result;
   1829 }
   1830 
   1831 /**
   1832  *  @cond MPL
   1833  *  @brief  inv_get_magnetometer_float is used to get magnetometer data
   1834  *
   1835  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1836  *          must have been called.
   1837  *
   1838  *  @param  data
   1839  *              A pointer to an array to be passed back to the user.
   1840  *              <b>Must be 3 cells long</b>.
   1841  *
   1842  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1843  *  @endcond
   1844  */
   1845 inv_error_t inv_get_magnetometer_float(float *data)
   1846 {
   1847     INVENSENSE_FUNC_START;
   1848 
   1849     inv_error_t result = INV_SUCCESS;
   1850 
   1851     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1852         return INV_ERROR_SM_IMPROPER_STATE;
   1853 
   1854     if (NULL == data) {
   1855         return INV_ERROR_INVALID_PARAMETER;
   1856     }
   1857 
   1858     data[0] = (float)inv_obj.compass_calibrated_data[0] / 65536.0f;
   1859     data[1] = (float)inv_obj.compass_calibrated_data[1] / 65536.0f;
   1860     data[2] = (float)inv_obj.compass_calibrated_data[2] / 65536.0f;
   1861 
   1862     return result;
   1863 }
   1864 
   1865 /**
   1866  *  @cond MPL
   1867  *  @brief  inv_get_pressure_float is used to get a single value representing the pressure in Pascal
   1868  *
   1869  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1870  *          must have been called.
   1871  *
   1872  *  @param  data
   1873  *              A pointer to the data to be passed back to the user.
   1874  *
   1875  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1876  *  @endcond
   1877  */
   1878 inv_error_t inv_get_pressure_float(float *data)
   1879 {
   1880     INVENSENSE_FUNC_START;
   1881 
   1882     inv_error_t result = INV_SUCCESS;
   1883 
   1884     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1885         return INV_ERROR_SM_IMPROPER_STATE;
   1886 
   1887     if (NULL == data) {
   1888         return INV_ERROR_INVALID_PARAMETER;
   1889     }
   1890 
   1891     data[0] = (float)inv_obj.pressure;
   1892 
   1893     return result;
   1894 }
   1895 
   1896 /**
   1897  *  @cond MPL
   1898  *  @brief  inv_get_heading_float is used to get single number representing the heading of the device
   1899  *          relative to the Earth, in which 0 represents North, 90 degrees
   1900  *          represents East, and so on.
   1901  *          The heading is defined as the direction of the +Y axis if the Y
   1902  *          axis is horizontal, and otherwise the direction of the -Z axis.
   1903  *
   1904  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1905  *          must have been called.
   1906  *
   1907  *  @param  data
   1908  *              A pointer to the data to be passed back to the user.
   1909  *
   1910  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1911  *  @endcond
   1912  */
   1913 inv_error_t inv_get_heading_float(float *data)
   1914 {
   1915     INVENSENSE_FUNC_START;
   1916 
   1917     inv_error_t result = INV_SUCCESS;
   1918     float rotMatrix[9];
   1919     float tmp;
   1920 
   1921     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1922         return INV_ERROR_SM_IMPROPER_STATE;
   1923 
   1924     if (NULL == data) {
   1925         return INV_ERROR_INVALID_PARAMETER;
   1926     }
   1927 
   1928     inv_get_rot_mat_float(rotMatrix);
   1929     if ((rotMatrix[7] < 0.707) && (rotMatrix[7] > -0.707)) {
   1930         tmp =
   1931             (float)(atan2f(rotMatrix[4], rotMatrix[1]) * 57.29577951308 -
   1932                     90.0f);
   1933     } else {
   1934         tmp =
   1935             (float)(atan2f(rotMatrix[5], rotMatrix[2]) * 57.29577951308 +
   1936                     90.0f);
   1937     }
   1938     if (tmp < 0) {
   1939         tmp += 360.0f;
   1940     }
   1941     data[0] = 360 - tmp;
   1942 
   1943     return result;
   1944 }
   1945 
   1946 /**
   1947  *  @cond MPL
   1948  *  @brief  inv_get_mag_bias_error_float is used to get an array of three numbers representing
   1949  *			the current estimated error in the compass biases. These numbers are unitless and serve
   1950  *          as rough estimates in which numbers less than 100 typically represent
   1951  *          reasonably well calibrated compass axes.
   1952  *
   1953  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1954  *          must have been called.
   1955  *
   1956  *  @param  data
   1957  *              A pointer to an array to be passed back to the user.
   1958  *              <b>Must be 3 cells long</b>.
   1959  *
   1960  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   1961  *  @endcond
   1962  */
   1963 inv_error_t inv_get_mag_bias_error_float(float *data)
   1964 {
   1965     INVENSENSE_FUNC_START;
   1966 
   1967     inv_error_t result = INV_SUCCESS;
   1968 
   1969     if (inv_get_state() < INV_STATE_DMP_OPENED)
   1970         return INV_ERROR_SM_IMPROPER_STATE;
   1971 
   1972     if (NULL == data) {
   1973         return INV_ERROR_INVALID_PARAMETER;
   1974     }
   1975 
   1976     if (inv_obj.large_field == 0) {
   1977         data[0] = (float)inv_obj.compass_bias_error[0];
   1978         data[1] = (float)inv_obj.compass_bias_error[1];
   1979         data[2] = (float)inv_obj.compass_bias_error[2];
   1980     } else {
   1981         data[0] = (float)P_INIT;
   1982         data[1] = (float)P_INIT;
   1983         data[2] = (float)P_INIT;
   1984     }
   1985 
   1986     return result;
   1987 }
   1988 
   1989 /**
   1990  *  @cond MPL
   1991  *  @brief  inv_get_mag_scale_float is used to get magnetometer scale.
   1992  *
   1993  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   1994  *          must have been called.
   1995  *
   1996  *  @param  data
   1997  *              A pointer to an array to be passed back to the user.
   1998  *              <b>Must be 3 cells long</b>.
   1999  *
   2000  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   2001  *  @endcond
   2002  */
   2003 inv_error_t inv_get_mag_scale_float(float *data)
   2004 {
   2005     INVENSENSE_FUNC_START;
   2006 
   2007     inv_error_t result = INV_SUCCESS;
   2008 
   2009     if (inv_get_state() < INV_STATE_DMP_OPENED)
   2010         return INV_ERROR_SM_IMPROPER_STATE;
   2011 
   2012     if (NULL == data) {
   2013         return INV_ERROR_INVALID_PARAMETER;
   2014     }
   2015 
   2016     data[0] = (float)inv_obj.compass_scale[0] / 65536.0f;
   2017     data[1] = (float)inv_obj.compass_scale[1] / 65536.0f;
   2018     data[2] = (float)inv_obj.compass_scale[2] / 65536.0f;
   2019 
   2020     return result;
   2021 }
   2022 
   2023 /**
   2024  *  @cond MPL
   2025  *  @brief  inv_get_local_field_float is used to get local magnetic field data.
   2026  *
   2027  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   2028  *          must have been called.
   2029  *
   2030  *  @param  data
   2031  *              A pointer to an array to be passed back to the user.
   2032  *              <b>Must be 3 cells long</b>.
   2033  *
   2034  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   2035  *  @endcond
   2036  */
   2037 inv_error_t inv_get_local_field_float(float *data)
   2038 {
   2039     INVENSENSE_FUNC_START;
   2040 
   2041     inv_error_t result = INV_SUCCESS;
   2042 
   2043     if (inv_get_state() < INV_STATE_DMP_OPENED)
   2044         return INV_ERROR_SM_IMPROPER_STATE;
   2045 
   2046     if (NULL == data) {
   2047         return INV_ERROR_INVALID_PARAMETER;
   2048     }
   2049 
   2050     data[0] = (float)inv_obj.local_field[0] / 65536.0f;
   2051     data[1] = (float)inv_obj.local_field[1] / 65536.0f;
   2052     data[2] = (float)inv_obj.local_field[2] / 65536.0f;
   2053 
   2054     return result;
   2055 }
   2056 
   2057 /**
   2058  *  @cond MPL
   2059  *  @brief  inv_get_relative_quaternion_float is used to get relative quaternion data.
   2060  *
   2061  *  @pre    MLDmpOpen() \ifnot UMPL or MLDmpPedometerStandAloneOpen() \endif
   2062  *          must have been called.
   2063  *
   2064  *  @param  data
   2065  *              A pointer to an array to be passed back to the user.
   2066  *              <b>Must be 4 cells long at least</b>.
   2067  *
   2068  *  @return INV_SUCCESS if the command is successful; an error code otherwise.
   2069  *  @endcond
   2070  */
   2071 inv_error_t inv_get_relative_quaternion_float(float *data)
   2072 {
   2073     INVENSENSE_FUNC_START;
   2074 
   2075     inv_error_t result = INV_SUCCESS;
   2076 
   2077     if (inv_get_state() < INV_STATE_DMP_OPENED)
   2078         return INV_ERROR_SM_IMPROPER_STATE;
   2079 
   2080     if (NULL == data) {
   2081         return INV_ERROR_INVALID_PARAMETER;
   2082     }
   2083 
   2084     data[0] = (float)inv_obj.relative_quat[0] / 1073741824.0f;
   2085     data[1] = (float)inv_obj.relative_quat[1] / 1073741824.0f;
   2086     data[2] = (float)inv_obj.relative_quat[2] / 1073741824.0f;
   2087     data[3] = (float)inv_obj.relative_quat[3] / 1073741824.0f;
   2088 
   2089     return result;
   2090 }
   2091 
   2092 /**
   2093  * Returns the curren compass accuracy.
   2094  *
   2095  * - 0: Unknown: The accuracy is unreliable and compass data should not be used
   2096  * - 1: Low: The compass accuracy is low.
   2097  * - 2: Medium: The compass accuracy is medium.
   2098  * - 3: High: The compas acurracy is high and can be trusted
   2099  *
   2100  * @param accuracy The accuracy level in the range 0-3
   2101  *
   2102  * @return ML_SUCCESS or non-zero error code
   2103  */
   2104 inv_error_t inv_get_compass_accuracy(int *accuracy)
   2105 {
   2106     if (inv_get_state() != INV_STATE_DMP_STARTED)
   2107         return INV_ERROR_SM_IMPROPER_STATE;
   2108 
   2109     *accuracy = inv_obj.compass_accuracy;
   2110     return INV_SUCCESS;
   2111 }
   2112 
   2113 /**
   2114  *  @brief  inv_set_gyro_bias is used to set the gyroscope bias.
   2115  *          The argument array elements are ordered X,Y,Z.
   2116  *          The values are scaled at 1 dps = 2^16 LSBs.
   2117  *
   2118  *          Please refer to the provided "9-Axis Sensor Fusion
   2119  *          Application Note" document provided.
   2120  *
   2121  *  @pre    MLDmpOpen() \ifnot UMPL or
   2122  *          MLDmpPedometerStandAloneOpen() \endif
   2123  *
   2124  *  @param  data        A pointer to an array to be copied from the user.
   2125  *
   2126  *  @return INV_SUCCESS if successful; a non-zero error code otherwise.
   2127  */
   2128 inv_error_t inv_set_gyro_bias(long *data)
   2129 {
   2130     INVENSENSE_FUNC_START;
   2131     inv_error_t result = INV_SUCCESS;
   2132     long biasTmp;
   2133     long sf = 0;
   2134     short offset[GYRO_NUM_AXES];
   2135     int i;
   2136     struct mldl_cfg *mldl_cfg = inv_get_dl_config();
   2137 
   2138     if (mldl_cfg->gyro_sens_trim != 0) {
   2139         sf = 2000 * 131 / mldl_cfg->gyro_sens_trim;
   2140     } else {
   2141         sf = 2000;
   2142     }
   2143     for (i = 0; i < GYRO_NUM_AXES; i++) {
   2144         inv_obj.gyro_bias[i] = data[i];
   2145         biasTmp = -inv_obj.gyro_bias[i] / sf;
   2146         if (biasTmp < 0)
   2147             biasTmp += 65536L;
   2148         offset[i] = (short)biasTmp;
   2149     }
   2150     result = inv_set_offset(offset);
   2151     if (result) {
   2152         LOG_RESULT_LOCATION(result);
   2153         return result;
   2154     }
   2155 
   2156     return INV_SUCCESS;
   2157 }
   2158 
   2159 /**
   2160  *  @brief  inv_set_accel_bias is used to set the accelerometer bias.
   2161  *          The argument array elements are ordered X,Y,Z.
   2162  *          The values are scaled in units of g (gravity),
   2163  *          where 1 g = 2^16 LSBs.
   2164  *
   2165  *          Please refer to the provided "9-Axis Sensor Fusion
   2166  *          Application Note" document provided.
   2167  *
   2168  *  @pre    MLDmpOpen() \ifnot UMPL or
   2169  *          MLDmpPedometerStandAloneOpen() \endif
   2170  *
   2171  *  @param  data        A pointer to an array to be copied from the user.
   2172  *
   2173  *  @return INV_SUCCESS if successful; a non-zero error code otherwise.
   2174  */
   2175 inv_error_t inv_set_accel_bias(long *data)
   2176 {
   2177     INVENSENSE_FUNC_START;
   2178     inv_error_t result = INV_SUCCESS;
   2179     long biasTmp;
   2180     int i, j;
   2181     unsigned char regs[6];
   2182     struct mldl_cfg *mldl_cfg = inv_get_dl_config();
   2183 
   2184     for (i = 0; i < ACCEL_NUM_AXES; i++) {
   2185         inv_obj.accel_bias[i] = data[i];
   2186         if (inv_obj.accel_sens != 0 && mldl_cfg && mldl_cfg->pdata) {
   2187             long long tmp64;
   2188             inv_obj.scaled_accel_bias[i] = 0;
   2189             for (j = 0; j < ACCEL_NUM_AXES; j++) {
   2190                 inv_obj.scaled_accel_bias[i] +=
   2191                     data[j] *
   2192                     (long)mldl_cfg->pdata->accel.orientation[i * 3 + j];
   2193             }
   2194             tmp64 = (long long)inv_obj.scaled_accel_bias[i] << 13;
   2195             biasTmp = (long)(tmp64 / inv_obj.accel_sens);
   2196         } else {
   2197             biasTmp = 0;
   2198         }
   2199         if (biasTmp < 0)
   2200             biasTmp += 65536L;
   2201         regs[2 * i + 0] = (unsigned char)(biasTmp / 256);
   2202         regs[2 * i + 1] = (unsigned char)(biasTmp % 256);
   2203     }
   2204     result = inv_set_mpu_memory(KEY_D_1_8, 2, &regs[0]);
   2205     if (result) {
   2206         LOG_RESULT_LOCATION(result);
   2207         return result;
   2208     }
   2209     result = inv_set_mpu_memory(KEY_D_1_10, 2, &regs[2]);
   2210     if (result) {
   2211         LOG_RESULT_LOCATION(result);
   2212         return result;
   2213     }
   2214     result = inv_set_mpu_memory(KEY_D_1_2, 2, &regs[4]);
   2215     if (result) {
   2216         LOG_RESULT_LOCATION(result);
   2217         return result;
   2218     }
   2219 
   2220     return INV_SUCCESS;
   2221 }
   2222 
   2223 /**
   2224  *  @cond MPL
   2225  *  @brief  inv_set_mag_bias is used to set Compass Bias
   2226  *
   2227  *          Please refer to the provided "9-Axis Sensor Fusion
   2228  *          Application Note" document provided.
   2229  *
   2230  *  @pre    MLDmpOpen() \ifnot UMPL or
   2231  *          MLDmpPedometerStandAloneOpen() \endif
   2232  *  @pre    MLDmpStart() must <b>NOT</b> have been called.
   2233  *
   2234  *  @param  data        A pointer to an array to be copied from the user.
   2235  *
   2236  *  @return INV_SUCCESS if successful; a non-zero error code otherwise.
   2237  *  @endcond
   2238  */
   2239 inv_error_t inv_set_mag_bias(long *data)
   2240 {
   2241     INVENSENSE_FUNC_START;
   2242     inv_error_t result = INV_SUCCESS;
   2243 
   2244     inv_set_compass_bias(data);
   2245     inv_obj.init_compass_bias[0] = 0;
   2246     inv_obj.init_compass_bias[1] = 0;
   2247     inv_obj.init_compass_bias[2] = 0;
   2248     inv_obj.got_compass_bias = 1;
   2249     inv_obj.got_init_compass_bias = 1;
   2250     inv_obj.compass_state = SF_STARTUP_SETTLE;
   2251 
   2252     if (result) {
   2253         LOG_RESULT_LOCATION(result);
   2254         return result;
   2255     }
   2256     return INV_SUCCESS;
   2257 }
   2258 
   2259 /**
   2260  *  @brief  inv_set_gyro_temp_slope is used to set the temperature
   2261  *          compensation algorithm's estimate of the gyroscope bias temperature
   2262  *          coefficient.
   2263  *          The argument array elements are ordered X,Y,Z.
   2264  *          Values are in units of dps per deg C (degrees per second per degree
   2265  *          Celcius), and scaled such that 1 dps per deg C = 2^16 LSBs.
   2266  *          Please refer to the provided "9-Axis Sensor Fusion
   2267  *          Application Note" document.
   2268  *
   2269  *  @brief  inv_set_gyro_temp_slope is used to set Gyro temperature slope
   2270  *
   2271  *
   2272  *  @pre    MLDmpOpen() \ifnot UMPL or
   2273  *          MLDmpPedometerStandAloneOpen() \endif
   2274  *
   2275  *  @param  data        A pointer to an array to be copied from the user.
   2276  *
   2277  *  @return INV_SUCCESS if successful; a non-zero error code otherwise.
   2278  */
   2279 inv_error_t inv_set_gyro_temp_slope(long *data)
   2280 {
   2281     INVENSENSE_FUNC_START;
   2282     inv_error_t result = INV_SUCCESS;
   2283     int i;
   2284     long sf;
   2285     unsigned char regs[3];
   2286 
   2287     inv_obj.factory_temp_comp = 1;
   2288     inv_obj.temp_slope[0] = data[0];
   2289     inv_obj.temp_slope[1] = data[1];
   2290     inv_obj.temp_slope[2] = data[2];
   2291     for (i = 0; i < GYRO_NUM_AXES; i++) {
   2292         sf = -inv_obj.temp_slope[i] / 1118;
   2293         if (sf > 127) {
   2294             sf -= 256;
   2295         }
   2296         regs[i] = (unsigned char)sf;
   2297     }
   2298     result = inv_set_offsetTC(regs);
   2299 
   2300     if (result) {
   2301         LOG_RESULT_LOCATION(result);
   2302         return result;
   2303     }
   2304     return INV_SUCCESS;
   2305 }
   2306 
   2307 /**
   2308  *  @cond MPL
   2309  *  @brief  inv_set_local_field is used to set local magnetic field
   2310  *
   2311  *          Please refer to the provided "9-Axis Sensor Fusion
   2312  *          Application Note" document provided.
   2313  *
   2314  *  @pre    MLDmpOpen() \ifnot UMPL or
   2315  *          MLDmpPedometerStandAloneOpen() \endif
   2316  *  @pre    MLDmpStart() must <b>NOT</b> have been called.
   2317  *
   2318  *  @param  data        A pointer to an array to be copied from the user.
   2319  *
   2320  *  @return INV_SUCCESS if successful; a non-zero error code otherwise.
   2321  *  @endcond
   2322  */
   2323 inv_error_t inv_set_local_field(long *data)
   2324 {
   2325     INVENSENSE_FUNC_START;
   2326     inv_error_t result = INV_SUCCESS;
   2327 
   2328     inv_obj.local_field[0] = data[0];
   2329     inv_obj.local_field[1] = data[1];
   2330     inv_obj.local_field[2] = data[2];
   2331     inv_obj.new_local_field = 1;
   2332 
   2333     if (result) {
   2334         LOG_RESULT_LOCATION(result);
   2335         return result;
   2336     }
   2337     return INV_SUCCESS;
   2338 }
   2339 
   2340 /**
   2341  *  @cond MPL
   2342  *  @brief  inv_set_mag_scale is used to set magnetometer scale
   2343  *
   2344  *          Please refer to the provided "9-Axis Sensor Fusion
   2345  *          Application Note" document provided.
   2346  *
   2347  *  @pre    MLDmpOpen() \ifnot UMPL or
   2348  *          MLDmpPedometerStandAloneOpen() \endif
   2349  *  @pre    MLDmpStart() must <b>NOT</b> have been called.
   2350  *
   2351  *  @param  data        A pointer to an array to be copied from the user.
   2352  *
   2353  *  @return INV_SUCCESS if successful; a non-zero error code otherwise.
   2354  *  @endcond
   2355  */
   2356 inv_error_t inv_set_mag_scale(long *data)
   2357 {
   2358     INVENSENSE_FUNC_START;
   2359     inv_error_t result = INV_SUCCESS;
   2360 
   2361     inv_obj.compass_scale[0] = data[0];
   2362     inv_obj.compass_scale[1] = data[1];
   2363     inv_obj.compass_scale[2] = data[2];
   2364 
   2365     if (result) {
   2366         LOG_RESULT_LOCATION(result);
   2367         return result;
   2368     }
   2369     return INV_SUCCESS;
   2370 }
   2371 
   2372 /**
   2373  *  @brief  inv_set_gyro_temp_slope_float is used to get the temperature
   2374  *          compensation algorithm's estimate of the gyroscope bias temperature
   2375  *          coefficient.
   2376  *          The argument array elements are ordered X,Y,Z.
   2377  *          Values are in units of dps per deg C (degrees per second per degree
   2378  *          Celcius)
   2379 
   2380  *          Please refer to the provided "9-Axis Sensor Fusion
   2381  *          Application Note" document provided.
   2382  *
   2383  *  @pre    MLDmpOpen() \ifnot UMPL or
   2384  *          MLDmpPedometerStandAloneOpen() \endif
   2385  *
   2386  *  @param  data        A pointer to an array to be copied from the user.
   2387  *
   2388  *  @return INV_SUCCESS if successful; a non-zero error code otherwise.
   2389  */
   2390 inv_error_t inv_set_gyro_temp_slope_float(float *data)
   2391 {
   2392     long arrayTmp[3];
   2393     arrayTmp[0] = (long)(data[0] * 65536.f);
   2394     arrayTmp[1] = (long)(data[1] * 65536.f);
   2395     arrayTmp[2] = (long)(data[2] * 65536.f);
   2396     return inv_set_gyro_temp_slope(arrayTmp);
   2397 }
   2398 
   2399 /**
   2400  *  @brief  inv_set_gyro_bias_float is used to set the gyroscope bias.
   2401  *          The argument array elements are ordered X,Y,Z.
   2402  *          The values are in units of dps (degrees per second).
   2403  *
   2404  *          Please refer to the provided "9-Axis Sensor Fusion
   2405  *          Application Note" document provided.
   2406  *
   2407  *  @pre    MLDmpOpen() \ifnot UMPL or
   2408  *          MLDmpPedometerStandAloneOpen() \endif
   2409  *  @pre    MLDmpStart() must <b>NOT</b> have been called.
   2410  *
   2411  *  @param  data        A pointer to an array to be copied from the user.
   2412  *
   2413  *  @return INV_SUCCESS if successful; a non-zero error code otherwise.
   2414  */
   2415 inv_error_t inv_set_gyro_bias_float(float *data)
   2416 {
   2417     long arrayTmp[3];
   2418     arrayTmp[0] = (long)(data[0] * 65536.f);
   2419     arrayTmp[1] = (long)(data[1] * 65536.f);
   2420     arrayTmp[2] = (long)(data[2] * 65536.f);
   2421     return inv_set_gyro_bias(arrayTmp);
   2422 
   2423 }
   2424 
   2425 /**
   2426  *  @brief  inv_set_accel_bias_float is used to set the accelerometer bias.
   2427  *          The argument array elements are ordered X,Y,Z.
   2428  *          The values are in units of g (gravity).
   2429  *
   2430  *          Please refer to the provided "9-Axis Sensor Fusion
   2431  *          Application Note" document provided.
   2432  *
   2433  *  @pre    MLDmpOpen() \ifnot UMPL or
   2434  *          MLDmpPedometerStandAloneOpen() \endif
   2435  *  @pre    MLDmpStart() must <b>NOT</b> have been called.
   2436  *
   2437  *  @param  data        A pointer to an array to be copied from the user.
   2438  *
   2439  *  @return INV_SUCCESS if successful; a non-zero error code otherwise.
   2440  */
   2441 inv_error_t inv_set_accel_bias_float(float *data)
   2442 {
   2443     long arrayTmp[3];
   2444     arrayTmp[0] = (long)(data[0] * 65536.f);
   2445     arrayTmp[1] = (long)(data[1] * 65536.f);
   2446     arrayTmp[2] = (long)(data[2] * 65536.f);
   2447     return inv_set_accel_bias(arrayTmp);
   2448 
   2449 }
   2450 
   2451 /**
   2452  *  @cond MPL
   2453  *  @brief  inv_set_mag_bias_float is used to set compass bias
   2454  *
   2455  *          Please refer to the provided "9-Axis Sensor Fusion
   2456  *          Application Note" document provided.
   2457  *
   2458  *  @pre    MLDmpOpen()\ifnot UMPL or
   2459  *          MLDmpPedometerStandAloneOpen() \endif
   2460  *  @pre    MLDmpStart() must <b>NOT</b> have been called.
   2461  *
   2462  *  @param  data        A pointer to an array to be copied from the user.
   2463  *
   2464  *  @return INV_SUCCESS if successful; a non-zero error code otherwise.
   2465  *  @endcond
   2466  */
   2467 inv_error_t inv_set_mag_bias_float(float *data)
   2468 {
   2469     long arrayTmp[3];
   2470     arrayTmp[0] = (long)(data[0] * 65536.f);
   2471     arrayTmp[1] = (long)(data[1] * 65536.f);
   2472     arrayTmp[2] = (long)(data[2] * 65536.f);
   2473     return inv_set_mag_bias(arrayTmp);
   2474 }
   2475 
   2476 /**
   2477  *  @cond MPL
   2478  *  @brief  inv_set_local_field_float is used to set local magnetic field
   2479  *
   2480  *          Please refer to the provided "9-Axis Sensor Fusion
   2481  *          Application Note" document provided.
   2482  *
   2483  *  @pre    MLDmpOpen() \ifnot UMPL or
   2484  *          MLDmpPedometerStandAloneOpen() \endif
   2485  *  @pre    MLDmpStart() must <b>NOT</b> have been called.
   2486  *
   2487  *  @param  data        A pointer to an array to be copied from the user.
   2488  *
   2489  *  @return INV_SUCCESS if successful; a non-zero error code otherwise.
   2490  *  @endcond
   2491  */
   2492 inv_error_t inv_set_local_field_float(float *data)
   2493 {
   2494     long arrayTmp[3];
   2495     arrayTmp[0] = (long)(data[0] * 65536.f);
   2496     arrayTmp[1] = (long)(data[1] * 65536.f);
   2497     arrayTmp[2] = (long)(data[2] * 65536.f);
   2498     return inv_set_local_field(arrayTmp);
   2499 }
   2500 
   2501 /**
   2502  *  @cond MPL
   2503  *  @brief  inv_set_mag_scale_float is used to set magnetometer scale
   2504  *
   2505  *          Please refer to the provided "9-Axis Sensor Fusion
   2506  *          Application Note" document provided.
   2507  *
   2508  *  @pre    MLDmpOpen() \ifnot UMPL or
   2509  *          MLDmpPedometerStandAloneOpen() \endif
   2510  *  @pre    MLDmpStart() must <b>NOT</b> have been called.
   2511  *
   2512  *  @param  data        A pointer to an array to be copied from the user.
   2513  *
   2514  *  @return INV_SUCCESS if successful; a non-zero error code otherwise.
   2515  *  @endcond
   2516  */
   2517 inv_error_t inv_set_mag_scale_float(float *data)
   2518 {
   2519     long arrayTmp[3];
   2520     arrayTmp[0] = (long)(data[0] * 65536.f);
   2521     arrayTmp[1] = (long)(data[1] * 65536.f);
   2522     arrayTmp[2] = (long)(data[2] * 65536.f);
   2523     return inv_set_mag_scale(arrayTmp);
   2524 }
   2525