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