1895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/*
2895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall $License:
3895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall   Copyright 2011 InvenSense, Inc.
4895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
5895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall Licensed under the Apache License, Version 2.0 (the "License");
6895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall you may not use this file except in compliance with the License.
7895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall You may obtain a copy of the License at
8895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
9895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall http://www.apache.org/licenses/LICENSE-2.0
10895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
11895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall Unless required by applicable law or agreed to in writing, software
12895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall distributed under the License is distributed on an "AS IS" BASIS,
13895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall See the License for the specific language governing permissions and
15895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall limitations under the License.
16895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall  $
17895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall */
18895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
19895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/******************************************************************************
20895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *
21895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * $Id:$
22895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *
23895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *****************************************************************************/
24895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
25895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "mlBiasNoMotion.h"
26895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "ml.h"
27895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "mlinclude.h"
28895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "mlos.h"
29895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "mlFIFO.h"
30895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "dmpKey.h"
31895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "accel.h"
32895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "mlMathFunc.h"
33895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "mldl.h"
34895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "mlstates.h"
35895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "mlSetGyroBias.h"
36895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
37895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "log.h"
38895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#undef MPL_LOG_TAG
39895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#define MPL_LOG_TAG "MPL-BiasNoMot"
40895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
41895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
42895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#define _mlDebug(x)             //{x}
43895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
44895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/**
45895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @brief  inv_set_motion_callback is used to register a callback function that
46895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          will trigger when a change of motion state is detected.
47895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *
48895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @pre    inv_dmp_open()
49895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          @ifnot MPL_MF
50895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *              or inv_open_low_power_pedometer()
51895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *              or inv_eis_open_dmp()
52895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          @endif
53895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          and inv_dmp_start()
54895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          must <b>NOT</b> have been called.
55895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *
56895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @param  func    A user defined callback function accepting a
57895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *                  motion_state parameter, the new motion state.
58895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *                  May be one of INV_MOTION or INV_NO_MOTION.
59895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @return INV_SUCCESS if successful or Non-zero error code otherwise.
60895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall */
61895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallinv_error_t inv_set_motion_callback(void (*func) (unsigned short motion_state))
62895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
63895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    INVENSENSE_FUNC_START;
64895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
65895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if ((inv_get_state() != INV_STATE_DMP_OPENED) &&
66895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        (inv_get_state() != INV_STATE_DMP_STARTED))
67895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        return INV_ERROR_SM_IMPROPER_STATE;
68895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
69895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_params_obj.motion_cb_func = func;
70895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
71895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return INV_SUCCESS;
72895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
73895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
74895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#if defined CONFIG_MPU_SENSORS_MPU6050A2 || \
75895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    defined CONFIG_MPU_SENSORS_MPU6050B1
76895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/** Turns on the feature to compute gyro bias from No Motion */
77895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallinv_error_t inv_turn_on_bias_from_no_motion()
78895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
79895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_error_t result;
80895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    unsigned char regs[3] = { 0x0d, DINA35, 0x5d };
81895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_params_obj.bias_mode |= INV_BIAS_FROM_NO_MOTION;
82895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    result = inv_set_mpu_memory(KEY_CFG_MOTION_BIAS, 3, regs);
83895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return result;
84895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
85895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
86895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/** Turns off the feature to compute gyro bias from No Motion
87895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall*/
88895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallinv_error_t inv_turn_off_bias_from_no_motion()
89895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
90895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_error_t result;
91895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    unsigned char regs[3] = { DINA90 + 8, DINA90 + 8, DINA90 + 8 };
92895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_params_obj.bias_mode &= ~INV_BIAS_FROM_NO_MOTION;
93895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    result = inv_set_mpu_memory(KEY_CFG_MOTION_BIAS, 3, regs);
94895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return result;
95895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
96895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#endif
97895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
98895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallinv_error_t inv_update_bias(void)
99895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
100895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    INVENSENSE_FUNC_START;
101895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_error_t result;
102895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    unsigned char regs[12];
103895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    short bias[GYRO_NUM_AXES];
104895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
105895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if ((inv_params_obj.bias_mode & INV_BIAS_FROM_NO_MOTION)
106895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        && inv_get_gyro_present()) {
107895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
108895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        regs[0] = DINAA0 + 3;
109895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        result = inv_set_mpu_memory(KEY_FCFG_6, 1, regs);
110895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (result) {
111895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            LOG_RESULT_LOCATION(result);
112895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            return result;
113895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
114895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
115895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        result = inv_get_mpu_memory(KEY_D_1_244, 12, regs);
116895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (result) {
117895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            LOG_RESULT_LOCATION(result);
118895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            return result;
119895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
120895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
121895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        inv_convert_bias(regs, bias);
122895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
123895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        regs[0] = DINAA0 + 15;
124895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        result = inv_set_mpu_memory(KEY_FCFG_6, 1, regs);
125895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (result) {
126895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            LOG_RESULT_LOCATION(result);
127895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            return result;
128895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
129895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
130895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        result = inv_set_gyro_bias_in_hw_unit(bias, INV_SGB_NO_MOTION);
131895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (result) {
132895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            LOG_RESULT_LOCATION(result);
133895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            return result;
134895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
135895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
136895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        result =
137895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            inv_serial_read(inv_get_serial_handle(), inv_get_mpu_slave_addr(),
138895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                            MPUREG_TEMP_OUT_H, 2, regs);
139895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (result) {
140895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            LOG_RESULT_LOCATION(result);
141895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            return result;
142895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
143895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        result = inv_set_mpu_memory(KEY_DMP_PREVPTAT, 2, regs);
144895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (result) {
145895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            LOG_RESULT_LOCATION(result);
146895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            return result;
147895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
148895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
149895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        inv_obj.got_no_motion_bias = TRUE;
150895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
151895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return INV_SUCCESS;
152895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
153895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
154895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallinv_error_t MLAccelMotionDetection(struct inv_obj_t *inv_obj)
155895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
156895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    long gain;
157895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    unsigned long timeChange;
158895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    long rate;
159895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_error_t result;
160895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    long accel[3], temp;
161895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    long long accelMag;
162895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    unsigned long currentTime;
163895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    int kk;
164895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
165895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if (!inv_accel_present()) {
166895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        return INV_SUCCESS;
167895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
168895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
169895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    currentTime = inv_get_tick_count();
170895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
171895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    // We always run the accel low pass filter at the highest sample rate possible
172895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    result = inv_get_accel(accel);
173895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if (result != INV_ERROR_FEATURE_NOT_ENABLED) {
174895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (result) {
175895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            LOG_RESULT_LOCATION(result);
176895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            return result;
177895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
178895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        rate = inv_get_fifo_rate() * 5 + 5;
179895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (rate > 200)
180895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            rate = 200;
181895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
182895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        gain = inv_obj->accel_lpf_gain * rate;
183895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        timeChange = inv_get_fifo_rate();
184895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
185895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        accelMag = 0;
186895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        for (kk = 0; kk < ACCEL_NUM_AXES; ++kk) {
187895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            inv_obj->accel_lpf[kk] =
188895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                inv_q30_mult(((1L << 30) - gain), inv_obj->accel_lpf[kk]);
189895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            inv_obj->accel_lpf[kk] += inv_q30_mult(gain, accel[kk]);
190895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            temp = accel[0] - inv_obj->accel_lpf[0];
191895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            accelMag += (long long)temp *temp;
192895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
193895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
194895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (accelMag > inv_obj->no_motion_accel_threshold) {
195895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            inv_obj->no_motion_accel_time = currentTime;
196895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
197895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            // Check for change of state
198895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            if (!inv_get_gyro_present())
199895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                inv_set_motion_state(INV_MOTION);
200895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
201895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        } else if ((currentTime - inv_obj->no_motion_accel_time) >
202895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                   5 * inv_obj->motion_duration) {
203895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            // We have no motion according to accel
204895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            // Check fsor change of state
205895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            if (!inv_get_gyro_present())
206895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                inv_set_motion_state(INV_NO_MOTION);
207895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
208895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
209895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return INV_SUCCESS;
210895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
211895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
212895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/**
213895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * @internal
214895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * @brief   Manually update the motion/no motion status.  This is a
215895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          convienence function for implementations that do not wish to use
216895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          inv_update_data.
217895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          This function can be called periodically to check for the
218895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          'no motion' state and update the internal motion status and bias
219895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          calculations.
220895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall */
221895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallinv_error_t MLPollMotionStatus(struct inv_obj_t * inv_obj)
222895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
223895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    INVENSENSE_FUNC_START;
224895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    unsigned char regs[3] = { 0 };
225895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    unsigned short motionFlag = 0;
226895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    unsigned long currentTime;
227895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_error_t result;
228895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
229895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    result = MLAccelMotionDetection(inv_obj);
230895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
231895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    currentTime = inv_get_tick_count();
232895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
233895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    // If it is not time to poll for a no motion event, return
234895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if (((inv_obj->interrupt_sources & INV_INT_MOTION) == 0) &&
235895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        ((currentTime - inv_obj->poll_no_motion) <= 1000))
236895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        return INV_SUCCESS;
237895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
238895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_obj->poll_no_motion = currentTime;
239895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
240895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#if defined CONFIG_MPU_SENSORS_MPU3050
241895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if (inv_get_gyro_present()
242895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        && ((inv_params_obj.bias_mode & INV_BIAS_FROM_FAST_NO_MOTION) == 0)) {
243895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        static long repeatBiasUpdateTime = 0;
244895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
245895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        result = inv_get_mpu_memory(KEY_D_1_98, 2, regs);
246895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (result) {
247895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            LOG_RESULT_LOCATION(result);
248895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            return result;
249895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
250895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
251895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        motionFlag = (unsigned short)regs[0] * 256 + (unsigned short)regs[1];
252895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
253895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        _mlDebug(MPL_LOGV("motionFlag from RAM : 0x%04X\n", motionFlag);
254895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            )
255895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            if (motionFlag == inv_obj->motion_duration) {
256895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            if (inv_obj->motion_state == INV_MOTION) {
257895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                inv_update_bias();
258895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                repeatBiasUpdateTime = inv_get_tick_count();
259895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
260895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                regs[0] = DINAD8 + 1;
261895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                regs[1] = DINA0C;
262895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                regs[2] = DINAD8 + 2;
263895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                result = inv_set_mpu_memory(KEY_CFG_18, 3, regs);
264895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                if (result) {
265895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                    LOG_RESULT_LOCATION(result);
266895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                    return result;
267895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                }
268895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
269895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                regs[0] = 0;
270895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                regs[1] = 5;
271895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                result = inv_set_mpu_memory(KEY_D_1_106, 2, regs);
272895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                if (result) {
273895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                    LOG_RESULT_LOCATION(result);
274895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                    return result;
275895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                }
276895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
277895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                //Trigger no motion callback
278895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                inv_set_motion_state(INV_NO_MOTION);
279895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            }
280895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
281895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (motionFlag == 5) {
282895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            if (inv_obj->motion_state == INV_NO_MOTION) {
283895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                regs[0] = DINAD8 + 2;
284895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                regs[1] = DINA0C;
285895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                regs[2] = DINAD8 + 1;
286895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                result = inv_set_mpu_memory(KEY_CFG_18, 3, regs);
287895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                if (result) {
288895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                    LOG_RESULT_LOCATION(result);
289895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                    return result;
290895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                }
291895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
292895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                regs[0] =
293895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                    (unsigned char)((inv_obj->motion_duration >> 8) & 0xff);
294895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                regs[1] = (unsigned char)(inv_obj->motion_duration & 0xff);
295895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                result = inv_set_mpu_memory(KEY_D_1_106, 2, regs);
296895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                if (result) {
297895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                    LOG_RESULT_LOCATION(result);
298895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                    return result;
299895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                }
300895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
301895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                //Trigger no motion callback
302895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                inv_set_motion_state(INV_MOTION);
303895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            }
304895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
305895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (inv_obj->motion_state == INV_NO_MOTION) {
306895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            if ((inv_get_tick_count() - repeatBiasUpdateTime) > 4000) {
307895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                inv_update_bias();
308895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                repeatBiasUpdateTime = inv_get_tick_count();
309895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            }
310895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
311895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
312895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#else                           // CONFIG_MPU_SENSORS_MPU3050
313895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if (inv_get_gyro_present()
314895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        && ((inv_params_obj.bias_mode & INV_BIAS_FROM_FAST_NO_MOTION) == 0)) {
315895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        result = inv_get_mpu_memory(KEY_D_1_98, 2, regs);
316895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (result) {
317895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            LOG_RESULT_LOCATION(result);
318895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            return result;
319895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
320895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
321895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        motionFlag = (unsigned short)regs[0] * 256 + (unsigned short)regs[1];
322895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
323895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        _mlDebug(MPL_LOGV("motionFlag from RAM : 0x%04X\n", motionFlag);
324895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            )
325895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            if (motionFlag > 0) {
326895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            unsigned char biasReg[12];
327895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            long biasTmp2[3], biasTmp[3];
328895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            int i;
329895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
330895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            if (inv_obj->last_motion != motionFlag) {
331895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                result = inv_get_mpu_memory(KEY_D_2_96, 12, biasReg);
332895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
333895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                for (i = 0; i < 3; i++) {
334895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                    biasTmp2[i] = inv_big8_to_int32(&biasReg[i * 4]);
335895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                }
336895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                // Rotate bias vector by the transpose of the orientation matrix
337895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                for (i = 0; i < 3; ++i) {
338895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                    biasTmp[i] =
339895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                        inv_q30_mult(biasTmp2[0],
340895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                                     inv_obj->gyro_orient[i]) +
341895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                        inv_q30_mult(biasTmp2[1],
342895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                                     inv_obj->gyro_orient[i + 3]) +
343895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                        inv_q30_mult(biasTmp2[2], inv_obj->gyro_orient[i + 6]);
344895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                }
345895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                inv_obj->gyro_bias[0] = inv_q30_mult(biasTmp[0], 1501974482L);
346895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                inv_obj->gyro_bias[1] = inv_q30_mult(biasTmp[1], 1501974482L);
347895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                inv_obj->gyro_bias[2] = inv_q30_mult(biasTmp[2], 1501974482L);
348895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            }
349895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            inv_set_motion_state(INV_NO_MOTION);
350895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        } else {
351895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            // We are in a motion state
352895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            inv_set_motion_state(INV_MOTION);
353895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
354895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        inv_obj->last_motion = motionFlag;
355895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
356895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
357895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#endif                          // CONFIG_MPU_SENSORS_MPU3050
358895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return INV_SUCCESS;
359895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
360895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
361895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallinv_error_t inv_enable_bias_no_motion(void)
362895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
363895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_error_t result;
364895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_params_obj.bias_mode |= INV_BIAS_FROM_NO_MOTION;
365895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    result =
366895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        inv_register_fifo_rate_process(MLPollMotionStatus,
367895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                                       INV_PRIORITY_BIAS_NO_MOTION);
368895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#if defined CONFIG_MPU_SENSORS_MPU6050A2 || \
369895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    defined CONFIG_MPU_SENSORS_MPU6050B1
370895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if (result) {
371895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        LOG_RESULT_LOCATION(result);
372895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        return result;
373895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
374895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    result = inv_turn_on_bias_from_no_motion();
375895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#endif
376895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return result;
377895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
378895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
379895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallinv_error_t inv_disable_bias_no_motion(void)
380895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
381895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_error_t result;
382895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_params_obj.bias_mode &= ~INV_BIAS_FROM_NO_MOTION;
383895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    result = inv_unregister_fifo_rate_process(MLPollMotionStatus);
384895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#if defined CONFIG_MPU_SENSORS_MPU6050A2 || \
385895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    defined CONFIG_MPU_SENSORS_MPU6050B1
386895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if (result) {
387895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        LOG_RESULT_LOCATION(result);
388895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        return result;
389895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
390895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    result = inv_turn_off_bias_from_no_motion();
391895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#endif
392895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return result;
393895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
394