I have a BMI160 configured to provide the FIFO Watermark interrupt and high-g wakeup interrupt on channels 1 and 2 respectively. When the device starts I see the FIFO watermark fire and it's gathering approximately 40 frames. After the high-g interrupt fires then every subsiquent FIFO high watermark interrupt only gathers 4 frames of data. Why is this occuring and what can be done so the number of frames gathered goes back to 40. I want to maximumize the time between high watermark interrupts to reduce load on my system. I have tried adusting the number of frames requested and flushing the FIFO this doesn't seem to make a difference. Here is the configuration (note I2C result checks have been removed for clarity) static void configureSensorDefaults(struct bmi160_dev* dev) {
/* Select the Output data rate, range of accelerometer sensor */
dev->accel_cfg.odr = BMI160_ACCEL_ODR_200HZ;
dev->accel_cfg.range = BMI160_ACCEL_RANGE_4G;
dev->accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
/* Select the power mode of accelerometer sensor */
dev->accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
/* Select the Output data rate, range of Gyroscope sensor */
dev->gyro_cfg.odr = BMI160_GYRO_ODR_100HZ;
dev->gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS;
dev->gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
/* Select the power mode of Gyroscope sensor */
dev->gyro_cfg.power = BMI160_GYRO_SUSPEND_MODE;
int8_t result = bmi160_set_sens_conf(dev);
}
static void configureAccelFifo(struct bmi160_dev* dev) {
int8_t rslt = 0;
/* Modify the FIFO buffer instance and link to the device instance */
fifo_frame.data = fifo_buff;
fifo_frame.length = FIFO_BUFFER_LEN_BYTES;
dev->fifo = &fifo_frame;
/* Configure the sensor's FIFO settings */
rslt = bmi160_set_fifo_config(BMI160_FIFO_ACCEL, BMI160_ENABLE, dev);
/* Set the FIFO watermark level for the interrupt */
rslt = bmi160_set_fifo_wm(69, dev); // Note the watermark is in units of words (4 bytes) so 69
// * 4 is 276
}
static void configureSensorInterrupts(struct bmi160_dev* dev) {
int8_t result;
struct bmi160_int_settg int_config;
int_config.int_channel = BMI160_INT_CHANNEL_1; // Interrupt channel/pin 1
/* Select the Interrupt type */
int_config.int_type = BMI160_ACC_GYRO_FIFO_WATERMARK_INT; // Choosing watermark interrupt
/* Select the interrupt channel/pin settings */
int_config.int_pin_settg.output_en =
BMI160_ENABLE; // Enabling interrupt pins to act as output pin
int_config.int_pin_settg.output_mode =
BMI160_DISABLE; // Choosing push-pull mode for interrupt pin
int_config.int_pin_settg.output_type = BMI160_ENABLE; // Choosing active high output
int_config.int_pin_settg.edge_ctrl = BMI160_ENABLE; // Choosing edge triggered output
int_config.int_pin_settg.input_en = BMI160_DISABLE; // Disabling interrupt pin to act as input
int_config.int_pin_settg.latch_dur = BMI160_LATCH_DUR_NONE; // non-latched output
/* Select the FIFO interrupt parameters */
int_config.fifo_WTM_int_en = BMI160_ENABLE; // 1- Enable, 0- Disable the watermark interrupt
result = bmi160_set_int_config(&int_config, dev);
/* Select the Interrupt channel/pin */
int_config.int_channel = BMI160_INT_CHANNEL_2; // Interrupt channel/pin 2
/* Select the Interrupt type */
int_config.int_type = BMI160_ACC_HIGH_G_INT; // Choosing High-g interrupt
/* Select the interrupt channel/pin settings */
int_config.int_pin_settg.output_en =
BMI160_ENABLE; // Enabling interrupt pins to act as output pin
int_config.int_pin_settg.output_mode =
BMI160_DISABLE; // Choosing push-pull mode for interrupt pin
int_config.int_pin_settg.output_type = BMI160_ENABLE; // Choosing active high output
int_config.int_pin_settg.edge_ctrl = BMI160_ENABLE; // Choosing edge triggered output
int_config.int_pin_settg.input_en = BMI160_DISABLE; // Disabling interrupt pin to act as
int_config.int_pin_settg.latch_dur = BMI160_LATCH_DUR_NONE; // non-latched output
int_config.int_type_cfg.acc_high_g_int.high_g_x = BMI160_ENABLE;
int_config.int_type_cfg.acc_high_g_int.high_g_y = BMI160_ENABLE;
int_config.int_type_cfg.acc_high_g_int.high_g_z = BMI160_ENABLE;
int_config.int_type_cfg.acc_high_g_int.high_data_src=BMI160_DISABLE;
int_config.int_type_cfg.acc_high_g_int.high_thres = 64; // 1 g @ (value * 15.63mg for 4 g range)
int_config.int_type_cfg.acc_high_g_int.high_dur = 7; // 20 ms [(value + 1) * 2.5ms]
result = bmi160_set_int_config(&int_config, dev);
} Interrupt Handler: void interruptHandler(bool val, void* ctx) {
struct bmi160_dev* dev = ctx;
union bmi160_int_status int_status;
int8_t rslt;
rslt = bmi160_get_int_status(BMI160_INT_STATUS_1, &int_status, dev);
if (int_status.bit.fwm == 1) {
printf("FIFO high water mark interrupt");
}
if (int_status.bit.high_g == 1) {
printf("High-G interrupt");
}
uint8_t data = 0x00;
rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); // disable the WM interrupt
/* Declare instances of the sensor data structure to store the parsed FIFO data */
struct bmi160_sensor_data accel_data[66]; // 896 bytes / ~7bytes per frame ~ 128 data frames
uint8_t accel_frames_req = 66;
uint8_t accel_index;
/* Read data from the sensor's FIFO and store it the FIFO buffer,"fifo_buff" */
LE_DEBUG("USER REQUESTED FIFO LENGTH : %d", dev->fifo->length);
rslt = bmi160_get_fifo_data(dev);
if (rslt == BMI160_OK) {
printf("AVAILABLE FIFO LENGTH : %d", dev->fifo->length);
/* Parse the FIFO data to extract gyro data from the FIFO buffer */
printf("REQUESTED ACCEL DATA FRAMES : %d", accel_frames_req);
rslt = bmi160_extract_accel(accel_data, &accel_frames_req, dev);
if (rslt == BMI160_OK) {
printf("AVAILABLE ACCEL DATA FRAMES : %d", accel_frames_req);
/* Print the parsed gyro data from the FIFO buffer */
for (accel_index = 0; accel_index < accel_frames_req; accel_index++) {
printf("FIFO FRM [%d]: %d, %d, %d", accel_index, accel_data[accel_index].x,
accel_data[accel_index].y, accel_data[accel_index].z);
}
}
}
data = (BMI160_FIFO_WATERMARK_INT_EN_MASK | BMI160_HIGH_G_Z_INT_EN_MASK |
BMI160_HIGH_G_Y_INT_EN_MASK | BMI160_HIGH_G_X_INT_EN_MASK);
rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); // enable the WM, and High-G interrupts
}
... View more