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