1c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/* 2c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro $License: 3c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. 4c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro See included License.txt for License information. 5c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro $ 6c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 7c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 8c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** 9c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @defgroup Data_Builder data_builder 10c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @brief Motion Library - Data Builder 11c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Constructs and Creates the data for MPL 12c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * 13c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @{ 14c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @file data_builder.c 15c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @brief Data Builder. 16c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 17c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 18c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#undef MPL_LOG_NDEBUG 19c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#define MPL_LOG_NDEBUG 1 /* Use 0 to turn on MPL_LOGV output */ 20c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 21c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#include <string.h> 22c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 23c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#include "ml_math_func.h" 24c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#include "data_builder.h" 25c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#include "mlmath.h" 26c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#include "storage_manager.h" 27c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#include "message_layer.h" 28c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#include "results_holder.h" 29c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 30c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#include "log.h" 31c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#undef MPL_LOG_TAG 32c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#define MPL_LOG_TAG "MLLITE" 33c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 34c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarotypedef inv_error_t (*inv_process_cb_func)(struct inv_sensor_cal_t *data); 35c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 36c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarostruct process_t { 37c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_process_cb_func func; 38c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int priority; 39c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int data_required; 40c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro}; 41c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 42c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarostruct inv_data_builder_t { 43c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int num_cb; 44c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro struct process_t process[INV_MAX_DATA_CB]; 45c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro struct inv_db_save_t save; 46c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro struct inv_db_save_mpl_t save_mpl; 47c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro struct inv_db_save_accel_mpl_t save_accel_mpl; 48c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int compass_disturbance; 49c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int mode; 50c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 51c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int debug_mode; 52c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int last_mode; 53c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro FILE *file; 54c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 55c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro}; 56c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 57c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_apply_calibration(struct inv_single_sensor_t *sensor, const long *bias); 58c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarostatic void inv_set_contiguous(void); 59c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 60c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarostatic struct inv_data_builder_t inv_data_builder; 61c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarostatic struct inv_sensor_cal_t sensors; 62c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 63c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 64c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 65c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Turn on data logging to allow playback of same scenario at a later time. 66c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] file File to write to, must be open. 67c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 68c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_turn_on_data_logging(FILE *file) 69c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 70c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro MPL_LOGV("input data logging started\n"); 71c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.file = file; 72c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.debug_mode = RD_RECORD; 73c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 74c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 75c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Turn off data logging to allow playback of same scenario at a later time. 76c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* File passed to inv_turn_on_data_logging() must be closed after calling this. 77c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 78c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_turn_off_data_logging() 79c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 80c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro MPL_LOGV("input data logging stopped\n"); 81c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.debug_mode = RD_NO_DEBUG; 82c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.file = NULL; 83c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 84c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 85c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 86c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Gets last value of raw compass data. 87c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[out] raw Raw compass data in mounting frame in hardware units. Length 3. 88c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 89c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_raw_compass(short *raw) 90c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 91c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(raw, sensors.compass.raw, sizeof(sensors.compass.raw)); 92c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 93c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 94c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This function receives the data that was stored in non-volatile memory between power off */ 95c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarostatic inv_error_t inv_db_load_func(const unsigned char *data) 96c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 97c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(&inv_data_builder.save, data, sizeof(inv_data_builder.save)); 98c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // copy in the saved accuracy in the actual sensors accuracy 99c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.gyro.accuracy = inv_data_builder.save.gyro_accuracy; 100c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.accuracy = inv_data_builder.save.accel_accuracy; 101c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.accuracy = inv_data_builder.save.compass_accuracy; 102c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // TODO 103c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.accel.accuracy == 3) { 104c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_set_accel_bias_found(1); 105c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 106c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.compass.accuracy == 3) { 107c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_set_compass_bias_found(1); 108c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 109c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_SUCCESS; 110c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 111c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 112c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This function returns the data to be stored in non-volatile memory between power off */ 113c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarostatic inv_error_t inv_db_save_func(unsigned char *data) 114c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 115c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(data, &inv_data_builder.save, sizeof(inv_data_builder.save)); 116c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_SUCCESS; 117c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 118c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 119c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This function receives the data for mpl that was stored in non-volatile memory between power off */ 120c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarostatic inv_error_t inv_db_load_mpl_func(const unsigned char *data) 121c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 122c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(&inv_data_builder.save_mpl, data, sizeof(inv_data_builder.save_mpl)); 123c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 124c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_SUCCESS; 125c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 126c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 127c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This function returns the data for mpl to be stored in non-volatile memory between power off */ 128c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarostatic inv_error_t inv_db_save_mpl_func(unsigned char *data) 129c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 130c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(data, &inv_data_builder.save_mpl, sizeof(inv_data_builder.save_mpl)); 131c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_SUCCESS; 132c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 133c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 134c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This function receives the data for mpl that was stored in non-volatile memory between power off */ 135c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarostatic inv_error_t inv_db_load_accel_mpl_func(const unsigned char *data) 136c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 137c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(&inv_data_builder.save_accel_mpl, data, sizeof(inv_data_builder.save_accel_mpl)); 138c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 139c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_SUCCESS; 140c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 141c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 142c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This function returns the data for mpl to be stored in non-volatile memory between power off */ 143c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarostatic inv_error_t inv_db_save_accel_mpl_func(unsigned char *data) 144c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 145c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(data, &inv_data_builder.save_accel_mpl, sizeof(inv_data_builder.save_accel_mpl)); 146c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_SUCCESS; 147c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 148c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 149c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Initialize the data builder 150c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 151c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroinv_error_t inv_init_data_builder(void) 152c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 153c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro /* TODO: Hardcode temperature scale/offset here. */ 154c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memset(&inv_data_builder, 0, sizeof(inv_data_builder)); 155c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memset(&sensors, 0, sizeof(sensors)); 156c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 157c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // disable the soft iron transform process 158c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_reset_compass_soft_iron_matrix(); 159c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 160c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return ((inv_register_load_store(inv_db_load_func, inv_db_save_func, 161c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sizeof(inv_data_builder.save), 162c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro INV_DB_SAVE_KEY)) 163c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro | (inv_register_load_store(inv_db_load_mpl_func, inv_db_save_mpl_func, 164c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sizeof(inv_data_builder.save_mpl), 165c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro INV_DB_SAVE_MPL_KEY)) 166c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro | (inv_register_load_store(inv_db_load_accel_mpl_func, inv_db_save_accel_mpl_func, 167c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sizeof(inv_data_builder.save_accel_mpl), 168c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro INV_DB_SAVE_ACCEL_MPL_KEY)) ); 169c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 170c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 171c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Gyro sensitivity. 172c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @return A scale factor to convert device units to degrees per second scaled by 2^16 173c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* such that degrees_per_second = device_units * sensitivity / 2^30. Typically 174c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* it works out to be the maximum rate * 2^15. 175c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 176c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarolong inv_get_gyro_sensitivity(void) 177c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 178c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return sensors.gyro.sensitivity; 179c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 180c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 181c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Accel sensitivity. 182c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @return A scale factor to convert device units to g's scaled by 2^16 183c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* such that g_s = device_units * sensitivity / 2^30. Typically 184c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* it works out to be the maximum accel value in g's * 2^15. 185c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 186c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarolong inv_get_accel_sensitivity(void) 187c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 188c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return sensors.accel.sensitivity; 189c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 190c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 191c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Compass sensitivity. 192c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @return A scale factor to convert device units to micro Tesla scaled by 2^16 193c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* such that uT = device_units * sensitivity / 2^30. Typically 194c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* it works out to be the maximum uT * 2^15. 195c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 196c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarolong inv_get_compass_sensitivity(void) 197c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 198c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return sensors.compass.sensitivity; 199c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 200c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 201c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Sets orientation and sensitivity field for a sensor. 202c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[out] sensor Structure to apply settings to 203c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] orientation Orientation description of how part is mounted. 204c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] sensitivity A Scale factor to convert from hardware units to 205c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* standard units (dps, uT, g). 206c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 207c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid set_sensor_orientation_and_scale(struct inv_single_sensor_t *sensor, 208c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int orientation, long sensitivity) 209c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 210c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int error = 0; 211c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 212c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (!sensitivity) { 213c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // Sensitivity can't be zero 214c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensitivity = 1L<<16; 215c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro MPL_LOGE("\n\nCritical error! Sensitivity is zero.\n\n"); 216c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 217c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 218c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensor->sensitivity = sensitivity; 219c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // Make sure we don't describe some impossible orientation 220c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((orientation & 3) == 3) { 221c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro error = 1; 222c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 223c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((orientation & 0x18) == 0x18) { 224c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro error = 1; 225c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 226c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((orientation & 0xc0) == 0xc0) { 227c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro error = 1; 228c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 229c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (error) { 230c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro orientation = 0x88; // Identity 231c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro MPL_LOGE("\n\nCritical error! Impossible mounting orientation given. Using Identity instead\n\n"); 232c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 233c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensor->orientation = orientation; 234c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 235c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 236c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Sets the Orientation and Sensitivity of the gyro data. 237c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] orientation A scalar defining the transformation from chip mounting 238c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* to the body frame. The function inv_orientation_matrix_to_scalar() 239c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* can convert the transformation matrix to this scalar and describes the 240c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* scalar in further detail. 241c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] sensitivity A scale factor to convert device units to degrees per second scaled by 2^16 242c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* such that degrees_per_second = device_units * sensitivity / 2^30. Typically 243c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* it works out to be the maximum rate * 2^15. 244c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 245c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_gyro_orientation_and_scale(int orientation, long sensitivity) 246c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 247c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 248c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 249c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_G_ORIENT; 250c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 251c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&orientation, sizeof(orientation), 1, inv_data_builder.file); 252c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&sensitivity, sizeof(sensitivity), 1, inv_data_builder.file); 253c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 254c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 255c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro set_sensor_orientation_and_scale(&sensors.gyro, orientation, 256c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensitivity); 257c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 258c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 259c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Set Gyro Sample rate in micro seconds. 260c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] sample_rate_us Set Gyro Sample rate in us 261c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 262c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_gyro_sample_rate(long sample_rate_us) 263c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 264c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 265c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 266c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_G_SAMPLE_RATE; 267c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 268c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&sample_rate_us, sizeof(sample_rate_us), 1, inv_data_builder.file); 269c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 270c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 271c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.gyro.sample_rate_us = sample_rate_us; 272c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.gyro.sample_rate_ms = sample_rate_us / 1000; 273c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.gyro.bandwidth == 0) { 274c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.gyro.bandwidth = (int)(1000000L / sample_rate_us); 275c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 276c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 277c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 278c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Set Accel Sample rate in micro seconds. 279c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] sample_rate_us Set Accel Sample rate in us 280c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 281c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_accel_sample_rate(long sample_rate_us) 282c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 283c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 284c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 285c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_A_SAMPLE_RATE; 286c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 287c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&sample_rate_us, sizeof(sample_rate_us), 1, inv_data_builder.file); 288c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 289c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 290c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.sample_rate_us = sample_rate_us; 291c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.sample_rate_ms = sample_rate_us / 1000; 292c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.accel.bandwidth == 0) { 293c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.bandwidth = (int)(1000000L / sample_rate_us); 294c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 295c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 296c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 297c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Pick the smallest non-negative number. Priority to td1 on equal 298c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* If both are negative, return the largest. 299c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 300c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarostatic int inv_pick_best_time_difference(long td1, long td2) 301c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 302c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (td1 >= 0) { 303c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (td2 >= 0) { 304c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (td1 <= td2) { 305c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // td1 306c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; 307c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } else { 308c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // td2 309c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 1; 310c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 311c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } else { 312c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // td1 313c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; 314c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 315c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } else if (td2 >= 0) { 316c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // td2 317c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 1; 318c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } else { 319c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // Both are negative 320c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (td1 >= td2) { 321c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // td1 322c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; 323c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } else { 324c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // td2 325c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 1; 326c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 327c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 328c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 329c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 330c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Returns timestame based upon a raw sensor, and returns if that sample has a new piece of data. 331c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 332c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarostatic int inv_raw_sensor_timestamp(int sensor_number, inv_time_t *ts) 333c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 334c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int status = 0; 335c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro switch (sensor_number) { 336c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro case 0: // Quat 337c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *ts = sensors.quat.timestamp; 338c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.mode & INV_QUAT_NEW) 339c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.quat.timestamp_prev != sensors.quat.timestamp) 340c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro status = 1; 341c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return status; 342c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro case 1: // Gyro 343c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *ts = sensors.gyro.timestamp; 344c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.mode & INV_GYRO_NEW) 345c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.gyro.timestamp_prev != sensors.gyro.timestamp) 346c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro status = 1; 3472eed2d4028b5706e977b016e49b010ee5595e48aNick Vaccaro return status; 3482eed2d4028b5706e977b016e49b010ee5595e48aNick Vaccaro case 2: // Accel 3492eed2d4028b5706e977b016e49b010ee5595e48aNick Vaccaro *ts = sensors.accel.timestamp; 3502eed2d4028b5706e977b016e49b010ee5595e48aNick Vaccaro if (inv_data_builder.mode & INV_ACCEL_NEW) 3512eed2d4028b5706e977b016e49b010ee5595e48aNick Vaccaro if (sensors.accel.timestamp_prev != sensors.accel.timestamp) 3522eed2d4028b5706e977b016e49b010ee5595e48aNick Vaccaro status = 1; 353c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return status; 3542eed2d4028b5706e977b016e49b010ee5595e48aNick Vaccaro case 3: // Compass 355c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *ts = sensors.compass.timestamp; 356c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.mode & INV_MAG_NEW) 357c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.compass.timestamp_prev != sensors.compass.timestamp) 358c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro status = 1; 359c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return status; 360c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro default: 361c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *ts = 0; 362c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; 363c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 364c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; 365c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 366c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 367c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Gets best timestamp and if there is a new piece of data for a 9-axis sensor combination. 368c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* It does this by finding a raw sensor that has the closest sample rate that is at least as 369c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* often desired. It also returns if that raw sensor has a new piece of data. 370c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* Priority is 9-axis quat, 6-axis quat, 3-axis quat, gyro, compass, accel on ties. 371c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @return Returns 1, if the raw sensor being attached has new data, 0 otherwise. 372c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 373c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroint inv_get_9_axis_timestamp(long sample_rate_us, inv_time_t *ts) 374c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 375c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int status = 0; 376c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro long td[3]; 377c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int idx,idx2; 378c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 379c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((sensors.quat.status & (INV_QUAT_9AXIS | INV_SENSOR_ON)) == (INV_QUAT_9AXIS | INV_SENSOR_ON)) { 380c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // 9-axis from DMP 381c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *ts = sensors.quat.timestamp; 382c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.mode & INV_QUAT_NEW) 383c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.quat.timestamp_prev != sensors.quat.timestamp) 384c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro status = 1; 385c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return status; 386c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 387c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 388c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((sensors.compass.status & INV_SENSOR_ON) == 0) { 389c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; // Compass must be on 390c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 391c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 392c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // At this point, we know compass is on. Check if accel or 6-axis quat is on 393c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro td[0] = sample_rate_us - sensors.quat.sample_rate_us; 394c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro td[1] = sample_rate_us - sensors.compass.sample_rate_us; 395c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((sensors.quat.status & (INV_QUAT_6AXIS | INV_SENSOR_ON)) == (INV_QUAT_6AXIS | INV_SENSOR_ON)) { 396c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // Sensor tied to compass or 6-axis 397c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx = inv_pick_best_time_difference(td[0], td[1]); 3982eed2d4028b5706e977b016e49b010ee5595e48aNick Vaccaro idx *= 3; // Sensor number is 0 (Quat) or 3 (Compass) 399c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return inv_raw_sensor_timestamp(idx, ts); 400c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } else if ((sensors.accel.status & INV_SENSOR_ON) == 0) { 401c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; // Accel must be on or 6-axis quat must be on 402c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 403c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 404c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // At this point, we know accel is on. Check if 3-axis quat is on 405c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro td[2] = sample_rate_us - sensors.accel.sample_rate_us; 406c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((sensors.quat.status & (INV_QUAT_3AXIS | INV_SENSOR_ON)) == (INV_QUAT_3AXIS | INV_SENSOR_ON)) { 407c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx = inv_pick_best_time_difference(td[0], td[1]); 408c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx2 = inv_pick_best_time_difference(td[idx], td[2]); 409c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (idx2 == 1) 410c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx = 2; 411c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (idx > 0) 412c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx++; // Skip gyro sensor in next function call 413c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // 0 = quat, 2 = compass, 3=accel 414c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return inv_raw_sensor_timestamp(idx, ts); 415c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 416c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 417c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // No Quaternion data from outside, Gyro must be on 418c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((sensors.gyro.status & INV_SENSOR_ON) == 0) { 419c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; // Gyro must be on 420c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 421c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 422c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro td[0] = sample_rate_us - sensors.gyro.sample_rate_us; 423c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx = inv_pick_best_time_difference(td[0], td[1]); 424c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx2 = inv_pick_best_time_difference(td[idx], td[2]); 425c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (idx2 == 1) 426c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx = 2; 427c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx++; 428c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // 1 = gyro, 2 = compass, 3=accel 429c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return inv_raw_sensor_timestamp(idx, ts); 430c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 431c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 432c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Gets best timestamp and if there is a new piece of data for a 9-axis sensor combination. 433c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* It does this by finding a raw sensor that has the closest sample rate that is at least as 434c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* often desired. It also returns if that raw sensor has a new piece of data. 435c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* Priority compass, accel on a tie 436c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @return Returns 1, if the raw sensor being attached has new data, 0 otherwise. 437c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 438c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroint inv_get_6_axis_compass_accel_timestamp(long sample_rate_us, inv_time_t *ts) 439c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 440c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro long td[2]; 441c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int idx; 442c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 443c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((sensors.compass.status & INV_SENSOR_ON) == 0) { 444c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; // Compass must be on 445c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 446c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((sensors.accel.status & INV_SENSOR_ON) == 0) { 447c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; // Accel must be on 448c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 449c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 450c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // At this point, we know compass & accel are both on. 4512eed2d4028b5706e977b016e49b010ee5595e48aNick Vaccaro td[0] = sample_rate_us - sensors.accel.sample_rate_us; 4522eed2d4028b5706e977b016e49b010ee5595e48aNick Vaccaro td[1] = sample_rate_us - sensors.compass.sample_rate_us; 453c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx = inv_pick_best_time_difference(td[0], td[1]); 454c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx += 2; 455c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return inv_raw_sensor_timestamp(idx, ts); 456c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 457c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 458c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Gets best timestamp and if there is a new piece of data for a 9-axis sensor combination. 459c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* It does this by finding a raw sensor that has the closest sample rate that is at least as 460c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* often desired. It also returns if that raw sensor has a new piece of data. 461c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* Priority is Quaternion-6axis, Quaternion 3-axis, Gyro, Accel 462c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @return Returns 1, if the raw sensor being attached has new data, 0 otherwise. 463c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 464c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroint inv_get_6_axis_gyro_accel_timestamp(long sample_rate_us, inv_time_t *ts) 465c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 466c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro long td[2]; 467c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int idx; 468c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 469c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((sensors.quat.status & (INV_QUAT_6AXIS | INV_SENSOR_ON)) == (INV_QUAT_6AXIS | INV_SENSOR_ON)) { 470c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // Sensor number is 0 (Quat) 471c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return inv_raw_sensor_timestamp(0, ts); 472c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } else if ((sensors.accel.status & INV_SENSOR_ON) == 0) { 473c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; // Accel must be on or 6-axis quat must be on 474c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 475c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 476c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // At this point, we know accel is on. Check if 3-axis quat is on 477c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro td[0] = sample_rate_us - sensors.quat.sample_rate_us; 478c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro td[1] = sample_rate_us - sensors.accel.sample_rate_us; 479c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((sensors.quat.status & (INV_QUAT_3AXIS | INV_SENSOR_ON)) == (INV_QUAT_3AXIS | INV_SENSOR_ON)) { 480c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx = inv_pick_best_time_difference(td[0], td[1]); 4812eed2d4028b5706e977b016e49b010ee5595e48aNick Vaccaro idx *= 2; 482c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // 0 = quat, 3=accel 483c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return inv_raw_sensor_timestamp(idx, ts); 484c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 485c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 486c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // No Quaternion data from outside, Gyro must be on 487c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((sensors.gyro.status & INV_SENSOR_ON) == 0) { 488c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; // Gyro must be on 489c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 490c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 491c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro td[0] = sample_rate_us - sensors.gyro.sample_rate_us; 492c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx = inv_pick_best_time_difference(td[0], td[1]); 493c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx *= 2; // 0=gyro 2=accel 494c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro idx++; 495c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // 1 = gyro, 3=accel 496c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return inv_raw_sensor_timestamp(idx, ts); 497c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 498c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 499c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Set Compass Sample rate in micro seconds. 500c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] sample_rate_us Set Gyro Sample rate in micro seconds. 501c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 502c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_compass_sample_rate(long sample_rate_us) 503c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 504c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 505c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 506c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_C_SAMPLE_RATE; 507c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 508c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&sample_rate_us, sizeof(sample_rate_us), 1, inv_data_builder.file); 509c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 510c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 511c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.sample_rate_us = sample_rate_us; 512c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.sample_rate_ms = sample_rate_us / 1000; 513c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.compass.bandwidth == 0) { 514c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.bandwidth = (int)(1000000L / sample_rate_us); 515c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 516c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 517c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 518c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_gyro_sample_rate_ms(long *sample_rate_ms) 519c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 520c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *sample_rate_ms = sensors.gyro.sample_rate_ms; 521c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 522c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 523c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_accel_sample_rate_ms(long *sample_rate_ms) 524c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 525c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *sample_rate_ms = sensors.accel.sample_rate_ms; 526c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 527c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 528c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_compass_sample_rate_ms(long *sample_rate_ms) 529c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 530c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *sample_rate_ms = sensors.compass.sample_rate_ms; 531c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 532c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 533c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Set Quat Sample rate in micro seconds. 534c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] sample_rate_us Set Quat Sample rate in us 535c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 536c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_quat_sample_rate(long sample_rate_us) 537c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 538c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 539c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 540c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_Q_SAMPLE_RATE; 541c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 542c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&sample_rate_us, sizeof(sample_rate_us), 1, inv_data_builder.file); 543c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 544c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 545c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.quat.sample_rate_us = sample_rate_us; 546c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.quat.sample_rate_ms = sample_rate_us / 1000; 547c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 548c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 549c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Set Gyro Bandwidth in Hz 550c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] bandwidth_hz Gyro bandwidth in Hz 551c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 552c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_gyro_bandwidth(int bandwidth_hz) 553c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 554c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.gyro.bandwidth = bandwidth_hz; 555c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 556c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 557c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Set Accel Bandwidth in Hz 558c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] bandwidth_hz Gyro bandwidth in Hz 559c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 560c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_accel_bandwidth(int bandwidth_hz) 561c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 562c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.bandwidth = bandwidth_hz; 563c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 564c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 565c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Set Compass Bandwidth in Hz 566c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] bandwidth_hz Gyro bandwidth in Hz 567c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 568c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_compass_bandwidth(int bandwidth_hz) 569c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 570c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.bandwidth = bandwidth_hz; 571c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 572c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 573c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Helper function stating whether the compass is on or off. 574c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @return TRUE if compass if on, 0 if compass if off 575c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 576c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroint inv_get_compass_on() 577c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 578c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return (sensors.compass.status & INV_SENSOR_ON) == INV_SENSOR_ON; 579c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 580c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 581c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Helper function stating whether the gyro is on or off. 582c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @return TRUE if gyro if on, 0 if gyro if off 583c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 584c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroint inv_get_gyro_on() 585c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 586c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return (sensors.gyro.status & INV_SENSOR_ON) == INV_SENSOR_ON; 587c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 588c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 589c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Helper function stating whether the acceleromter is on or off. 590c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @return TRUE if accel if on, 0 if accel if off 591c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 592c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroint inv_get_accel_on() 593c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 594c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return (sensors.accel.status & INV_SENSOR_ON) == INV_SENSOR_ON; 595c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 596c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 597c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Get last timestamp across all 3 sensors that are on. 598c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* This find out which timestamp has the largest value for sensors that are on. 599c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @return Returns INV_SUCCESS if successful or an error code if not. 600c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 601c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroinv_time_t inv_get_last_timestamp() 602c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 603c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_time_t timestamp = 0; 604c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.accel.status & INV_SENSOR_ON) { 605c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro timestamp = sensors.accel.timestamp; 606c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 607c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.gyro.status & INV_SENSOR_ON) { 608c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (timestamp < sensors.gyro.timestamp) { 609c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro timestamp = sensors.gyro.timestamp; 610c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 611c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro MPL_LOGV("g ts: %lld", timestamp); 612c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 613c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.compass.status & INV_SENSOR_ON) { 614c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (timestamp < sensors.compass.timestamp) { 615c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro timestamp = sensors.compass.timestamp; 616c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 617c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 618c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.temp.status & INV_SENSOR_ON) { 619c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (timestamp < sensors.temp.timestamp) { 620c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro timestamp = sensors.temp.timestamp; 621c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 622c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 623c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.quat.status & INV_SENSOR_ON) { 624c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (timestamp < sensors.quat.timestamp) { 625c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro timestamp = sensors.quat.timestamp; 626c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 627c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro MPL_LOGV("q ts: %lld", timestamp); 628c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 629c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 630c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return timestamp; 631c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 632c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 633c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Sets the orientation and sensitivity of the gyro data. 634c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] orientation A scalar defining the transformation from chip mounting 635c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* to the body frame. The function inv_orientation_matrix_to_scalar() 636c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* can convert the transformation matrix to this scalar and describes the 637c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* scalar in further detail. 638c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] sensitivity A scale factor to convert device units to g's 639c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* such that g's = device_units * sensitivity / 2^30. Typically 640c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* it works out to be the maximum g_value * 2^15. 641c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 642c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_accel_orientation_and_scale(int orientation, long sensitivity) 643c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 644c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 645c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 646c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_A_ORIENT; 647c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 648c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&orientation, sizeof(orientation), 1, inv_data_builder.file); 649c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&sensitivity, sizeof(sensitivity), 1, inv_data_builder.file); 650c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 651c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 652c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro set_sensor_orientation_and_scale(&sensors.accel, orientation, 653c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensitivity); 654c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 655c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 656c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Sets the Orientation and Sensitivity of the gyro data. 657c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] orientation A scalar defining the transformation from chip mounting 658c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* to the body frame. The function inv_orientation_matrix_to_scalar() 659c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* can convert the transformation matrix to this scalar and describes the 660c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* scalar in further detail. 661c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] sensitivity A scale factor to convert device units to uT 662c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* such that uT = device_units * sensitivity / 2^30. Typically 663c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* it works out to be the maximum uT_value * 2^15. 664c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 665c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_compass_orientation_and_scale(int orientation, long sensitivity) 666c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 667c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 668c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 669c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_C_ORIENT; 670c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 671c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&orientation, sizeof(orientation), 1, inv_data_builder.file); 672c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&sensitivity, sizeof(sensitivity), 1, inv_data_builder.file); 673c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 674c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 675c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro set_sensor_orientation_and_scale(&sensors.compass, orientation, sensitivity); 676c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 677c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 678c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_matrix_vector_mult(const long *A, const long *x, long *y) 679c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 680c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro y[0] = inv_q30_mult(A[0], x[0]) + inv_q30_mult(A[1], x[1]) + inv_q30_mult(A[2], x[2]); 681c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro y[1] = inv_q30_mult(A[3], x[0]) + inv_q30_mult(A[4], x[1]) + inv_q30_mult(A[5], x[2]); 682c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro y[2] = inv_q30_mult(A[6], x[0]) + inv_q30_mult(A[7], x[1]) + inv_q30_mult(A[8], x[2]); 683c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 684c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 685c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Takes raw data stored in the sensor, removes bias, and converts it to 686c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* calibrated data in the body frame. Also store raw data for body frame. 687c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in,out] sensor structure to modify 688c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] bias bias in the mounting frame, in hardware units scaled by 689c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* 2^16. Length 3. 690c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 691c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_apply_calibration(struct inv_single_sensor_t *sensor, const long *bias) 692c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 693c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro long raw32[3]; 694c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 695c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // Convert raw to calibrated 696c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro raw32[0] = (long)sensor->raw[0] << 15; 697c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro raw32[1] = (long)sensor->raw[1] << 15; 698c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro raw32[2] = (long)sensor->raw[2] << 15; 699c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 700c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_convert_to_body_with_scale(sensor->orientation, sensor->sensitivity << 1, raw32, sensor->raw_scaled); 701c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 702c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro raw32[0] -= bias[0] >> 1; 703c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro raw32[1] -= bias[1] >> 1; 704c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro raw32[2] -= bias[2] >> 1; 705c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 706c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_convert_to_body_with_scale(sensor->orientation, sensor->sensitivity << 1, raw32, sensor->calibrated); 707c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 708c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensor->status |= INV_CALIBRATED; 709c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 710c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 711c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Returns the current bias for the compass 712c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[out] bias Compass bias in hardware units scaled by 2^16. In mounting frame. 713c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* Length 3. 714c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 715c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_compass_bias(long *bias) 716c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 717c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (bias != NULL) { 718c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(bias, inv_data_builder.save.compass_bias, sizeof(inv_data_builder.save.compass_bias)); 719c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 720c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 721c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 722c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Sets the compass bias 723c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] bias Length 3, in body frame, in hardware units scaled by 2^16 to allow fractional bit correction. 724c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] accuracy Accuracy of compass data, where 3=most accurate, and 0=least accurate. 725c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 726c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_compass_bias(const long *bias, int accuracy) 727c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 728c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (memcmp(inv_data_builder.save.compass_bias, bias, sizeof(inv_data_builder.save.compass_bias))) { 729c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(inv_data_builder.save.compass_bias, bias, sizeof(inv_data_builder.save.compass_bias)); 730c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_apply_calibration(&sensors.compass, inv_data_builder.save.compass_bias); 731c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 732c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.accuracy = accuracy; 733c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save.compass_accuracy = accuracy; 734c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_set_message(INV_MSG_NEW_CB_EVENT, INV_MSG_NEW_CB_EVENT, 0); 735c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 736c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 737c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Set the state of a compass disturbance 738c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] dist 1=disturbance, 0=no disturbance 739c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 740c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_compass_disturbance(int dist) 741c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 742c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.compass_disturbance = dist; 743c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 744c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 745c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroint inv_get_compass_disturbance(void) { 746c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return inv_data_builder.compass_disturbance; 747c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 748c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 749c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** 750c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Sets the factory accel bias 751c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] bias 752c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Accel bias in hardware units (+/- 2 gee full scale assumed) 753c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * scaled by 2^16. In chip mounting frame. Length of 3. 754c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 755c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_accel_bias(const long *bias) 756c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 757c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (!bias) 758c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return; 759c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 760c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (memcmp(inv_data_builder.save.factory_accel_bias, bias, 761c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sizeof(inv_data_builder.save.factory_accel_bias))) { 762c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(inv_data_builder.save.factory_accel_bias, bias, 763c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sizeof(inv_data_builder.save.factory_accel_bias)); 764c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 765c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_set_message(INV_MSG_NEW_FAB_EVENT, INV_MSG_NEW_FAB_EVENT, 0); 766c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 767c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 768c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Sets the accel accuracy. 769c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] accuracy Accuracy rating from 0 to 3, with 3 being most accurate. 770c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 771c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_accel_accuracy(int accuracy) 772c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 773c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.accuracy = accuracy; 774c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save.accel_accuracy = accuracy; 775c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 776c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 777c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Sets the accel bias with control over which axis. 778c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] bias Accel bias, length 3. In HW units scaled by 2^16 in body frame 779c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] accuracy Accuracy rating from 0 to 3, with 3 being most accurate. 780c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] mask Mask to select axis to apply bias set. 781c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 782c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_accel_bias_mask(const long *bias, int accuracy, int mask) 783c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 784c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (bias) { 785c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (mask & 1){ 786c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save_accel_mpl.accel_bias[0] = bias[0]; 787c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 788c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (mask & 2){ 789c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save_accel_mpl.accel_bias[1] = bias[1]; 790c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 791c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (mask & 4){ 792c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save_accel_mpl.accel_bias[2] = bias[2]; 793c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 794c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 795c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_apply_calibration(&sensors.accel, inv_data_builder.save_accel_mpl.accel_bias); 796c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 797c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_set_accel_accuracy(accuracy); 798c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_set_message(INV_MSG_NEW_AB_EVENT, INV_MSG_NEW_AB_EVENT, 0); 799c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 800c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 801c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef WIN32 802c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Sends out a message to activate writing 9-axis quaternion to the DMP. 803c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 804c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_overwrite_dmp_9quat(void) 805c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 806c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_set_message(INV_MSG_NEW_DMP_QUAT_WRITE_EVENT, INV_MSG_NEW_DMP_QUAT_WRITE_EVENT, 0); 807c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 808c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 809c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 810c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** 811c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Sets the factory gyro bias 812c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] bias 813c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Gyro bias in hardware units (+/- 2000 dps full scale assumed) 814c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * scaled by 2^16. In chip mounting frame. Length of 3. 815c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 816c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_gyro_bias(const long *bias) 817c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 818c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (!bias) 819c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return; 820c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 821c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (memcmp(inv_data_builder.save.factory_gyro_bias, bias, 822c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sizeof(inv_data_builder.save.factory_gyro_bias))) { 823c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(inv_data_builder.save.factory_gyro_bias, bias, 824c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sizeof(inv_data_builder.save.factory_gyro_bias)); 825c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 826c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_set_message(INV_MSG_NEW_FGB_EVENT, INV_MSG_NEW_FGB_EVENT, 0); 827c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 828c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 829c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** 830c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Sets the mpl gyro bias 831c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] bias 832c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Gyro bias in hardware units scaled by 2^16 (+/- 2000 dps full 833c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * scale assumed). In chip mounting frame. Length 3. 834c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] accuracy 835c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Accuracy of bias. 0 = least accurate, 3 = most accurate. 836c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 837c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_mpl_gyro_bias(const long *bias, int accuracy) 838c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 839c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (bias != NULL) { 840c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (memcmp(inv_data_builder.save_mpl.gyro_bias, bias, 841c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sizeof(inv_data_builder.save_mpl.gyro_bias))) { 842c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(inv_data_builder.save_mpl.gyro_bias, bias, 843c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sizeof(inv_data_builder.save_mpl.gyro_bias)); 844c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_apply_calibration(&sensors.gyro, 845c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save_mpl.gyro_bias); 846c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 847c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 848c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.gyro.accuracy = accuracy; 849c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save.gyro_accuracy = accuracy; 850c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 851c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro /* TODO: What should we do if there's no temperature data? */ 852c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.temp.calibrated[0]) 853c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save.gyro_temp = sensors.temp.calibrated[0]; 854c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro else 855c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro /* Set to 27 deg C for now until we've got a better solution. */ 856c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save.gyro_temp = 27L << 16; 857c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_set_message(INV_MSG_NEW_GB_EVENT, INV_MSG_NEW_GB_EVENT, 0); 858c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 859c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro /* TODO: this flag works around the synchronization problem seen with using 860c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro the user-exposed message layer to signal the temperature compensation 861c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro module that gyro biases were set. 862c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro A better, cleaner method is certainly needed. */ 863c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save.gyro_bias_tc_set = true; 864c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 865c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 866c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** 867c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @internal 868c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @brief Return whether gyro biases were set to signal the temperature 869c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * compensation algorithm that it can collect a data point to build 870c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * the temperature slope while in no motion state. 871c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * The flag clear automatically after is read. 872c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @return true if the flag was set, indicating gyro biases were set. 873c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * false if the flag was not set. 874c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 875c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroint inv_get_gyro_bias_tc_set(void) 876c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 877c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int flag = (inv_data_builder.save.gyro_bias_tc_set == true); 878c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save.gyro_bias_tc_set = false; 879c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return flag; 880c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 881c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 882c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 883c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** 884c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Get the mpl gyro biases 885c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] bias 886c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Gyro calibrated bias. 887c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Length 3. 888c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 889c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_mpl_gyro_bias(long *bias, long *temp) 890c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 891c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (bias != NULL) 892c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(bias, inv_data_builder.save_mpl.gyro_bias, 893c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sizeof(inv_data_builder.save_mpl.gyro_bias)); 894c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 895c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (temp != NULL) 896c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro temp[0] = inv_data_builder.save.gyro_temp; 897c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 898c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 899c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Gyro Bias in the form used by the DMP. 900c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[out] bias Gyro Bias in the form used by the DMP. It is scaled appropriately 901c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* and is in the body frame as needed. If this bias is applied in the DMP 902c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* then any quaternion must have the flag INV_BIAS_APPLIED set if it is a 903c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* 3-axis quaternion, or INV_QUAT_6AXIS if it is a 6-axis quaternion 904c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 905c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_gyro_bias_dmp_units(long *bias) 906c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 907c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (bias == NULL) 908c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return; 909c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_convert_to_body_with_scale(sensors.gyro.orientation, 46850825L, 910c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save_mpl.gyro_bias, bias); 911c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 912c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 913c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/* TODO: Add this information to inv_sensor_cal_t */ 914c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** 915c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Get the gyro biases and temperature record from MPL 916c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] bias 917c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Gyro bias in hardware units scaled by 2^16. 918c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * In chip mounting frame. 919c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Length 3. 920c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 921c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_gyro_bias(long *bias) 922c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 923c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (bias != NULL) 924c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(bias, inv_data_builder.save.factory_gyro_bias, 925c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sizeof(inv_data_builder.save.factory_gyro_bias)); 926c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 927c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 928c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** 929c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Get factory accel bias mask 930c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] bias 931c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Accel bias mask 932c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * 1 is set, 0 is not set, Length 3 = x,y,z. 933c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 934c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroint inv_get_factory_accel_bias_mask() 935c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 936c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro long bias[3]; 937c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int bias_mask = 0; 938c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_get_accel_bias(bias); 939c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (bias != NULL) { 940c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int i; 941c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for(i = 0; i < 3; i++) { 942c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if(bias[i] != 0) { 943c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro bias_mask |= 1 << i; 944c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } else { 945c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro bias_mask &= ~ (1 << i); 946c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 947c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 948c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 949c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return bias_mask; 950c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 951c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 952c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** 953c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Get accel bias from MPL 954c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] bias 955c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Accel bias in hardware units scaled by 2^16. 956c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * In chp mounting frame. 957c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Length 3. 958c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 959c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_accel_bias(long *bias) 960c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 961c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (bias != NULL) 962c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(bias, inv_data_builder.save.factory_accel_bias, 963c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sizeof(inv_data_builder.save.factory_accel_bias)); 964c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 965c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 966c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Get Accel Bias 967c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[out] bias Accel bias 968c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[out] temp Temperature where 1 C = 2^16 969c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 970c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_mpl_accel_bias(long *bias, long *temp) 971c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 972c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (bias != NULL) 973c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(bias, inv_data_builder.save_accel_mpl.accel_bias, 974c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sizeof(inv_data_builder.save_accel_mpl.accel_bias)); 975c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (temp != NULL) 976c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro temp[0] = inv_data_builder.save.accel_temp; 977c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 978c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 979c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Accel Bias in the form used by the DMP. 980c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[out] bias Accel Bias in the form used by the DMP. It is scaled appropriately 981c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* and is in the body frame as needed. 982c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 983c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_accel_bias_dmp_units(long *bias) 984c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 985c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (bias == NULL) 986c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return; 987c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_convert_to_body_with_scale(sensors.accel.orientation, 536870912L, 988c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save_accel_mpl.accel_bias, bias); 989c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 990c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 991c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** 992c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Record new accel data for use when inv_execute_on_data() is called 993c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] accel 994c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * accel data, length 3. 995c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Calibrated data is in m/s^2 scaled by 2^16 in body frame. 996c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Raw data is in device units in chip mounting frame. 997c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] status 998c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Lower 2 bits are the accuracy, with 0 being inaccurate, and 3 999c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * being most accurate. 1000c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * The upper bit INV_CALIBRATED, is set if the data was calibrated 1001c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * outside MPL and it is not set if the data being passed is raw. 1002c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Raw data should be in device units, typically in a 16-bit range. 1003c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] timestamp 1004c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * Monotonic time stamp, for Android it's in nanoseconds. 1005c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @return Returns INV_SUCCESS if successful or an error code if not. 1006c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 1007c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroinv_error_t inv_build_accel(const long *accel, int status, inv_time_t timestamp) 1008c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1009c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 1010c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 1011c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_ACCEL; 1012c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 1013c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(accel, sizeof(accel[0]), 3, inv_data_builder.file); 1014c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); 1015c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1016c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 1017c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1018c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((status & INV_CALIBRATED) == 0) { 1019c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.raw[0] = (short)accel[0]; 1020c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.raw[1] = (short)accel[1]; 1021c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.raw[2] = (short)accel[2]; 1022c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.status |= INV_RAW_DATA; 1023c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_apply_calibration(&sensors.accel, inv_data_builder.save_accel_mpl.accel_bias); 1024c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } else { 1025c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.calibrated[0] = accel[0]; 1026c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.calibrated[1] = accel[1]; 1027c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.calibrated[2] = accel[2]; 1028c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.status |= INV_CALIBRATED; 1029c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.accuracy = status & 3; 1030c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save.accel_accuracy = status & 3; 1031c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1032c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.status |= INV_NEW_DATA | INV_SENSOR_ON; 1033c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.timestamp_prev = sensors.accel.timestamp; 1034c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.timestamp = timestamp; 1035c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1036c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_SUCCESS; 1037c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1038c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1039c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Record new gyro data and calls inv_execute_on_data() if previous 1040c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* sample has not been processed. 1041c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] gyro Data is in device units. Length 3. 1042c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] timestamp Monotonic time stamp, for Android it's in nanoseconds. 1043c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[out] executed Set to 1 if data processing was done. 1044c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @return Returns INV_SUCCESS if successful or an error code if not. 1045c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1046c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroinv_error_t inv_build_gyro(const short *gyro, inv_time_t timestamp) 1047c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1048c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 1049c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 1050c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_GYRO; 1051c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 1052c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(gyro, sizeof(gyro[0]), 3, inv_data_builder.file); 1053c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); 1054c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1055c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 1056c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1057c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(sensors.gyro.raw, gyro, 3 * sizeof(short)); 1058c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.gyro.status |= INV_NEW_DATA | INV_RAW_DATA | INV_SENSOR_ON; 1059c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.gyro.timestamp_prev = sensors.gyro.timestamp; 1060c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.gyro.timestamp = timestamp; 1061c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_apply_calibration(&sensors.gyro, inv_data_builder.save_mpl.gyro_bias); 1062c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1063c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_SUCCESS; 1064c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1065c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1066c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Record new compass data for use when inv_execute_on_data() is called 1067c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] compass Compass data, if it was calibrated outside MPL, the units are uT scaled by 2^16. 1068c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* Length 3. 1069c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] status Lower 2 bits are the accuracy, with 0 being inaccurate, and 3 being most accurate. 1070c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* The upper bit INV_CALIBRATED, is set if the data was calibrated outside MPL and it is 1071c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* not set if the data being passed is raw. Raw data should be in device units, typically 1072c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* in a 16-bit range. 1073c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] timestamp Monotonic time stamp, for Android it's in nanoseconds. 1074c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[out] executed Set to 1 if data processing was done. 1075c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @return Returns INV_SUCCESS if successful or an error code if not. 1076c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1077c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroinv_error_t inv_build_compass(const long *compass, int status, 1078c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_time_t timestamp) 1079c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1080c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 1081c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 1082c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_COMPASS; 1083c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 1084c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(compass, sizeof(compass[0]), 3, inv_data_builder.file); 1085c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); 1086c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1087c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 1088c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1089c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((status & INV_CALIBRATED) == 0) { 1090c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro long data[3]; 1091c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_set_compass_soft_iron_input_data(compass); 1092c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_get_compass_soft_iron_output_data(data); 1093c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.raw[0] = (short)data[0]; 1094c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.raw[1] = (short)data[1]; 1095c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.raw[2] = (short)data[2]; 1096c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_apply_calibration(&sensors.compass, inv_data_builder.save.compass_bias); 1097c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.status |= INV_RAW_DATA; 1098c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } else { 1099c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.calibrated[0] = compass[0]; 1100c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.calibrated[1] = compass[1]; 1101c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.calibrated[2] = compass[2]; 1102c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.status |= INV_CALIBRATED; 1103c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.accuracy = status & 3; 1104c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.save.compass_accuracy = status & 3; 1105c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1106c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.timestamp_prev = sensors.compass.timestamp; 1107c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.timestamp = timestamp; 1108c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.status |= INV_NEW_DATA | INV_SENSOR_ON; 1109c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1110c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_SUCCESS; 1111c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1112c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1113c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Record new temperature data for use when inv_execute_on_data() is called. 1114c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] temp Temperature data in q16 format. 1115c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] timestamp Monotonic time stamp; for Android it's in 1116c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * nanoseconds. 1117c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @return Returns INV_SUCCESS if successful or an error code if not. 1118c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 1119c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroinv_error_t inv_build_temp(const long temp, inv_time_t timestamp) 1120c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1121c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 1122c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 1123c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_TEMPERATURE; 1124c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 1125c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&temp, sizeof(temp), 1, inv_data_builder.file); 1126c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); 1127c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1128c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 1129c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.temp.calibrated[0] = temp; 1130c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.temp.status |= INV_NEW_DATA | INV_RAW_DATA | INV_SENSOR_ON; 1131c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.temp.timestamp_prev = sensors.temp.timestamp; 1132c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.temp.timestamp = timestamp; 1133c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro /* TODO: Apply scale, remove offset. */ 1134c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1135c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_SUCCESS; 1136c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1137c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** quaternion data 1138c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] quat Quaternion data. 2^30 = 1.0 or 2^14=1 for 16-bit data. 1139c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* Real part first. Length 4. 1140c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] status number of axis, 16-bit or 32-bit 1141c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* set INV_QUAT_3ELEMENT if input quaternion has only 3 elements (no scalar). 1142c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* inv_compute_scalar_part() assumes 32-bit data. If using 16-bit quaternion, 1143c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* shift 16 bits first before calling this function. 1144c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] timestamp 1145c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] timestamp Monotonic time stamp; for Android it's in 1146c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* nanoseconds. 1147c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[out] executed Set to 1 if data processing was done. 1148c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @return Returns INV_SUCCESS if successful or an error code if not. 1149c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1150c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroinv_error_t inv_build_quat(const long *quat, int status, inv_time_t timestamp) 1151c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1152c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 1153c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 1154c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_QUAT; 1155c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 1156c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(quat, sizeof(quat[0]), 4, inv_data_builder.file); 1157c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(×tamp, sizeof(timestamp), 1, inv_data_builder.file); 1158c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1159c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 1160c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1161c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro /* Android version DMP does not have scalar part */ 1162c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (status & INV_QUAT_3ELEMENT) { 1163c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro long resultQuat[4]; 1164c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro MPL_LOGV("3q: %ld,%ld,%ld\n", quat[0], quat[1], quat[2]); 1165c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_compute_scalar_part(quat, resultQuat); 1166c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro MPL_LOGV("4q: %ld,%ld,%ld,%ld\n", resultQuat[0], resultQuat[1], resultQuat[2], resultQuat[3]); 1167c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(sensors.quat.raw, resultQuat, sizeof(sensors.quat.raw)); 1168c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } else { 1169c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(sensors.quat.raw, quat, sizeof(sensors.quat.raw)); 1170c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1171c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.quat.timestamp_prev = sensors.quat.timestamp; 1172c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.quat.timestamp = timestamp; 1173c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.quat.status |= INV_NEW_DATA | INV_RAW_DATA | INV_SENSOR_ON; 1174c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.quat.status |= (INV_QUAT_3AXIS & status); 1175c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.quat.status |= (INV_QUAT_6AXIS & status); 1176c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.quat.status |= (INV_QUAT_9AXIS & status); 1177c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.quat.status |= (INV_BIAS_APPLIED & status); 1178c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.quat.status |= (INV_DMP_BIAS_APPLIED & status); 1179c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.quat.status |= (INV_QUAT_3ELEMENT & status); 1180c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro MPL_LOGV("quat.status: %d", sensors.quat.status); 1181c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.quat.status & (INV_QUAT_9AXIS | INV_QUAT_6AXIS)) { 1182c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // Set quaternion 1183c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_store_gaming_quaternion(quat, timestamp); 1184c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1185c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.quat.status & INV_QUAT_9AXIS) { 1186c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro long identity[4] = {(1L<<30), 0, 0, 0}; 1187c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_set_compass_correction(identity, timestamp); 1188c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1189c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_SUCCESS; 1190c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1191c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1192c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroinv_error_t inv_build_pressure(const long pressure, int status, inv_time_t timestamp) 1193c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1194c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.pressure.status |= INV_NEW_DATA; 1195c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_SUCCESS; 1196c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1197c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1198c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This should be called when the accel has been turned off. This is so 1199c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* that we will know if the data is contiguous. 1200c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1201c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_accel_was_turned_off() 1202c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1203c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 1204c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 1205c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_COMPASS_OFF; 1206c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 1207c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1208c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 1209c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.status = 0; 1210c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1211c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1212c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This should be called when the compass has been turned off. This is so 1213c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* that we will know if the data is contiguous. 1214c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1215c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_compass_was_turned_off() 1216c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1217c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 1218c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 1219c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_COMPASS_OFF; 1220c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 1221c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1222c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 1223c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.status = 0; 1224c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1225c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1226c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This should be called when the quaternion data from the DMP has been turned off. This is so 1227c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* that we will know if the data is contiguous. 1228c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1229c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_quaternion_sensor_was_turned_off(void) 1230c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1231c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 1232c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 1233c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_QUAT_OFF; 1234c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 1235c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1236c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 1237c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.quat.status = 0; 1238c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1239c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1240c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This should be called when the gyro has been turned off. This is so 1241c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* that we will know if the data is contiguous. 1242c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1243c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_gyro_was_turned_off() 1244c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1245c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 1246c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 1247c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_GYRO_OFF; 1248c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 1249c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1250c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 1251c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.gyro.status = 0; 1252c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1253c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1254c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This should be called when the temperature sensor has been turned off. 1255c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * This is so that we will know if the data is contiguous. 1256c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 1257c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_temperature_was_turned_off() 1258c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1259c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.temp.status = 0; 1260c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1261c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1262c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Registers to receive a callback when there is new sensor data. 1263c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @internal 1264c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] func Function pointer to receive callback when there is new sensor data 1265c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] priority Lower priority numbers receive a callback before larger numbers. All priority 1266c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* numbers must be unique. 1267c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] sensor_type Sets the type of data that triggers the callback. Must be non-zero. May be 1268c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* a combination. INV_ACCEL_NEW = accel data, INV_GYRO_NEW = 1269c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* gyro data, INV_MAG_NEW = compass data. So passing in 1270c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* INV_ACCEL_NEW | INV_MAG_NEW, a 1271c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* callback would be generated if there was new magnetomer data OR new accel data. 1272c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1273c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroinv_error_t inv_register_data_cb( 1274c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_error_t (*func)(struct inv_sensor_cal_t *data), 1275c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int priority, int sensor_type) 1276c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1277c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_error_t result = INV_SUCCESS; 1278c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int kk, nn; 1279c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1280c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // Make sure we haven't registered this function already 1281c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // Or used the same priority 1282c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (kk = 0; kk < inv_data_builder.num_cb; ++kk) { 1283c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if ((inv_data_builder.process[kk].func == func) || 1284c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro (inv_data_builder.process[kk].priority == priority)) { 1285c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_ERROR_INVALID_PARAMETER; //fixme give a warning 1286c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1287c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1288c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1289c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // Make sure we have not filled up our number of allowable callbacks 1290c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.num_cb <= INV_MAX_DATA_CB - 1) { 1291c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro kk = 0; 1292c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.num_cb != 0) { 1293c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // set kk to be where this new callback goes in the array 1294c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro while ((kk < inv_data_builder.num_cb) && 1295c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro (inv_data_builder.process[kk].priority < priority)) { 1296c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro kk++; 1297c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1298c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (kk != inv_data_builder.num_cb) { 1299c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // We need to move the others 1300c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (nn = inv_data_builder.num_cb; nn > kk; --nn) { 1301c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.process[nn] = 1302c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.process[nn - 1]; 1303c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1304c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1305c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1306c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // Add new callback 1307c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.process[kk].func = func; 1308c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.process[kk].priority = priority; 1309c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.process[kk].data_required = sensor_type; 1310c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.num_cb++; 1311c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } else { 1312c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro MPL_LOGE("Unable to add feature callback as too many were already registered\n"); 1313c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro result = INV_ERROR_MEMORY_EXAUSTED; 1314c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1315c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1316c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return result; 1317c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1318c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1319c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Unregisters the callback that happens when new sensor data is received. 1320c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @internal 1321c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] func Function pointer to receive callback when there is new sensor data 1322c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] priority Lower priority numbers receive a callback before larger numbers. All priority 1323c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* numbers must be unique. 1324c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[in] sensor_type Sets the type of data that triggers the callback. Must be non-zero. May be 1325c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* a combination. INV_ACCEL_NEW = accel data, INV_GYRO_NEW = 1326c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* gyro data, INV_MAG_NEW = compass data. So passing in 1327c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* INV_ACCEL_NEW | INV_MAG_NEW, a 1328c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* callback would be generated if there was new magnetomer data OR new accel data. 1329c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1330c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroinv_error_t inv_unregister_data_cb( 1331c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_error_t (*func)(struct inv_sensor_cal_t *data)) 1332c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1333c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int kk, nn; 1334c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1335c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (kk = 0; kk < inv_data_builder.num_cb; ++kk) { 1336c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.process[kk].func == func) { 1337c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // Delete this callback 1338c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (nn = kk + 1; nn < inv_data_builder.num_cb; ++nn) { 1339c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.process[nn - 1] = 1340c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.process[nn]; 1341c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1342c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.num_cb--; 1343c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_SUCCESS; 1344c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1345c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1346c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1347c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return INV_SUCCESS; // We did not find the callback 1348c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1349c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1350c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** After at least one of inv_build_gyro(), inv_build_accel(), or 1351c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* inv_build_compass() has been called, this function should be called. 1352c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* It will process the data it has received and update all the internal states 1353c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* and features that have been turned on. 1354c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @return Returns INV_SUCCESS if successful or an error code if not. 1355c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1356c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroinv_error_t inv_execute_on_data(void) 1357c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1358c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_error_t result, first_error; 1359c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int kk; 1360c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1361c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#ifdef INV_PLAYBACK_DBG 1362c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.debug_mode == RD_RECORD) { 1363c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int type = PLAYBACK_DBG_TYPE_EXECUTE; 1364c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro fwrite(&type, sizeof(type), 1, inv_data_builder.file); 1365c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1366c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 1367c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // Determine what new data we have 1368c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.mode = 0; 1369c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.gyro.status & INV_NEW_DATA) 1370c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.mode |= INV_GYRO_NEW; 1371c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.accel.status & INV_NEW_DATA) 1372c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.mode |= INV_ACCEL_NEW; 1373c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.compass.status & INV_NEW_DATA) 1374c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.mode |= INV_MAG_NEW; 1375c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.temp.status & INV_NEW_DATA) 1376c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.mode |= INV_TEMP_NEW; 1377c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.quat.status & INV_NEW_DATA) 1378c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.mode |= INV_QUAT_NEW; 1379c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.pressure.status & INV_NEW_DATA) 1380c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_data_builder.mode |= INV_PRESSURE_NEW; 1381c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1382c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro first_error = INV_SUCCESS; 1383c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1384c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (kk = 0; kk < inv_data_builder.num_cb; ++kk) { 1385c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.mode & inv_data_builder.process[kk].data_required) { 1386c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro result = inv_data_builder.process[kk].func(&sensors); 1387c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (result && !first_error) { 1388c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro first_error = result; 1389c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1390c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1391c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1392c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1393c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_set_contiguous(); 1394c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1395c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return first_error; 1396c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1397c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1398c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Cleans up status bits after running all the callbacks. It sets the contiguous flag. 1399c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* 1400c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1401c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarostatic void inv_set_contiguous(void) 1402c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1403c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_time_t current_time = 0; 1404c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.gyro.status & INV_NEW_DATA) { 1405c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.gyro.status |= INV_CONTIGUOUS; 1406c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro current_time = sensors.gyro.timestamp; 1407c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1408c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.accel.status & INV_NEW_DATA) { 1409c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.status |= INV_CONTIGUOUS; 1410c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro current_time = MAX(current_time, sensors.accel.timestamp); 1411c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1412c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.compass.status & INV_NEW_DATA) { 1413c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.status |= INV_CONTIGUOUS; 1414c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro current_time = MAX(current_time, sensors.compass.timestamp); 1415c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1416c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.temp.status & INV_NEW_DATA) { 1417c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.temp.status |= INV_CONTIGUOUS; 1418c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro current_time = MAX(current_time, sensors.temp.timestamp); 1419c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1420c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.quat.status & INV_NEW_DATA) { 1421c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.quat.status |= INV_CONTIGUOUS; 1422c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro current_time = MAX(current_time, sensors.quat.timestamp); 1423c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1424c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1425c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#if 0 1426c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro /* See if sensors are still on. These should be turned off by inv_*_was_turned_off() 1427c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * type functions. This is just in case that breaks down. We make sure 1428c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * all the data is within 2 seconds of the newest piece of data*/ 1429c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_delta_time_ms(current_time, sensors.gyro.timestamp) >= 2000) 1430c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_gyro_was_turned_off(); 1431c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_delta_time_ms(current_time, sensors.accel.timestamp) >= 2000) 1432c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_accel_was_turned_off(); 1433c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_delta_time_ms(current_time, sensors.compass.timestamp) >= 2000) 1434c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_compass_was_turned_off(); 1435c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro /* TODO: Temperature might not need to be read this quickly. */ 1436c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_delta_time_ms(current_time, sensors.temp.timestamp) >= 2000) 1437c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_temperature_was_turned_off(); 1438c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro#endif 1439c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1440c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro /* clear bits */ 1441c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.gyro.status &= ~INV_NEW_DATA; 1442c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.accel.status &= ~INV_NEW_DATA; 1443c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.compass.status &= ~INV_NEW_DATA; 1444c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.temp.status &= ~INV_NEW_DATA; 1445c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.quat.status &= ~INV_NEW_DATA; 1446c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.pressure.status &= ~INV_NEW_DATA; 1447c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1448c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1449c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Gets a whole set of accel data including data, accuracy and timestamp. 1450c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] data Accel Data where 1g = 2^16 1451c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] accuracy Accuracy 0 being not accurate, and 3 being most accurate. 1452c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] timestamp The timestamp of the data sample. 1453c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1454c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_accel_set(long *data, int8_t *accuracy, inv_time_t *timestamp) 1455c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1456c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (data != NULL) { 1457c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(data, sensors.accel.calibrated, sizeof(sensors.accel.calibrated)); 1458c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1459c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (timestamp != NULL) { 1460c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *timestamp = sensors.accel.timestamp; 1461c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1462c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (accuracy != NULL) { 1463c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *accuracy = sensors.accel.accuracy; 1464c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1465c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1466c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1467c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Gets a whole set of gyro data including data, accuracy and timestamp. 1468c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] data Gyro Data where 1 dps = 2^16 1469c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] accuracy Accuracy 0 being not accurate, and 3 being most accurate. 1470c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] timestamp The timestamp of the data sample. 1471c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1472c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_gyro_set(long *data, int8_t *accuracy, inv_time_t *timestamp) 1473c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1474c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(data, sensors.gyro.calibrated, sizeof(sensors.gyro.calibrated)); 1475c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (timestamp != NULL) { 1476c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *timestamp = sensors.gyro.timestamp; 1477c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1478c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (accuracy != NULL) { 1479c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *accuracy = sensors.gyro.accuracy; 1480c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1481c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1482c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1483c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Gets a whole set of gyro raw data including data, accuracy and timestamp. 1484c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] data Gyro Data where 1 dps = 2^16 1485c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] accuracy Accuracy 0 being not accurate, and 3 being most accurate. 1486c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] timestamp The timestamp of the data sample. 1487c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1488c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_gyro_set_raw(long *data, int8_t *accuracy, inv_time_t *timestamp) 1489c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1490c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(data, sensors.gyro.raw_scaled, sizeof(sensors.gyro.raw_scaled)); 1491c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (timestamp != NULL) { 1492c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *timestamp = sensors.gyro.timestamp; 1493c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1494c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (accuracy != NULL) { 1495c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *accuracy = 0; 1496c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1497c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1498c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1499c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Get's latest gyro data. 1500c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro* @param[out] gyro Gyro Data, Length 3. 1 dps = 2^16. 1501c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1502c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_gyro(long *gyro) 1503c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1504c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(gyro, sensors.gyro.calibrated, sizeof(sensors.gyro.calibrated)); 1505c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1506c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1507c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Gets a whole set of compass data including data, accuracy and timestamp. 1508c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] data Compass Data where 1 uT = 2^16 1509c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] accuracy Accuracy 0 being not accurate, and 3 being most accurate. 1510c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] timestamp The timestamp of the data sample. 1511c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1512c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_compass_set(long *data, int8_t *accuracy, inv_time_t *timestamp) 1513c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1514c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(data, sensors.compass.calibrated, sizeof(sensors.compass.calibrated)); 1515c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (timestamp != NULL) { 1516c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *timestamp = sensors.compass.timestamp; 1517c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1518c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (accuracy != NULL) { 1519c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.compass_disturbance) 1520c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *accuracy = 0; 1521c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro else 1522c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *accuracy = sensors.compass.accuracy; 1523c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1524c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1525c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1526c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Gets a whole set of compass raw data including data, accuracy and timestamp. 1527c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] data Compass Data where 1 uT = 2^16 1528c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] accuracy Accuracy 0 being not accurate, and 3 being most accurate. 1529c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] timestamp The timestamp of the data sample. 1530c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1531c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_compass_set_raw(long *data, int8_t *accuracy, inv_time_t *timestamp) 1532c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1533c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memcpy(data, sensors.compass.raw_scaled, sizeof(sensors.compass.raw_scaled)); 1534c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (timestamp != NULL) { 1535c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *timestamp = sensors.compass.timestamp; 1536c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1537c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro //per Michele, since data is raw, accuracy should = 0 1538c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *accuracy = 0; 1539c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1540c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1541c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Gets a whole set of temperature data including data, accuracy and timestamp. 1542c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] data Temperature data where 1 degree C = 2^16 1543c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] accuracy 0 to 3, where 3 is most accurate. 1544c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] timestamp The timestamp of the data sample. 1545c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 1546c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_temp_set(long *data, int *accuracy, inv_time_t *timestamp) 1547c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1548c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro data[0] = sensors.temp.calibrated[0]; 1549c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (timestamp) 1550c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *timestamp = sensors.temp.timestamp; 1551c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (accuracy) 1552c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *accuracy = sensors.temp.accuracy; 1553c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1554c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1555c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Returns accuracy of gyro. 1556c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @return Accuracy of gyro with 0 being not accurate, and 3 being most accurate. 1557c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1558c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroint inv_get_gyro_accuracy(void) 1559c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1560c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return sensors.gyro.accuracy; 1561c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1562c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1563c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Returns accuracy of compass. 1564c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @return Accuracy of compass with 0 being not accurate, and 3 being most accurate. 1565c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1566c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroint inv_get_mag_accuracy(void) 1567c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1568c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (inv_data_builder.compass_disturbance) 1569c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; 1570c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return sensors.compass.accuracy; 1571c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1572c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1573c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Returns accuracy of accel. 1574c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @return Accuracy of accel with 0 being not accurate, and 3 being most accurate. 1575c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1576c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroint inv_get_accel_accuracy(void) 1577c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1578c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return sensors.accel.accuracy; 1579c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1580c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1581c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroinv_error_t inv_get_gyro_orient(int *orient) 1582c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1583c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *orient = sensors.gyro.orientation; 1584c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; 1585c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1586c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1587c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaroinv_error_t inv_get_accel_orient(int *orient) 1588c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro{ 1589c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro *orient = sensors.accel.orientation; 1590c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro return 0; 1591c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1592c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1593c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/*======================================================================*/ 1594c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/* compass soft iron module */ 1595c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/*======================================================================*/ 1596c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1597c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Gets the 3x3 compass transform matrix in 32 bit Q30 fixed point format. 1598c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] the pointer of the 3x3 matrix in Q30 format 1599c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1600c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_compass_soft_iron_matrix_d(long *matrix) { 1601c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int i; 1602c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (i=0; i<9; i++) { 1603c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro matrix[i] = sensors.soft_iron.matrix_d[i]; 1604c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1605c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1606c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1607c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Sets the 3x3 compass transform matrix in 32 bit Q30 fixed point format. 1608c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] the pointer of the 3x3 matrix in Q30 format 1609c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1610c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_compass_soft_iron_matrix_d(long *matrix) { 1611c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int i; 1612c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (i=0; i<9; i++) { 1613c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // set the floating point matrix 1614c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.soft_iron.matrix_d[i] = matrix[i]; 1615c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // convert to Q30 format 1616c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.soft_iron.matrix_f[i] = inv_q30_to_float(matrix[i]); 1617c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1618c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1619c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Gets the 3x3 compass transform matrix in 32 bit floating point format. 1620c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] the pointer of the 3x3 matrix in floating point format 1621c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1622c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_compass_soft_iron_matrix_f(float *matrix) { 1623c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int i; 1624c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (i=0; i<9; i++) { 1625c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro matrix[i] = sensors.soft_iron.matrix_f[i]; 1626c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1627c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1628c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** Sets the 3x3 compass transform matrix in 32 bit floating point format. 1629c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[in] the pointer of the 3x3 matrix in floating point format 1630c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1631c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_compass_soft_iron_matrix_f(float *matrix) { 1632c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int i; 1633c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (i=0; i<9; i++) { 1634c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // set the floating point matrix 1635c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.soft_iron.matrix_f[i] = matrix[i]; 1636c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // convert to Q30 format 1637c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.soft_iron.matrix_d[i] = (long )(matrix[i]*ROT_MATRIX_SCALE_LONG); 1638c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1639c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1640c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1641c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This subroutine gets the fixed point Q30 compass data after the soft iron transformation. 1642c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] the pointer of the 3x1 vector compass data in MPL format 1643c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1644c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_compass_soft_iron_output_data(long *data) { 1645c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int i; 1646c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (i=0; i<3; i++) { 1647c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro data[i] = sensors.soft_iron.trans[i]; 1648c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1649c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1650c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This subroutine gets the fixed point Q30 compass data before the soft iron transformation. 1651c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[out] the pointer of the 3x1 vector compass data in MPL format 1652c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1653c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_get_compass_soft_iron_input_data(long *data) { 1654c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int i; 1655c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (i=0; i<3; i++) { 1656c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro data[i] = sensors.soft_iron.raw[i]; 1657c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1658c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1659c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This subroutine sets the compass raw data for the soft iron transformation. 1660c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @param[int] the pointer of the 3x1 vector compass raw data in MPL format 1661c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1662c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_set_compass_soft_iron_input_data(const long *data) { 1663c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int i; 1664c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (i=0; i<3; i++) { 1665c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.soft_iron.raw[i] = data[i]; 1666c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1667c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro if (sensors.soft_iron.enable == 1) { 1668c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro mlMatrixVectorMult(sensors.soft_iron.matrix_d, data, sensors.soft_iron.trans); 1669c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } else { 1670c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (i=0; i<3; i++) { 1671c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.soft_iron.trans[i] = data[i]; 1672c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1673c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1674c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1675c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1676c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This subroutine resets the the soft iron transformation to unity matrix and 1677c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * disable the soft iron transformation process by default. 1678c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1679c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_reset_compass_soft_iron_matrix(void) { 1680c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro int i; 1681c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (i=0; i<9; i++) { 1682c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.soft_iron.matrix_f[i] = 0.0f; 1683c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1684c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1685c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro memset(&sensors.soft_iron.matrix_d,0,sizeof(sensors.soft_iron.matrix_d)); 1686c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1687c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro for (i=0; i<3; i++) { 1688c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // set the floating point matrix 1689c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.soft_iron.matrix_f[i*4] = 1.0; 1690c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro // set the fixed point matrix 1691c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.soft_iron.matrix_d[i*4] = ROT_MATRIX_SCALE_LONG; 1692c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro } 1693c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1694c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro inv_disable_compass_soft_iron_matrix(); 1695c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1696c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1697c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This subroutine enables the the soft iron transformation process. 1698c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1699c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_enable_compass_soft_iron_matrix(void) { 1700c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.soft_iron.enable = 1; 1701c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1702c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1703c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** This subroutine disables the the soft iron transformation process. 1704c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro*/ 1705c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccarovoid inv_disable_compass_soft_iron_matrix(void) { 1706c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro sensors.soft_iron.enable = 0; 1707c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro} 1708c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro 1709c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro/** 1710c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro * @} 1711c3d4ca9f2df5ddf9894b36d1554fdfc95d625d3fNick Vaccaro */ 1712