orientation.c revision ae081f1f47013ddf08e5af685b9f6d02ac76421b
1960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <stdlib.h> 2960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <string.h> 3960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <timer.h> 4960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <heap.h> 5960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <plat/inc/rtc.h> 6960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <plat/inc/syscfg.h> 7960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <hostIntf.h> 87062239aaa63d8a5260d7d325483755acbb8c35cBen Fennema#include <nanohubPacket.h> 9ae081f1f47013ddf08e5af685b9f6d02ac76421bDmitry Grinberg#include <floatRt.h> 10960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 11960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <seos.h> 12960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <accelerometer.h> 13960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 14960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <nanohub_math.h> 15960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <fusion/fusion.h> 16960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <sensors.h> 17960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <limits.h> 18e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian#include <slab.h> 19960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 20960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#define MAX_NUM_COMMS_EVENT_SAMPLES 15 21c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian#define FIFO_MARGIN 10 22c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian#define MAX_NUM_SAMPLES (MAX_NUM_COMMS_EVENT_SAMPLES + FIFO_MARGIN) 23c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian#define MAX_NUM_RAW_DATA_SAMPLES 50000000000ull 2418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian#define EVT_SENSOR_ACC_DATA_RDY sensorGetMyEventType(SENS_TYPE_ACCEL) 2518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian#define EVT_SENSOR_GYR_DATA_RDY sensorGetMyEventType(SENS_TYPE_GYRO) 2618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian#define EVT_SENSOR_MAG_DATA_RDY sensorGetMyEventType(SENS_TYPE_MAG) 2718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 2818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian#define kGravityEarth 9.80665f 2918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian#define DEFAULT_GYRO_RATE_HZ SENSOR_HZ(100.0f) 3018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian#define DEFAULT_MAG_RATE_HZ SENSOR_HZ(50.0f) 31960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 321be10b6751f50675307716747bd4d729d9e7aff5Ben Fennemaenum 331be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema{ 341be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema FUSION_FLAG_ENABLED = 0x01, 351be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema FUSION_FLAG_INITIALIZED = 0x08, 361be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema FUSION_FLAG_GAME_ENABLED = 0x10, 371be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema FUSION_FLAG_GAME_INITIALIZED = 0x20 38960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian}; 39960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 4018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianenum RawSensorType 4118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 4218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian ACC, 4318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian GYR, 4418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian MAG, 4518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian NUM_OF_RAW_SENSOR 4618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian}; 4718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 4818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianenum FusionSensorType 491be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema{ 5018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian ORIENT, 5118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian GRAVITY, 5218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian GEOMAG, 5318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian LINEAR, 5418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian GAME, 5518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian ROTAT, 5618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian NUM_OF_FUSION_SENSOR 571be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema}; 581be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 591be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 6018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstruct FusionSensorSample { 61960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian uint64_t time; 62960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian float x, y, z; 63960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian}; 64960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 6518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstruct FusionSensor { 66960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian uint32_t handle; 6718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian struct TripleAxisDataEvent *ev; 68c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian uint64_t prev_time; 6918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian uint64_t latency; 7018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian uint32_t rate; 7118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian bool active; 7218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian bool use_gyr_data; 7318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian bool use_mag_data; 7418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian uint8_t idx; 7518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian}; 7618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 7718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstruct FusionTask { 7818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian uint32_t tid; 791be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema uint32_t accelHandle; 801be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema uint32_t gyroHandle; 811be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema uint32_t magHandle; 82960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 83960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian struct Fusion fusion; 8418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian struct Fusion game; 85960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 8618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian struct FusionSensor sensors[NUM_OF_FUSION_SENSOR]; 8718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian struct FusionSensorSample samples[NUM_OF_RAW_SENSOR][MAX_NUM_SAMPLES]; 8818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian size_t sample_indices[NUM_OF_RAW_SENSOR]; 8918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian size_t sample_counts[NUM_OF_RAW_SENSOR]; 9018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian uint32_t counters[NUM_OF_RAW_SENSOR]; 9118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian uint64_t ResamplePeriodNs[NUM_OF_RAW_SENSOR]; 9218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian uint64_t last_time[NUM_OF_RAW_SENSOR]; 9318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian struct TripleAxisDataPoint last_sample[NUM_OF_RAW_SENSOR]; 94960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 95960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian uint64_t last_gyro_time; 96960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian uint64_t last_acc_time; 97960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian uint32_t flags; 98960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 99c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian uint32_t raw_sensor_rate[NUM_OF_RAW_SENSOR]; 100c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian uint64_t raw_sensor_latency; 101c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian 10218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian uint8_t acc_cnt; 10318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian uint8_t gyr_cnt; 10418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian uint8_t mag_cnt; 105960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian}; 106960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 10718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic uint32_t FusionRates[] = { 108960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian SENSOR_HZ(12.5f), 109960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian SENSOR_HZ(25.0f), 110960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian SENSOR_HZ(50.0f), 111960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian SENSOR_HZ(100.0f), 112960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian SENSOR_HZ(200.0f), 113960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 0, 114960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian}; 115960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 11618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic struct FusionTask mTask; 11718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic const struct SensorInfo mSi[NUM_OF_FUSION_SENSOR] = 11864eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian{ 119f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema {"Orientation", FusionRates, SENS_TYPE_ORIENTATION, NUM_AXIS_THREE, NANOHUB_INT_NONWAKEUP, 20 }, 120f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema {"Gravity", FusionRates, SENS_TYPE_GRAVITY, NUM_AXIS_THREE, NANOHUB_INT_NONWAKEUP, 20 }, 121f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema {"Geomagnetic Rotation Vector", FusionRates, SENS_TYPE_GEO_MAG_ROT_VEC, NUM_AXIS_THREE, NANOHUB_INT_NONWAKEUP, 20 }, 122f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema {"Linear Acceleration", FusionRates, SENS_TYPE_LINEAR_ACCEL, NUM_AXIS_THREE, NANOHUB_INT_NONWAKEUP, 20 }, 123f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema {"Game Rotation Vector", FusionRates, SENS_TYPE_GAME_ROT_VECTOR, NUM_AXIS_THREE, NANOHUB_INT_NONWAKEUP, 300 }, 124f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema {"Rotation Vector", FusionRates, SENS_TYPE_ROTATION_VECTOR, NUM_AXIS_THREE, NANOHUB_INT_NONWAKEUP, 20 }, 12564eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian}; 126960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 127e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qianstatic struct SlabAllocator *mDataSlab; 128e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian 129e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qianstatic void dataEvtFree(void *ptr) 130960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 131e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian slabAllocatorFree(mDataSlab, ptr); 132960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 133960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 13418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic void fillSamples(struct TripleAxisDataEvent *ev, enum RawSensorType index) 135960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 13618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian bool bad_timestamp; 13718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian size_t i, w, n, num_samples; 13818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian struct TripleAxisDataPoint *curr_sample, *next_sample; 139f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema uint32_t counter; 140f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema uint64_t ResamplePeriodNs, curr_time, next_time; 14118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian uint64_t sample_spacing_ns; 14218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian float weight_next; 14318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 14418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (index == GYR && mTask.gyr_cnt == 0) { 145960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian return; 146960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 14718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (index == MAG && mTask.mag_cnt == 0) { 148960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian return; 149960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 150960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 15118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian n = mTask.sample_counts[index]; 15218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian i = mTask.sample_indices[index]; 15318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian counter = mTask.counters[index]; 15418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian ResamplePeriodNs = mTask.ResamplePeriodNs[index]; 15518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian w = (mTask.sample_indices[index] + n) % MAX_NUM_SAMPLES; 15618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 15718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian // check if this sensor was used before 15818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.last_time[index] == ULONG_LONG_MAX) { 15918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian curr_sample = ev->samples; 16018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian next_sample = curr_sample + 1; 161f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema num_samples = ev->samples[0].firstSample.numSamples; 16218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian curr_time = ev->referenceTime; 163960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } else { 16418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian curr_sample = &mTask.last_sample[index]; 16518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian next_sample = ev->samples; 166f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema num_samples = ev->samples[0].firstSample.numSamples + 1; 16718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian curr_time = mTask.last_time[index]; 16818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 169960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 17018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian while (num_samples > 1) { 171960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 17218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (next_sample == ev->samples) 17318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian next_time = ev->referenceTime; 17418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian else 17518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian next_time = curr_time + next_sample->deltaTime; 176960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 17718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian // error handling for non-chronological accel timestamps 17818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian sample_spacing_ns = (next_time > curr_time) ? (next_time - curr_time) : 0; 179960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 18018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian // This happens during BMI160 config changes 18118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian bad_timestamp = (sample_spacing_ns > 10 * ResamplePeriodNs); 182960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 18318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian // Check to see if we need to move the interpolation window or 18418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian // interpolate 18518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if ((counter >= sample_spacing_ns) || bad_timestamp) { 18618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian num_samples--; 18718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian counter -= (bad_timestamp ? counter : sample_spacing_ns); 18818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian curr_sample = next_sample; 18918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian next_sample++; 190960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 191c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian curr_time = next_time; 19218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } else { 193ae081f1f47013ddf08e5af685b9f6d02ac76421bDmitry Grinberg weight_next = (float)counter / floatFromUint64(sample_spacing_ns); 19418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 19518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.samples[index][w].x = curr_sample->x + weight_next * 19618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian (next_sample->x - curr_sample->x); 19718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.samples[index][w].y = curr_sample->y + weight_next * 19818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian (next_sample->y - curr_sample->y); 19918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.samples[index][w].z = curr_sample->z + weight_next * 20018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian (next_sample->z - curr_sample->z); 20118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.samples[index][w].time = curr_time + counter; 20218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 20318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian // Move the read index when buffer is full 20418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (++n > MAX_NUM_SAMPLES) { 20518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian n = MAX_NUM_SAMPLES; 20618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 20718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (++i == MAX_NUM_SAMPLES) { 20818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian i = 0; 20918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 21018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 21118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 21218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian // Reset the write index 21318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (++w == MAX_NUM_SAMPLES) { 21418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian w = 0; 21518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 21618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 21718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian // Move to the next resample 21818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian counter += ResamplePeriodNs; 219960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 220960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 22118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 22218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sample_counts[index] = n; 22318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sample_indices[index] = i; 22418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.counters[index] = counter; 22518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.last_sample[index] = *curr_sample; 22618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.last_time[index] = curr_time; 227960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 228960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 22918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic void addSample(struct FusionSensor *mSensor, uint64_t time, float x, float y, float z) 230960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 2317062239aaa63d8a5260d7d325483755acbb8c35cBen Fennema struct TripleAxisDataPoint *sample; 232c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian uint32_t deltaTime = 0; 233e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian 23418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mSensor->ev == NULL) { 23518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mSensor->ev = slabAllocatorAlloc(mDataSlab); 23618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mSensor->ev == NULL) { 237e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian // slaballocation failed 238c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian osLog(LOG_ERROR, "FUSION: Slab Allocation Failed\n"); 239e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian return; 240e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian } 241f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema mSensor->ev->samples[0].firstSample.numSamples = 0; 24218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mSensor->ev->referenceTime = time; 243c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian mSensor->prev_time = time; 244960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 245960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 246f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema if (mSensor->ev->samples[0].firstSample.numSamples >= MAX_NUM_COMMS_EVENT_SAMPLES) { 247960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian osLog(LOG_ERROR, "BAD_INDEX\n"); 248960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian return; 249960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 250960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 251f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema sample = &mSensor->ev->samples[mSensor->ev->samples[0].firstSample.numSamples++]; 252e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian 253c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian if (mSensor->ev->samples[0].firstSample.numSamples > 1) { 254c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian deltaTime = time - mSensor->prev_time; 255c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian deltaTime = deltaTime < 0 ? 0 : deltaTime; 256e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian sample->deltaTime = deltaTime; 257c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian mSensor->prev_time = time; 258c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian } 259960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 260960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian sample->x = x; 261960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian sample->y = y; 262960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian sample->z = z; 263960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 264f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema if (mSensor->ev->samples[0].firstSample.numSamples == MAX_NUM_COMMS_EVENT_SAMPLES) { 26535339af82310e6a49884f5b845fb9557af360de7Zhengyin Qian osEnqueueEvt(EVENT_TYPE_BIT_DISCARDABLE | sensorGetMyEventType(mSi[mSensor->idx].sensorType), 26635339af82310e6a49884f5b845fb9557af360de7Zhengyin Qian mSensor->ev, dataEvtFree); 26718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mSensor->ev = NULL; 268960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 269960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 270960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 271960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic void updateOutput(ssize_t last_accel_sample_index, uint64_t last_sensor_time) 272960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 27318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian struct Vec4 attitude; 27418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian struct Vec3 g, a; 27518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian struct Mat33 R; 27618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 27718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (fusionHasEstimate(&mTask.game)) { 27818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.sensors[GAME].active) { 27918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian fusionGetAttitude(&mTask.game, &attitude); 28018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian addSample(&mTask.sensors[GAME], 28118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian last_sensor_time, 28218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian attitude.x, 28318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian attitude.y, 28418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian attitude.z); 28518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 28618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 28718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.sensors[GRAVITY].active) { 28818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian fusionGetRotationMatrix(&mTask.game, &R); 28918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian initVec3(&g, R.elem[0][2], R.elem[1][2], R.elem[2][2]); 29018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian vec3ScalarMul(&g, kGravityEarth); 29118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian addSample(&mTask.sensors[GRAVITY], 29218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian last_sensor_time, 29318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian g.x, g.y, g.z); 29418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 29518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 29618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 297960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian if (fusionHasEstimate(&mTask.fusion)) { 298960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian fusionGetRotationMatrix(&mTask.fusion, &R); 299960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian fusionGetAttitude(&mTask.fusion, &attitude); 300960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 30118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.sensors[ORIENT].active) { 30218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian // x, y, z = yaw, pitch, roll 30318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian static const float kRad2deg = 180.0f / M_PI; 30418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian float x = atan2f(-R.elem[0][1], R.elem[0][0]) * kRad2deg; 30518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian float y = atan2f(-R.elem[1][2], R.elem[2][2]) * kRad2deg; 30618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian float z = asinf(R.elem[0][2]) * kRad2deg; 30718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 30818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (x < 0.0f) { 30918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian x += 360.0f; 31018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 31118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 31218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian addSample(&mTask.sensors[ORIENT], 31318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian last_sensor_time, x, y, z); 31418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 315960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 31618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.sensors[GEOMAG].active) { 31718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian addSample(&mTask.sensors[GEOMAG], 31818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian last_sensor_time, 31918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian attitude.x, 32018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian attitude.y, 32118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian attitude.z); 322960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 323960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 32418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.sensors[ROTAT].active) { 32518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian addSample(&mTask.sensors[ROTAT], 32618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian last_sensor_time, 32718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian attitude.x, 32818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian attitude.y, 32918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian attitude.z); 33018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 33118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 33218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (last_accel_sample_index >= 0 33318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian && mTask.sensors[LINEAR].active) { 33418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian initVec3(&g, R.elem[0][2], R.elem[1][2], R.elem[2][2]); 33518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian vec3ScalarMul(&g, kGravityEarth); 33618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian initVec3(&a, 33718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.samples[0][last_accel_sample_index].x, 33818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.samples[0][last_accel_sample_index].y, 33918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.samples[0][last_accel_sample_index].z); 34018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 34118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian addSample(&mTask.sensors[LINEAR], 34218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.samples[0][last_accel_sample_index].time, 34318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian a.x - g.x, 34418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian a.y - g.y, 34518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian a.z - g.z); 34618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 347960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 348960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 349960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 350960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic void drainSamples() 351960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 35218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian size_t i = mTask.sample_indices[ACC]; 353960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian size_t j = 0; 354960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian size_t k = 0; 3551be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema size_t which; 3561be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema struct Vec3 a, w, m; 3571be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema float dT; 3581be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema uint64_t a_time, g_time, m_time; 3591be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 36018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.gyr_cnt > 0) 36118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian j = mTask.sample_indices[GYR]; 3621be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 36318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.mag_cnt > 0) 36418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian k = mTask.sample_indices[MAG]; 3651be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 36618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian while (mTask.sample_counts[ACC] > 0 36718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian && (!mTask.gyr_cnt > 0 || mTask.sample_counts[GYR] > 0) 36818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian && (!mTask.mag_cnt > 0 || mTask.sample_counts[MAG] > 0)) { 36918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian a_time = mTask.samples[ACC][i].time; 37018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian g_time = mTask.gyr_cnt > 0 ? mTask.samples[GYR][j].time 371960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian : ULONG_LONG_MAX; 37218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian m_time = mTask.mag_cnt > 0 ? mTask.samples[MAG][k].time 373960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian : ULONG_LONG_MAX; 374960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 375960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian // priority with same timestamp: gyro > acc > mag 376960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian if (g_time <= a_time && g_time <= m_time) { 37718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian which = GYR; 378960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } else if (a_time <= m_time) { 37918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian which = ACC; 380960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } else { 38118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian which = MAG; 382960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 383960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 3841be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema switch (which) { 38518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian case ACC: 38618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian initVec3(&a, mTask.samples[ACC][i].x, mTask.samples[ACC][i].y, mTask.samples[ACC][i].z); 38718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 388ae081f1f47013ddf08e5af685b9f6d02ac76421bDmitry Grinberg dT = floatFromUint64(mTask.samples[ACC][i].time - mTask.last_acc_time) * 1.0E-9f; 38918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.last_acc_time = mTask.samples[ACC][i].time; 390960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 39118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.flags & FUSION_FLAG_ENABLED) 39218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian fusionHandleAcc(&mTask.fusion, &a, dT); 393960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 39418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.flags & FUSION_FLAG_GAME_ENABLED) 39518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian fusionHandleAcc(&mTask.game, &a, dT); 396960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 39718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian updateOutput(i, mTask.samples[ACC][i].time); 398960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 39918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian --mTask.sample_counts[ACC]; 4001be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (++i == MAX_NUM_SAMPLES) 4011be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema i = 0; 4021be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 40318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian case GYR: 40418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian initVec3(&w, mTask.samples[GYR][j].x, mTask.samples[GYR][j].y, mTask.samples[GYR][j].z); 405960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 406ae081f1f47013ddf08e5af685b9f6d02ac76421bDmitry Grinberg dT = floatFromUint64(mTask.samples[GYR][j].time - mTask.last_gyro_time) * 1.0E-9f; 40718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.last_gyro_time = mTask.samples[GYR][j].time; 408960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 40918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.flags & FUSION_FLAG_ENABLED) 41018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian fusionHandleGyro(&mTask.fusion, &w, dT); 411960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 41218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.flags & FUSION_FLAG_GAME_ENABLED) 41318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian fusionHandleGyro(&mTask.game, &w, dT); 41418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 41518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian --mTask.sample_counts[GYR]; 4161be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (++j == MAX_NUM_SAMPLES) 4171be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema j = 0; 4181be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 41918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian case MAG: 42018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian initVec3(&m, mTask.samples[MAG][k].x, mTask.samples[MAG][k].y, mTask.samples[MAG][k].z); 421960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 4221be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema fusionHandleMag(&mTask.fusion, &m); 423960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 42418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian --mTask.sample_counts[MAG]; 4251be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (++k == MAX_NUM_SAMPLES) 4261be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema k = 0; 4271be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 428960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 429960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 430960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 43118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sample_indices[ACC] = i; 432960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 43318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.gyr_cnt > 0) 43418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sample_indices[GYR] = j; 435960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 43618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.mag_cnt > 0) 43718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sample_indices[MAG] = k; 438960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 43918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian for (i = ORIENT; i < NUM_OF_FUSION_SENSOR; i++) { 44018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.sensors[i].ev != NULL) { 44135339af82310e6a49884f5b845fb9557af360de7Zhengyin Qian osEnqueueEvt(EVENT_TYPE_BIT_DISCARDABLE | sensorGetMyEventType(mSi[i].sensorType), 44235339af82310e6a49884f5b845fb9557af360de7Zhengyin Qian mTask.sensors[i].ev, dataEvtFree); 44318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sensors[i].ev = NULL; 44418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 445960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 446960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 447960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 448960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic void configureFusion() 449960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 45018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.sensors[ORIENT].active 45118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian || mTask.sensors[ROTAT].active 45218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian || mTask.sensors[LINEAR].active 45318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian || mTask.sensors[GEOMAG].active) { 45418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.flags |= FUSION_FLAG_ENABLED; 45518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian initFusion(&mTask.fusion, 45618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian (mTask.mag_cnt > 0 ? FUSION_USE_MAG : 0) | 45718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian (mTask.gyr_cnt > 0 ? FUSION_USE_GYRO : 0) | 45818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian ((mTask.flags & FUSION_FLAG_INITIALIZED) ? 0 : FUSION_REINITIALIZE)); 45918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.flags |= FUSION_FLAG_INITIALIZED; 46018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } else { 46118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.flags &= ~FUSION_FLAG_ENABLED; 46218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.flags &= ~FUSION_FLAG_INITIALIZED; 46318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 464960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 465960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 46618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic void configureGame() 467960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 46818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.sensors[GAME].active || mTask.sensors[GRAVITY].active) { 46918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.flags |= FUSION_FLAG_GAME_ENABLED; 47018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian initFusion(&mTask.game, 47118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian FUSION_USE_GYRO | ((mTask.flags & FUSION_FLAG_INITIALIZED) ? 0 : FUSION_REINITIALIZE)); 47218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.flags |= FUSION_FLAG_GAME_INITIALIZED; 47318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } else { 47418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.flags &= ~FUSION_FLAG_GAME_ENABLED; 47518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.flags &= ~FUSION_FLAG_GAME_INITIALIZED; 476960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 477960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 478960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 479c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qianstatic void fusionSetRateAcc(void) 480960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 4811be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema int i; 48218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.accelHandle == 0) { 48318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sample_counts[ACC] = 0; 48418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sample_indices[ACC] = 0; 48518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.counters[ACC] = 0; 48618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.last_time[ACC] = ULONG_LONG_MAX; 4871be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema for (i=0; sensorFind(SENS_TYPE_ACCEL, i, &mTask.accelHandle) != NULL; i++) { 488c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian if (sensorRequest(mTask.tid, mTask.accelHandle, mTask.raw_sensor_rate[ACC], mTask.raw_sensor_latency)) { 4891be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema osEventSubscribe(mTask.tid, EVT_SENSOR_ACC_DATA_RDY); 4901be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 4911be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 4921be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 4931be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } else { 494c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian sensorRequestRateChange(mTask.tid, mTask.accelHandle, mTask.raw_sensor_rate[ACC], mTask.raw_sensor_latency); 4951be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 49618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 49718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 498c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qianstatic void fusionSetRateGyr(void) 49918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 50018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian int i; 5011be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (mTask.gyroHandle == 0) { 50218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sample_counts[GYR] = 0; 50318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sample_indices[GYR] = 0; 50418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.counters[GYR] = 0; 50518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.last_time[GYR] = ULONG_LONG_MAX; 5061be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema for (i=0; sensorFind(SENS_TYPE_GYRO, i, &mTask.gyroHandle) != NULL; i++) { 507c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian if (sensorRequest(mTask.tid, mTask.gyroHandle, mTask.raw_sensor_rate[GYR], mTask.raw_sensor_latency)) { 5081be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema osEventSubscribe(mTask.tid, EVT_SENSOR_GYR_DATA_RDY); 5091be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 5101be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 5111be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 5121be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } else { 513c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian sensorRequestRateChange(mTask.tid, mTask.gyroHandle, mTask.raw_sensor_rate[GYR], mTask.raw_sensor_latency); 5141be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 51518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 51618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 517c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qianstatic void fusionSetRateMag(void) 51818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 51918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian int i; 5201be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (mTask.magHandle == 0) { 52118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sample_counts[MAG] = 0; 52218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sample_indices[MAG] = 0; 52318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.counters[MAG] = 0; 52418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.last_time[MAG] = ULONG_LONG_MAX; 5251be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema for (i=0; sensorFind(SENS_TYPE_MAG, i, &mTask.magHandle) != NULL; i++) { 526c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian if (sensorRequest(mTask.tid, mTask.magHandle, mTask.raw_sensor_rate[MAG], mTask.raw_sensor_latency)) { 5271be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema osEventSubscribe(mTask.tid, EVT_SENSOR_MAG_DATA_RDY); 5281be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 5291be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 5301be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 5311be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } else { 532c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian sensorRequestRateChange(mTask.tid, mTask.magHandle, mTask.raw_sensor_rate[MAG], mTask.raw_sensor_latency); 533c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian } 534c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian} 535c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian 536c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qianstatic bool fusionSetRate(struct FusionSensor *mSensor, uint32_t rate, uint64_t latency) 537c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian{ 538c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian 539c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian int i; 540c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian uint32_t max_rate = 0; 541c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian uint32_t gyr_rate, mag_rate; 542c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian uint32_t total_sample = 0; 543c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian 544c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian mSensor->rate = rate; 545c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian mSensor->latency = latency; 546c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian 547c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian for (i = ORIENT; i < NUM_OF_FUSION_SENSOR; i++) { 548c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian if (mTask.sensors[i].active) { 549c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian max_rate = max_rate > mTask.sensors[i].rate ? max_rate : mTask.sensors[i].rate; 550c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian } 551c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian } 552c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian 553c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian if (mTask.acc_cnt > 0) { 554c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian mTask.ResamplePeriodNs[ACC] = (1000000000ull * 1024ull / max_rate); 555c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian mTask.raw_sensor_rate[ACC] = max_rate; 556c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian total_sample += mTask.raw_sensor_rate[ACC]; 557c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian } 558c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian 559c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian if (mTask.gyr_cnt > 0) { 560c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian mTask.ResamplePeriodNs[GYR] = (1000000000ull * 1024ull / max_rate); 561c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian gyr_rate = max_rate > DEFAULT_GYRO_RATE_HZ ? max_rate : DEFAULT_GYRO_RATE_HZ; 562c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian mTask.raw_sensor_rate[GYR] = gyr_rate; 563c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian total_sample += mTask.raw_sensor_rate[GYR]; 564c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian } 565c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian 566c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian if (mTask.mag_cnt > 0) { 567c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian mag_rate = max_rate < DEFAULT_MAG_RATE_HZ ? max_rate : DEFAULT_MAG_RATE_HZ; 568c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian mTask.ResamplePeriodNs[MAG] = (1000000000ull * 1024ull / mag_rate); 569c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian mTask.raw_sensor_rate[MAG] = mag_rate; 570c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian total_sample += mTask.raw_sensor_rate[MAG]; 571c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian } 572c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian 573c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian mTask.raw_sensor_latency = (total_sample == 0 ? 0 : MAX_NUM_RAW_DATA_SAMPLES * 1024ull / total_sample); 574c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian for (i = ORIENT; i < NUM_OF_FUSION_SENSOR; i++) { 575c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian if (mTask.sensors[i].active) { 576c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian mTask.raw_sensor_latency = mTask.sensors[i].latency < mTask.raw_sensor_latency ? 577c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian mTask.sensors[i].latency : mTask.raw_sensor_latency; 578c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian } 57918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 580c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian 581c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian if (mTask.acc_cnt > 0) 582c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian fusionSetRateAcc(); 583c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian if (mTask.gyr_cnt > 0) 584c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian fusionSetRateGyr(); 585c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian if (mTask.mag_cnt > 0) 586c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian fusionSetRateMag(); 587c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian if (mSensor->rate > 0) 588c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian sensorSignalInternalEvt(mSensor->handle, SENSOR_INTERNAL_EVT_RATE_CHG, rate, latency); 589c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian 590c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian return true; 59118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 59218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 59318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool fusionPower(struct FusionSensor *mSensor, bool on) 59418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 59518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mSensor->active = on; 59618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (on == false) { 59718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.acc_cnt--; 59818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mSensor->idx != GEOMAG) 59918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.gyr_cnt--; 60018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mSensor->idx != GAME && mSensor->idx != GRAVITY) 60118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.mag_cnt--; 60218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 60318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian // if cnt == 0 and Handle == 0, nothing need to be done. 60418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian // if cnt > 0 and Handle == 0, something else is turning it on, all will be done. 60518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.acc_cnt == 0 && mTask.accelHandle != 0) { 60618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian sensorRelease(mTask.tid, mTask.accelHandle); 60718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.accelHandle = 0; 60818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian osEventUnsubscribe(mTask.tid, EVT_SENSOR_ACC_DATA_RDY); 60918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 61018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 61118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.gyr_cnt == 0 && mTask.gyroHandle != 0) { 61218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian sensorRelease(mTask.tid, mTask.gyroHandle); 61318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.gyroHandle = 0; 61418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian osEventUnsubscribe(mTask.tid, EVT_SENSOR_GYR_DATA_RDY); 61518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 61618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 61718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mTask.mag_cnt == 0 && mTask.magHandle != 0) { 61818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian sensorRelease(mTask.tid, mTask.magHandle); 61918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.magHandle = 0; 62018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian osEventUnsubscribe(mTask.tid, EVT_SENSOR_MAG_DATA_RDY); 62118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 622c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian 623c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian (void) fusionSetRate(mSensor, 0, ULONG_LONG_MAX); 62418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } else { 62518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.acc_cnt++; 62618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mSensor->idx != GEOMAG) 62718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.gyr_cnt++; 62818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian if (mSensor->idx != GAME && mSensor->idx != GRAVITY) 62918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.mag_cnt++; 6301be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 6311be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 63218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian configureFusion(); 63318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian configureGame(); 63418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian sensorSignalInternalEvt(mSensor->handle, SENSOR_INTERNAL_EVT_POWER_STATE_CHG, on, 0); 635960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 636960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian return true; 637960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 638960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 63918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool orientPower(bool on) 64018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 64118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionPower(&mTask.sensors[ORIENT], on); 64218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 64318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 64418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool geoMagPower(bool on) 64518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 64618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionPower(&mTask.sensors[GEOMAG], on); 64718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 64818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 64918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool linearAccPower(bool on) 65018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 65118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionPower(&mTask.sensors[LINEAR], on); 65218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 65318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 65418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool gamePower(bool on) 65518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 65618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionPower(&mTask.sensors[GAME], on); 65718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 65818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 65918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool rotationPower(bool on) 66018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 66118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionPower(&mTask.sensors[ROTAT], on); 66218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 66318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 66418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool gravityPower(bool on) 66518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 66618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionPower(&mTask.sensors[GRAVITY], on); 66718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 66818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 66918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool orientSetRate(uint32_t rate, uint64_t latency) 67018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 67118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionSetRate(&mTask.sensors[ORIENT], rate, latency); 67218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 67318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 67418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool gravitySetRate(uint32_t rate, uint64_t latency) 67518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 67618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionSetRate(&mTask.sensors[GRAVITY], rate, latency); 67718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 67818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 67918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool linearAccSetRate(uint32_t rate, uint64_t latency) 680960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 68118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionSetRate(&mTask.sensors[LINEAR], rate, latency); 682960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 683960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 68418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool geoMagSetRate(uint32_t rate, uint64_t latency) 68518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 68618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionSetRate(&mTask.sensors[GEOMAG], rate, latency); 68718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 68818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 68918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool gameSetRate(uint32_t rate, uint64_t latency) 69018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 69118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionSetRate(&mTask.sensors[GAME], rate, latency); 69218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 69318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 69418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool rotationSetRate(uint32_t rate, uint64_t latency) 69518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 69618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionSetRate(&mTask.sensors[ROTAT], rate, latency); 69718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 69818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 69918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool fusionFirmwareUpload(struct FusionSensor *mSensor) 70018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 70118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian sensorSignalInternalEvt(mSensor->handle, SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0); 70218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return true; 70318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 70418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 70518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool orientFirmwareUpload() 70618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 70718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionFirmwareUpload(&mTask.sensors[ORIENT]); 70818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 70918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 71018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool gravityFirmwareUpload() 71118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 71218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionFirmwareUpload(&mTask.sensors[GRAVITY]); 71318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 71418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 71518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool geoMagFirmwareUpload() 71618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 71718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionFirmwareUpload(&mTask.sensors[GEOMAG]); 71818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 71918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 72018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool linearAccFirmwareUpload() 72118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 72218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionFirmwareUpload(&mTask.sensors[LINEAR]); 72318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 72418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 72518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool gameFirmwareUpload() 72618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 72718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionFirmwareUpload(&mTask.sensors[GAME]); 72818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 72918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 73018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool rotationFirmwareUpload() 73118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 73218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionFirmwareUpload(&mTask.sensors[ROTAT]); 73318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 73418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 73518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool fusionFlush(struct FusionSensor *mSensor) 73618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 73718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian uint32_t evtType = sensorGetMyEventType(mSi[mSensor->idx].sensorType); 73818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian osEnqueueEvt(evtType, SENSOR_DATA_EVENT_FLUSH, NULL); 73918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return true; 74018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 74118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 74218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool orientFlush() 74318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 74418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionFlush(&mTask.sensors[ORIENT]); 74518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 74618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 74718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool gravityFlush() 74818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 74918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionFlush(&mTask.sensors[GRAVITY]); 75018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 75118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 75218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool linearAccFlush() 75318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 75418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionFlush(&mTask.sensors[LINEAR]); 75518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 75618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 75718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool gameFlush() 75818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 75918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionFlush(&mTask.sensors[GAME]); 76018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 76118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 76218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool geoMagFlush() 76318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 76418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionFlush(&mTask.sensors[GEOMAG]); 76518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 76618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 76718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool rotationFlush() 76818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian{ 76918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian return fusionFlush(&mTask.sensors[ROTAT]); 77018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian} 77118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 77218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian 77318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic void fusionHandleEvent(uint32_t evtType, const void* evtData) 774960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 7757062239aaa63d8a5260d7d325483755acbb8c35cBen Fennema struct TripleAxisDataEvent *ev; 776960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 7770bcb1a3baec93492e58afff27f2ef92afcbf1698Ben Fennema if (evtData == SENSOR_DATA_EVENT_FLUSH) 7780bcb1a3baec93492e58afff27f2ef92afcbf1698Ben Fennema return; 7790bcb1a3baec93492e58afff27f2ef92afcbf1698Ben Fennema 780960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian switch (evtType) { 7811be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema case EVT_SENSOR_ACC_DATA_RDY: 7821be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema ev = (struct TripleAxisDataEvent *)evtData; 78318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian fillSamples(ev, ACC); 7841be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema drainSamples(); 7851be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 7861be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema case EVT_SENSOR_GYR_DATA_RDY: 7871be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema ev = (struct TripleAxisDataEvent *)evtData; 78818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian fillSamples(ev, GYR); 7891be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema drainSamples(); 7901be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 7911be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema case EVT_SENSOR_MAG_DATA_RDY: 7921be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema ev = (struct TripleAxisDataEvent *)evtData; 79318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian fillSamples(ev, MAG); 7941be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema drainSamples(); 7951be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 796960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 797960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 798960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 79918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic const struct SensorOps mSops[NUM_OF_FUSION_SENSOR] = 80064eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian{ 80118040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian {orientPower, orientFirmwareUpload, orientSetRate, orientFlush, NULL, NULL}, 80218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian {gravityPower, gravityFirmwareUpload, gravitySetRate, gravityFlush, NULL, NULL}, 80318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian {geoMagPower, geoMagFirmwareUpload, geoMagSetRate, geoMagFlush, NULL, NULL}, 80418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian {linearAccPower, linearAccFirmwareUpload, linearAccSetRate, linearAccFlush, NULL, NULL}, 80518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian {gamePower, gameFirmwareUpload, gameSetRate, gameFlush, NULL, NULL}, 80618040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian {rotationPower, rotationFirmwareUpload, rotationSetRate, rotationFlush, NULL, NULL}, 80764eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian}; 80864eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian 80918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic bool fusionStart(uint32_t tid) 810960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 811960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian osLog(LOG_INFO, " ORIENTATION: %ld\n", tid); 812e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian size_t i, slabSize; 813960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 814960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.tid = tid; 815960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.last_gyro_time = 0ull; 816960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.last_acc_time = 0ull; 817960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.flags = 0; 818960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 81918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian for (i = 0; i < NUM_OF_RAW_SENSOR; i++) { 820960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.sample_counts[i] = 0; 821960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.sample_indices[i] = 0; 822960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 823960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 82418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian for (i = ORIENT; i < NUM_OF_FUSION_SENSOR; i++) { 82518040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sensors[i].handle = sensorRegister(&mSi[i], &mSops[i]); 826f45dac303dc3756b80036a68f23cdc48f34d870eBen Fennema sensorRegisterInitComplete(mTask.sensors[i].handle); 82718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sensors[i].idx = i; 82818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sensors[i].use_gyr_data = true; 82918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sensors[i].use_mag_data = true; 83018040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian } 831960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 83218040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sensors[GEOMAG].use_gyr_data = false; 83318040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sensors[GAME].use_mag_data = false; 83418040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian mTask.sensors[GRAVITY].use_mag_data = false; 835960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 836960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 8377062239aaa63d8a5260d7d325483755acbb8c35cBen Fennema slabSize = sizeof(struct TripleAxisDataEvent) 8387062239aaa63d8a5260d7d325483755acbb8c35cBen Fennema + MAX_NUM_COMMS_EVENT_SAMPLES * sizeof(struct TripleAxisDataPoint); 839e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian mDataSlab = slabAllocatorNew(slabSize, 4, 10); // 10 slots for now.. 840c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian if (!mDataSlab) { 841c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian osLog(LOG_ERROR, "FUSION SLAB ALLOCATION FAILED\n"); 842c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian return false; 843c900c013a76aa73bd612da12000c76e0d4169595Zhengyin Qian } 844e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian 845960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian return true; 846960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 847960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 84818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qianstatic void fusionEnd() 849960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 850960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.flags &= ~FUSION_FLAG_INITIALIZED; 851e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian slabAllocatorDestroy(mDataSlab); 852960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 853960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 854960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin QianINTERNAL_APP_INIT( 855dca61fcfcc85a8240bc46a650c71008ded2d32ddBen Fennema APP_ID_MAKE(APP_ID_VENDOR_GOOGLE, 4), 856cc77708f80db23714a92638ddee64f59dbdf5483Dmitry Grinberg 0, 85718040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian fusionStart, 85818040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian fusionEnd, 85918040c9213658bbcc2ccc9e6cdb654d7a228eb66Zhengyin Qian fusionHandleEvent); 860