Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    BMI160 High-G and FIFO Watermark Interrupt

    New Poster

    BMI160 High-G and FIFO Watermark Interrupt

    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
    
    }

     

     

    1 REPLY 1
    Community Moderator

    Re: BMI160 High-G and FIFO Watermark Interrupt

    It looks like a combination condition to trigger this case:

    1. in your interrupt handler funcion,  you will always call bmi160_get_fifo_data whatever interrupt received.

    2. in the funciton bmi160_get_fifo_data,  the API will call get_fifo_byte_counter to get the available FIFO bytes to read

    3.  if dev->fifo->Length is bigger than avaiable bytes to read, then Length will be given a small value.

    4.  Then you will read FIFO by dev->fifo->Length

    5.   In case, the bytes available is bigger than dev->fifo->Length. it will still keep the value.

    6.   when you high-g interrupt happened,  you also call bmi160_get_fifo_data.  Then only 4 frames available that time.   Then original your dev->fifo->Length is bigger than this value.  it will be reset as 4 frames bytes.

    7.    later on, for fifo water marker interrupt, even you have big bytes available, you will still read 4 frames because dev->fifo->Length  will not be given a bigger value

    8. then you keep read 4 frames afterwards. 

    BTW, you only enable accel data into FIFO, so each frame should be 6 bytes (without header).

     

    Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist