orientation.c revision 0bcb1a3baec93492e58afff27f2ef92afcbf1698
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> 9960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 10960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <seos.h> 11960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <accelerometer.h> 12960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 13960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <nanohub_math.h> 14960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <fusion/fusion.h> 15960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <sensors.h> 16960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#include <limits.h> 17e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian#include <slab.h> 18960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 19960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#define MAX_NUM_COMMS_EVENT_SAMPLES 15 20960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#define MAX_NUM_SAMPLES MAX_NUM_COMMS_EVENT_SAMPLES 21960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#define EVT_SENSOR_ACC_DATA_RDY sensorGetMyEventType(SENS_TYPE_ACCEL) 22960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#define EVT_SENSOR_GYR_DATA_RDY sensorGetMyEventType(SENS_TYPE_GYRO) 23960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian#define EVT_SENSOR_MAG_DATA_RDY sensorGetMyEventType(SENS_TYPE_MAG) 24e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian#define EVT_SENSOR_ORIENTATION_DATA_RDY sensorGetMyEventType(SENS_TYPE_ORIENTATION) 25960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 261be10b6751f50675307716747bd4d729d9e7aff5Ben Fennemaenum 271be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema{ 281be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema FUSION_FLAG_ENABLED = 0x01, 291be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema FUSION_FLAG_INITIALIZED = 0x08, 301be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema FUSION_FLAG_GAME_ENABLED = 0x10, 311be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema FUSION_FLAG_GAME_INITIALIZED = 0x20 32960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian}; 33960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 341be10b6751f50675307716747bd4d729d9e7aff5Ben Fennemaenum SampleType 351be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema{ 361be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema SAMPLE_TYPE_ACCEL, 371be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema SAMPLE_TYPE_GYRO, 381be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema SAMPLE_TYPE_MAG, 391be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema SAMPLE_TYPE_COUNT 401be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema}; 411be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 421be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 43960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstruct OrientationSensorSample { 44960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian uint64_t time; 45960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian float x, y, z; 46960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian}; 47960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 48960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstruct OrientationTask { 49960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian uint32_t tid; 50960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian uint32_t handle; 511be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema uint32_t accelHandle; 521be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema uint32_t gyroHandle; 531be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema uint32_t magHandle; 54960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 55960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian struct Fusion fusion; 56960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 571be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema struct OrientationSensorSample samples[SAMPLE_TYPE_COUNT][MAX_NUM_SAMPLES]; 587062239aaa63d8a5260d7d325483755acbb8c35cBen Fennema struct TripleAxisDataEvent *ev; 591be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema size_t sample_indices[SAMPLE_TYPE_COUNT]; 601be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema size_t sample_counts[SAMPLE_TYPE_COUNT]; 61960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 62960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian uint64_t last_gyro_time; 63960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian uint64_t last_acc_time; 64960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian uint64_t latency; 65960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian uint32_t rate; 66960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian uint32_t flags; 67960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 68960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian bool use_gyro_data; 69960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian bool use_mag_data; 70960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian bool first_evt; 71960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian}; 72960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 73960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic uint32_t OrientationRates[] = { 74960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian SENSOR_HZ(12.5f), 75960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian SENSOR_HZ(25.0f), 76960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian SENSOR_HZ(50.0f), 77960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian SENSOR_HZ(100.0f), 78960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian SENSOR_HZ(200.0f), 79960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 0, 80960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian}; 81960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 82960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic struct OrientationTask mTask; 8364eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qianstatic const struct SensorInfo mSi = 8464eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian{ 8564eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian "Orientation", 8664eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian OrientationRates, 8764eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian SENS_TYPE_ORIENTATION, 887062239aaa63d8a5260d7d325483755acbb8c35cBen Fennema NUM_AXIS_THREE, 897062239aaa63d8a5260d7d325483755acbb8c35cBen Fennema { NANOHUB_INT_NONWAKEUP } 9064eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian}; 91960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 92e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qianstatic struct SlabAllocator *mDataSlab; 93e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian 94e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qianstatic void dataEvtFree(void *ptr) 95960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 96e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian slabAllocatorFree(mDataSlab, ptr); 97960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 98960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 991be10b6751f50675307716747bd4d729d9e7aff5Ben Fennemastatic void fillSamples(struct TripleAxisDataEvent *ev, enum SampleType index) 100960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 1011be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema size_t i, sampleCnt, n, start, copy, copy2; 1021be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema struct TripleAxisDataPoint *sample; 103960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 1041be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (index == SAMPLE_TYPE_GYRO && !mTask.use_gyro_data) { 105960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian return; 106960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 1071be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (index == SAMPLE_TYPE_MAG && !mTask.use_mag_data) { 108960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian return; 109960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 110960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 1111be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema sampleCnt = ev->samples[0].numSamples; 112e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian if (sampleCnt >= MAX_NUM_SAMPLES) { 113960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian // Copy the last MAX_NUM_SAMPLES samples over and reset the sample index. 114960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.sample_indices[index] = 0; 115960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.sample_counts[index] = MAX_NUM_SAMPLES; 116960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 117960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian for (i = 0; i < MAX_NUM_SAMPLES; ++i) { 118e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian sample = &ev->samples[sampleCnt - MAX_NUM_SAMPLES + i]; 119960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.samples[index][i].x = sample->x; 120960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.samples[index][i].y = sample->y; 121960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.samples[index][i].z = sample->z; 122e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian if (i == 0) 123e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian mTask.samples[index][i].time = ev->referenceTime; 124e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian else 125e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian mTask.samples[index][i].time = ev->referenceTime + sample->deltaTime; 126960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 127960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 128960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } else { 1291be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema n = mTask.sample_counts[index]; 1301be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema start = (mTask.sample_indices[index] + n) % MAX_NUM_SAMPLES; 131960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 132e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian copy = MAX_NUM_SAMPLES - start; 133e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian if (copy > sampleCnt) { 134e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian copy = sampleCnt; 135960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 136960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 137960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian for (i = 0; i < copy; ++i) { 138e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian sample = &ev->samples[i]; 139960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.samples[index][start + i].x = sample->x; 140960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.samples[index][start + i].y = sample->y; 141960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.samples[index][start + i].z = sample->z; 142e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian if (i == 0) 1431be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema mTask.samples[index][start + i].time = ev->referenceTime; 144e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian else 145e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian mTask.samples[index][start + i].time = ev->referenceTime + sample->deltaTime; 146960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 147960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 148e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian copy2 = sampleCnt - copy; 149960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 150960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian for (i = 0; i < copy2; ++i) { 151e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian sample = &ev->samples[copy + i]; 152960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.samples[index][i].x = sample->x; 153960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.samples[index][i].y = sample->y; 154960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.samples[index][i].z = sample->z; 155e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian if (copy + i == 0) 156e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian mTask.samples[index][i].time = ev->referenceTime; 157e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian else 158e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian mTask.samples[index][i].time = ev->referenceTime + sample->deltaTime; 159960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 160960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 161e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian mTask.sample_counts[index] += sampleCnt; 162960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 163960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian // FIFO overflow: over-write the oldest samples and move the sample index 164960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian if (mTask.sample_counts[index] > MAX_NUM_SAMPLES) { 165960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.sample_indices[index] = (mTask.sample_indices[index] 166960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian + mTask.sample_counts[index] 167960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian - MAX_NUM_SAMPLES) % MAX_NUM_SAMPLES; 168960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.sample_counts[index] = MAX_NUM_SAMPLES; 169960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 170960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 171960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 172960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 173960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic void addSample(uint64_t time, float x, float y, float z) 174960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 1757062239aaa63d8a5260d7d325483755acbb8c35cBen Fennema struct TripleAxisDataPoint *sample; 176e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian uint32_t deltaTime; 177e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian 178e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian if (mTask.ev == NULL) { 179e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian mTask.ev = slabAllocatorAlloc(mDataSlab); 180e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian if (mTask.ev == NULL) { 181e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian // slaballocation failed 182e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian osLog(LOG_ERROR, "Slab Allocation Failed\n"); 183e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian return; 184e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian } 185e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian mTask.ev->samples[0].deltaTime = 0; 186e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian mTask.ev->referenceTime = time; 187960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 188960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 189e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian if (mTask.ev->samples[0].deltaTime >= MAX_NUM_COMMS_EVENT_SAMPLES) { 190960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian osLog(LOG_ERROR, "BAD_INDEX\n"); 191960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian return; 192960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 193960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 194e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian sample = &mTask.ev->samples[mTask.ev->samples[0].deltaTime++]; 195e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian 196e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian deltaTime = (time > mTask.ev->referenceTime) 197e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian ? (time - mTask.ev->referenceTime) : 0; 198e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian 199e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian // the first deltatime is for sample count 200e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian if (mTask.ev->samples[0].deltaTime > 1) 201e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian sample->deltaTime = deltaTime; 202960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 203960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian sample->x = x; 204960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian sample->y = y; 205960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian sample->z = z; 206960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 207e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian if (mTask.ev->samples[0].deltaTime == MAX_NUM_COMMS_EVENT_SAMPLES) { 2087062239aaa63d8a5260d7d325483755acbb8c35cBen Fennema osEnqueueEvt(EVT_SENSOR_ORIENTATION_DATA_RDY, mTask.ev, dataEvtFree); 209e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian mTask.ev = NULL; 210960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 211960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 212960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 213960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic void updateOutput(ssize_t last_accel_sample_index, uint64_t last_sensor_time) 214960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 215960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian if (fusionHasEstimate(&mTask.fusion)) { 216960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian struct Mat33 R; 217960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian fusionGetRotationMatrix(&mTask.fusion, &R); 218960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 219960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian struct Vec4 attitude; 220960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian fusionGetAttitude(&mTask.fusion, &attitude); 221960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 222960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian // x, y, z = yaw, pitch, roll 223960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian static const float kRad2deg = 180.0f / M_PI; 224960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian float x = atan2f(-R.elem[0][1], R.elem[0][0]) * kRad2deg; 225960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian float y = atan2f(-R.elem[1][2], R.elem[2][2]) * kRad2deg; 226960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian float z = asinf(R.elem[0][2]) * kRad2deg; 227960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 228960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian if (x < 0.0f) { 229960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian x += 360.0f; 230960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 231960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 232960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian addSample(last_sensor_time, x, y, z); 233960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 234960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 235960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 236960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic void drainSamples() 237960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 2381be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema size_t i = mTask.sample_indices[SAMPLE_TYPE_ACCEL]; 239960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian size_t j = 0; 240960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian size_t k = 0; 2411be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema size_t which; 2421be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema struct Vec3 a, w, m; 2431be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema float dT; 2441be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema uint64_t a_time, g_time, m_time; 2451be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 2461be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (mTask.use_gyro_data) 2471be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema j = mTask.sample_indices[SAMPLE_TYPE_GYRO]; 2481be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 2491be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (mTask.use_mag_data) 2501be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema k = mTask.sample_indices[SAMPLE_TYPE_MAG]; 2511be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 2521be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema while (mTask.sample_counts[SAMPLE_TYPE_ACCEL] > 0 2531be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema && (!mTask.use_gyro_data || mTask.sample_counts[SAMPLE_TYPE_GYRO] > 0) 2541be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema && (!mTask.use_mag_data || mTask.sample_counts[SAMPLE_TYPE_MAG] > 0)) { 2551be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema a_time = mTask.samples[SAMPLE_TYPE_ACCEL][i].time; 2561be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema g_time = mTask.use_gyro_data ? mTask.samples[SAMPLE_TYPE_GYRO][j].time 257960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian : ULONG_LONG_MAX; 2581be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema m_time = mTask.use_mag_data ? mTask.samples[SAMPLE_TYPE_MAG][k].time 259960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian : ULONG_LONG_MAX; 260960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 261960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian // priority with same timestamp: gyro > acc > mag 262960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian if (g_time <= a_time && g_time <= m_time) { 2631be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema which = SAMPLE_TYPE_GYRO; 264960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } else if (a_time <= m_time) { 2651be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema which = SAMPLE_TYPE_ACCEL; 266960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } else { 2671be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema which = SAMPLE_TYPE_MAG; 268960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 269960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 2701be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema switch (which) { 2711be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema case SAMPLE_TYPE_ACCEL: 2721be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema initVec3(&a, mTask.samples[SAMPLE_TYPE_ACCEL][i].x, mTask.samples[SAMPLE_TYPE_ACCEL][i].y, mTask.samples[SAMPLE_TYPE_ACCEL][i].z); 273960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 2741be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema dT = (mTask.samples[SAMPLE_TYPE_ACCEL][i].time - mTask.last_acc_time) * 1.0E-6f; 2751be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema mTask.last_acc_time = mTask.samples[SAMPLE_TYPE_ACCEL][i].time; 276960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 2771be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema fusionHandleAcc(&mTask.fusion, &a, dT); 278960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 2791be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema updateOutput(i, mTask.samples[SAMPLE_TYPE_ACCEL][i].time); 280960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 2811be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema --mTask.sample_counts[SAMPLE_TYPE_ACCEL]; 2821be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (++i == MAX_NUM_SAMPLES) 2831be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema i = 0; 2841be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 2851be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema case SAMPLE_TYPE_GYRO: 2861be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema initVec3(&w, mTask.samples[SAMPLE_TYPE_GYRO][j].x, mTask.samples[SAMPLE_TYPE_GYRO][j].y, mTask.samples[SAMPLE_TYPE_GYRO][j].z); 287960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 2881be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema dT = (mTask.samples[SAMPLE_TYPE_GYRO][j].time - mTask.last_gyro_time) * 1.0E-6f; 2891be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema mTask.last_gyro_time = mTask.samples[SAMPLE_TYPE_GYRO][j].time; 290960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 2911be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema fusionHandleGyro(&mTask.fusion, &w, dT); 292960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 2931be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema --mTask.sample_counts[SAMPLE_TYPE_GYRO]; 2941be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (++j == MAX_NUM_SAMPLES) 2951be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema j = 0; 2961be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 2971be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema case SAMPLE_TYPE_MAG: 2981be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema initVec3(&m, mTask.samples[SAMPLE_TYPE_MAG][k].x, mTask.samples[SAMPLE_TYPE_MAG][k].y, mTask.samples[SAMPLE_TYPE_MAG][k].z); 299960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 3001be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema fusionHandleMag(&mTask.fusion, &m); 301960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 3021be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema --mTask.sample_counts[SAMPLE_TYPE_MAG]; 3031be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (++k == MAX_NUM_SAMPLES) 3041be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema k = 0; 3051be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 306960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 307960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 308960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 3091be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema mTask.sample_indices[SAMPLE_TYPE_ACCEL] = i; 310960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 3111be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (mTask.use_gyro_data) 3121be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema mTask.sample_indices[SAMPLE_TYPE_GYRO] = j; 313960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 3141be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (mTask.use_mag_data) 3151be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema mTask.sample_indices[SAMPLE_TYPE_MAG] = k; 316960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 317960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian if (mTask.ev != NULL) { 3181be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema osEnqueueEvt(EVT_SENSOR_ORIENTATION_DATA_RDY, mTask.ev, dataEvtFree); 319960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.ev = NULL; 320960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 321960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 322960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 323960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic void configureFusion() 324960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 325960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.flags |= FUSION_FLAG_ENABLED; 326960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian initFusion( 327960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian &mTask.fusion, 328960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian (mTask.use_mag_data ? FUSION_USE_MAG : 0) | 329960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian (mTask.use_gyro_data ? FUSION_USE_GYRO : 0) | 330960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian ((mTask.flags & FUSION_FLAG_INITIALIZED) ? 0 : FUSION_REINITIALIZE)); 331960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.flags |= FUSION_FLAG_INITIALIZED; 332960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 333960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 334960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic bool orientationPower(bool on) 335960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 3361be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (on == false) { 3371be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (mTask.accelHandle != 0) { 3381be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema sensorRelease(mTask.tid, mTask.accelHandle); 3391be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema mTask.accelHandle = 0; 3401be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema osEventUnsubscribe(mTask.tid, EVT_SENSOR_ACC_DATA_RDY); 3411be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 342960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 3431be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (mTask.gyroHandle != 0) { 3441be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema sensorRelease(mTask.tid, mTask.gyroHandle); 3451be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema mTask.gyroHandle = 0; 3461be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema osEventUnsubscribe(mTask.tid, EVT_SENSOR_GYR_DATA_RDY); 3471be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 348960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 3491be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (mTask.magHandle != 0) { 3501be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema sensorRelease(mTask.tid, mTask.magHandle); 3511be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema mTask.magHandle = 0; 3521be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema osEventUnsubscribe(mTask.tid, EVT_SENSOR_MAG_DATA_RDY); 3531be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 354960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 355960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 356960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian sensorSignalInternalEvt(mTask.handle, SENSOR_INTERNAL_EVT_POWER_STATE_CHG, on, 0); 357960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 358960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian return true; 359960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 360960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 361960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic bool orientationSetRate(uint32_t rate, uint64_t latency) 362960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 3631be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema int i; 364960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.rate = rate; 365960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.latency = latency; 366960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 3671be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (mTask.accelHandle == 0) { 3681be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema for (i=0; sensorFind(SENS_TYPE_ACCEL, i, &mTask.accelHandle) != NULL; i++) { 3691be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (sensorRequest(mTask.tid, mTask.accelHandle, rate, latency)) { 3701be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema osEventSubscribe(mTask.tid, EVT_SENSOR_ACC_DATA_RDY); 3711be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 3721be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 3731be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 3741be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } else { 3751be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema sensorRequestRateChange(mTask.tid, mTask.accelHandle, rate, latency); 3761be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 3771be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 3781be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (mTask.gyroHandle == 0) { 3791be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema for (i=0; sensorFind(SENS_TYPE_GYRO, i, &mTask.gyroHandle) != NULL; i++) { 3801be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (sensorRequest(mTask.tid, mTask.gyroHandle, rate, latency)) { 3811be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema osEventSubscribe(mTask.tid, EVT_SENSOR_GYR_DATA_RDY); 3821be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 3831be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 3841be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 3851be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } else { 3861be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema sensorRequestRateChange(mTask.tid, mTask.gyroHandle, rate, latency); 3871be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 3881be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 3891be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (mTask.magHandle == 0) { 3901be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema for (i=0; sensorFind(SENS_TYPE_MAG, i, &mTask.magHandle) != NULL; i++) { 3911be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema if (sensorRequest(mTask.tid, mTask.magHandle, rate, latency)) { 3921be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema osEventSubscribe(mTask.tid, EVT_SENSOR_MAG_DATA_RDY); 3931be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 3941be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 3951be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 3961be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } else { 3971be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema sensorRequestRateChange(mTask.tid, mTask.magHandle, rate, latency); 3981be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema } 3991be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 4001be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema sensorSignalInternalEvt(mTask.handle, SENSOR_INTERNAL_EVT_RATE_CHG, rate, latency); 401960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 402960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian return true; 403960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 404960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 405960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic bool orientationFirmwareUpload() 406960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 407960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian sensorSignalInternalEvt(mTask.handle, SENSOR_INTERNAL_EVT_FW_STATE_CHG, 4081be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema 1, 0); 409960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian return true; 410960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 411960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 4121be10b6751f50675307716747bd4d729d9e7aff5Ben Fennemastatic bool orientationFlush() 413960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 4141be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema return osEnqueueEvt(EVT_SENSOR_ORIENTATION_DATA_RDY, SENSOR_DATA_EVENT_FLUSH, NULL); 415960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 416960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 417960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic void orientationHandleEvent(uint32_t evtType, const void* evtData) 418960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 4197062239aaa63d8a5260d7d325483755acbb8c35cBen Fennema struct TripleAxisDataEvent *ev; 420960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 4210bcb1a3baec93492e58afff27f2ef92afcbf1698Ben Fennema if (evtData == SENSOR_DATA_EVENT_FLUSH) 4220bcb1a3baec93492e58afff27f2ef92afcbf1698Ben Fennema return; 4230bcb1a3baec93492e58afff27f2ef92afcbf1698Ben Fennema 424960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian switch (evtType) { 4251be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema case EVT_SENSOR_ACC_DATA_RDY: 4261be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema ev = (struct TripleAxisDataEvent *)evtData; 4271be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema fillSamples(ev, SAMPLE_TYPE_ACCEL); 4281be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema drainSamples(); 4291be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 4301be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema case EVT_SENSOR_GYR_DATA_RDY: 4311be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema ev = (struct TripleAxisDataEvent *)evtData; 4321be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema fillSamples(ev, SAMPLE_TYPE_GYRO); 4331be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema drainSamples(); 4341be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 4351be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema case EVT_SENSOR_MAG_DATA_RDY: 4361be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema ev = (struct TripleAxisDataEvent *)evtData; 4371be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema fillSamples(ev, SAMPLE_TYPE_MAG); 4381be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema drainSamples(); 4391be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema break; 440960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 441960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 442960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 44364eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qianstatic const struct SensorOps mSops = 44464eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian{ 44564eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian orientationPower, 44664eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian orientationFirmwareUpload, 44764eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian orientationSetRate, 4481be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema orientationFlush, 44964eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian NULL 45064eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian}; 45164eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian 452960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic bool orientationStart(uint32_t tid) 453960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 454960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian osLog(LOG_INFO, " ORIENTATION: %ld\n", tid); 455e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian size_t i, slabSize; 456960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 457960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.tid = tid; 458960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.use_gyro_data = true; 459960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.use_mag_data = true; 460960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.last_gyro_time = 0ull; 461960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.last_acc_time = 0ull; 462960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.flags = 0; 463960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 464960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.first_evt = true; 465960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 4661be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema for (i = 0; i < SAMPLE_TYPE_COUNT; i++) { 467960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.sample_counts[i] = 0; 468960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.sample_indices[i] = 0; 469960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian } 470960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 471960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian configureFusion(); 472960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 47364eb1702a319ad4bbc181ed1e5af0703aea7ea22Zhengyin Qian mTask.handle = sensorRegister(&mSi, &mSops); 474960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 4751be10b6751f50675307716747bd4d729d9e7aff5Ben Fennema mTask.rate = 0; 476960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.latency = 0; 477960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 4787062239aaa63d8a5260d7d325483755acbb8c35cBen Fennema slabSize = sizeof(struct TripleAxisDataEvent) 4797062239aaa63d8a5260d7d325483755acbb8c35cBen Fennema + MAX_NUM_COMMS_EVENT_SAMPLES * sizeof(struct TripleAxisDataPoint); 480e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian mDataSlab = slabAllocatorNew(slabSize, 4, 10); // 10 slots for now.. 481e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian 482960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian return true; 483960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 484960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 485960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qianstatic void orientationEnd() 486960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian{ 487960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian mTask.flags &= ~FUSION_FLAG_INITIALIZED; 488e0e5b567748b8d46f60ede2ff12c4b2358ffe0dbZhengyin Qian slabAllocatorDestroy(mDataSlab); 489960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian} 490960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 491960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin QianINTERNAL_APP_INIT( 492960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian 0x0000000000000005ULL, 493960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian orientationStart, 494960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian orientationEnd, 495960c2ec577b48937271d3d951bfbc66b070283a1Zhengyin Qian orientationHandleEvent); 496