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  *
     21  * $Id: mldmp.c 5629 2011-06-11 03:13:08Z mcaramello $
     22  *
     23  *****************************************************************************/
     24 
     25 /**
     26  * @addtogroup MLDMP
     27  *
     28  * @{
     29  *      @file     mldmp.c
     30  *      @brief    Shared functions between all the different DMP versions
     31 **/
     32 
     33 #include <stdio.h>
     34 
     35 #include "mltypes.h"
     36 #include "mlinclude.h"
     37 #include "mltypes.h"
     38 #include "ml.h"
     39 #include "mldl_cfg.h"
     40 #include "mldl.h"
     41 #include "compass.h"
     42 #include "mlSetGyroBias.h"
     43 #include "mlsl.h"
     44 #include "mlFIFO.h"
     45 #include "mldmp.h"
     46 #include "mlstates.h"
     47 #include "dmpDefault.h"
     48 #include "mlFIFOHW.h"
     49 #include "mlsupervisor.h"
     50 
     51 #include "log.h"
     52 #undef MPL_LOG_TAG
     53 #define MPL_LOG_TAG "MPL-dmp"
     54 
     55 /**
     56  *  @brief  Open the default motion sensor engine.
     57  *          This function is used to open the default MPL engine,
     58  *          featuring, for example, sensor fusion (6 axes and 9 axes),
     59  *          sensor calibration, accelerometer data byte swapping, among
     60  *          others.
     61  *          Compare with the other provided engines.
     62  *
     63  *  @pre    inv_serial_start() must have been called to instantiate the serial
     64  *          communication.
     65  *
     66  *  Example:
     67  *  @code
     68  *    result = inv_dmp_open( );
     69  *    if (INV_SUCCESS != result) {
     70  *        // Handle the error case
     71  *    }
     72  *  @endcode
     73  *
     74  *  @return Zero on success; Error Code on any failure.
     75  *
     76  */
     77 inv_error_t inv_dmp_open(void)
     78 {
     79     INVENSENSE_FUNC_START;
     80     inv_error_t result;
     81     unsigned char state = inv_get_state();
     82     struct mldl_cfg *mldl_cfg;
     83     unsigned long requested_sensors;
     84 
     85     /*************************************************************
     86      * Common operations before calling DMPOpen
     87      ************************************************************/
     88     if (state == INV_STATE_DMP_OPENED)
     89         return INV_SUCCESS;
     90 
     91     if (state == INV_STATE_DMP_STARTED) {
     92         return inv_dmp_stop();
     93     }
     94 
     95     result = inv_state_transition(INV_STATE_DMP_OPENED);
     96     if (result) {
     97         LOG_RESULT_LOCATION(result);
     98         return result;
     99     }
    100 
    101     result = inv_dl_open(inv_get_serial_handle());
    102     if (result) {
    103         LOG_RESULT_LOCATION(result);
    104         return result;
    105     }
    106 #ifdef ML_USE_DMP_SIM
    107     do {
    108         void setup_univ();
    109         setup_univ();           /* hijack the read and write paths
    110                                    and re-direct them to the simulator */
    111     } while (0);
    112 #endif
    113 
    114     result = inv_setup_dmp();
    115     if (result) {
    116         LOG_RESULT_LOCATION(result);
    117         return result;
    118     }
    119 
    120     // Init vars.
    121     inv_init_ml();
    122 
    123     result = inv_init_fifo_param();
    124     if (result) {
    125         LOG_RESULT_LOCATION(result);
    126         return result;
    127     }
    128     result = inv_enable_set_bias();
    129     if (result) {
    130         LOG_RESULT_LOCATION(result);
    131         return result;
    132     }
    133     inv_init_fifo_hardare();
    134     mldl_cfg = inv_get_dl_config();
    135     requested_sensors = INV_THREE_AXIS_GYRO;
    136     if (mldl_cfg->accel && mldl_cfg->accel->resume)
    137         requested_sensors |= INV_THREE_AXIS_ACCEL;
    138 
    139     if (mldl_cfg->compass && mldl_cfg->compass->resume)
    140         requested_sensors |= INV_THREE_AXIS_COMPASS;
    141 
    142     if (mldl_cfg->pressure && mldl_cfg->pressure->resume)
    143         requested_sensors |= INV_THREE_AXIS_PRESSURE;
    144 
    145     result = inv_init_requested_sensors(requested_sensors);
    146     if (result) {
    147         LOG_RESULT_LOCATION(result);
    148         return result;
    149     }
    150     result = inv_apply_calibration();
    151     if (result) {
    152         LOG_RESULT_LOCATION(result);
    153         return result;
    154     }
    155     result = inv_apply_endian_accel();
    156 
    157     return result;
    158 }
    159 
    160 /**
    161  *  @brief  Start the DMP.
    162  *
    163  *  @pre    inv_dmp_open() must have been called.
    164  *
    165  *  @code
    166  *     result = inv_dmp_start();
    167  *     if (INV_SUCCESS != result) {
    168  *         // Handle the error case
    169  *     }
    170  *  @endcode
    171  *
    172  *  @return INV_SUCCESS if successful, or Non-zero error code otherwise.
    173  */
    174 inv_error_t inv_dmp_start(void)
    175 {
    176     INVENSENSE_FUNC_START;
    177     inv_error_t result;
    178 
    179     if (inv_get_state() == INV_STATE_DMP_STARTED)
    180         return INV_SUCCESS;
    181 
    182     result = inv_state_transition(INV_STATE_DMP_STARTED);
    183     if (result) {
    184         LOG_RESULT_LOCATION(result);
    185         return result;
    186     }
    187     inv_init_sensor_fusion_supervisor();
    188     result = inv_dl_start(inv_get_dl_config()->requested_sensors);
    189     if (result) {
    190         LOG_RESULT_LOCATION(result);
    191         return result;
    192     }
    193     /* This is done after the start since it will modify DMP memory, which
    194      * will cause a full reset is most cases */
    195     result = inv_reset_motion();
    196     if (result) {
    197         LOG_RESULT_LOCATION(result);
    198         return result;
    199     }
    200 
    201     return result;
    202 }
    203 
    204 /**
    205  *  @brief  Stops the DMP and puts it in low power.
    206  *
    207  *  @pre    inv_dmp_start() must have been called.
    208  *
    209  *  @return INV_SUCCESS, Non-zero error code otherwise.
    210  */
    211 inv_error_t inv_dmp_stop(void)
    212 {
    213     INVENSENSE_FUNC_START;
    214     inv_error_t result;
    215 
    216     if (inv_get_state() == INV_STATE_DMP_OPENED)
    217         return INV_SUCCESS;
    218 
    219     result = inv_state_transition(INV_STATE_DMP_OPENED);
    220     if (result) {
    221         LOG_RESULT_LOCATION(result);
    222         return result;
    223     }
    224     result = inv_dl_stop(INV_ALL_SENSORS);
    225     if (result) {
    226         LOG_RESULT_LOCATION(result);
    227         return result;
    228     }
    229 
    230     return result;
    231 }
    232 
    233 /**
    234  *  @brief  Closes the motion sensor engine.
    235  *          Does not close the serial communication. To do that,
    236  *          call inv_serial_stop().
    237  *          After calling inv_dmp_close() another DMP module can be
    238  *          loaded in the MPL with the corresponding necessary
    239  *          intialization and configurations, via any of the
    240  *          MLDmpXXXOpen functions.
    241  *
    242  *  @pre    inv_dmp_open() must have been called.
    243  *
    244  *  @code
    245  *     result = inv_dmp_close();
    246  *     if (INV_SUCCESS != result) {
    247  *         // Handle the error case
    248  *     }
    249  *  @endcode
    250  *
    251  *  @return INV_SUCCESS, Non-zero error code otherwise.
    252  */
    253 inv_error_t inv_dmp_close(void)
    254 {
    255     INVENSENSE_FUNC_START;
    256     inv_error_t result;
    257     inv_error_t firstError = INV_SUCCESS;
    258 
    259     if (inv_get_state() <= INV_STATE_DMP_CLOSED)
    260         return INV_SUCCESS;
    261 
    262     result = inv_disable_set_bias();
    263     ERROR_CHECK_FIRST(firstError, result);
    264 
    265     result = inv_dl_stop(INV_ALL_SENSORS);
    266     ERROR_CHECK_FIRST(firstError, result);
    267 
    268     result = inv_close_fifo();
    269     ERROR_CHECK_FIRST(firstError, result);
    270 
    271     result = inv_dl_close();
    272     ERROR_CHECK_FIRST(firstError, result);
    273 
    274     result = inv_state_transition(INV_STATE_SERIAL_OPENED);
    275     ERROR_CHECK_FIRST(firstError, result);
    276 
    277     return result;
    278 }
    279 
    280 /**
    281  *  @}
    282  */
    283