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