1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <algos/time_sync.h>
18 #include <atomic.h>
19 #include <cpu/inc/cpuMath.h>
20 #include <gpio.h>
21 #include <heap.h>
22 #include <hostIntf.h>
23 #include <isr.h>
24 #include <nanohub_math.h>
25 #include <nanohubPacket.h>
26 #include <plat/inc/exti.h>
27 #include <plat/inc/gpio.h>
28 #include <plat/inc/syscfg.h>
29 #include <plat/inc/rtc.h>
30 #include <sensors.h>
31 #include <seos.h>
32 #include <slab.h>
33 #include <spi.h>
34 #include <timer.h>
35 #include <variant/inc/sensType.h>
36 #include <variant/inc/variant.h>
37 
38 #ifdef MAG_SLAVE_PRESENT
39 #include <algos/mag_cal.h>
40 #endif
41 
42 #include <limits.h>
43 #include <stdlib.h>
44 #include <string.h>
45 
46 #define INFO_PRINT(fmt, ...) do { \
47         osLog(LOG_INFO, "%s " fmt, "[BMI160]", ##__VA_ARGS__); \
48     } while (0);
49 
50 #define ERROR_PRINT(fmt, ...) do { \
51         osLog(LOG_ERROR, "%s " fmt, "[BMI160] ERROR:", ##__VA_ARGS__); \
52     } while (0);
53 
54 #define DEBUG_PRINT(fmt, ...) do { \
55         if (DBG_ENABLE) {  \
56             INFO_PRINT(fmt,  ##__VA_ARGS__); \
57         } \
58     } while (0);
59 
60 #define DEBUG_PRINT_IF(cond, fmt, ...) do { \
61         if ((cond) && DBG_ENABLE) {  \
62             INFO_PRINT(fmt,  ##__VA_ARGS__); \
63         } \
64     } while (0);
65 
66 #define DBG_ENABLE                0
67 #define DBG_CHUNKED               0
68 #define DBG_INT                   0
69 #define DBG_SHALLOW_PARSE         0
70 #define DBG_STATE                 0
71 #define DBG_WM_CALC               0
72 #define TIMESTAMP_DBG             0
73 
74 // fixme: to list required definitions for a slave mag
75 #ifdef USE_BMM150
76 #include "bosch_bmm150_slave.h"
77 #elif USE_AK09915
78 #include "akm_ak09915_slave.h"
79 #endif
80 
81 #define BMI160_APP_ID APP_ID_MAKE(APP_ID_VENDOR_GOOGLE, 2)
82 
83 #define BMI160_SPI_WRITE          0x00
84 #define BMI160_SPI_READ           0x80
85 
86 #define BMI160_SPI_BUS_ID         1
87 #define BMI160_SPI_SPEED_HZ       8000000
88 #define BMI160_SPI_MODE           3
89 
90 #define BMI160_INT_IRQ            EXTI9_5_IRQn
91 #define BMI160_INT1_PIN           GPIO_PB(6)
92 #define BMI160_INT2_PIN           GPIO_PB(7)
93 
94 #define BMI160_ID                 0xd1
95 
96 #define BMI160_REG_ID             0x00
97 #define BMI160_REG_ERR            0x02
98 #define BMI160_REG_PMU_STATUS     0x03
99 #define BMI160_REG_DATA_0         0x04
100 #define BMI160_REG_DATA_1         0x05
101 #define BMI160_REG_DATA_14        0x12
102 #define BMI160_REG_SENSORTIME_0   0x18
103 #define BMI160_REG_STATUS         0x1b
104 #define BMI160_REG_INT_STATUS_0   0x1c
105 #define BMI160_REG_INT_STATUS_1   0x1d
106 #define BMI160_REG_TEMPERATURE_0  0x20
107 #define BMI160_REG_TEMPERATURE_1  0x21
108 #define BMI160_REG_FIFO_LENGTH_0  0x22
109 #define BMI160_REG_FIFO_DATA      0x24
110 #define BMI160_REG_ACC_CONF       0x40
111 #define BMI160_REG_ACC_RANGE      0x41
112 #define BMI160_REG_GYR_CONF       0x42
113 #define BMI160_REG_GYR_RANGE      0x43
114 #define BMI160_REG_MAG_CONF       0x44
115 #define BMI160_REG_FIFO_DOWNS     0x45
116 #define BMI160_REG_FIFO_CONFIG_0  0x46
117 #define BMI160_REG_FIFO_CONFIG_1  0x47
118 #define BMI160_REG_MAG_IF_0       0x4b
119 #define BMI160_REG_MAG_IF_1       0x4c
120 #define BMI160_REG_MAG_IF_2       0x4d
121 #define BMI160_REG_MAG_IF_3       0x4e
122 #define BMI160_REG_MAG_IF_4       0x4f
123 #define BMI160_REG_INT_EN_0       0x50
124 #define BMI160_REG_INT_EN_1       0x51
125 #define BMI160_REG_INT_EN_2       0x52
126 #define BMI160_REG_INT_OUT_CTRL   0x53
127 #define BMI160_REG_INT_LATCH      0x54
128 #define BMI160_REG_INT_MAP_0      0x55
129 #define BMI160_REG_INT_MAP_1      0x56
130 #define BMI160_REG_INT_MAP_2      0x57
131 #define BMI160_REG_INT_DATA_0     0x58
132 #define BMI160_REG_INT_MOTION_0   0x5f
133 #define BMI160_REG_INT_MOTION_1   0x60
134 #define BMI160_REG_INT_MOTION_2   0x61
135 #define BMI160_REG_INT_MOTION_3   0x62
136 #define BMI160_REG_INT_TAP_0      0x63
137 #define BMI160_REG_INT_TAP_1      0x64
138 #define BMI160_REG_INT_FLAT_0     0x67
139 #define BMI160_REG_INT_FLAT_1     0x68
140 #define BMI160_REG_PMU_TRIGGER    0x6C
141 #define BMI160_REG_FOC_CONF       0x69
142 #define BMI160_REG_CONF           0x6a
143 #define BMI160_REG_IF_CONF        0x6b
144 #define BMI160_REG_SELF_TEST      0x6d
145 #define BMI160_REG_OFFSET_0       0x71
146 #define BMI160_REG_OFFSET_3       0x74
147 #define BMI160_REG_OFFSET_6       0x77
148 #define BMI160_REG_STEP_CNT_0     0x78
149 #define BMI160_REG_STEP_CONF_0    0x7a
150 #define BMI160_REG_STEP_CONF_1    0x7b
151 #define BMI160_REG_CMD            0x7e
152 #define BMI160_REG_MAGIC          0x7f
153 
154 #define INT_STEP        0x01
155 #define INT_ANY_MOTION  0x04
156 #define INT_DOUBLE_TAP  0x10
157 #define INT_SINGLE_TAP  0x20
158 #define INT_ORIENT      0x40
159 #define INT_FLAT        0x80
160 #define INT_HIGH_G_Z    0x04
161 #define INT_LOW_G       0x08
162 #define INT_DATA_RDY    0x10
163 #define INT_FIFO_FULL   0x20
164 #define INT_FIFO_WM     0x40
165 #define INT_NO_MOTION   0x80
166 
167 #define BMI160_FRAME_HEADER_INVALID  0x80   // mark the end of valid data
168 #define BMI160_FRAME_HEADER_SKIP     0x81   // not defined by hw, used for skip a byte in buffer
169 
170 #define WATERMARK_MIN                1
171 #define WATERMARK_MAX                200    // must <= 255 (0xff)
172 
173 #define WATERMARK_MAX_SENSOR_RATE    400    // Accel and gyro are 400 Hz max
174 #define WATERMARK_TIME_UNIT_NS       (1000000000ULL/(WATERMARK_MAX_SENSOR_RATE))
175 
176 #define gSPI    BMI160_SPI_BUS_ID
177 
178 #define ACCL_INT_LINE EXTI_LINE_P6
179 #define GYR_INT_LINE EXTI_LINE_P7
180 
181 #define SPI_WRITE_0(addr, data) spiQueueWrite(addr, data, 2)
182 #define SPI_WRITE_1(addr, data, delay) spiQueueWrite(addr, data, delay)
183 #define GET_SPI_WRITE_MACRO(_1,_2,_3,NAME,...) NAME
184 #define SPI_WRITE(...) GET_SPI_WRITE_MACRO(__VA_ARGS__, SPI_WRITE_1, SPI_WRITE_0)(__VA_ARGS__)
185 
186 #define SPI_READ_0(addr, size, buf) spiQueueRead(addr, size, buf, 0)
187 #define SPI_READ_1(addr, size, buf, delay) spiQueueRead(addr, size, buf, delay)
188 #define GET_SPI_READ_MACRO(_1,_2,_3,_4,NAME,...) NAME
189 #define SPI_READ(...) GET_SPI_READ_MACRO(__VA_ARGS__, SPI_READ_1, SPI_READ_0)(__VA_ARGS__)
190 
191 #define EVT_SENSOR_ACC_DATA_RDY sensorGetMyEventType(SENS_TYPE_ACCEL)
192 #define EVT_SENSOR_GYR_DATA_RDY sensorGetMyEventType(SENS_TYPE_GYRO)
193 #define EVT_SENSOR_MAG_DATA_RDY sensorGetMyEventType(SENS_TYPE_MAG)
194 #define EVT_SENSOR_STEP sensorGetMyEventType(SENS_TYPE_STEP_DETECT)
195 #define EVT_SENSOR_NO_MOTION sensorGetMyEventType(SENS_TYPE_NO_MOTION)
196 #define EVT_SENSOR_ANY_MOTION sensorGetMyEventType(SENS_TYPE_ANY_MOTION)
197 #define EVT_SENSOR_FLAT sensorGetMyEventType(SENS_TYPE_FLAT)
198 #define EVT_SENSOR_DOUBLE_TAP sensorGetMyEventType(SENS_TYPE_DOUBLE_TAP)
199 #define EVT_SENSOR_STEP_COUNTER sensorGetMyEventType(SENS_TYPE_STEP_COUNT)
200 
201 #define MAX_NUM_COMMS_EVENT_SAMPLES 15
202 
203 #define kScale_acc    0.00239501953f  // ACC_range * 9.81f / 32768.0f;
204 #define kScale_gyr    0.00106472439f  // GYR_range * M_PI / (180.0f * 32768.0f);
205 #define kScale_temp   0.001953125f    // temperature in deg C
206 #define kTempInvalid  -1000.0f
207 
208 #define kTimeSyncPeriodNs        100000000ull // sync sensor and RTC time every 100ms
209 #define kSensorTimerIntervalUs   39ull        // bmi160 clock increaments every 39000ns
210 
211 #define kMinRTCTimeIncrementNs   1250000ull // forced min rtc time increment, 1.25ms for 400Hz
212 #define kMinSensorTimeIncrement  64         // forced min sensortime increment,
213                                             // 64 = 2.5 msec for 400Hz
214 
215 #define ACC_MIN_RATE    5
216 #define GYR_MIN_RATE    6
217 #define ACC_MAX_RATE    12
218 #define GYR_MAX_RATE    13
219 #define MAG_MAX_RATE    11
220 #define ACC_MAX_OSR     3
221 #define GYR_MAX_OSR     4
222 #define OSR_THRESHOLD   8
223 
224 #define MOTION_ODR         7
225 
226 #define RETRY_CNT_CALIBRATION 10
227 #define RETRY_CNT_ID 5
228 #define RETRY_CNT_MAG 30
229 
230 #define SPI_PACKET_SIZE 30
231 #define FIFO_READ_SIZE  (1024+4)
232 #define CHUNKED_READ_SIZE (64)
233 #define BUF_MARGIN 32   // some extra buffer for additional reg RW when a FIFO read happens
234 #define SPI_BUF_SIZE (FIFO_READ_SIZE + CHUNKED_READ_SIZE + BUF_MARGIN)
235 
236 enum SensorIndex {
237     ACC = 0,
238     GYR,
239     MAG,
240     STEP,
241     DTAP,
242     FLAT,
243     ANYMO,
244     NOMO,
245     STEPCNT,
246     NUM_OF_SENSOR,
247 };
248 
249 enum SensorEvents {
250     NO_EVT = -1,
251     EVT_SPI_DONE = EVT_APP_START + 1,
252     EVT_SENSOR_INTERRUPT_1,
253     EVT_SENSOR_INTERRUPT_2,
254     EVT_TIME_SYNC,
255 };
256 
257 enum InitState {
258     RESET_BMI160,
259     INIT_BMI160,
260     INIT_MAG,
261     INIT_ON_CHANGE_SENSORS,
262     INIT_DONE,
263 };
264 
265 enum CalibrationState {
266     CALIBRATION_START,
267     CALIBRATION_FOC,
268     CALIBRATION_WAIT_FOC_DONE,
269     CALIBRATION_SET_OFFSET,
270     CALIBRATION_DONE,
271     CALIBRATION_TIMEOUT,
272 };
273 
274 enum SensorState {
275     SENSOR_BOOT,
276     SENSOR_VERIFY_ID,
277     SENSOR_INITIALIZING,
278     SENSOR_IDLE,
279     SENSOR_POWERING_UP,
280     SENSOR_POWERING_DOWN,
281     SENSOR_CONFIG_CHANGING,
282     SENSOR_INT_1_HANDLING,
283     SENSOR_INT_2_HANDLING,
284     SENSOR_CALIBRATING,
285     SENSOR_STEP_CNT,
286     SENSOR_TIME_SYNC,
287     SENSOR_SAVE_CALIBRATION,
288     SENSOR_NUM_OF_STATE
289 };
getStateName(int32_t s)290 static const char * getStateName(int32_t s) {
291 #if DBG_STATE
292     static const char* const l[] = {"BOOT", "VERIFY_ID", "INIT", "IDLE", "PWR_UP",
293             "PWR-DN", "CFG_CHANGE", "INT1", "INT2", "CALIB", "STEP_CNT", "SYNC", "SAVE_CALIB"};
294     if (s >= 0 && s < SENSOR_NUM_OF_STATE) {
295         return l[s];
296     }
297 #endif
298     return "???";
299 }
300 
301 enum MagConfigState {
302     MAG_SET_START,
303     MAG_SET_IF,
304 
305     // BMM150 only
306     MAG_SET_REPXY,
307     MAG_SET_REPZ,
308     MAG_GET_DIG_X,
309     MAG_GET_DIG_Y,
310     MAG_GET_DIG_Z,
311     MAG_SET_SAVE_DIG,
312 
313     MAG_SET_FORCE,
314     MAG_SET_ADDR,
315     MAG_SET_DATA,
316     MAG_SET_DONE,
317 
318     MAG_INIT_FAILED
319 };
320 
321 struct ConfigStat {
322     uint64_t latency;
323     uint32_t rate;
324     bool enable;
325 };
326 
327 struct CalibrationData {
328     struct HostHubRawPacket header;
329     struct SensorAppEventHeader data_header;
330     int32_t xBias;
331     int32_t yBias;
332     int32_t zBias;
333 } __attribute__((packed));
334 
335 struct BMI160Sensor {
336     struct ConfigStat pConfig; // pending config status request
337     struct TripleAxisDataEvent *data_evt;
338     uint32_t handle;
339     uint32_t rate;
340     uint64_t latency;
341     uint64_t prev_rtc_time;
342     uint32_t offset[3];
343     bool powered; // activate status
344     bool configed; // configure status
345     bool offset_enable;
346     uint8_t flush;
347     enum SensorIndex idx;
348 };
349 
350 struct BMI160Task {
351     uint32_t tid;
352     struct BMI160Sensor sensors[NUM_OF_SENSOR];
353 
354     // time keeping.
355     uint64_t last_sensortime;
356     uint64_t frame_sensortime;
357     uint64_t prev_frame_time[3];
358     uint64_t time_delta[3];
359     uint64_t next_delta[3];
360     uint64_t tempTime;
361 
362     // spi and interrupt
363     spi_cs_t cs;
364     struct SpiMode mode;
365     struct SpiPacket packets[SPI_PACKET_SIZE];
366     struct SpiDevice *spiDev;
367     struct Gpio *Int1;
368     struct Gpio *Int2;
369     struct ChainedIsr Isr1;
370     struct ChainedIsr Isr2;
371 #ifdef MAG_SLAVE_PRESENT
372     struct MagCal moc;
373 #endif
374     time_sync_t gSensorTime2RTC;
375 
376     float tempCelsius;
377     float last_charging_bias_x;
378     uint32_t total_step_cnt;
379     uint32_t last_step_cnt;
380     uint32_t poll_generation;
381     uint32_t active_poll_generation;
382     uint8_t active_oneshot_sensor_cnt;
383     uint8_t interrupt_enable_0;
384     uint8_t interrupt_enable_2;
385     uint8_t acc_downsample;
386     uint8_t gyr_downsample;
387     bool magBiasPosted;
388     bool magBiasCurrent;
389     bool fifo_enabled[3];
390 
391     // for step count
392     uint32_t stepCntSamplingTimerHandle;
393     bool step_cnt_changed;
394 
395     // spi buffers
396     int xferCnt;
397     uint8_t *dataBuffer;
398     uint8_t *statusBuffer;
399     uint8_t *sensorTimeBuffer;
400     uint8_t *temperatureBuffer;
401     uint8_t txrxBuffer[SPI_BUF_SIZE];
402 
403     // states
404     volatile uint8_t state;  //task state, type enum SensorState, do NOT change this directly
405     enum InitState init_state;
406     enum MagConfigState mag_state;
407     enum CalibrationState calibration_state;
408 
409     // pending configs
410     bool pending_int[2];
411     bool pending_step_cnt;
412     bool pending_config[NUM_OF_SENSOR];
413     bool pending_calibration_save;
414     bool pending_time_sync;
415     bool pending_delta[3];
416     bool pending_dispatch;
417     bool frame_sensortime_valid;
418 
419     // FIFO setting
420     uint16_t chunkReadSize;
421     uint8_t  watermark;
422 
423     // spi rw
424     struct SlabAllocator *mDataSlab;
425     uint16_t mWbufCnt;
426     uint8_t mRegCnt;
427     uint8_t mRetryLeft;
428     bool spiInUse;
429 };
430 
431 static uint32_t AccRates[] = {
432     SENSOR_HZ(25.0f/8.0f),
433     SENSOR_HZ(25.0f/4.0f),
434     SENSOR_HZ(25.0f/2.0f),
435     SENSOR_HZ(25.0f),
436     SENSOR_HZ(50.0f),
437     SENSOR_HZ(100.0f),
438     SENSOR_HZ(200.0f),
439     SENSOR_HZ(400.0f),
440     0,
441 };
442 
443 static uint32_t GyrRates[] = {
444     SENSOR_HZ(25.0f/8.0f),
445     SENSOR_HZ(25.0f/4.0f),
446     SENSOR_HZ(25.0f/2.0f),
447     SENSOR_HZ(25.0f),
448     SENSOR_HZ(50.0f),
449     SENSOR_HZ(100.0f),
450     SENSOR_HZ(200.0f),
451     SENSOR_HZ(400.0f),
452     0,
453 };
454 
455 static uint32_t MagRates[] = {
456     SENSOR_HZ(25.0f/8.0f),
457     SENSOR_HZ(25.0f/4.0f),
458     SENSOR_HZ(25.0f/2.0f),
459     SENSOR_HZ(25.0f),
460     SENSOR_HZ(50.0f),
461     SENSOR_HZ(100.0f),
462     0,
463 };
464 
465 static uint32_t StepCntRates[] = {
466     SENSOR_HZ(1.0f/300.0f),
467     SENSOR_HZ(1.0f/240.0f),
468     SENSOR_HZ(1.0f/180.0f),
469     SENSOR_HZ(1.0f/120.0f),
470     SENSOR_HZ(1.0f/90.0f),
471     SENSOR_HZ(1.0f/60.0f),
472     SENSOR_HZ(1.0f/45.0f),
473     SENSOR_HZ(1.0f/30.0f),
474     SENSOR_HZ(1.0f/15.0f),
475     SENSOR_HZ(1.0f/10.0f),
476     SENSOR_HZ(1.0f/5.0f),
477     SENSOR_RATE_ONCHANGE,
478     0
479 };
480 
481 static const uint64_t stepCntRateTimerVals[] = // should match StepCntRates and be the timer length for that rate in nanosecs
482 {
483     300 * 1000000000ULL,
484     240 * 1000000000ULL,
485     180 * 1000000000ULL,
486     120 * 1000000000ULL,
487     90 * 1000000000ULL,
488     60 * 1000000000ULL,
489     45 * 1000000000ULL,
490     30 * 1000000000ULL,
491     15 * 1000000000ULL,
492     10 * 1000000000ULL,
493     5 * 1000000000ULL,
494 };
495 
496 static struct BMI160Task mTask;
497 
498 #ifdef MAG_SLAVE_PRESENT
499 static struct MagTask magTask;
500 #endif
501 
502 #define MAG_WRITE(addr, data)                                   \
503     do {                                                        \
504         SPI_WRITE(BMI160_REG_MAG_IF_4, data);                   \
505         SPI_WRITE(BMI160_REG_MAG_IF_3, addr);                   \
506     } while (0)
507 
508 #define MAG_READ(addr, size)                                    \
509     do {                                                        \
510         SPI_WRITE(BMI160_REG_MAG_IF_2, addr, 5000);             \
511         SPI_READ(BMI160_REG_DATA_0, size, &mTask.dataBuffer);   \
512     } while (0)
513 
514 #define DEC_INFO(name, type, axis, inter, samples) \
515     .sensorName = name, \
516     .sensorType = type, \
517     .numAxis = axis, \
518     .interrupt = inter, \
519     .minSamples = samples
520 
521 #define DEC_INFO_RATE(name, rates, type, axis, inter, samples) \
522     DEC_INFO(name, type, axis, inter, samples), \
523     .supportedRates = rates
524 
525 #define DEC_INFO_RATE_RAW(name, rates, type, axis, inter, samples, raw, scale) \
526     DEC_INFO(name, type, axis, inter, samples), \
527     .supportedRates = rates, \
528     .flags1 = SENSOR_INFO_FLAGS1_RAW, \
529     .rawType = raw, \
530     .rawScale = scale
531 
532 #define DEC_INFO_RATE_BIAS(name, rates, type, axis, inter, samples, bias) \
533     DEC_INFO(name, type, axis, inter, samples), \
534     .supportedRates = rates, \
535     .flags1 = SENSOR_INFO_FLAGS1_BIAS, \
536     .biasType = bias
537 
538 typedef struct BMI160Task _Task;
539 #define TASK  _Task* const _task
540 
541 // To get rid of static variables all task functions should have a task structure pointer input.
542 // This is an intermediate step.
543 #define TDECL()  TASK = &mTask; (void)_task
544 
545 // Access task variables without explicitly specify the task structure pointer.
546 #define T(v)  (_task->v)
547 
548 // Atomic get state
549 #define GET_STATE() (atomicReadByte(&(_task->state)))
550 
551 // Atomic set state, this set the state to arbitrary value, use with caution
552 #define SET_STATE(s) do{\
553         DEBUG_PRINT_IF(DBG_STATE, "set state %s\n", getStateName(s));\
554         atomicWriteByte(&(_task->state), (s));\
555     }while(0)
556 
557 // Atomic switch state from IDLE to desired state.
trySwitchState_(TASK,enum SensorState newState)558 static bool trySwitchState_(TASK, enum SensorState newState) {
559 #if DBG_STATE
560     bool ret = atomicCmpXchgByte(&T(state), SENSOR_IDLE, newState);
561     uint8_t prevState = ret ? SENSOR_IDLE : GET_STATE();
562     DEBUG_PRINT("switch state %s->%s, %s\n",
563             getStateName(prevState), getStateName(newState), ret ? "ok" : "failed");
564     return ret;
565 #else
566     return atomicCmpXchgByte(&T(state), SENSOR_IDLE, newState);
567 #endif
568 }
569 // Short-hand
570 #define trySwitchState(s) trySwitchState_(_task, (s))
571 
572 // Chunked FIFO read functions
573 static void chunkedReadInit_(TASK, int index, int size);
574 #define chunkedReadInit(a,b) chunkedReadInit_(_task, (a), (b))
575 static void chunkedReadSpiCallback(void *cookie, int error);
576 static void initiateFifoRead_(TASK, bool isInterruptContext);
577 #define initiateFifoRead(a) initiateFifoRead_(_task, (a))
578 static uint8_t* shallowParseFrame(uint8_t * buf, int size);
579 
580 // Watermark calculation
581 static uint8_t calcWatermark2_(TASK);
582 #define calcWatermark2() calcWatermark2_(_task)
583 
584 static const struct SensorInfo mSensorInfo[NUM_OF_SENSOR] =
585 {
586     { DEC_INFO_RATE_RAW("Accelerometer", AccRates, SENS_TYPE_ACCEL, NUM_AXIS_THREE,
587             NANOHUB_INT_NONWAKEUP, 3000, SENS_TYPE_ACCEL_RAW, 1.0/kScale_acc) },
588     { DEC_INFO_RATE("Gyroscope", GyrRates, SENS_TYPE_GYRO, NUM_AXIS_THREE,
589             NANOHUB_INT_NONWAKEUP, 20) },
590     { DEC_INFO_RATE_BIAS("Magnetometer", MagRates, SENS_TYPE_MAG, NUM_AXIS_THREE,
591             NANOHUB_INT_NONWAKEUP, 600, SENS_TYPE_MAG_BIAS) },
592     { DEC_INFO("Step Detector", SENS_TYPE_STEP_DETECT, NUM_AXIS_EMBEDDED,
593             NANOHUB_INT_NONWAKEUP, 100) },
594     { DEC_INFO("Double Tap", SENS_TYPE_DOUBLE_TAP, NUM_AXIS_EMBEDDED,
595             NANOHUB_INT_NONWAKEUP, 20) },
596     { DEC_INFO("Flat", SENS_TYPE_FLAT, NUM_AXIS_EMBEDDED, NANOHUB_INT_NONWAKEUP, 20) },
597     { DEC_INFO("Any Motion", SENS_TYPE_ANY_MOTION, NUM_AXIS_EMBEDDED, NANOHUB_INT_NONWAKEUP, 20) },
598     { DEC_INFO("No Motion", SENS_TYPE_NO_MOTION, NUM_AXIS_EMBEDDED, NANOHUB_INT_NONWAKEUP, 20) },
599     { DEC_INFO_RATE("Step Counter", StepCntRates, SENS_TYPE_STEP_COUNT, NUM_AXIS_EMBEDDED,
600             NANOHUB_INT_NONWAKEUP, 20) },
601 };
602 
time_init(void)603 static void time_init(void) {
604     time_sync_init(&mTask.gSensorTime2RTC);
605 }
606 
sensortime_to_rtc_time(uint64_t sensor_time,uint64_t * rtc_time_ns)607 static bool sensortime_to_rtc_time(uint64_t sensor_time, uint64_t *rtc_time_ns) {
608 // fixme: nsec?
609     return time_sync_estimate_time1(
610             &mTask.gSensorTime2RTC, sensor_time * 39ull, rtc_time_ns);
611 }
612 
map_sensortime_to_rtc_time(uint64_t sensor_time,uint64_t rtc_time_ns)613 static void map_sensortime_to_rtc_time(uint64_t sensor_time, uint64_t rtc_time_ns) {
614 // fixme: nsec?
615     time_sync_add(&mTask.gSensorTime2RTC, rtc_time_ns, sensor_time * 39ull);
616 }
617 
invalidate_sensortime_to_rtc_time(void)618 static void invalidate_sensortime_to_rtc_time(void) {
619     time_sync_reset(&mTask.gSensorTime2RTC);
620 }
621 
minimize_sensortime_history(void)622 static void minimize_sensortime_history(void) {
623     // truncate datapoints to the latest two to maintain valid sensortime to rtc
624     // mapping and minimize the inflence of the past mapping
625     time_sync_truncate(&mTask.gSensorTime2RTC, 2);
626 
627     // drop the oldest datapoint when a new one arrives for two times to
628     // completely shift out the influence of the past mapping
629     time_sync_hold(&mTask.gSensorTime2RTC, 2);
630 }
631 
dataEvtFree(void * ptr)632 static void dataEvtFree(void *ptr)
633 {
634     TDECL();
635     struct TripleAxisDataEvent *ev = (struct TripleAxisDataEvent *)ptr;
636     slabAllocatorFree(T(mDataSlab), ev);
637 }
638 
spiQueueWrite(uint8_t addr,uint8_t data,uint32_t delay)639 static void spiQueueWrite(uint8_t addr, uint8_t data, uint32_t delay)
640 {
641     TDECL();
642     if (T(spiInUse)) {
643         ERROR_PRINT("SPI in use, cannot queue write\n");
644         return;
645     }
646     T(packets[T(mRegCnt)]).size = 2;
647     T(packets[T(mRegCnt)]).txBuf = &T(txrxBuffer[T(mWbufCnt)]);
648     T(packets[T(mRegCnt)]).rxBuf = &T(txrxBuffer[T(mWbufCnt)]);
649     T(packets[T(mRegCnt)]).delay = delay * 1000;
650     T(txrxBuffer[T(mWbufCnt++)]) = BMI160_SPI_WRITE | addr;
651     T(txrxBuffer[T(mWbufCnt++)]) = data;
652     T(mRegCnt)++;
653 }
654 
655 /*
656  * need to be sure size of buf is larger than read size
657  */
spiQueueRead(uint8_t addr,size_t size,uint8_t ** buf,uint32_t delay)658 static void spiQueueRead(uint8_t addr, size_t size, uint8_t **buf, uint32_t delay)
659 {
660     TDECL();
661     if (T(spiInUse)) {
662         ERROR_PRINT("SPI in use, cannot queue read %d %d\n", (int)addr, (int)size);
663         return;
664     }
665 
666     *buf = &T(txrxBuffer[T(mWbufCnt)]);
667     T(packets[T(mRegCnt)]).size = size + 1; // first byte will not contain valid data
668     T(packets[T(mRegCnt)]).txBuf = &T(txrxBuffer[T(mWbufCnt)]);
669     T(packets[T(mRegCnt)]).rxBuf = *buf;
670     T(packets[T(mRegCnt)]).delay = delay * 1000;
671     T(txrxBuffer[T(mWbufCnt)++]) = BMI160_SPI_READ | addr;
672     T(mWbufCnt) += size;
673     T(mRegCnt)++;
674 }
675 
spiBatchTxRx(struct SpiMode * mode,SpiCbkF callback,void * cookie,const char * src)676 static void spiBatchTxRx(struct SpiMode *mode,
677         SpiCbkF callback, void *cookie, const char * src)
678 {
679     TDECL();
680     if (T(mWbufCnt) > SPI_BUF_SIZE) {
681         ERROR_PRINT("NO enough SPI buffer space, dropping transaction.\n");
682         return;
683     }
684     if (T(mRegCnt) > SPI_PACKET_SIZE) {
685         ERROR_PRINT("spiBatchTxRx too many packets!\n");
686         return;
687     }
688 
689     T(spiInUse) = true;
690 
691     // Reset variables before issuing SPI transaction.
692     // SPI may finish before spiMasterRxTx finish
693     uint8_t regCount = T(mRegCnt);
694     T(mRegCnt) = 0;
695     T(mWbufCnt) = 0;
696 
697     if (spiMasterRxTx(T(spiDev), T(cs), T(packets), regCount, mode, callback, cookie) < 0) {
698         ERROR_PRINT("spiMasterRxTx failed!\n");
699     }
700 }
701 
702 
bmi160Isr1(struct ChainedIsr * isr)703 static bool bmi160Isr1(struct ChainedIsr *isr)
704 {
705     TASK = container_of(isr, struct BMI160Task, Isr1);
706 
707     if (!extiIsPendingGpio(T(Int1))) {
708         return false;
709     }
710     DEBUG_PRINT_IF(DBG_INT, "i1\n");
711     initiateFifoRead(true /*isInterruptContext*/);
712     extiClearPendingGpio(T(Int1));
713     return true;
714 }
715 
716 
bmi160Isr2(struct ChainedIsr * isr)717 static bool bmi160Isr2(struct ChainedIsr *isr)
718 {
719     TASK = container_of(isr, struct BMI160Task, Isr2);
720 
721     if (!extiIsPendingGpio(T(Int2)))
722         return false;
723 
724     DEBUG_PRINT_IF(DBG_INT, "i2\n");
725     osEnqueuePrivateEvt(EVT_SENSOR_INTERRUPT_2, _task, NULL, T(tid));
726     extiClearPendingGpio(T(Int2));
727     return true;
728 }
729 
sensorSpiCallback(void * cookie,int err)730 static void sensorSpiCallback(void *cookie, int err)
731 {
732     mTask.spiInUse = false;
733     osEnqueuePrivateEvt(EVT_SPI_DONE, cookie, NULL, mTask.tid);
734 }
735 
sensorTimerCallback(uint32_t timerId,void * data)736 static void sensorTimerCallback(uint32_t timerId, void *data)
737 {
738     osEnqueuePrivateEvt(EVT_SPI_DONE, data, NULL, mTask.tid);
739 }
740 
timeSyncCallback(uint32_t timerId,void * data)741 static void timeSyncCallback(uint32_t timerId, void *data)
742 {
743     osEnqueuePrivateEvt(EVT_TIME_SYNC, data, NULL, mTask.tid);
744 }
745 
stepCntSamplingCallback(uint32_t timerId,void * data)746 static void stepCntSamplingCallback(uint32_t timerId, void *data)
747 {
748     union EmbeddedDataPoint step_cnt;
749 
750     if (mTask.sensors[STEPCNT].powered && mTask.step_cnt_changed) {
751         mTask.step_cnt_changed = false;
752         step_cnt.idata = mTask.total_step_cnt;
753         osEnqueueEvt(EVT_SENSOR_STEP_COUNTER, step_cnt.vptr, NULL);
754     }
755 }
756 
accFirmwareUpload(void * cookie)757 static bool accFirmwareUpload(void *cookie)
758 {
759     sensorSignalInternalEvt(mTask.sensors[ACC].handle,
760             SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0);
761     return true;
762 }
763 
gyrFirmwareUpload(void * cookie)764 static bool gyrFirmwareUpload(void *cookie)
765 {
766     sensorSignalInternalEvt(mTask.sensors[GYR].handle,
767             SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0);
768     return true;
769 }
770 
magFirmwareUpload(void * cookie)771 static bool magFirmwareUpload(void *cookie)
772 {
773     sensorSignalInternalEvt(mTask.sensors[MAG].handle,
774             SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0);
775     return true;
776 }
777 
stepFirmwareUpload(void * cookie)778 static bool stepFirmwareUpload(void *cookie)
779 {
780     sensorSignalInternalEvt(mTask.sensors[STEP].handle,
781             SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0);
782     return true;
783 }
784 
doubleTapFirmwareUpload(void * cookie)785 static bool doubleTapFirmwareUpload(void *cookie)
786 {
787     sensorSignalInternalEvt(mTask.sensors[DTAP].handle,
788             SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0);
789     return true;
790 }
791 
noMotionFirmwareUpload(void * cookie)792 static bool noMotionFirmwareUpload(void *cookie)
793 {
794     sensorSignalInternalEvt(mTask.sensors[NOMO].handle,
795             SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0);
796     return true;
797 }
798 
anyMotionFirmwareUpload(void * cookie)799 static bool anyMotionFirmwareUpload(void *cookie)
800 {
801     sensorSignalInternalEvt(mTask.sensors[ANYMO].handle,
802             SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0);
803     return true;
804 }
805 
flatFirmwareUpload(void * cookie)806 static bool flatFirmwareUpload(void *cookie)
807 {
808     sensorSignalInternalEvt(mTask.sensors[FLAT].handle,
809             SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0);
810     return true;
811 }
812 
stepCntFirmwareUpload(void * cookie)813 static bool stepCntFirmwareUpload(void *cookie)
814 {
815     sensorSignalInternalEvt(mTask.sensors[STEPCNT].handle,
816             SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0);
817     return true;
818 }
819 
enableInterrupt(struct Gpio * pin,struct ChainedIsr * isr)820 static bool enableInterrupt(struct Gpio *pin, struct ChainedIsr *isr)
821 {
822     gpioConfigInput(pin, GPIO_SPEED_LOW, GPIO_PULL_NONE);
823     syscfgSetExtiPort(pin);
824     extiEnableIntGpio(pin, EXTI_TRIGGER_RISING);
825     extiChainIsr(BMI160_INT_IRQ, isr);
826     return true;
827 }
828 
disableInterrupt(struct Gpio * pin,struct ChainedIsr * isr)829 static bool disableInterrupt(struct Gpio *pin, struct ChainedIsr *isr)
830 {
831     extiUnchainIsr(BMI160_INT_IRQ, isr);
832     extiDisableIntGpio(pin);
833     return true;
834 }
835 
magConfigMagic(void)836 static void magConfigMagic(void)
837 {
838     // set the MAG power to NORMAL mode
839     SPI_WRITE(BMI160_REG_CMD, 0x19, 10000);
840 
841     // Magic register sequence to shift register page table to access hidden
842     // register
843     SPI_WRITE(BMI160_REG_CMD, 0x37);
844     SPI_WRITE(BMI160_REG_CMD, 0x9a);
845     SPI_WRITE(BMI160_REG_CMD, 0xc0);
846     SPI_WRITE(BMI160_REG_MAGIC, 0x90);
847     SPI_READ(BMI160_REG_DATA_1, 1, &mTask.dataBuffer);
848 }
849 
magConfigIf(void)850 static void magConfigIf(void)
851 {
852     // Set the on-chip I2C pull-up register settings and shift the register
853     // table back down (magic)
854     SPI_WRITE(BMI160_REG_DATA_1, mTask.dataBuffer[1] | 0x30);
855     SPI_WRITE(BMI160_REG_MAGIC, 0x80);
856 
857     // Config the MAG I2C device address
858 #ifdef MAG_SLAVE_PRESENT
859     SPI_WRITE(BMI160_REG_MAG_IF_0, (MAG_I2C_ADDR << 1));
860 #endif
861 
862     // set mag_manual_enable, mag_offset=0, mag_rd_burst='8 bytes'
863     SPI_WRITE(BMI160_REG_MAG_IF_1, 0x83);
864 
865     // primary interface: autoconfig, secondary: magnetometer.
866     SPI_WRITE(BMI160_REG_IF_CONF, 0x20);
867 
868     // fixme: move to mag-specific function
869 #ifdef USE_BMM150
870     // set mag to SLEEP mode
871     MAG_WRITE(BMM150_REG_CTRL_1, 0x01);
872 #elif USE_AK09915
873     // set "low" Noise Suppression Filter (NSF) settings
874     MAG_WRITE(AKM_AK09915_REG_CNTL1, 0x20);
875 #endif
876 }
877 
878 // fixme: break this up to master/slave-specific, so it'll be eventually slave-agnostic,
879 // and slave provides its own stateless config function
880 // fixme: not all async_elem_t is supported
magConfig(void)881 static void magConfig(void)
882 {
883     switch (mTask.mag_state) {
884     case MAG_SET_START:
885         magConfigMagic();
886         mTask.mag_state = MAG_SET_IF;
887         break;
888     case MAG_SET_IF:
889         magConfigIf();
890 #ifdef USE_AK09915
891         mTask.mag_state = MAG_SET_FORCE;
892 #elif USE_BMM150
893         mTask.mag_state = MAG_SET_REPXY;
894 #endif
895         break;
896 
897 #ifdef USE_BMM150
898     case MAG_SET_REPXY:
899         // MAG_SET_REPXY and MAG_SET_REPZ case set:
900         // regular preset, f_max,ODR ~ 102 Hz
901         MAG_WRITE(BMM150_REG_REPXY, 9);
902         mTask.mag_state = MAG_SET_REPZ;
903         break;
904     case MAG_SET_REPZ:
905         MAG_WRITE(BMM150_REG_REPZ, 15);
906         mTask.mag_state = MAG_GET_DIG_X;
907         break;
908     case MAG_GET_DIG_X:
909         // MAG_GET_DIG_X, MAG_GET_DIG_Y and MAG_GET_DIG_Z cases:
910         // save parameters for temperature compensation.
911         MAG_READ(BMM150_REG_DIG_X1, 8);
912         mTask.mag_state = MAG_GET_DIG_Y;
913         break;
914     case MAG_GET_DIG_Y:
915         bmm150SaveDigData(&magTask, &mTask.dataBuffer[1], 0);
916         MAG_READ(BMM150_REG_DIG_X1 + 8, 8);
917         mTask.mag_state = MAG_GET_DIG_Z;
918         break;
919     case MAG_GET_DIG_Z:
920         bmm150SaveDigData(&magTask, &mTask.dataBuffer[1], 8);
921         MAG_READ(BMM150_REG_DIG_X1 + 16, 8);
922         mTask.mag_state = MAG_SET_SAVE_DIG;
923         break;
924     case MAG_SET_SAVE_DIG:
925         bmm150SaveDigData(&magTask, &mTask.dataBuffer[1], 16);
926         // fall through, no break;
927         mTask.mag_state = MAG_SET_FORCE;
928 #endif
929 
930     case MAG_SET_FORCE:
931         // set MAG mode to "forced". ready to pull data
932 #ifdef USE_AK09915
933         MAG_WRITE(AKM_AK09915_REG_CNTL2, 0x01);
934 #elif USE_BMM150
935         MAG_WRITE(BMM150_REG_CTRL_2, 0x02);
936 #endif
937         mTask.mag_state = MAG_SET_ADDR;
938         break;
939     case MAG_SET_ADDR:
940         // config MAG read data address to the first data register
941 #ifdef MAG_SLAVE_PRESENT
942         SPI_WRITE(BMI160_REG_MAG_IF_2, MAG_REG_DATA);
943 #endif
944         mTask.mag_state = MAG_SET_DATA;
945         break;
946     case MAG_SET_DATA:
947         // clear mag_manual_en.
948         SPI_WRITE(BMI160_REG_MAG_IF_1, 0x03, 1000);
949         // set the MAG power to SUSPEND mode
950         SPI_WRITE(BMI160_REG_CMD, 0x18, 10000);
951         mTask.mag_state = MAG_SET_DONE;
952         mTask.init_state = INIT_ON_CHANGE_SENSORS;
953         break;
954     default:
955         break;
956     }
957     SPI_READ(BMI160_REG_STATUS, 1, &mTask.statusBuffer, 1000);
958 }
959 
anyFifoEnabled(void)960 static inline bool anyFifoEnabled(void)
961 {
962     return (mTask.fifo_enabled[ACC] || mTask.fifo_enabled[GYR] || mTask.fifo_enabled[MAG]);
963 }
964 
configFifo(void)965 static void configFifo(void)
966 {
967     TDECL();
968     int i;
969     uint8_t val = 0x12;
970     bool any_fifo_enabled_prev = anyFifoEnabled();
971     // if ACC is configed, enable ACC bit in fifo_config reg.
972     if (mTask.sensors[ACC].configed && mTask.sensors[ACC].latency != SENSOR_LATENCY_NODATA) {
973         val |= 0x40;
974         mTask.fifo_enabled[ACC] = true;
975     } else {
976         mTask.fifo_enabled[ACC] = false;
977     }
978 
979     // if GYR is configed, enable GYR bit in fifo_config reg.
980     if (mTask.sensors[GYR].configed && mTask.sensors[GYR].latency != SENSOR_LATENCY_NODATA) {
981         val |= 0x80;
982         mTask.fifo_enabled[GYR] = true;
983     } else {
984         mTask.fifo_enabled[GYR] = false;
985     }
986 
987     // if MAG is configed, enable MAG bit in fifo_config reg.
988     if (mTask.sensors[MAG].configed && mTask.sensors[MAG].latency != SENSOR_LATENCY_NODATA) {
989         val |= 0x20;
990         mTask.fifo_enabled[MAG] = true;
991     } else {
992         mTask.fifo_enabled[MAG] = false;
993     }
994 
995     // if this is the first data sensor fifo to enable, start to
996     // sync the sensor time and rtc time
997     if (!any_fifo_enabled_prev && anyFifoEnabled()) {
998         invalidate_sensortime_to_rtc_time();
999 
1000         // start a new poll generation and attach the generation number to event
1001         osEnqueuePrivateEvt(EVT_TIME_SYNC, (void *)mTask.poll_generation, NULL, mTask.tid);
1002     }
1003 
1004     // cancel current poll generation
1005     if (any_fifo_enabled_prev && !anyFifoEnabled()) {
1006         ++mTask.poll_generation;
1007     }
1008 
1009     // if this is not the first fifo enabled or last fifo disabled, flush all fifo data;
1010     if (any_fifo_enabled_prev && anyFifoEnabled()) {
1011         mTask.pending_dispatch = true;
1012         mTask.xferCnt = FIFO_READ_SIZE;
1013         SPI_READ(BMI160_REG_FIFO_DATA, mTask.xferCnt, &mTask.dataBuffer);
1014     }
1015 
1016     // calculate the new watermark level
1017     if (anyFifoEnabled()) {
1018         mTask.watermark = calcWatermark2_(_task);
1019         DEBUG_PRINT("wm=%d", mTask.watermark);
1020         SPI_WRITE(BMI160_REG_FIFO_CONFIG_0, mTask.watermark);
1021     }
1022 
1023     // config the fifo register
1024     SPI_WRITE(BMI160_REG_FIFO_CONFIG_1, val);
1025 
1026     // if no more fifo enabled, we need to cleanup the fifo and invalidate time
1027     if (!anyFifoEnabled()) {
1028         SPI_WRITE(BMI160_REG_CMD, 0xb0);
1029         mTask.frame_sensortime_valid = false;
1030         for (i = ACC; i <= MAG; i++) {
1031             mTask.pending_delta[i] = false;
1032             mTask.prev_frame_time[i] = ULONG_LONG_MAX;
1033         }
1034     }
1035 }
1036 
accPower(bool on,void * cookie)1037 static bool accPower(bool on, void *cookie)
1038 {
1039     TDECL();
1040 
1041     INFO_PRINT("accPower: on=%d, state=%s\n", on, getStateName(GET_STATE()));
1042     if (trySwitchState(on ? SENSOR_POWERING_UP : SENSOR_POWERING_DOWN)) {
1043         if (on) {
1044             // set ACC power mode to NORMAL
1045             SPI_WRITE(BMI160_REG_CMD, 0x11, 50000);
1046         } else {
1047             // set ACC power mode to SUSPEND
1048             mTask.sensors[ACC].configed = false;
1049             configFifo();
1050             SPI_WRITE(BMI160_REG_CMD, 0x10, 5000);
1051         }
1052         mTask.sensors[ACC].powered = on;
1053         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[ACC], __FUNCTION__);
1054     } else {
1055         mTask.pending_config[ACC] = true;
1056         mTask.sensors[ACC].pConfig.enable = on;
1057     }
1058     return true;
1059 }
1060 
gyrPower(bool on,void * cookie)1061 static bool gyrPower(bool on, void *cookie)
1062 {
1063     TDECL();
1064     INFO_PRINT("gyrPower: on=%d, state=%s\n", on, getStateName(GET_STATE()));
1065 
1066     if (trySwitchState(on ? SENSOR_POWERING_UP : SENSOR_POWERING_DOWN)) {
1067         if (on) {
1068             // set GYR power mode to NORMAL
1069             SPI_WRITE(BMI160_REG_CMD, 0x15, 50000);
1070         } else {
1071             // set GYR power mode to SUSPEND
1072             mTask.sensors[GYR].configed = false;
1073             configFifo();
1074             SPI_WRITE(BMI160_REG_CMD, 0x14, 5000);
1075         }
1076 
1077         if (anyFifoEnabled() && on != mTask.sensors[GYR].powered) {
1078 #if TIMESTAMP_DBG
1079             DEBUG_PRINT("minimize_sensortime_history()\n");
1080 #endif
1081             minimize_sensortime_history();
1082         }
1083 
1084         mTask.sensors[GYR].powered = on;
1085         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[GYR], __FUNCTION__);
1086     } else {
1087         mTask.pending_config[GYR] = true;
1088         mTask.sensors[GYR].pConfig.enable = on;
1089     }
1090     return true;
1091 }
1092 
magPower(bool on,void * cookie)1093 static bool magPower(bool on, void *cookie)
1094 {
1095     TDECL();
1096     INFO_PRINT("magPower: on=%d, state=%s\n", on, getStateName(GET_STATE()));
1097     if (trySwitchState(on ? SENSOR_POWERING_UP : SENSOR_POWERING_DOWN)) {
1098         if (on) {
1099             // set MAG power mode to NORMAL
1100             SPI_WRITE(BMI160_REG_CMD, 0x19, 10000);
1101         } else {
1102             // set MAG power mode to SUSPEND
1103             mTask.sensors[MAG].configed = false;
1104             configFifo();
1105             SPI_WRITE(BMI160_REG_CMD, 0x18, 5000);
1106         }
1107         mTask.sensors[MAG].powered = on;
1108         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[MAG], __FUNCTION__);
1109     } else {
1110         mTask.pending_config[MAG] = true;
1111         mTask.sensors[MAG].pConfig.enable = on;
1112     }
1113     return true;
1114 }
1115 
stepPower(bool on,void * cookie)1116 static bool stepPower(bool on, void *cookie)
1117 {
1118     TDECL();
1119     if (trySwitchState(on ? SENSOR_POWERING_UP : SENSOR_POWERING_DOWN)) {
1120         // if step counter is powered, no need to change actual config of step
1121         // detector.
1122         // But we choose to perform one SPI_WRITE anyway to go down the code path
1123         // to state SENSOR_POWERING_UP/DOWN to update sensor manager.
1124         if (on) {
1125             mTask.interrupt_enable_2 |= 0x08;
1126         } else {
1127             if (!mTask.sensors[STEPCNT].powered)
1128                 mTask.interrupt_enable_2 &= ~0x08;
1129             mTask.sensors[STEP].configed = false;
1130         }
1131         mTask.sensors[STEP].powered = on;
1132         SPI_WRITE(BMI160_REG_INT_EN_2, mTask.interrupt_enable_2, 450);
1133         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[STEP], __FUNCTION__);
1134     } else {
1135         mTask.pending_config[STEP] = true;
1136         mTask.sensors[STEP].pConfig.enable = on;
1137     }
1138     return true;
1139 }
1140 
flatPower(bool on,void * cookie)1141 static bool flatPower(bool on, void *cookie)
1142 {
1143     TDECL();
1144     if (trySwitchState(on ? SENSOR_POWERING_UP : SENSOR_POWERING_DOWN)) {
1145         if (on) {
1146             mTask.interrupt_enable_0 |= 0x80;
1147         } else {
1148             mTask.interrupt_enable_0 &= ~0x80;
1149             mTask.sensors[FLAT].configed = false;
1150         }
1151         mTask.sensors[FLAT].powered = on;
1152         SPI_WRITE(BMI160_REG_INT_EN_0, mTask.interrupt_enable_0, 450);
1153         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[FLAT], __FUNCTION__);
1154     } else {
1155         mTask.pending_config[FLAT] = true;
1156         mTask.sensors[FLAT].pConfig.enable = on;
1157     }
1158     return true;
1159 }
1160 
doubleTapPower(bool on,void * cookie)1161 static bool doubleTapPower(bool on, void *cookie)
1162 {
1163     TDECL();
1164     if (trySwitchState(on ? SENSOR_POWERING_UP : SENSOR_POWERING_DOWN)) {
1165         if (on) {
1166             mTask.interrupt_enable_0 |= 0x10;
1167         } else {
1168             mTask.interrupt_enable_0 &= ~0x10;
1169             mTask.sensors[DTAP].configed = false;
1170         }
1171         mTask.sensors[DTAP].powered = on;
1172         SPI_WRITE(BMI160_REG_INT_EN_0, mTask.interrupt_enable_0, 450);
1173         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[DTAP], __FUNCTION__);
1174     } else {
1175         mTask.pending_config[DTAP] = true;
1176         mTask.sensors[DTAP].pConfig.enable = on;
1177     }
1178     return true;
1179 }
1180 
anyMotionPower(bool on,void * cookie)1181 static bool anyMotionPower(bool on, void *cookie)
1182 {
1183     TDECL();
1184     DEBUG_PRINT("anyMotionPower: on=%d, oneshot_cnt %d, state=%s\n",
1185             on, mTask.active_oneshot_sensor_cnt, getStateName(GET_STATE()));
1186 
1187     if (trySwitchState(on ? SENSOR_POWERING_UP : SENSOR_POWERING_DOWN)) {
1188         if (on) {
1189             mTask.interrupt_enable_0 |= 0x07;
1190         } else {
1191             mTask.interrupt_enable_0 &= ~0x07;
1192             mTask.sensors[ANYMO].configed = false;
1193         }
1194         mTask.sensors[ANYMO].powered = on;
1195         SPI_WRITE(BMI160_REG_INT_EN_0, mTask.interrupt_enable_0, 450);
1196         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[ANYMO], __FUNCTION__);
1197     } else {
1198         mTask.pending_config[ANYMO] = true;
1199         mTask.sensors[ANYMO].pConfig.enable = on;
1200     }
1201     return true;
1202 }
1203 
noMotionPower(bool on,void * cookie)1204 static bool noMotionPower(bool on, void *cookie)
1205 {
1206     TDECL();
1207     DEBUG_PRINT("noMotionPower: on=%d, oneshot_cnt %d, state=%s\n",
1208             on, mTask.active_oneshot_sensor_cnt, getStateName(GET_STATE()));
1209     if (trySwitchState(on ? SENSOR_POWERING_UP : SENSOR_POWERING_DOWN)) {
1210         if (on) {
1211             mTask.interrupt_enable_2 |= 0x07;
1212         } else {
1213             mTask.interrupt_enable_2 &= ~0x07;
1214             mTask.sensors[NOMO].configed = false;
1215         }
1216         mTask.sensors[NOMO].powered = on;
1217         SPI_WRITE(BMI160_REG_INT_EN_2, mTask.interrupt_enable_2, 450);
1218         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[NOMO], __FUNCTION__);
1219     } else {
1220         mTask.pending_config[NOMO] = true;
1221         mTask.sensors[NOMO].pConfig.enable = on;
1222     }
1223     return true;
1224 }
1225 
stepCntPower(bool on,void * cookie)1226 static bool stepCntPower(bool on, void *cookie)
1227 {
1228     TDECL();
1229     if (trySwitchState(on ? SENSOR_POWERING_UP : SENSOR_POWERING_DOWN)) {
1230         if (on) {
1231             if (!mTask.sensors[STEP].powered) {
1232                 mTask.interrupt_enable_2 |= 0x08;
1233                 SPI_WRITE(BMI160_REG_INT_EN_2, mTask.interrupt_enable_2, 450);
1234             }
1235             // set step_cnt_en bit
1236             SPI_WRITE(BMI160_REG_STEP_CONF_1, 0x08 | 0x03, 1000);
1237         } else {
1238             if (mTask.stepCntSamplingTimerHandle) {
1239                 timTimerCancel(mTask.stepCntSamplingTimerHandle);
1240                 mTask.stepCntSamplingTimerHandle = 0;
1241             }
1242             if (!mTask.sensors[STEP].powered) {
1243                 mTask.interrupt_enable_2 &= ~0x08;
1244                 SPI_WRITE(BMI160_REG_INT_EN_2, mTask.interrupt_enable_2);
1245             }
1246             // unset step_cnt_en bit
1247             SPI_WRITE(BMI160_REG_STEP_CONF_1, 0x03);
1248             mTask.last_step_cnt = 0;
1249             mTask.sensors[STEPCNT].configed = false;
1250         }
1251         mTask.sensors[STEPCNT].powered = on;
1252         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[STEPCNT], __FUNCTION__);
1253     } else {
1254         mTask.pending_config[STEPCNT] = true;
1255         mTask.sensors[STEPCNT].pConfig.enable = on;
1256     }
1257     return true;
1258 }
1259 
updateTimeDelta(uint8_t idx,uint8_t odr)1260 static void updateTimeDelta(uint8_t idx, uint8_t odr)
1261 {
1262     if (mTask.fifo_enabled[idx]) {
1263         // wait till control frame to update, if not disabled
1264         mTask.next_delta[idx] = 1ull << (16 - odr);
1265         mTask.pending_delta[idx] = true;
1266     } else {
1267         mTask.time_delta[idx] = 1ull << (16 - odr);
1268     }
1269 }
1270 
1271 // compute the register value from sensor rate.
computeOdr(uint32_t rate)1272 static uint8_t computeOdr(uint32_t rate)
1273 {
1274     uint8_t odr = 0x00;
1275     switch (rate) {
1276     // fall through intended to get the correct register value
1277     case SENSOR_HZ(3200): odr ++;
1278     case SENSOR_HZ(1600): odr ++;
1279     case SENSOR_HZ(800): odr ++;
1280     case SENSOR_HZ(400): odr ++;
1281     case SENSOR_HZ(200): odr ++;
1282     case SENSOR_HZ(100): odr ++;
1283     case SENSOR_HZ(50): odr ++;
1284     case SENSOR_HZ(25): odr ++;
1285     case SENSOR_HZ(25.0f/2.0f): odr ++;
1286     case SENSOR_HZ(25.0f/4.0f): odr ++;
1287     case SENSOR_HZ(25.0f/8.0f): odr ++;
1288     case SENSOR_HZ(25.0f/16.0f): odr ++;
1289     case SENSOR_HZ(25.0f/32.0f): odr ++;
1290     default:
1291         return odr;
1292     }
1293 }
1294 
configMotion(uint8_t odr)1295 static void configMotion(uint8_t odr) {
1296     // motion threshold is element * 15.63mg (for 8g range)
1297     static const uint8_t motion_thresholds[ACC_MAX_RATE+1] =
1298         {5, 5, 5, 5, 5, 5, 5, 5, 4, 3, 2, 2, 2};
1299 
1300     // set any_motion duration to 1 point
1301     // set no_motion duration to (3+1)*1.28sec=5.12sec
1302     SPI_WRITE(BMI160_REG_INT_MOTION_0, 0x03 << 2, 450);
1303 
1304     // set any_motion threshold
1305     SPI_WRITE(BMI160_REG_INT_MOTION_1, motion_thresholds[odr], 450);
1306 
1307     // set no_motion threshold
1308     SPI_WRITE(BMI160_REG_INT_MOTION_2, motion_thresholds[odr], 450);
1309 }
1310 
accSetRate(uint32_t rate,uint64_t latency,void * cookie)1311 static bool accSetRate(uint32_t rate, uint64_t latency, void *cookie)
1312 {
1313     TDECL();
1314     int odr, osr = 0;
1315 
1316     INFO_PRINT("accSetRate: rate=%ld, latency=%lld, state=%s\n", rate, latency,
1317             getStateName(GET_STATE()));
1318 
1319     if (trySwitchState(SENSOR_CONFIG_CHANGING)) {
1320         odr = computeOdr(rate);
1321         if (!odr) {
1322             ERROR_PRINT("invalid acc rate\n");
1323             return false;
1324         }
1325 
1326         updateTimeDelta(ACC, odr);
1327 
1328         // minimum supported rate for ACCEL is 12.5Hz.
1329         // Anything lower than that shall be acheived by downsampling.
1330         if (odr < ACC_MIN_RATE) {
1331             osr = ACC_MIN_RATE - odr;
1332             odr = ACC_MIN_RATE;
1333         }
1334 
1335         // for high odrs, oversample to reduce hw latency and downsample
1336         // to get desired odr
1337         if (odr > OSR_THRESHOLD) {
1338             osr = (ACC_MAX_OSR + odr) > ACC_MAX_RATE ? (ACC_MAX_RATE - odr) : ACC_MAX_OSR;
1339             odr += osr;
1340         }
1341 
1342         mTask.sensors[ACC].rate = rate;
1343         mTask.sensors[ACC].latency = latency;
1344         mTask.sensors[ACC].configed = true;
1345         mTask.acc_downsample = osr;
1346 
1347         // configure ANY_MOTION and NO_MOTION based on odr
1348         configMotion(odr);
1349 
1350         // set ACC bandwidth parameter to 2 (bits[4:6])
1351         // set the rate (bits[0:3])
1352         SPI_WRITE(BMI160_REG_ACC_CONF, 0x20 | odr);
1353 
1354         // configure down sampling ratio, 0x88 is to specify we are using
1355         // filtered samples
1356         SPI_WRITE(BMI160_REG_FIFO_DOWNS, (mTask.acc_downsample << 4) | mTask.gyr_downsample | 0x88);
1357 
1358         // flush the data and configure the fifo
1359         configFifo();
1360 
1361         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[ACC], __FUNCTION__);
1362     } else {
1363         mTask.pending_config[ACC] = true;
1364         mTask.sensors[ACC].pConfig.enable = 1;
1365         mTask.sensors[ACC].pConfig.rate = rate;
1366         mTask.sensors[ACC].pConfig.latency = latency;
1367     }
1368     return true;
1369 }
1370 
gyrSetRate(uint32_t rate,uint64_t latency,void * cookie)1371 static bool gyrSetRate(uint32_t rate, uint64_t latency, void *cookie)
1372 {
1373     TDECL();
1374     int odr, osr = 0;
1375     INFO_PRINT("gyrSetRate: rate=%ld, latency=%lld, state=%s\n", rate, latency,
1376             getStateName(GET_STATE()));
1377 
1378     if (trySwitchState(SENSOR_CONFIG_CHANGING)) {
1379         odr = computeOdr(rate);
1380         if (!odr) {
1381             ERROR_PRINT("invalid gyr rate\n");
1382             return false;
1383         }
1384 
1385         updateTimeDelta(GYR, odr);
1386 
1387         // minimum supported rate for GYRO is 25.0Hz.
1388         // Anything lower than that shall be acheived by downsampling.
1389         if (odr < GYR_MIN_RATE) {
1390             osr = GYR_MIN_RATE - odr;
1391             odr = GYR_MIN_RATE;
1392         }
1393 
1394         // for high odrs, oversample to reduce hw latency and downsample
1395         // to get desired odr
1396         if (odr > OSR_THRESHOLD) {
1397             osr = (GYR_MAX_OSR + odr) > GYR_MAX_RATE ? (GYR_MAX_RATE - odr) : GYR_MAX_OSR;
1398             odr += osr;
1399         }
1400 
1401         mTask.sensors[GYR].rate = rate;
1402         mTask.sensors[GYR].latency = latency;
1403         mTask.sensors[GYR].configed = true;
1404         mTask.gyr_downsample = osr;
1405 
1406         // set GYR bandwidth parameter to 2 (bits[4:6])
1407         // set the rate (bits[0:3])
1408         SPI_WRITE(BMI160_REG_GYR_CONF, 0x20 | odr);
1409 
1410         // configure down sampling ratio, 0x88 is to specify we are using
1411         // filtered samples
1412         SPI_WRITE(BMI160_REG_FIFO_DOWNS, (mTask.acc_downsample << 4) | mTask.gyr_downsample | 0x88);
1413 
1414         // flush the data and configure the fifo
1415         configFifo();
1416 
1417         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[GYR], __FUNCTION__);
1418     } else {
1419         mTask.pending_config[GYR] = true;
1420         mTask.sensors[GYR].pConfig.enable = 1;
1421         mTask.sensors[GYR].pConfig.rate = rate;
1422         mTask.sensors[GYR].pConfig.latency = latency;
1423     }
1424     return true;
1425 }
1426 
magSetRate(uint32_t rate,uint64_t latency,void * cookie)1427 static bool magSetRate(uint32_t rate, uint64_t latency, void *cookie)
1428 {
1429     TDECL();
1430     int odr;
1431 
1432     if (rate == SENSOR_RATE_ONCHANGE)
1433         rate = SENSOR_HZ(100);
1434 
1435     INFO_PRINT("magSetRate: rate=%ld, latency=%lld, state=%s\n", rate, latency,
1436             getStateName(GET_STATE()));
1437 
1438     if (trySwitchState(SENSOR_CONFIG_CHANGING)) {
1439         mTask.sensors[MAG].rate = rate;
1440         mTask.sensors[MAG].latency = latency;
1441         mTask.sensors[MAG].configed = true;
1442 
1443         odr = computeOdr(rate);
1444         if (!odr) {
1445             ERROR_PRINT("invalid mag rate\n");
1446             return false;
1447         }
1448 
1449         updateTimeDelta(MAG, odr);
1450 
1451         odr = odr > MAG_MAX_RATE ? MAG_MAX_RATE : odr;
1452 
1453         // set the rate for MAG
1454         SPI_WRITE(BMI160_REG_MAG_CONF, odr);
1455 
1456         // flush the data and configure the fifo
1457         configFifo();
1458 
1459         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[MAG], __FUNCTION__);
1460     } else {
1461         mTask.pending_config[MAG] = true;
1462         mTask.sensors[MAG].pConfig.enable = 1;
1463         mTask.sensors[MAG].pConfig.rate = rate;
1464         mTask.sensors[MAG].pConfig.latency = latency;
1465     }
1466     return true;
1467 }
1468 
stepSetRate(uint32_t rate,uint64_t latency,void * cookie)1469 static bool stepSetRate(uint32_t rate, uint64_t latency, void *cookie)
1470 {
1471     mTask.sensors[STEP].rate = rate;
1472     mTask.sensors[STEP].latency = latency;
1473     mTask.sensors[STEP].configed = true;
1474 
1475     sensorSignalInternalEvt(mTask.sensors[STEP].handle,
1476             SENSOR_INTERNAL_EVT_RATE_CHG, rate, latency);
1477     return true;
1478 }
1479 
flatSetRate(uint32_t rate,uint64_t latency,void * cookie)1480 static bool flatSetRate(uint32_t rate, uint64_t latency, void *cookie)
1481 {
1482     mTask.sensors[FLAT].rate = rate;
1483     mTask.sensors[FLAT].latency = latency;
1484     mTask.sensors[FLAT].configed = true;
1485 
1486     sensorSignalInternalEvt(mTask.sensors[FLAT].handle,
1487             SENSOR_INTERNAL_EVT_RATE_CHG, rate, latency);
1488     return true;
1489 }
1490 
doubleTapSetRate(uint32_t rate,uint64_t latency,void * cookie)1491 static bool doubleTapSetRate(uint32_t rate, uint64_t latency, void *cookie)
1492 {
1493     mTask.sensors[DTAP].rate = rate;
1494     mTask.sensors[DTAP].latency = latency;
1495     mTask.sensors[DTAP].configed = true;
1496 
1497     sensorSignalInternalEvt(mTask.sensors[DTAP].handle,
1498             SENSOR_INTERNAL_EVT_RATE_CHG, rate, latency);
1499     return true;
1500 }
1501 
anyMotionSetRate(uint32_t rate,uint64_t latency,void * cookie)1502 static bool anyMotionSetRate(uint32_t rate, uint64_t latency, void *cookie)
1503 {
1504     mTask.sensors[ANYMO].rate = rate;
1505     mTask.sensors[ANYMO].latency = latency;
1506     mTask.sensors[ANYMO].configed = true;
1507 
1508     sensorSignalInternalEvt(mTask.sensors[ANYMO].handle,
1509             SENSOR_INTERNAL_EVT_RATE_CHG, rate, latency);
1510 
1511     return true;
1512 }
1513 
noMotionSetRate(uint32_t rate,uint64_t latency,void * cookie)1514 static bool noMotionSetRate(uint32_t rate, uint64_t latency, void *cookie)
1515 {
1516     mTask.sensors[NOMO].rate = rate;
1517     mTask.sensors[NOMO].latency = latency;
1518     mTask.sensors[NOMO].configed = true;
1519 
1520     sensorSignalInternalEvt(mTask.sensors[NOMO].handle,
1521             SENSOR_INTERNAL_EVT_RATE_CHG, rate, latency);
1522     return true;
1523 }
1524 
stepCntSetRate(uint32_t rate,uint64_t latency,void * cookie)1525 static bool stepCntSetRate(uint32_t rate, uint64_t latency, void *cookie)
1526 {
1527     mTask.sensors[STEPCNT].rate = rate;
1528     mTask.sensors[STEPCNT].latency = latency;
1529     mTask.sensors[STEPCNT].configed = true;
1530 
1531     if (rate == SENSOR_RATE_ONCHANGE && mTask.stepCntSamplingTimerHandle) {
1532         timTimerCancel(mTask.stepCntSamplingTimerHandle);
1533         mTask.stepCntSamplingTimerHandle = 0;
1534     } else if (rate != SENSOR_RATE_ONCHANGE) {
1535         if (mTask.stepCntSamplingTimerHandle) {
1536             timTimerCancel(mTask.stepCntSamplingTimerHandle);
1537         }
1538         mTask.stepCntSamplingTimerHandle = timTimerSet(sensorTimerLookupCommon(StepCntRates, stepCntRateTimerVals, rate),
1539                                                        0, 50, stepCntSamplingCallback, NULL, false);
1540     }
1541 
1542     sensorSignalInternalEvt(mTask.sensors[STEPCNT].handle,
1543             SENSOR_INTERNAL_EVT_RATE_CHG, rate, latency);
1544     return true;
1545 }
1546 
sendFlushEvt(void)1547 static void sendFlushEvt(void)
1548 {
1549     while (mTask.sensors[ACC].flush > 0) {
1550         osEnqueueEvt(EVT_SENSOR_ACC_DATA_RDY, SENSOR_DATA_EVENT_FLUSH, NULL);
1551         mTask.sensors[ACC].flush--;
1552     }
1553     while (mTask.sensors[GYR].flush > 0) {
1554         osEnqueueEvt(EVT_SENSOR_GYR_DATA_RDY, SENSOR_DATA_EVENT_FLUSH, NULL);
1555         mTask.sensors[GYR].flush--;
1556     }
1557     while (mTask.sensors[MAG].flush > 0) {
1558         osEnqueueEvt(EVT_SENSOR_MAG_DATA_RDY, SENSOR_DATA_EVENT_FLUSH, NULL);
1559         mTask.sensors[MAG].flush--;
1560     }
1561 }
1562 
accFlush(void * cookie)1563 static bool accFlush(void *cookie)
1564 {
1565     TDECL();
1566     mTask.sensors[ACC].flush++;
1567     initiateFifoRead(false /*isInterruptContext*/);
1568     return true;
1569 }
1570 
gyrFlush(void * cookie)1571 static bool gyrFlush(void *cookie)
1572 {
1573     TDECL();
1574     mTask.sensors[GYR].flush++;
1575     initiateFifoRead(false /*isInterruptContext*/);
1576     return true;
1577 }
1578 
magFlush(void * cookie)1579 static bool magFlush(void *cookie)
1580 {
1581     TDECL();
1582     mTask.sensors[MAG].flush++;
1583     initiateFifoRead(false /*isInterruptContext*/);
1584     return true;
1585 }
1586 
stepFlush(void * cookie)1587 static bool stepFlush(void *cookie)
1588 {
1589     return osEnqueueEvt(EVT_SENSOR_STEP, SENSOR_DATA_EVENT_FLUSH, NULL);
1590 }
1591 
flatFlush(void * cookie)1592 static bool flatFlush(void *cookie)
1593 {
1594     return osEnqueueEvt(EVT_SENSOR_FLAT, SENSOR_DATA_EVENT_FLUSH, NULL);
1595 }
1596 
doubleTapFlush(void * cookie)1597 static bool doubleTapFlush(void *cookie)
1598 {
1599     return osEnqueueEvt(EVT_SENSOR_DOUBLE_TAP, SENSOR_DATA_EVENT_FLUSH, NULL);
1600 }
1601 
anyMotionFlush(void * cookie)1602 static bool anyMotionFlush(void *cookie)
1603 {
1604     return osEnqueueEvt(EVT_SENSOR_ANY_MOTION, SENSOR_DATA_EVENT_FLUSH, NULL);
1605 }
1606 
noMotionFlush(void * cookie)1607 static bool noMotionFlush(void *cookie)
1608 {
1609     return osEnqueueEvt(EVT_SENSOR_NO_MOTION, SENSOR_DATA_EVENT_FLUSH, NULL);
1610 }
1611 
stepCntFlushGetData()1612 static bool stepCntFlushGetData()
1613 {
1614     TDECL();
1615     if (trySwitchState(SENSOR_STEP_CNT)) {
1616         SPI_READ(BMI160_REG_STEP_CNT_0, 2, &mTask.dataBuffer);
1617         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[STEPCNT], __FUNCTION__);
1618         return true;
1619     }
1620     return false;
1621 }
1622 
stepCntFlush(void * cookie)1623 static bool stepCntFlush(void *cookie)
1624 {
1625     mTask.sensors[STEPCNT].flush++;
1626     stepCntFlushGetData();
1627     return true;
1628 }
1629 
sendStepCnt()1630 static void sendStepCnt()
1631 {
1632     union EmbeddedDataPoint step_cnt;
1633     uint32_t cur_step_cnt;
1634     cur_step_cnt = (int)(mTask.dataBuffer[1] | (mTask.dataBuffer[2] << 8));
1635 
1636     if (cur_step_cnt != mTask.last_step_cnt) {
1637         // Check for possible overflow
1638         if (cur_step_cnt < mTask.last_step_cnt) {
1639             mTask.total_step_cnt += cur_step_cnt + (0xFFFF - mTask.last_step_cnt);
1640         } else {
1641             mTask.total_step_cnt += (cur_step_cnt - mTask.last_step_cnt);
1642         }
1643         mTask.last_step_cnt = cur_step_cnt;
1644 
1645         // Send the event if the current rate is ONCHANGE or we need to flush;
1646         // otherwise, wait until step count sampling timer expires
1647         if (mTask.sensors[STEPCNT].rate == SENSOR_RATE_ONCHANGE || mTask.sensors[STEPCNT].flush) {
1648             step_cnt.idata = mTask.total_step_cnt;
1649             osEnqueueEvt(EVT_SENSOR_STEP_COUNTER, step_cnt.vptr, NULL);
1650         } else {
1651             mTask.step_cnt_changed = true;
1652         }
1653     }
1654 
1655     while (mTask.sensors[STEPCNT].flush) {
1656         osEnqueueEvt(EVT_SENSOR_STEP_COUNTER, SENSOR_DATA_EVENT_FLUSH, NULL);
1657         mTask.sensors[STEPCNT].flush--;
1658     }
1659 }
1660 
stepCntSendLastData(void * cookie,uint32_t tid)1661 static bool stepCntSendLastData(void *cookie, uint32_t tid)
1662 {
1663     // If this comes in and we don't have data yet, there's no harm in reporting step_cnt = 0
1664     return osEnqueuePrivateEvt(EVT_SENSOR_STEP_COUNTER, (void *) mTask.total_step_cnt, NULL, tid);
1665 }
1666 
parseSensortime(uint32_t sensor_time24)1667 static uint64_t parseSensortime(uint32_t sensor_time24)
1668 {
1669     uint32_t prev_time24;
1670     uint32_t kHalf = 1ul << 23;
1671     uint64_t full;
1672 
1673     prev_time24 = (uint32_t)mTask.last_sensortime & 0xffffff;
1674 
1675     if (mTask.last_sensortime == 0) {
1676         mTask.last_sensortime = (uint64_t)sensor_time24;
1677         return (uint64_t)(sensor_time24);
1678     }
1679 
1680     if (sensor_time24 == prev_time24) {
1681         return (uint64_t)(mTask.last_sensortime);
1682     }
1683 
1684     full = (mTask.last_sensortime & ~0xffffffull) | sensor_time24;
1685 
1686     if (((prev_time24 < sensor_time24) && (sensor_time24 - prev_time24) < kHalf)
1687             || ((prev_time24 > sensor_time24) && (prev_time24 - sensor_time24) > kHalf)) {
1688         if (full < mTask.last_sensortime) {
1689             full += 0x1000000ull;
1690         }
1691         mTask.last_sensortime = full;
1692         return mTask.last_sensortime;
1693     }
1694 
1695     if (full < mTask.last_sensortime) {
1696         return full;
1697     }
1698 
1699     return (full -  0x1000000ull);
1700 }
1701 
flushData(struct BMI160Sensor * sensor,uint32_t eventId)1702 static bool flushData(struct BMI160Sensor *sensor, uint32_t eventId)
1703 {
1704     bool success = false;
1705 
1706     if (sensor->data_evt) {
1707         success = osEnqueueEvtOrFree(eventId, sensor->data_evt, dataEvtFree);
1708         sensor->data_evt = NULL;
1709     }
1710 
1711     return success;
1712 }
1713 
flushAllData(void)1714 static void flushAllData(void)
1715 {
1716     int i;
1717     for (i = ACC; i <= MAG; i++) {
1718         flushData(&mTask.sensors[i],
1719                 EVENT_TYPE_BIT_DISCARDABLE | sensorGetMyEventType(mSensorInfo[i].sensorType));
1720     }
1721 }
1722 
allocateDataEvt(struct BMI160Sensor * mSensor,uint64_t rtc_time)1723 static bool allocateDataEvt(struct BMI160Sensor *mSensor, uint64_t rtc_time)
1724 {
1725     TDECL();
1726     mSensor->data_evt = slabAllocatorAlloc(T(mDataSlab));
1727     if (mSensor->data_evt == NULL) {
1728         // slab allocation failed
1729         ERROR_PRINT("slabAllocatorAlloc() failed\n");
1730         return false;
1731     }
1732 
1733     // delta time for the first sample is sample count
1734     memset(&mSensor->data_evt->samples[0].firstSample, 0x00, sizeof(struct SensorFirstSample));
1735     mSensor->data_evt->referenceTime = rtc_time;
1736     mSensor->prev_rtc_time = rtc_time;
1737 
1738     return true;
1739 }
1740 
parseRawData(struct BMI160Sensor * mSensor,uint8_t * buf,float kScale,uint64_t sensorTime)1741 static void parseRawData(struct BMI160Sensor *mSensor, uint8_t *buf, float kScale, uint64_t sensorTime)
1742 {
1743     float x, y, z;
1744     int16_t raw_x, raw_y, raw_z;
1745     struct TripleAxisDataPoint *sample;
1746     uint32_t delta_time;
1747     uint64_t rtc_time;
1748     bool newMagBias = false;
1749 
1750     if (!sensortime_to_rtc_time(sensorTime, &rtc_time)) {
1751         return;
1752     }
1753 
1754     if (rtc_time < mSensor->prev_rtc_time + kMinRTCTimeIncrementNs) {
1755 #if TIMESTAMP_DBG
1756         DEBUG_PRINT("%s prev rtc 0x%08x %08x, curr 0x%08x %08x, delta %d usec\n",
1757                 mSensorInfo[mSensor->idx].sensorName,
1758                 (unsigned int)((mSensor->prev_rtc_time >> 32) & 0xffffffff),
1759                 (unsigned int)(mSensor->prev_rtc_time & 0xffffffff),
1760                 (unsigned int)((rtc_time >> 32) & 0xffffffff),
1761                 (unsigned int)(rtc_time & 0xffffffff),
1762                 (int)(rtc_time - mSensor->prev_rtc_time) / 1000);
1763 #endif
1764         rtc_time = mSensor->prev_rtc_time + kMinRTCTimeIncrementNs;
1765     }
1766 
1767     if (mSensor->idx == MAG) {
1768 #ifdef MAG_SLAVE_PRESENT
1769         parseMagData(&magTask, &buf[0], &x, &y, &z);
1770         BMM150_TO_ANDROID_COORDINATE(x, y, z);
1771 
1772         float xi, yi, zi;
1773         magCalRemoveSoftiron(&mTask.moc, x, y, z, &xi, &yi, &zi);
1774 
1775         newMagBias |= magCalUpdate(&mTask.moc, sensorTime * kSensorTimerIntervalUs, xi, yi, zi);
1776 
1777         magCalRemoveBias(&mTask.moc, xi, yi, zi, &x, &y, &z);
1778 #else
1779         return;
1780 #endif
1781     } else {
1782         raw_x = (buf[0] | buf[1] << 8);
1783         raw_y = (buf[2] | buf[3] << 8);
1784         raw_z = (buf[4] | buf[5] << 8);
1785 
1786         x = (float)raw_x * kScale;
1787         y = (float)raw_y * kScale;
1788         z = (float)raw_z * kScale;
1789 
1790         BMI160_TO_ANDROID_COORDINATE(x, y, z);
1791     }
1792 
1793     if (mSensor->data_evt == NULL) {
1794         if (!allocateDataEvt(mSensor, rtc_time))
1795             return;
1796     }
1797 
1798     if (mSensor->data_evt->samples[0].firstSample.numSamples >= MAX_NUM_COMMS_EVENT_SAMPLES) {
1799         ERROR_PRINT("BAD INDEX\n");
1800         return;
1801     }
1802 
1803     if (mSensor->idx == MAG && (newMagBias || !mTask.magBiasPosted)) {
1804         if (mSensor->data_evt->samples[0].firstSample.numSamples > 0) {
1805             // flush existing samples so the bias appears after them
1806             flushData(mSensor,
1807                     EVENT_TYPE_BIT_DISCARDABLE | sensorGetMyEventType(mSensorInfo[MAG].sensorType));
1808             if (!allocateDataEvt(mSensor, rtc_time))
1809                 return;
1810         }
1811         if (newMagBias)
1812             mTask.magBiasCurrent = true;
1813         mSensor->data_evt->samples[0].firstSample.biasCurrent = mTask.magBiasCurrent;
1814         mSensor->data_evt->samples[0].firstSample.biasPresent = 1;
1815         mSensor->data_evt->samples[0].firstSample.biasSample =
1816                 mSensor->data_evt->samples[0].firstSample.numSamples;
1817         sample = &mSensor->data_evt->samples[mSensor->data_evt->samples[0].firstSample.numSamples++];
1818 #ifdef MAG_SLAVE_PRESENT
1819         magCalGetBias(&mTask.moc, &sample->x, &sample->y, &sample->z);
1820 #endif
1821         // bias is non-discardable, if we fail to enqueue, don't clear new_mag_bias
1822         if (flushData(mSensor, sensorGetMyEventType(mSensorInfo[MAG].biasType)))
1823             mTask.magBiasPosted = true;
1824 
1825         if (!allocateDataEvt(mSensor, rtc_time))
1826             return;
1827     }
1828 
1829     sample = &mSensor->data_evt->samples[mSensor->data_evt->samples[0].firstSample.numSamples++];
1830 
1831     // the first deltatime is for sample size
1832     if (mSensor->data_evt->samples[0].firstSample.numSamples > 1) {
1833         delta_time = rtc_time - mSensor->prev_rtc_time;
1834         delta_time = delta_time < 0 ? 0 : delta_time;
1835         sample->deltaTime = delta_time;
1836         mSensor->prev_rtc_time = rtc_time;
1837     }
1838 
1839     sample->x = x;
1840     sample->y = y;
1841     sample->z = z;
1842 
1843     //DEBUG_PRINT("bmi160: x: %d, y: %d, z: %d\n", (int)(1000*x), (int)(1000*y), (int)(1000*z));
1844 
1845     //TODO: This was added to prevent to much data of the same type accumulate in internal buffer.
1846     //      It might no longer be necessary and can be removed.
1847     if (mSensor->data_evt->samples[0].firstSample.numSamples == MAX_NUM_COMMS_EVENT_SAMPLES) {
1848         flushAllData();
1849     }
1850 
1851 }
1852 
dispatchData(void)1853 static void dispatchData(void)
1854 {
1855     size_t i = 1, j;
1856     size_t size = mTask.xferCnt;
1857     int fh_mode, fh_param;
1858     uint8_t *buf = mTask.dataBuffer;
1859 
1860     uint64_t min_delta = ULONG_LONG_MAX;
1861     uint32_t sensor_time24;
1862     uint64_t full_sensor_time;
1863     uint64_t frame_sensor_time = mTask.frame_sensortime;
1864     bool observed[3] = {false, false, false};
1865     uint64_t tmp_frame_time, tmp_time[3];
1866     bool frame_sensor_time_valid = mTask.frame_sensortime_valid;
1867     bool saved_pending_delta[3];
1868     uint64_t saved_time_delta[3];
1869 #if TIMESTAMP_DBG
1870     int frame_num = -1;
1871 #endif
1872 
1873     if (!mTask.frame_sensortime_valid) {
1874         // This is the first FIFO delivery after any sensor is enabled in
1875         // bmi160. Sensor time reference is not establised until end of this
1876         // FIFO frame. Assume time start from zero and do a dry run to estimate
1877         // the time and then go through this FIFO again.
1878         frame_sensor_time = 0ull;
1879 
1880         // Save these states for future recovery by the end of dry run.
1881         for (j = ACC; j <= MAG; j++) {
1882             saved_pending_delta[j] = mTask.pending_delta[j];
1883             saved_time_delta[j] = mTask.time_delta[j];
1884         }
1885     }
1886 
1887     while (size > 0) {
1888         if (buf[i] == BMI160_FRAME_HEADER_INVALID) {
1889             // reaching invalid header means no more data
1890             break;
1891         } else if (buf[i] == BMI160_FRAME_HEADER_SKIP) {
1892             // manually injected skip header
1893             DEBUG_PRINT_IF(DBG_CHUNKED, "skip nop header");
1894             i++;
1895             size--;
1896             continue;
1897         }
1898 
1899         fh_mode = buf[i] >> 6;
1900         fh_param = (buf[i] >> 2) & 0xf;
1901 
1902         i++;
1903         size--;
1904 #if TIMESTAMP_DBG
1905         ++frame_num;
1906 #endif
1907 
1908         if (fh_mode == 1) {
1909             // control frame.
1910             if (fh_param == 0) {
1911                 // skip frame, we skip it
1912                 if (size >= 1) {
1913                     i++;
1914                     size--;
1915                 } else {
1916                     size = 0;
1917                 }
1918             } else if (fh_param == 1) {
1919                 // sensortime frame
1920                 if (size >= 3) {
1921                     // The active sensor with the highest odr/lowest delta is the one that
1922                     // determines the sensor time increments.
1923                     for (j = ACC; j <= MAG; j++) {
1924                         if (mTask.sensors[j].configed &&
1925                                 mTask.sensors[j].latency != SENSOR_LATENCY_NODATA) {
1926                             min_delta = min_delta < mTask.time_delta[j] ? min_delta :
1927                                     mTask.time_delta[j];
1928                         }
1929                     }
1930                     sensor_time24 = buf[i + 2] << 16 | buf[i + 1] << 8 | buf[i];
1931 
1932                     // clear lower bits that measure time from taking the sample to reading the
1933                     // FIFO, something we're not interested in.
1934                     sensor_time24 &= ~(min_delta - 1);
1935 
1936                     full_sensor_time = parseSensortime(sensor_time24);
1937 
1938 #if TIMESTAMP_DBG
1939                     if (frame_sensor_time == full_sensor_time) {
1940                         //DEBUG_PRINT("frame %d FrameTime 0x%08x\n",
1941                         //        frame_num - 1,
1942                         //        (unsigned int)frame_sensor_time);
1943                     } else if (frame_sensor_time_valid) {
1944                         DEBUG_PRINT("frame %d FrameTime 0x%08x != SensorTime 0x%08x, jumped %d msec\n",
1945                                 frame_num - 1,
1946                                 (unsigned int)frame_sensor_time,
1947                                 (unsigned int)full_sensor_time,
1948                                 (int)(5 * ((int64_t)(full_sensor_time - frame_sensor_time) >> 7)));
1949                     }
1950 #endif
1951 
1952 
1953                     if (frame_sensor_time_valid) {
1954                         mTask.frame_sensortime = full_sensor_time;
1955                     } else {
1956                         // Dry run if frame_sensortime_valid == false,
1957                         // no sample is added this round.
1958                         // So let's time travel back to beginning of frame.
1959                         mTask.frame_sensortime_valid = true;
1960                         mTask.frame_sensortime = full_sensor_time - frame_sensor_time;
1961 
1962                         // recover states
1963                         for (j = ACC; j <= MAG; j++) {
1964                             // reset all prev_frame_time to invalid values
1965                             // they should be so anyway at the first FIFO
1966                             mTask.prev_frame_time[j] = ULONG_LONG_MAX;
1967 
1968                             // recover saved time_delta and pending_delta values
1969                             mTask.pending_delta[j] = saved_pending_delta[j];
1970                             mTask.time_delta[j] = saved_time_delta[j];
1971                         }
1972 
1973                         DEBUG_PRINT_IF(TIMESTAMP_DBG,
1974                                 "sensortime invalid: full, frame, task = %llu, %llu, %llu\n",
1975                                 full_sensor_time,
1976                                 frame_sensor_time,
1977                                 mTask.frame_sensortime);
1978 
1979                         // Parse again with known valid timing.
1980                         // This time the sensor events will be committed into event buffer.
1981                         return dispatchData();
1982                     }
1983 
1984                     // Invalidate sensor timestamp that didn't get corrected by full_sensor_time,
1985                     // so it can't be used as a reference at next FIFO read.
1986                     // Use (ULONG_LONG_MAX - 1) to indicate this.
1987                     for (j = ACC; j <= MAG; j++) {
1988                         mTask.prev_frame_time[j] = observed[j] ? full_sensor_time : (ULONG_LONG_MAX - 1);
1989 
1990                         // sensor can be disabled in the middle of the FIFO, but wait till the FIFO
1991                         // end to invalidate prev_frame_time since it's still needed for parsing.
1992                         // Also invalidate pending delta just to be safe.
1993                         if (!mTask.sensors[j].configed ||
1994                                 mTask.sensors[j].latency == SENSOR_LATENCY_NODATA) {
1995                             mTask.prev_frame_time[j] = ULONG_LONG_MAX;
1996                             mTask.pending_delta[j] = false;
1997                         }
1998                     }
1999                     i += 3;
2000                     size -= 3;
2001                 } else {
2002                     size = 0;
2003                 }
2004             } else if (fh_param == 2) {
2005                 // fifo_input config frame
2006 #if TIMESTAMP_DBG
2007                 DEBUG_PRINT("frame %d config change 0x%02x\n", frame_num, buf[i]);
2008 #endif
2009                 if (size >= 1) {
2010                     for (j = ACC; j <= MAG; j++) {
2011                         if (buf[i] & (0x01 << (j << 1)) && mTask.pending_delta[j]) {
2012                             mTask.pending_delta[j] = false;
2013                             mTask.time_delta[j] = mTask.next_delta[j];
2014 #if TIMESTAMP_DBG
2015                             DEBUG_PRINT("%s new delta %u\n", mSensorInfo[j].sensorName,
2016                                     (unsigned int)mTask.time_delta[j]);
2017 #endif
2018                         }
2019                     }
2020                     i++;
2021                     size--;
2022                 } else {
2023                     size = 0;
2024                 }
2025             } else {
2026                 size = 0; // drop this batch
2027                 ERROR_PRINT("Invalid fh_param in conttrol frame\n");
2028             }
2029         } else if (fh_mode == 2) {
2030             // Calcutate candidate frame time (tmp_frame_time):
2031             // 1) When sensor is first enabled, reference from other sensors if possible.
2032             // Otherwise, add the smallest increment to the previous data frame time.
2033             // 2) The newly enabled sensor could only underestimate its
2034             // frame time without reference from other sensors.
2035             // 3) The underestimated frame time of a newly enabled sensor will be corrected
2036             // as soon as it shows up in the same frame with another sensor.
2037             // 4) (prev_frame_time == ULONG_LONG_MAX) means the sensor wasn't enabled.
2038             // 5) (prev_frame_time == ULONG_LONG_MAX -1) means the sensor didn't appear in the last
2039             // data frame of the previous fifo read.  So it won't be used as a frame time reference.
2040 
2041             tmp_frame_time = 0;
2042             for (j = ACC; j <= MAG; j++) {
2043                 observed[j] = false; // reset at each data frame
2044                 tmp_time[j] = 0;
2045                 if ((mTask.prev_frame_time[j] < ULONG_LONG_MAX - 1) && (fh_param & (1 << j))) {
2046                     tmp_time[j] = mTask.prev_frame_time[j] + mTask.time_delta[j];
2047                     tmp_frame_time = (tmp_time[j] > tmp_frame_time) ? tmp_time[j] : tmp_frame_time;
2048                 }
2049             }
2050             tmp_frame_time = (frame_sensor_time + kMinSensorTimeIncrement > tmp_frame_time)
2051                 ? (frame_sensor_time + kMinSensorTimeIncrement) : tmp_frame_time;
2052 
2053             // regular frame, dispatch data to each sensor's own fifo
2054             if (fh_param & 4) { // have mag data
2055                 if (size >= 8) {
2056                     if (frame_sensor_time_valid) {
2057                         // scale not used
2058                         parseRawData(&mTask.sensors[MAG], &buf[i], 0, tmp_frame_time);
2059 #if TIMESTAMP_DBG
2060                         if (mTask.prev_frame_time[MAG] == ULONG_LONG_MAX) {
2061                             DEBUG_PRINT("mag enabled: frame %d time 0x%08x\n",
2062                                     frame_num, (unsigned int)tmp_frame_time);
2063                         } else if ((tmp_frame_time != tmp_time[MAG]) && (tmp_time[MAG] != 0)) {
2064                             DEBUG_PRINT("frame %d mag time: 0x%08x -> 0x%08x, jumped %d msec\n",
2065                                     frame_num,
2066                                     (unsigned int)tmp_time[MAG],
2067                                     (unsigned int)tmp_frame_time,
2068                                     (int)(5 * ((int64_t)(tmp_frame_time - tmp_time[MAG]) >> 7)));
2069                         }
2070 #endif
2071                     }
2072                     mTask.prev_frame_time[MAG] = tmp_frame_time;
2073                     i += 8;
2074                     size -= 8;
2075                     observed[MAG] = true;
2076                 } else {
2077                     size = 0;
2078                 }
2079             }
2080             if (fh_param & 2) { // have gyro data
2081                 if (size >= 6) {
2082                     if (frame_sensor_time_valid) {
2083                         parseRawData(&mTask.sensors[GYR], &buf[i], kScale_gyr, tmp_frame_time);
2084 #if TIMESTAMP_DBG
2085                         if (mTask.prev_frame_time[GYR] == ULONG_LONG_MAX) {
2086                             DEBUG_PRINT("gyr enabled: frame %d time 0x%08x\n",
2087                                     frame_num, (unsigned int)tmp_frame_time);
2088                         } else if ((tmp_frame_time != tmp_time[GYR]) && (tmp_time[GYR] != 0)) {
2089                             DEBUG_PRINT("frame %d gyr time: 0x%08x -> 0x%08x, jumped %d msec\n",
2090                                     frame_num,
2091                                     (unsigned int)tmp_time[GYR],
2092                                     (unsigned int)tmp_frame_time,
2093                                     (int)(5 * ((int64_t)(tmp_frame_time - tmp_time[GYR]) >> 7)));
2094                         }
2095 #endif
2096                     }
2097                     mTask.prev_frame_time[GYR] = tmp_frame_time;
2098                     i += 6;
2099                     size -= 6;
2100                     observed[GYR] = true;
2101                 } else {
2102                     size = 0;
2103                 }
2104             }
2105             if (fh_param & 1) { // have accel data
2106                 if (size >= 6) {
2107                     if (frame_sensor_time_valid) {
2108                         parseRawData(&mTask.sensors[ACC], &buf[i], kScale_acc, tmp_frame_time);
2109 #if TIMESTAMP_DBG
2110                         if (mTask.prev_frame_time[ACC] == ULONG_LONG_MAX) {
2111                             DEBUG_PRINT("acc enabled: frame %d time 0x%08x\n",
2112                                     frame_num, (unsigned int)tmp_frame_time);
2113                         } else if ((tmp_frame_time != tmp_time[ACC]) && (tmp_time[ACC] != 0)) {
2114                             DEBUG_PRINT("frame %d gyr time: 0x%08x -> 0x%08x, jumped %d msec\n",
2115                                     frame_num,
2116                                     (unsigned int)tmp_time[ACC],
2117                                     (unsigned int)tmp_frame_time,
2118                                     (int)(5 * ((int64_t)(tmp_frame_time - tmp_time[ACC]) >> 7)));
2119                         }
2120 #endif
2121                     }
2122                     mTask.prev_frame_time[ACC] = tmp_frame_time;
2123                     i += 6;
2124                     size -= 6;
2125                     observed[ACC] = true;
2126                 } else {
2127                     size = 0;
2128                 }
2129             }
2130 
2131             if (observed[ACC] || observed[GYR] || observed[MAG])
2132                 frame_sensor_time = tmp_frame_time;
2133         } else {
2134             size = 0; // drop this batch
2135             ERROR_PRINT("Invalid fh_mode\n");
2136         }
2137     }
2138 
2139     //flush data events.
2140     flushAllData();
2141 }
2142 
2143 /*
2144  * Read the interrupt type and send corresponding event
2145  * If it's anymo or double tap, also send a single uint32 to indicate which axies
2146  * is this interrupt triggered.
2147  * If it's flat, also send a bit to indicate flat/non-flat position.
2148  * If it's step detector, check if we need to send the total step count.
2149  */
int2Handling(void)2150 static void int2Handling(void)
2151 {
2152     TDECL();
2153     union EmbeddedDataPoint trigger_axies;
2154     uint8_t int_status_0 = mTask.statusBuffer[1];
2155     uint8_t int_status_1 = mTask.statusBuffer[2];
2156     if (int_status_0 & INT_STEP) {
2157         if (mTask.sensors[STEP].powered) {
2158             DEBUG_PRINT("Detected step\n");
2159             osEnqueueEvt(EVT_SENSOR_STEP, NULL, NULL);
2160         }
2161         if (mTask.sensors[STEPCNT].powered) {
2162             T(pending_step_cnt) = true;
2163         }
2164     }
2165     if ((int_status_0 & INT_ANY_MOTION) && mTask.sensors[ANYMO].powered) {
2166         // bit [0:2] of INT_STATUS[2] is set when anymo is triggered by x, y or
2167         // z axies respectively. bit [3] indicates the slope.
2168         trigger_axies.idata = (mTask.statusBuffer[3] & 0x0f);
2169         DEBUG_PRINT("Detected any motion\n");
2170         osEnqueueEvt(EVT_SENSOR_ANY_MOTION, trigger_axies.vptr, NULL);
2171     }
2172     if ((int_status_0 & INT_DOUBLE_TAP) && mTask.sensors[DTAP].powered) {
2173         // bit [4:6] of INT_STATUS[2] is set when double tap is triggered by
2174         // x, y or z axies respectively. bit [7] indicates the slope.
2175         trigger_axies.idata = ((mTask.statusBuffer[3] & 0xf0) >> 4);
2176         DEBUG_PRINT("Detected double tap\n");
2177         osEnqueueEvt(EVT_SENSOR_DOUBLE_TAP, trigger_axies.vptr, NULL);
2178     }
2179     if ((int_status_0 & INT_FLAT) && mTask.sensors[FLAT].powered) {
2180         // bit [7] of INT_STATUS[3] indicates flat/non-flat position
2181         trigger_axies.idata = ((mTask.statusBuffer[4] & 0x80) >> 7);
2182         DEBUG_PRINT("Detected flat\n");
2183         osEnqueueEvt(EVT_SENSOR_FLAT, trigger_axies.vptr, NULL);
2184     }
2185     if ((int_status_1 & INT_NO_MOTION) && mTask.sensors[NOMO].powered) {
2186         DEBUG_PRINT("Detected no motion\n");
2187         osEnqueueEvt(EVT_SENSOR_NO_MOTION, NULL, NULL);
2188     }
2189     return;
2190 }
2191 
int2Evt(void)2192 static void int2Evt(void)
2193 {
2194     TDECL();
2195     if (trySwitchState(SENSOR_INT_2_HANDLING)) {
2196         // Read the interrupt reg value to determine what interrupts
2197         SPI_READ(BMI160_REG_INT_STATUS_0, 4, &mTask.statusBuffer);
2198         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask, __FUNCTION__);
2199     } else {
2200         // even if we are still in SENSOR_INT_2_HANDLING, the SPI may already finished and we need
2201         // to issue another SPI read to get the latest status
2202         mTask.pending_int[1] = true;
2203     }
2204 }
2205 
2206 // bits[6:7] in OFFSET[6] to enable/disable gyro/accel offset.
2207 // bits[0:5] in OFFSET[6] stores the most significant 2 bits of gyro offset at
2208 // its x, y, z axies.
2209 // Calculate the stored gyro offset and compose it with the intended
2210 // enable/disable mode for gyro/accel offset to determine the value for
2211 // OFFSET[6].
offset6Mode(void)2212 static uint8_t offset6Mode(void)
2213 {
2214     uint8_t mode = 0;
2215     if (mTask.sensors[GYR].offset_enable)
2216         mode |= 0x01 << 7;
2217     if (mTask.sensors[ACC].offset_enable)
2218         mode |= 0x01 << 6;
2219     mode |= (mTask.sensors[GYR].offset[2] & 0x0300) >> 4;
2220     mode |= (mTask.sensors[GYR].offset[1] & 0x0300) >> 6;
2221     mode |= (mTask.sensors[GYR].offset[0] & 0x0300) >> 8;
2222     DEBUG_PRINT("OFFSET_6_MODE is: %02x\n", mode);
2223     return mode;
2224 }
2225 
saveCalibration()2226 static bool saveCalibration()
2227 {
2228     TDECL();
2229     if (trySwitchState(SENSOR_SAVE_CALIBRATION)) {
2230         if (mTask.sensors[ACC].offset_enable) {
2231             SPI_WRITE(BMI160_REG_OFFSET_0, mTask.sensors[ACC].offset[0] & 0xFF, 450);
2232             SPI_WRITE(BMI160_REG_OFFSET_0 + 1, mTask.sensors[ACC].offset[1] & 0xFF, 450);
2233             SPI_WRITE(BMI160_REG_OFFSET_0 + 2, mTask.sensors[ACC].offset[2] & 0xFF, 450);
2234         }
2235         if (mTask.sensors[GYR].offset_enable) {
2236             SPI_WRITE(BMI160_REG_OFFSET_3, mTask.sensors[GYR].offset[0] & 0xFF, 450);
2237             SPI_WRITE(BMI160_REG_OFFSET_3 + 1, mTask.sensors[GYR].offset[1] & 0xFF, 450);
2238             SPI_WRITE(BMI160_REG_OFFSET_3 + 2, mTask.sensors[GYR].offset[2] & 0xFF, 450);
2239         }
2240         SPI_WRITE(BMI160_REG_OFFSET_6, offset6Mode(), 450);
2241         SPI_READ(BMI160_REG_OFFSET_0, 7, &mTask.dataBuffer);
2242         spiBatchTxRx(&mTask.mode, sensorSpiCallback, NULL, __FUNCTION__);
2243         return true;
2244     } else {
2245         DEBUG_PRINT("%s, state != IDLE", __FUNCTION__);
2246         return false;
2247     }
2248 }
2249 
sendCalibrationResult(uint8_t status,uint8_t sensorType,int32_t xBias,int32_t yBias,int32_t zBias)2250 static void sendCalibrationResult(uint8_t status, uint8_t sensorType,
2251         int32_t xBias, int32_t yBias, int32_t zBias) {
2252     struct CalibrationData *data = heapAlloc(sizeof(struct CalibrationData));
2253     if (!data) {
2254         osLog(LOG_WARN, "Couldn't alloc cal result pkt");
2255         return;
2256     }
2257 
2258     data->header.appId = BMI160_APP_ID;
2259     data->header.dataLen = (sizeof(struct CalibrationData) - sizeof(struct HostHubRawPacket));
2260     data->data_header.msgId = SENSOR_APP_MSG_ID_CAL_RESULT;
2261     data->data_header.sensorType = sensorType;
2262     data->data_header.status = status;
2263 
2264     data->xBias = xBias;
2265     data->yBias = yBias;
2266     data->zBias = zBias;
2267 
2268     if (!osEnqueueEvtOrFree(EVT_APP_TO_HOST, data, heapFree))
2269         osLog(LOG_WARN, "Couldn't send cal result evt");
2270 }
2271 
accCalibrationHandling(void)2272 static void accCalibrationHandling(void)
2273 {
2274     TDECL();
2275     switch (mTask.calibration_state) {
2276     case CALIBRATION_START:
2277         T(mRetryLeft) = RETRY_CNT_CALIBRATION;
2278 
2279         // turn ACC to NORMAL mode
2280         SPI_WRITE(BMI160_REG_CMD, 0x11, 50000);
2281 
2282         mTask.calibration_state = CALIBRATION_FOC;
2283         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[ACC], __FUNCTION__);
2284         break;
2285     case CALIBRATION_FOC:
2286 
2287         // set accel range to +-8g
2288         SPI_WRITE(BMI160_REG_ACC_RANGE, 0x08);
2289 
2290         // enable accel fast offset compensation,
2291         // x: 0g, y: 0g, z: 1g
2292         SPI_WRITE(BMI160_REG_FOC_CONF, ACC_FOC_CONFIG);
2293 
2294         // start calibration
2295         SPI_WRITE(BMI160_REG_CMD, 0x03, 100000);
2296 
2297         // poll the status reg until the calibration finishes.
2298         SPI_READ(BMI160_REG_STATUS, 1, &mTask.statusBuffer, 50000);
2299 
2300         mTask.calibration_state = CALIBRATION_WAIT_FOC_DONE;
2301         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[ACC], __FUNCTION__);
2302         break;
2303     case CALIBRATION_WAIT_FOC_DONE:
2304         // if the STATUS REG has bit 3 set, it means calbration is done.
2305         // otherwise, check back in 50ms later.
2306         if (mTask.statusBuffer[1] & 0x08) {
2307 
2308             //disable FOC
2309             SPI_WRITE(BMI160_REG_FOC_CONF, 0x00);
2310 
2311             //read the offset value for accel
2312             SPI_READ(BMI160_REG_OFFSET_0, 3, &mTask.dataBuffer);
2313             mTask.calibration_state = CALIBRATION_SET_OFFSET;
2314             DEBUG_PRINT("FOC set FINISHED!\n");
2315         } else {
2316 
2317             // calibration hasn't finished yet, go back to wait for 50ms.
2318             SPI_READ(BMI160_REG_STATUS, 1, &mTask.statusBuffer, 50000);
2319             mTask.calibration_state = CALIBRATION_WAIT_FOC_DONE;
2320             T(mRetryLeft)--;
2321         }
2322         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[ACC], __FUNCTION__);
2323 
2324         // if calbration hasn't finished after 10 polling on the STATUS reg,
2325         // declare timeout.
2326         if (T(mRetryLeft) == 0) {
2327             mTask.calibration_state = CALIBRATION_TIMEOUT;
2328         }
2329         break;
2330     case CALIBRATION_SET_OFFSET:
2331         mTask.sensors[ACC].offset[0] = mTask.dataBuffer[1];
2332         mTask.sensors[ACC].offset[1] = mTask.dataBuffer[2];
2333         mTask.sensors[ACC].offset[2] = mTask.dataBuffer[3];
2334         // sign extend values
2335         if (mTask.sensors[ACC].offset[0] & 0x80)
2336             mTask.sensors[ACC].offset[0] |= 0xFFFFFF00;
2337         if (mTask.sensors[ACC].offset[1] & 0x80)
2338             mTask.sensors[ACC].offset[1] |= 0xFFFFFF00;
2339         if (mTask.sensors[ACC].offset[2] & 0x80)
2340             mTask.sensors[ACC].offset[2] |= 0xFFFFFF00;
2341 
2342         mTask.sensors[ACC].offset_enable = true;
2343         DEBUG_PRINT("ACCELERATION OFFSET is %02x  %02x  %02x\n",
2344                 (unsigned int)mTask.sensors[ACC].offset[0],
2345                 (unsigned int)mTask.sensors[ACC].offset[1],
2346                 (unsigned int)mTask.sensors[ACC].offset[2]);
2347 
2348         sendCalibrationResult(SENSOR_APP_EVT_STATUS_SUCCESS, SENS_TYPE_ACCEL,
2349                 mTask.sensors[ACC].offset[0], mTask.sensors[ACC].offset[1],
2350                 mTask.sensors[ACC].offset[2]);
2351 
2352         // Enable offset compensation for accel
2353         uint8_t mode = offset6Mode();
2354         SPI_WRITE(BMI160_REG_OFFSET_6, mode);
2355 
2356         // turn ACC to SUSPEND mode
2357         SPI_WRITE(BMI160_REG_CMD, 0x10, 5000);
2358 
2359         mTask.calibration_state = CALIBRATION_DONE;
2360         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[ACC], __FUNCTION__);
2361         break;
2362     default:
2363         ERROR_PRINT("Invalid calibration state\n");
2364         break;
2365     }
2366 }
2367 
accCalibration(void * cookie)2368 static bool accCalibration(void *cookie)
2369 {
2370     TDECL();
2371     if (!mTask.sensors[ACC].powered && trySwitchState(SENSOR_CALIBRATING)) {
2372         mTask.calibration_state = CALIBRATION_START;
2373         accCalibrationHandling();
2374         return true;
2375     } else {
2376         ERROR_PRINT("cannot calibrate accel because sensor is busy\n");
2377         sendCalibrationResult(SENSOR_APP_EVT_STATUS_BUSY, SENS_TYPE_ACCEL, 0, 0, 0);
2378         return false;
2379     }
2380 }
2381 
accCfgData(void * data,void * cookie)2382 static bool accCfgData(void *data, void *cookie)
2383 {
2384     int32_t *values = data;
2385 
2386     mTask.sensors[ACC].offset[0] = values[0];
2387     mTask.sensors[ACC].offset[1] = values[1];
2388     mTask.sensors[ACC].offset[2] = values[2];
2389     mTask.sensors[ACC].offset_enable = true;
2390 
2391     INFO_PRINT("accCfgData: data=%02lx, %02lx, %02lx\n",
2392             values[0] & 0xFF, values[1] & 0xFF, values[2] & 0xFF);
2393 
2394     if (!saveCalibration()) {
2395         mTask.pending_calibration_save = true;
2396     }
2397 
2398     return true;
2399 }
2400 
gyrCalibrationHandling(void)2401 static void gyrCalibrationHandling(void)
2402 {
2403     TDECL();
2404     switch (mTask.calibration_state) {
2405     case CALIBRATION_START:
2406         T(mRetryLeft) = RETRY_CNT_CALIBRATION;
2407 
2408         // turn GYR to NORMAL mode
2409         SPI_WRITE(BMI160_REG_CMD, 0x15, 50000);
2410 
2411         mTask.calibration_state = CALIBRATION_FOC;
2412         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[GYR], __FUNCTION__);
2413         break;
2414     case CALIBRATION_FOC:
2415 
2416         // set gyro range to +-2000 deg/sec
2417         SPI_WRITE(BMI160_REG_GYR_RANGE, 0x00);
2418 
2419         // enable gyro fast offset compensation
2420         SPI_WRITE(BMI160_REG_FOC_CONF, 0x40);
2421 
2422         // start FOC
2423         SPI_WRITE(BMI160_REG_CMD, 0x03, 100000);
2424 
2425         // poll the status reg until the calibration finishes.
2426         SPI_READ(BMI160_REG_STATUS, 1, &mTask.statusBuffer, 50000);
2427 
2428         mTask.calibration_state = CALIBRATION_WAIT_FOC_DONE;
2429         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[GYR], __FUNCTION__);
2430         break;
2431     case CALIBRATION_WAIT_FOC_DONE:
2432 
2433         // if the STATUS REG has bit 3 set, it means calbration is done.
2434         // otherwise, check back in 50ms later.
2435         if (mTask.statusBuffer[1] & 0x08) {
2436 
2437             // disable gyro fast offset compensation
2438             SPI_WRITE(BMI160_REG_FOC_CONF, 0x00);
2439 
2440             //read the offset value for gyro
2441             SPI_READ(BMI160_REG_OFFSET_3, 4, &mTask.dataBuffer);
2442             mTask.calibration_state = CALIBRATION_SET_OFFSET;
2443             DEBUG_PRINT("FOC set FINISHED!\n");
2444         } else {
2445 
2446             // calibration hasn't finished yet, go back to wait for 50ms.
2447             SPI_READ(BMI160_REG_STATUS, 1, &mTask.statusBuffer, 50000);
2448             mTask.calibration_state = CALIBRATION_WAIT_FOC_DONE;
2449             T(mRetryLeft)--;
2450         }
2451         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[GYR], __FUNCTION__);
2452 
2453         // if calbration hasn't finished after 10 polling on the STATUS reg,
2454         // declare timeout.
2455         if (T(mRetryLeft) == 0) {
2456             mTask.calibration_state = CALIBRATION_TIMEOUT;
2457         }
2458         break;
2459     case CALIBRATION_SET_OFFSET:
2460         mTask.sensors[GYR].offset[0] = ((mTask.dataBuffer[4] & 0x03) << 8) | mTask.dataBuffer[1];
2461         mTask.sensors[GYR].offset[1] = ((mTask.dataBuffer[4] & 0x0C) << 6) | mTask.dataBuffer[2];
2462         mTask.sensors[GYR].offset[2] = ((mTask.dataBuffer[4] & 0x30) << 4) | mTask.dataBuffer[3];
2463         // sign extend values
2464         if (mTask.sensors[GYR].offset[0] & 0x200)
2465             mTask.sensors[GYR].offset[0] |= 0xFFFFFC00;
2466         if (mTask.sensors[GYR].offset[1] & 0x200)
2467             mTask.sensors[GYR].offset[1] |= 0xFFFFFC00;
2468         if (mTask.sensors[GYR].offset[2] & 0x200)
2469             mTask.sensors[GYR].offset[2] |= 0xFFFFFC00;
2470 
2471         mTask.sensors[GYR].offset_enable = true;
2472         DEBUG_PRINT("GYRO OFFSET is %02x  %02x  %02x\n",
2473                 (unsigned int)mTask.sensors[GYR].offset[0],
2474                 (unsigned int)mTask.sensors[GYR].offset[1],
2475                 (unsigned int)mTask.sensors[GYR].offset[2]);
2476 
2477         sendCalibrationResult(SENSOR_APP_EVT_STATUS_SUCCESS, SENS_TYPE_GYRO,
2478                 mTask.sensors[GYR].offset[0], mTask.sensors[GYR].offset[1],
2479                 mTask.sensors[GYR].offset[2]);
2480 
2481         // Enable offset compensation for gyro
2482         uint8_t mode = offset6Mode();
2483         SPI_WRITE(BMI160_REG_OFFSET_6, mode);
2484 
2485         // turn GYR to SUSPEND mode
2486         SPI_WRITE(BMI160_REG_CMD, 0x14, 1000);
2487 
2488         mTask.calibration_state = CALIBRATION_DONE;
2489         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask.sensors[GYR], __FUNCTION__);
2490         break;
2491     default:
2492         ERROR_PRINT("Invalid calibration state\n");
2493         break;
2494     }
2495 }
2496 
gyrCalibration(void * cookie)2497 static bool gyrCalibration(void *cookie)
2498 {
2499     TDECL();
2500     if (!mTask.sensors[GYR].powered && trySwitchState(SENSOR_CALIBRATING)) {
2501         mTask.calibration_state = CALIBRATION_START;
2502         gyrCalibrationHandling();
2503         return true;
2504     } else {
2505         ERROR_PRINT("cannot calibrate gyro because sensor is busy\n");
2506         sendCalibrationResult(SENSOR_APP_EVT_STATUS_BUSY, SENS_TYPE_GYRO, 0, 0, 0);
2507         return false;
2508     }
2509 }
2510 
gyrCfgData(void * data,void * cookie)2511 static bool gyrCfgData(void *data, void *cookie)
2512 {
2513     int32_t *values = data;
2514 
2515     mTask.sensors[GYR].offset[0] = values[0];
2516     mTask.sensors[GYR].offset[1] = values[1];
2517     mTask.sensors[GYR].offset[2] = values[2];
2518     mTask.sensors[GYR].offset_enable = true;
2519 
2520     INFO_PRINT("gyrCfgData: data=%02lx, %02lx, %02lx\n",
2521             values[0] & 0xFF, values[1] & 0xFF, values[2] & 0xFF);
2522 
2523     if (!saveCalibration()) {
2524         mTask.pending_calibration_save = true;
2525     }
2526 
2527     return true;
2528 }
2529 
magCfgData(void * data,void * cookie)2530 static bool magCfgData(void *data, void *cookie)
2531 {
2532     float *values = data;
2533 
2534     INFO_PRINT("magCfgData: %ld, %ld, %ld\n",
2535             (int32_t)(values[0] * 1000), (int32_t)(values[1] * 1000), (int32_t)(values[2] * 1000));
2536 
2537 #ifdef MAG_SLAVE_PRESENT
2538     mTask.moc.x_bias = values[0];
2539     mTask.moc.y_bias = values[1];
2540     mTask.moc.z_bias = values[2];
2541 #endif
2542 
2543     mTask.magBiasPosted = false;
2544 
2545     return true;
2546 }
2547 
2548 #define DEC_OPS(power, firmware, rate, flush) \
2549     .sensorPower = power, \
2550     .sensorFirmwareUpload = firmware, \
2551     .sensorSetRate = rate, \
2552     .sensorFlush = flush
2553 
2554 #define DEC_OPS_SEND(power, firmware, rate, flush, send) \
2555     DEC_OPS(power, firmware, rate, flush), \
2556     .sensorSendOneDirectEvt = send
2557 
2558 #define DEC_OPS_CAL_CFG(power, firmware, rate, flush, cal, cfg) \
2559     DEC_OPS(power, firmware, rate, flush), \
2560     .sensorCalibrate = cal, \
2561     .sensorCfgData = cfg
2562 
2563 #define DEC_OPS_CFG(power, firmware, rate, flush, cfg) \
2564     DEC_OPS(power, firmware, rate, flush), \
2565     .sensorCfgData = cfg
2566 
2567 static const struct SensorOps mSensorOps[NUM_OF_SENSOR] =
2568 {
2569     { DEC_OPS_CAL_CFG(accPower, accFirmwareUpload, accSetRate, accFlush, accCalibration,
2570             accCfgData) },
2571     { DEC_OPS_CAL_CFG(gyrPower, gyrFirmwareUpload, gyrSetRate, gyrFlush, gyrCalibration,
2572             gyrCfgData) },
2573     { DEC_OPS_CFG(magPower, magFirmwareUpload, magSetRate, magFlush, magCfgData) },
2574     { DEC_OPS(stepPower, stepFirmwareUpload, stepSetRate, stepFlush) },
2575     { DEC_OPS(doubleTapPower, doubleTapFirmwareUpload, doubleTapSetRate, doubleTapFlush) },
2576     { DEC_OPS(flatPower, flatFirmwareUpload, flatSetRate, flatFlush) },
2577     { DEC_OPS(anyMotionPower, anyMotionFirmwareUpload, anyMotionSetRate, anyMotionFlush) },
2578     { DEC_OPS(noMotionPower, noMotionFirmwareUpload, noMotionSetRate, noMotionFlush) },
2579     { DEC_OPS_SEND(stepCntPower, stepCntFirmwareUpload, stepCntSetRate, stepCntFlush,
2580             stepCntSendLastData) },
2581 };
2582 
configEvent(struct BMI160Sensor * mSensor,struct ConfigStat * ConfigData)2583 static void configEvent(struct BMI160Sensor *mSensor, struct ConfigStat *ConfigData)
2584 {
2585     int i;
2586 
2587     for (i = 0; &mTask.sensors[i] != mSensor; i++) ;
2588 
2589     if (ConfigData->enable == 0 && mSensor->powered)
2590         mSensorOps[i].sensorPower(false, (void *)i);
2591     else if (ConfigData->enable == 1 && !mSensor->powered)
2592         mSensorOps[i].sensorPower(true, (void *)i);
2593     else
2594         mSensorOps[i].sensorSetRate(ConfigData->rate, ConfigData->latency, (void *)i);
2595 }
2596 
timeSyncEvt(uint32_t evtGeneration,bool evtDataValid)2597 static void timeSyncEvt(uint32_t evtGeneration, bool evtDataValid)
2598 {
2599     TDECL();
2600     // not processing pending events
2601     if (evtDataValid) {
2602         // stale event
2603         if (evtGeneration != mTask.poll_generation)
2604             return;
2605 
2606         mTask.active_poll_generation = mTask.poll_generation;
2607     }
2608 
2609     if (trySwitchState(SENSOR_TIME_SYNC)) {
2610         SPI_READ(BMI160_REG_SENSORTIME_0, 3, &mTask.sensorTimeBuffer);
2611         SPI_READ(BMI160_REG_TEMPERATURE_0, 2, &mTask.temperatureBuffer);
2612         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask, __FUNCTION__);
2613     } else {
2614         mTask.pending_time_sync = true;
2615     }
2616 }
2617 
processPendingEvt(void)2618 static void processPendingEvt(void)
2619 {
2620     TDECL();
2621     enum SensorIndex i;
2622     if (mTask.pending_int[0]) {
2623         mTask.pending_int[0] = false;
2624         initiateFifoRead(false /*isInterruptContext*/);
2625         return;
2626     }
2627     if (mTask.pending_int[1]) {
2628         mTask.pending_int[1] = false;
2629         int2Evt();
2630         return;
2631     }
2632     if (mTask.pending_time_sync) {
2633         mTask.pending_time_sync = false;
2634         timeSyncEvt(0, false);
2635         return;
2636     }
2637     for (i = ACC; i < NUM_OF_SENSOR; i++) {
2638         if (mTask.pending_config[i]) {
2639             mTask.pending_config[i] = false;
2640             configEvent(&mTask.sensors[i], &mTask.sensors[i].pConfig);
2641             return;
2642         }
2643     }
2644     if (mTask.sensors[STEPCNT].flush > 0 || T(pending_step_cnt)) {
2645         T(pending_step_cnt) = T(pending_step_cnt) && !stepCntFlushGetData();
2646         return;
2647     }
2648     if (mTask.pending_calibration_save) {
2649         mTask.pending_calibration_save = !saveCalibration();
2650         return;
2651     }
2652 }
2653 
sensorInit(void)2654 static void sensorInit(void)
2655 {
2656     TDECL();
2657     switch (mTask.init_state) {
2658     case RESET_BMI160:
2659         DEBUG_PRINT("Performing soft reset\n");
2660         // perform soft reset and wait for 100ms
2661         SPI_WRITE(BMI160_REG_CMD, 0xb6, 100000);
2662         // dummy reads after soft reset, wait 100us
2663         SPI_READ(BMI160_REG_MAGIC, 1, &mTask.dataBuffer, 100);
2664 
2665         mTask.init_state = INIT_BMI160;
2666         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask, "sensorInit RESET" );
2667         break;
2668 
2669     case INIT_BMI160:
2670         // Read any pending interrupts to reset them
2671         SPI_READ(BMI160_REG_INT_STATUS_0, 4, &mTask.statusBuffer);
2672 
2673         // disable accel, gyro and mag data in FIFO, enable header, enable time.
2674         SPI_WRITE(BMI160_REG_FIFO_CONFIG_1, 0x12, 450);
2675 
2676         // set the watermark to 24 byte
2677         SPI_WRITE(BMI160_REG_FIFO_CONFIG_0, 0x06, 450);
2678 
2679         // FIFO watermark and fifo_full interrupt enabled
2680         SPI_WRITE(BMI160_REG_INT_EN_0, 0x00, 450);
2681         SPI_WRITE(BMI160_REG_INT_EN_1, 0x60, 450);
2682         SPI_WRITE(BMI160_REG_INT_EN_2, 0x00, 450);
2683 
2684         // INT1, INT2 enabled, high-edge (push-pull) triggered.
2685         SPI_WRITE(BMI160_REG_INT_OUT_CTRL, 0xbb, 450);
2686 
2687         // INT1, INT2 input disabled, interrupt mode: non-latched
2688         SPI_WRITE(BMI160_REG_INT_LATCH, 0x00, 450);
2689 
2690         // Map data interrupts (e.g., FIFO) to INT1 and physical
2691         // interrupts (e.g., any motion) to INT2
2692         SPI_WRITE(BMI160_REG_INT_MAP_0, 0x00, 450);
2693         SPI_WRITE(BMI160_REG_INT_MAP_1, 0xE1, 450);
2694         SPI_WRITE(BMI160_REG_INT_MAP_2, 0xFF, 450);
2695 
2696         // Use pre-filtered data for tap interrupt
2697         SPI_WRITE(BMI160_REG_INT_DATA_0, 0x08);
2698 
2699         // Disable PMU_TRIGGER
2700         SPI_WRITE(BMI160_REG_PMU_TRIGGER, 0x00, 450);
2701 
2702         // tell gyro and accel to NOT use the FOC offset.
2703         mTask.sensors[ACC].offset_enable = false;
2704         mTask.sensors[GYR].offset_enable = false;
2705         SPI_WRITE(BMI160_REG_OFFSET_6, offset6Mode(), 450);
2706 
2707         // initial range for accel (+-8g) and gyro (+-2000 degree).
2708         SPI_WRITE(BMI160_REG_ACC_RANGE, 0x08, 450);
2709         SPI_WRITE(BMI160_REG_GYR_RANGE, 0x00, 450);
2710 
2711         // Reset step counter
2712         SPI_WRITE(BMI160_REG_CMD, 0xB2, 10000);
2713         // Reset interrupt
2714         SPI_WRITE(BMI160_REG_CMD, 0xB1, 10000);
2715         // Reset fifo
2716         SPI_WRITE(BMI160_REG_CMD, 0xB0, 10000);
2717 
2718 #ifdef MAG_SLAVE_PRESENT
2719         mTask.init_state = INIT_MAG;
2720         mTask.mag_state = MAG_SET_START;
2721 #else
2722         // no mag connected to secondary interface
2723         mTask.init_state = INIT_ON_CHANGE_SENSORS;
2724 #endif
2725         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask, "sensorInit INIT");
2726         break;
2727 
2728     case INIT_MAG:
2729         // Don't check statusBuffer if we are just starting mag config
2730         if (mTask.mag_state == MAG_SET_START) {
2731             T(mRetryLeft) = RETRY_CNT_MAG;
2732             magConfig();
2733         } else if (mTask.mag_state < MAG_SET_DATA && mTask.statusBuffer[1] & 0x04) {
2734             // fixme: poll_until to reduce states
2735             // fixme: check should be done before SPI_READ in MAG_READ
2736             SPI_READ(BMI160_REG_STATUS, 1, &mTask.statusBuffer, 1000);
2737             if (--T(mRetryLeft) == 0) {
2738                 ERROR_PRINT("INIT_MAG failed\n");
2739                 // fixme: duplicate suspend mag here
2740                 mTask.mag_state = MAG_INIT_FAILED;
2741                 mTask.init_state = INIT_ON_CHANGE_SENSORS;
2742             }
2743         } else {
2744             T(mRetryLeft) = RETRY_CNT_MAG;
2745             magConfig();
2746         }
2747 
2748         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask, "sensorInit INIT_MAG");
2749         break;
2750 
2751     case INIT_ON_CHANGE_SENSORS:
2752         // configure any_motion and no_motion for 50Hz accel samples
2753         configMotion(MOTION_ODR);
2754 
2755         // select no_motion over slow_motion
2756         // select any_motion over significant motion
2757         SPI_WRITE(BMI160_REG_INT_MOTION_3, 0x15, 450);
2758 
2759         // int_tap_quiet=30ms, int_tap_shock=75ms, int_tap_dur=150ms
2760         SPI_WRITE(BMI160_REG_INT_TAP_0, 0x42, 450);
2761 
2762         // int_tap_th = 7 * 250 mg (8-g range)
2763         SPI_WRITE(BMI160_REG_INT_TAP_1, TAP_THRESHOLD, 450);
2764 
2765         // config step detector
2766         SPI_WRITE(BMI160_REG_STEP_CONF_0, 0x15, 450);
2767         SPI_WRITE(BMI160_REG_STEP_CONF_1, 0x03, 450);
2768 
2769         // int_flat_theta = 44.8 deg * (16/64) = 11.2 deg
2770         SPI_WRITE(BMI160_REG_INT_FLAT_0, 0x10, 450);
2771 
2772         // int_flat_hold_time = (640 msec)
2773         // int_flat_hy = 44.8 * 4 / 64 = 2.8 deg
2774         SPI_WRITE(BMI160_REG_INT_FLAT_1, 0x14, 450);
2775 
2776         mTask.init_state = INIT_DONE;
2777         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask, "sensorInit INIT_ONC");
2778         break;
2779 
2780     default:
2781         INFO_PRINT("Invalid init_state.\n");
2782     }
2783 }
2784 
handleSpiDoneEvt(const void * evtData)2785 static void handleSpiDoneEvt(const void* evtData)
2786 {
2787     TDECL();
2788     struct BMI160Sensor *mSensor;
2789     uint64_t SensorTime;
2790     int16_t temperature16;
2791     int i;
2792     bool returnIdle = false;
2793 
2794     switch (GET_STATE()) {
2795     case SENSOR_BOOT:
2796         T(mRetryLeft) = RETRY_CNT_ID;
2797         SET_STATE(SENSOR_VERIFY_ID);
2798         // dummy reads after boot, wait 100us
2799         SPI_READ(BMI160_REG_MAGIC, 1, &mTask.statusBuffer, 100);
2800         // read the device ID for bmi160
2801         SPI_READ(BMI160_REG_ID, 1, &mTask.dataBuffer);
2802         spiBatchTxRx(&mTask.mode, sensorSpiCallback, &mTask, "spiDone SENSOR_BOOT");
2803         break;
2804     case SENSOR_VERIFY_ID:
2805         if (mTask.dataBuffer[1] != BMI160_ID) {
2806             T(mRetryLeft) --;
2807             ERROR_PRINT("failed id match: %02x\n", mTask.dataBuffer[1]);
2808             if (T(mRetryLeft) == 0)
2809                 break;
2810             // For some reason the first ID read will fail to get the
2811             // correct value. need to retry a few times.
2812             SET_STATE(SENSOR_BOOT);
2813             timTimerSet(100000000, 100, 100, sensorTimerCallback, NULL, true);
2814             break;
2815         } else {
2816             SET_STATE(SENSOR_INITIALIZING);
2817             mTask.init_state = RESET_BMI160;
2818             sensorInit();
2819             break;
2820         }
2821     case SENSOR_INITIALIZING:
2822         if (mTask.init_state == INIT_DONE) {
2823             DEBUG_PRINT("Done initialzing, system IDLE\n");
2824             for (i=0; i<NUM_OF_SENSOR; i++)
2825                 sensorRegisterInitComplete(mTask.sensors[i].handle);
2826             // In case other tasks have already requested us before we finish booting up.
2827             returnIdle = true;
2828         } else {
2829             sensorInit();
2830         }
2831         break;
2832     case SENSOR_POWERING_UP:
2833         mSensor = (struct BMI160Sensor *)evtData;
2834         if (mSensor->idx > MAG && ++mTask.active_oneshot_sensor_cnt == 1) {
2835             // if this is the first one-shot sensor to enable, we need
2836             // to request the accel at 50Hz.
2837             sensorRequest(mTask.tid, mTask.sensors[ACC].handle, SENSOR_HZ(50), SENSOR_LATENCY_NODATA);
2838             //DEBUG_PRINT("oneshot on\n");
2839         }
2840         sensorSignalInternalEvt(mSensor->handle, SENSOR_INTERNAL_EVT_POWER_STATE_CHG, 1, 0);
2841         returnIdle = true;
2842         break;
2843     case SENSOR_POWERING_DOWN:
2844         mSensor = (struct BMI160Sensor *)evtData;
2845         if (mSensor->idx > MAG && --mTask.active_oneshot_sensor_cnt == 0) {
2846             // if this is the last one-shot sensor to disable, we need to
2847             // release the accel.
2848             sensorRelease(mTask.tid, mTask.sensors[ACC].handle);
2849             //DEBUG_PRINT("oneshot off\n");
2850         }
2851         sensorSignalInternalEvt(mSensor->handle, SENSOR_INTERNAL_EVT_POWER_STATE_CHG, 0, 0);
2852 
2853         if (mTask.pending_dispatch) {
2854             mTask.pending_dispatch = false;
2855             dispatchData();
2856         }
2857         returnIdle = true;
2858         break;
2859     case SENSOR_INT_1_HANDLING:
2860         dispatchData();
2861         sendFlushEvt();
2862         returnIdle = true;
2863         break;
2864     case SENSOR_INT_2_HANDLING:
2865         int2Handling();
2866         returnIdle = true;
2867         break;
2868     case SENSOR_CONFIG_CHANGING:
2869         mSensor = (struct BMI160Sensor *)evtData;
2870         sensorSignalInternalEvt(mSensor->handle,
2871                 SENSOR_INTERNAL_EVT_RATE_CHG, mSensor->rate, mSensor->latency);
2872 
2873         if (mTask.pending_dispatch) {
2874             mTask.pending_dispatch = false;
2875             dispatchData();
2876         }
2877 
2878         returnIdle = true;
2879         break;
2880     case SENSOR_CALIBRATING:
2881         mSensor = (struct BMI160Sensor *)evtData;
2882         if (mTask.calibration_state == CALIBRATION_DONE) {
2883             DEBUG_PRINT("DONE calibration\n");
2884             returnIdle = true;
2885         } else if (mTask.calibration_state == CALIBRATION_TIMEOUT) {
2886             DEBUG_PRINT("Calibration TIMED OUT\n");
2887             sendCalibrationResult(SENSOR_APP_EVT_STATUS_ERROR,
2888                     (mSensor->idx == ACC) ? SENS_TYPE_ACCEL : SENS_TYPE_GYRO, 0, 0, 0);
2889             returnIdle = true;
2890         } else if (mSensor->idx == ACC) {
2891             accCalibrationHandling();
2892         } else if (mSensor->idx == GYR) {
2893             gyrCalibrationHandling();
2894         }
2895         break;
2896     case SENSOR_STEP_CNT:
2897         sendStepCnt();
2898         returnIdle = true;
2899         break;
2900     case SENSOR_TIME_SYNC:
2901         SensorTime = parseSensortime(mTask.sensorTimeBuffer[1] |
2902                 (mTask.sensorTimeBuffer[2] << 8) | (mTask.sensorTimeBuffer[3] << 16));
2903         map_sensortime_to_rtc_time(SensorTime, rtcGetTime());
2904 
2905         temperature16 = (mTask.temperatureBuffer[1] | (mTask.temperatureBuffer[2] << 8));
2906         if (temperature16 == 0x8000) {
2907             mTask.tempCelsius = kTempInvalid;
2908         } else {
2909             mTask.tempCelsius = 23.0f + temperature16 * kScale_temp;
2910             mTask.tempTime = rtcGetTime();
2911         }
2912 
2913         if (mTask.active_poll_generation == mTask.poll_generation) {
2914             // attach the generation number to event
2915             timTimerSet(kTimeSyncPeriodNs, 100, 100, timeSyncCallback,
2916                     (void *)mTask.poll_generation, true);
2917         }
2918 
2919         returnIdle = true;
2920         break;
2921     case SENSOR_SAVE_CALIBRATION:
2922         DEBUG_PRINT("SENSOR_SAVE_CALIBRATION: %02x %02x %02x %02x %02x %02x %02x\n",
2923                 mTask.dataBuffer[1], mTask.dataBuffer[2], mTask.dataBuffer[3], mTask.dataBuffer[4],
2924                 mTask.dataBuffer[5], mTask.dataBuffer[6], mTask.dataBuffer[7]);
2925         returnIdle = true;
2926         break;
2927     default:
2928         break;
2929     }
2930 
2931     if (returnIdle) {
2932         SET_STATE(SENSOR_IDLE);
2933         processPendingEvt();
2934     }
2935 }
2936 
handleEvent(uint32_t evtType,const void * evtData)2937 static void handleEvent(uint32_t evtType, const void* evtData)
2938 {
2939     TDECL();
2940     uint64_t currTime;
2941     uint8_t *packet;
2942     float newMagBias;
2943 
2944     switch (evtType) {
2945     case EVT_APP_START:
2946         SET_STATE(SENSOR_BOOT);
2947         osEventUnsubscribe(mTask.tid, EVT_APP_START);
2948 
2949         // wait 100ms for sensor to boot
2950         currTime = timGetTime();
2951         if (currTime < 100000000ULL) {
2952             timTimerSet(100000000 - currTime, 100, 100, sensorTimerCallback, NULL, true);
2953             break;
2954         }
2955         /* We have already been powered on long enough - fall through */
2956     case EVT_SPI_DONE:
2957         handleSpiDoneEvt(evtData);
2958         break;
2959 
2960     case EVT_APP_FROM_HOST:
2961         packet = (uint8_t*)evtData;
2962         if (packet[0] == sizeof(float)) {
2963             memcpy(&newMagBias, packet+1, sizeof(float));
2964 #ifdef MAG_SLAVE_PRESENT
2965             magCalAddBias(&mTask.moc, (mTask.last_charging_bias_x - newMagBias), 0.0, 0.0);
2966 #endif
2967             mTask.last_charging_bias_x = newMagBias;
2968             mTask.magBiasPosted = false;
2969         }
2970         break;
2971 
2972     case EVT_SENSOR_INTERRUPT_1:
2973         initiateFifoRead(false /*isInterruptContext*/);
2974         break;
2975     case EVT_SENSOR_INTERRUPT_2:
2976         int2Evt();
2977         break;
2978     case EVT_TIME_SYNC:
2979         timeSyncEvt((uint32_t)evtData, true);
2980     default:
2981         break;
2982     }
2983 }
2984 
initSensorStruct(struct BMI160Sensor * sensor,enum SensorIndex idx)2985 static void initSensorStruct(struct BMI160Sensor *sensor, enum SensorIndex idx)
2986 {
2987     sensor->idx = idx;
2988     sensor->powered = false;
2989     sensor->configed = false;
2990     sensor->rate = 0;
2991     sensor->offset[0] = 0;
2992     sensor->offset[1] = 0;
2993     sensor->offset[2] = 0;
2994     sensor->latency = 0;
2995     sensor->data_evt = NULL;
2996     sensor->flush = 0;
2997     sensor->prev_rtc_time = 0;
2998 }
2999 
startTask(uint32_t task_id)3000 static bool startTask(uint32_t task_id)
3001 {
3002     TDECL();
3003     DEBUG_PRINT("        IMU:  %ld\n", task_id);
3004 
3005     enum SensorIndex i;
3006     size_t slabSize;
3007 
3008     time_init();
3009 
3010     T(tid) = task_id;
3011 
3012     T(Int1) = gpioRequest(BMI160_INT1_PIN);
3013     T(Isr1).func = bmi160Isr1;
3014     T(Int2) = gpioRequest(BMI160_INT2_PIN);
3015     T(Isr2).func = bmi160Isr2;
3016     T(pending_int[0]) = false;
3017     T(pending_int[1]) = false;
3018     T(pending_step_cnt) = false;
3019     T(pending_dispatch) = false;
3020     T(frame_sensortime_valid) = false;
3021     T(poll_generation) = 0;
3022     T(tempCelsius) = kTempInvalid;
3023     T(tempTime) = 0;
3024 
3025     T(mode).speed = BMI160_SPI_SPEED_HZ;
3026     T(mode).bitsPerWord = 8;
3027     T(mode).cpol = SPI_CPOL_IDLE_HI;
3028     T(mode).cpha = SPI_CPHA_TRAILING_EDGE;
3029     T(mode).nssChange = true;
3030     T(mode).format = SPI_FORMAT_MSB_FIRST;
3031     T(cs) = GPIO_PB(12);
3032 
3033     T(watermark) = 0;
3034 
3035     spiMasterRequest(BMI160_SPI_BUS_ID, &T(spiDev));
3036 
3037     for (i = ACC; i < NUM_OF_SENSOR; i++) {
3038         initSensorStruct(&T(sensors[i]), i);
3039         T(sensors[i]).handle = sensorRegister(&mSensorInfo[i], &mSensorOps[i], NULL, false);
3040         T(pending_config[i]) = false;
3041     }
3042 
3043     osEventSubscribe(mTask.tid, EVT_APP_START);
3044 
3045 #ifdef MAG_SLAVE_PRESENT
3046     initMagCal(&mTask.moc,
3047             0.0f, 0.0f, 0.0f,      // bias x, y, z
3048             1.0f, 0.0f, 0.0f,      // c00, c01, c02
3049             0.0f, 1.0f, 0.0f,      // c10, c11, c12
3050             0.0f, 0.0f, 1.0f);     // c20, c21, c22
3051 #endif
3052 
3053     slabSize = sizeof(struct TripleAxisDataEvent) +
3054         MAX_NUM_COMMS_EVENT_SAMPLES * sizeof(struct TripleAxisDataPoint);
3055 
3056     // each event has 15 samples, with 7 bytes per sample from the fifo.
3057     // the fifo size is 1K.
3058     // 20 slabs because some slabs may only hold 1-2 samples.
3059     // XXX: this consumes too much memeory, need to optimize
3060     T(mDataSlab) = slabAllocatorNew(slabSize, 4, 20);
3061     if (!T(mDataSlab)) {
3062         INFO_PRINT("slabAllocatorNew() failed\n");
3063         return false;
3064     }
3065     T(mWbufCnt) = 0;
3066     T(mRegCnt) = 0;
3067     T(spiInUse) = false;
3068 
3069     T(interrupt_enable_0) = 0x00;
3070     T(interrupt_enable_2) = 0x00;
3071 
3072     // initialize the last bmi160 time to be ULONG_MAX, so that we know it's
3073     // not valid yet.
3074     T(last_sensortime) = 0;
3075     T(frame_sensortime) = ULONG_LONG_MAX;
3076 
3077     // it's ok to leave interrupt open all the time.
3078     enableInterrupt(T(Int1), &T(Isr1));
3079     enableInterrupt(T(Int2), &T(Isr2));
3080 
3081     return true;
3082 }
3083 
endTask(void)3084 static void endTask(void)
3085 {
3086     TDECL();
3087 #ifdef MAG_SLAVE_PRESENT
3088     destroy_mag_cal(&mTask.moc);
3089 #endif
3090     slabAllocatorDestroy(T(mDataSlab));
3091     spiMasterRelease(mTask.spiDev);
3092 
3093     // disable and release interrupt.
3094     disableInterrupt(mTask.Int1, &mTask.Isr1);
3095     disableInterrupt(mTask.Int2, &mTask.Isr2);
3096     gpioRelease(mTask.Int1);
3097     gpioRelease(mTask.Int2);
3098 }
3099 
3100 /**
3101  * Parse BMI160 FIFO frame without side effect.
3102  *
3103  * The major purpose of this function is to determine if FIFO content is received completely (start
3104  * to see invalid headers). If not, return the pointer to the beginning last incomplete frame so
3105  * additional read can use this pointer as start of read buffer.
3106  *
3107  * @param buf  buffer location
3108  * @param size size of data to be parsed
3109  *
3110  * @return NULL if the FIFO is received completely; or pointer to the beginning of last incomplete
3111  * frame for additional read.
3112  */
shallowParseFrame(uint8_t * buf,int size)3113 static uint8_t* shallowParseFrame(uint8_t * buf, int size) {
3114     int i = 0;
3115     int iLastFrame = 0; // last valid frame header index
3116 
3117     DEBUG_PRINT_IF(DBG_SHALLOW_PARSE, "spf start %p: %x %x %x\n", buf, buf[0], buf[1], buf[2]);
3118     while (size > 0) {
3119         int fh_mode, fh_param;
3120         iLastFrame = i;
3121 
3122         if (buf[i] == BMI160_FRAME_HEADER_INVALID) {
3123             // no more data
3124             DEBUG_PRINT_IF(DBG_SHALLOW_PARSE, "spf:at%d=0x80\n", iLastFrame);
3125             return NULL;
3126         } else if (buf[i] == BMI160_FRAME_HEADER_SKIP) {
3127             // artifically added nop frame header, skip
3128             DEBUG_PRINT_IF(DBG_SHALLOW_PARSE, "at %d, skip header\n", i);
3129             i++;
3130             size--;
3131             continue;
3132         }
3133 
3134         //++frame_num;
3135 
3136         fh_mode = buf[i] >> 6;
3137         fh_param = (buf[i] >> 2) & 0xf;
3138 
3139         i++;
3140         size--;
3141 
3142         if (fh_mode == 1) {
3143             // control frame.
3144             if (fh_param == 0) {
3145                 // skip frame, we skip it (1 byte)
3146                 i++;
3147                 size--;
3148                 DEBUG_PRINT_IF(DBG_SHALLOW_PARSE, "at %d, a skip frame\n", iLastFrame);
3149             } else if (fh_param == 1) {
3150                 // sensortime frame  (3 bytes)
3151                 i += 3;
3152                 size -= 3;
3153                 DEBUG_PRINT_IF(DBG_SHALLOW_PARSE, "at %d, a sensor_time frame\n", iLastFrame);
3154             } else if (fh_param == 2) {
3155                 // fifo_input config frame (1byte)
3156                 i++;
3157                 size--;
3158                 DEBUG_PRINT_IF(DBG_SHALLOW_PARSE, "at %d, a fifo cfg frame\n", iLastFrame);
3159             } else {
3160                 size = 0; // drop this batch
3161                 DEBUG_PRINT_IF(DBG_SHALLOW_PARSE, "Invalid fh_param in control frame!!\n");
3162                 // mark invalid
3163                 buf[iLastFrame] = BMI160_FRAME_HEADER_INVALID;
3164                 return NULL;
3165             }
3166         } else if (fh_mode == 2) {
3167             // regular frame, dispatch data to each sensor's own fifo
3168             if (fh_param & 4) { // have mag data
3169                 i += 8;
3170                 size -= 8;
3171             }
3172             if (fh_param & 2) { // have gyro data
3173                 i += 6;
3174                 size -= 6;
3175             }
3176             if (fh_param & 1) { // have accel data
3177                 i += 6;
3178                 size -= 6;
3179             }
3180             DEBUG_PRINT_IF(DBG_SHALLOW_PARSE, "at %d, a reg frame acc %d, gyro %d, mag %d\n",
3181                        iLastFrame, fh_param &1 ? 1:0, fh_param&2?1:0, fh_param&4?1:0);
3182         } else {
3183             size = 0; // drop this batch
3184             DEBUG_PRINT_IF(DBG_SHALLOW_PARSE, "spf: Invalid fh_mode %d!!\n", fh_mode);
3185             //mark invalid
3186             buf[iLastFrame] = BMI160_FRAME_HEADER_INVALID;
3187             return NULL;
3188         }
3189     }
3190 
3191     // there is a partial frame, return where to write next chunck of data
3192     DEBUG_PRINT_IF(DBG_SHALLOW_PARSE, "partial frame ends %p\n", buf + iLastFrame);
3193     return buf + iLastFrame;
3194 }
3195 
3196 /**
3197  * Intialize the first read of chunked SPI read sequence.
3198  *
3199  * @param index starting index of the txrxBuffer in which the data will be write into.
3200  */
chunkedReadInit_(TASK,int index,int size)3201 static void chunkedReadInit_(TASK, int index, int size) {
3202 
3203     if (GET_STATE() != SENSOR_INT_1_HANDLING) {
3204         ERROR_PRINT("chunkedReadInit in wrong mode");
3205         return;
3206     }
3207 
3208     if (T(mRegCnt)) {
3209         //chunked read are always executed as a single command. This should never happen.
3210         ERROR_PRINT("SPI queue not empty at chunkedReadInit, regcnt = %d", T(mRegCnt));
3211         // In case it did happen, we do not want to write crap to BMI160.
3212         T(mRegCnt) = 0;
3213     }
3214 
3215     T(mWbufCnt) = index;
3216     if (T(mWbufCnt) > FIFO_READ_SIZE) {
3217         // drop data to prevent bigger issue
3218         T(mWbufCnt) = 0;
3219     }
3220     T(chunkReadSize) = size > CHUNKED_READ_SIZE ? size : CHUNKED_READ_SIZE;
3221 
3222     DEBUG_PRINT_IF(DBG_CHUNKED, "crd %d>>%d\n", T(chunkReadSize), index);
3223     SPI_READ(BMI160_REG_FIFO_DATA, T(chunkReadSize), &T(dataBuffer));
3224     spiBatchTxRx(&T(mode), chunkedReadSpiCallback, _task, __FUNCTION__);
3225 }
3226 
3227 /**
3228  * Chunked SPI read callback.
3229  *
3230  * Handles the chunked read logic: issue additional read if necessary, or calls sensorSpiCallback()
3231  * if the entire FIFO is read.
3232  *
3233  * @param cookie extra data
3234  * @param err    error
3235  *
3236  * @see sensorSpiCallback()
3237  */
chunkedReadSpiCallback(void * cookie,int err)3238 static void chunkedReadSpiCallback(void *cookie, int err) {
3239     TASK = (_Task*) cookie;
3240 
3241     T(spiInUse) = false;
3242     DEBUG_PRINT_IF(err !=0 || GET_STATE() != SENSOR_INT_1_HANDLING,
3243             "crcb,e:%d,s:%d", err, (int)GET_STATE());
3244     bool int1 = gpioGet(T(Int1));
3245     if (err != 0) {
3246         DEBUG_PRINT_IF(DBG_CHUNKED, "crd retry");
3247         // read full fifo length to be safe
3248         chunkedReadInit(0, FIFO_READ_SIZE);
3249         return;
3250     }
3251 
3252     *T(dataBuffer) = BMI160_FRAME_HEADER_SKIP; // fill the 0x00/0xff hole at the first byte
3253     uint8_t* end = shallowParseFrame(T(dataBuffer), T(chunkReadSize));
3254 
3255     if (end == NULL) {
3256         // if interrupt is still set after read for some reason, set the pending interrupt
3257         // to handle it immediately after data is handled.
3258         T(pending_int[0]) = T(pending_int[0]) || int1;
3259 
3260         // recover the buffer and valid data size to make it looks like a single read so that
3261         // real frame parse works properly
3262         T(dataBuffer) = T(txrxBuffer);
3263         T(xferCnt) = FIFO_READ_SIZE;
3264         sensorSpiCallback(cookie, err);
3265     } else {
3266         DEBUG_PRINT_IF(DBG_CHUNKED, "crd cont");
3267         chunkedReadInit(end - T(txrxBuffer), CHUNKED_READ_SIZE);
3268     }
3269 }
3270 
3271 /**
3272  * Initiate read of sensor fifo.
3273  *
3274  * If task is in idle state, init chunked FIFO read; otherwise, submit an interrupt message or mark
3275  * the read pending depending if it is called in interrupt context.
3276  *
3277  * @param isInterruptContext true if called from interrupt context; false otherwise.
3278  *
3279  */
initiateFifoRead_(TASK,bool isInterruptContext)3280 static void initiateFifoRead_(TASK, bool isInterruptContext) {
3281     if (trySwitchState(SENSOR_INT_1_HANDLING)) {
3282         // estimate first read size to be watermark + 1 more sample + some extra
3283         int firstReadSize = T(watermark) * 4 + 32; // 1+6+6+8+1+3 + extra = 25 + extra = 32
3284         if (firstReadSize < CHUNKED_READ_SIZE) {
3285             firstReadSize = CHUNKED_READ_SIZE;
3286         }
3287         chunkedReadInit(0, firstReadSize);
3288     } else {
3289         if (isInterruptContext) {
3290             // called from interrupt context, queue event
3291             osEnqueuePrivateEvt(EVT_SENSOR_INTERRUPT_1, _task, NULL, T(tid));
3292         } else {
3293             // non-interrupt context, set pending flag, so next time it will be picked up after
3294             // switching back to idle.
3295             // Note: even if we are still in SENSOR_INT_1_HANDLING, the SPI may already finished and
3296             // we need to issue another SPI read to get the latest status.
3297             T(pending_int[0]) = true;
3298         }
3299     }
3300 }
3301 
3302 /**
3303  * Calculate fifo size using normalized input.
3304  *
3305  * @param iPeriod normalized period vector
3306  * @param iLatency normalized latency vector
3307  * @param factor vector that contains size factor for each sensor
3308  * @param n size of the vectors
3309  *
3310  * @return max size of FIFO to guarantee latency requirements of all sensors or SIZE_MAX if no
3311  * sensor is active.
3312  */
calcFifoSize(const int * iPeriod,const int * iLatency,const int * factor,int n)3313 static size_t calcFifoSize(const int* iPeriod, const int* iLatency, const int* factor, int n) {
3314     int i;
3315 
3316     int minLatency = INT_MAX;
3317     for (i = 0; i < n; i++) {
3318         if (iLatency[i] > 0) {
3319             minLatency = iLatency[i] < minLatency ? iLatency[i] : minLatency;
3320         }
3321     }
3322     DEBUG_PRINT_IF(DBG_WM_CALC, "cfifo: min latency %d unit", minLatency);
3323 
3324     bool anyActive = false;
3325     size_t s = 0;
3326     size_t head = 0;
3327     for (i = 0; i < n; i++) {
3328         if (iPeriod[i] > 0) {
3329             anyActive = true;
3330             size_t t =  minLatency / iPeriod[i];
3331             head = t > head ? t : head;
3332             s += t * factor[i];
3333             DEBUG_PRINT_IF(DBG_WM_CALC, "cfifo: %d, s+= %d*%d, head = %d", i, t, factor[i], head);
3334         }
3335     }
3336 
3337     return anyActive ? head + s : SIZE_MAX;
3338 }
3339 
3340 /**
3341  * Calculate the watermark setting from sensor registration information
3342  *
3343  * It is assumed  that all sensor period share a common denominator (true for BMI160) and the
3344  * latency of sensor will be lower bounded by its sampling period.
3345  *
3346  * @return watermark register setting
3347  */
calcWatermark2_(TASK)3348 static uint8_t calcWatermark2_(TASK) {
3349     int period[] = {-1, -1, -1};
3350     int latency[] = {-1, -1, -1};
3351     const int factor[] = {6, 6, 8};
3352     int i;
3353 
3354     for (i = ACC; i <= MAG; ++i) {
3355         if (T(sensors[i]).configed) {
3356             period[i - ACC] = SENSOR_HZ((float)WATERMARK_MAX_SENSOR_RATE) / T(sensors[i]).rate;
3357             latency[i - ACC] = U64_DIV_BY_U64_CONSTANT(
3358                     T(sensors[i]).latency + WATERMARK_TIME_UNIT_NS/2, WATERMARK_TIME_UNIT_NS);
3359             DEBUG_PRINT_IF(DBG_WM_CALC, "cwm2: f %dHz, l %dus => T %d unit, L %d unit",
3360                     (int) T(sensors[i]).rate/1024,
3361                     (int) U64_DIV_BY_U64_CONSTANT(T(sensors[i]).latency, 1000),
3362                     period[i-ACC], latency[i-ACC]);
3363         }
3364     }
3365 
3366 
3367     size_t watermark = calcFifoSize(period, latency, factor, MAG - ACC + 1) / 4;
3368     DEBUG_PRINT_IF(DBG_WM_CALC, "cwm2: wm = %d", watermark);
3369     watermark = watermark < WATERMARK_MIN ? WATERMARK_MIN : watermark;
3370     watermark = watermark > WATERMARK_MAX ? WATERMARK_MAX : watermark;
3371 
3372     return watermark;
3373 }
3374 
3375 INTERNAL_APP_INIT(BMI160_APP_ID, 1, startTask, endTask, handleEvent);
3376 
3377 
3378