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