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