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