Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 
    SOLVED

    BMI160 FIFO readings are not updating data

    BMI160 FIFO readings are not updating data

    tmeeusen
    Member

    Dear, 

    We are integrating your BMI Bosch driver https://github.com/BoschSensortec/BMI160_driver  in our code.
    We have rewritten the FIFO example in to a FIFO watermark interrupt handler.
    We are able to get the watermark interrupt trigger, but are not able to see the FIFO accelero nor gyro data updated as you can see in the following snippet: 

    <info> app: Buffer FULL
    <info> app: 
     REQUESTED GYRO DATA FRAMES : 33
     
    <info> app: 
     AVAILABLE GYRO DATA FRAMES : 33
     
    <info> app: 
    GYRO X-DATA : -29120 	 Y-DATA : 8192 	 Z-DATA : -1138
    <info> app: SKIPPED FRAME COUNT : 0
    <info> app: 
     REQUESTED ACCEL DATA FRAMES : 33
     
    <info> app: 
     AVAILABLE ACCEL DATA FRAMES : 33
     
    <info> app: 
    ACCEL X-DATA : 8195 	 Y-DATA : -29120 	 Z-DATA : 8192
    <info> app: SKIPPED FRAME COUNT : 0
    <info> app: Buffer FULL
    <info> app: 
     REQUESTED GYRO DATA FRAMES : 33
     
    <info> app: 
     AVAILABLE GYRO DATA FRAMES : 33
     
    <info> app: 
    GYRO X-DATA : -29120 	 Y-DATA : 8192 	 Z-DATA : -1138
    <info> app: SKIPPED FRAME COUNT : 0
    <info> app: 
     REQUESTED ACCEL DATA FRAMES : 33
     
    <info> app: 
     AVAILABLE ACCEL DATA FRAMES : 33
     
    <info> app: 
    ACCEL X-DATA : 8195 	 Y-DATA : -29120 	 Z-DATA : 8192


    Do you have an idea what could possibly is going on? We are able to read correct data without the usage of the FIFO (with the function bmi160_get_sensor_data()).

    Here is some code below for your reference. 
    Within our main code, we do the configuration of the sensor BMI160 and its FIFO in the following order: 

        ////Init and dev IMU
        inertial_sensor_init();
        inertial_sensor_self_test();
        inertial_sensor_config();
        inertial_sensor_fifo_config(&inertial_sensor);
        inertial_sensor_fifo_interrupt_config(&inertial_sensor);    
        inertial_sensor_interrupt_init();

     
    The driver inertial_sensor is an abstraction layer that integrates your BOSCH driver. 

    The driver inertial_sensor has the following code: 

    void inertial_sensor_init(void){
    
      inertial_sensor.id = BMI160_I2C_ADDR;
      inertial_sensor.interface = BMI160_I2C_INTF;
      inertial_sensor.read = &inertial_sensor_i2c_read;     
      inertial_sensor.write = &inertial_sensor_i2c_write;  
      inertial_sensor.delay_ms = &inertial_sensor_delay_ms; 
      
      rslt = bmi160_init(&inertial_sensor);
      if(rslt == BMI160_OK){
        NRF_LOG_INFO("Inertial sensor initialized.");
      } else {
        NRF_LOG_INFO("Inertial sensor not initialized.");
      }
      /* After the above function call, accel and gyro parameters in the device structure 
      are set with default values, found in the datasheet of the sensor */
    }
    
    void inertial_sensor_config(void){
      
      /*Configuring accel and gyro sensors in normal mode */
      /* Select the Output data rate, range of accelerometer sensor */
      inertial_sensor.accel_cfg.odr = BMI160_ACCEL_ODR_50HZ; //BMI160_ACCEL_ODR_1600HZ
      inertial_sensor.accel_cfg.range = BMI160_ACCEL_RANGE_4G; //To avoid overshoot when going over + or - 1G. //BMI160_ACCEL_RANGE_2G;
      inertial_sensor.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;//No oversampling --> equidistant points over time, just normal mode. See p20 datasheet. AVG = 4 means 4 averaging cycles
    
      /* Select the power mode of accelerometer sensor */
      inertial_sensor.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
    
      /* Select the Output data rate, range of Gyroscope sensor */
      inertial_sensor.gyro_cfg.odr = BMI160_GYRO_ODR_50HZ; //BMI160_GYRO_ODR_3200HZ;
      inertial_sensor.gyro_cfg.range = BMI160_GYRO_RANGE_500_DPS; //From magic numbers, 500 DPS seems to be okay. //BMI160_GYRO_RANGE_2000_DPS;
      inertial_sensor.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;//No oversampling --> equidistant points over time, just normal mode. See p21 datasheet
    
      /* Select the power mode of Gyroscope sensor */
      inertial_sensor.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE; 
    
      /* Set the sensor configuration */
      rslt = bmi160_set_sens_conf(&inertial_sensor);
      if(rslt == BMI160_OK){
        NRF_LOG_INFO("Inertial sensor configured.");
      } else {
        NRF_LOG_INFO("Inertial sensor not configured.");
      }
    
    }
    void inertial_sensor_fifo_config(struct bmi160_dev *dev)
    {
    	
            int8_t rslt = 0;
            
             /* Disable other FIFO settings */
    	rslt = bmi160_set_fifo_config(BMI160_FIFO_CONFIG_1_MASK , BMI160_DISABLE, dev); 
    
            /* 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_HEADER, BMI160_DISABLE, dev);
    	rslt = bmi160_set_fifo_config(BMI160_FIFO_GYRO | BMI160_FIFO_ACCEL ,
    					BMI160_ENABLE, dev);
    
            /* Set the FIFO watermark level for the interrupt */
            rslt = bmi160_set_fifo_wm(97, dev);  // Note the watermark is in units of words (4 bytes) so 141
                                   // * 4 is 564 bytes which is equal to the FIFO_BUFFER_LEN_BYTES
            return rslt;
    
    
    }
    
    void inertial_sensor_fifo_interrupt_config(struct bmi160_dev *dev)
    {       
            int8_t rslt;
            struct bmi160_int_settg int_config;
    
            /* Select the Interrupt channel/pin */
            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 //BMI160_ACC_GYRO_FIFO_FULL_INT; 
            
            /* 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_DISABLE;// Choosing active low 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
            
            /* */
            int_config.fifo_full_int_en = 0; // 1- Enable, 0- Disable the full interrupt
            int_config.fifo_wtm_int_en = 1;  // 1- Enable, 0- Disable the watermark interrupt
    
            /*Configure the sensor's interrupt settings */
            rslt = bmi160_set_int_config(&int_config, dev);
    
            return rslt;
    }
    
    void inertial_sensor_fifo_read(struct bmi160_dev *dev){
            int8_t rslt = 0;
    
    	/* Declare memory to store the raw FIFO buffer information */
    	//uint8_t fifo_buff[FIFO_BUFFER_LEN_BYTES]; //220
    	
    	/* Modify the FIFO buffer instance and link to the device instance */
    	//struct bmi160_fifo_frame fifo_frame;
    	//fifo_frame.data = fifo_buff;
    	//fifo_frame.length = FIFO_BUFFER_LEN_BYTES; //max window size algo is 235 samples ==>235*12bytes=2820 ==> 5 fifo_frame burst and the window size is filled. 
    	//dev->fifo = &fifo_frame;
    
    	uint16_t index = 0;
    	
    	/* Declare instances of the sensor data structure to store the parsed FIFO data */
            struct bmi160_sensor_data gyro_data[33]; 
            struct bmi160_sensor_data accel_data[33];
            uint8_t gyro_frames_req = 33;   // fifo_frame_length or size (bytes) / #bytes per frame(=6*gyro bytes+6*accel bytes) ==> 564/12 = 47 data frames
            uint8_t accel_frames_req = 33;  // fifo_frame_length or size (bytes) / #bytes per frame(=6*gyro bytes+6*accel bytes) ==> 564/12 = 47 data frames
    
            
    	uint8_t gyro_index;
            uint8_t accel_index;
    
            //NRF_LOG_INFO("\n USER REQUESTED FIFO LENGTH : %d\n",dev->fifo->length);
            rslt = bmi160_get_fifo_data(dev);
    
            if (rslt == BMI160_OK) {
               // NRF_LOG_INFO("\n AVAILABLE FIFO LENGTH : %d\n",dev->fifo->length);
                /* Print the raw FIFO data */
                //for (index = 0; index < dev->fifo->length; index++) {
                //	NRF_LOG_INFO("\n FIFO DATA INDEX[%d] = %d", index,
                //		dev->fifo->data[index]);
                //    nrf_delay_ms(1); //allow printing
                //}
                NRF_LOG_INFO("\n REQUESTED GYRO DATA FRAMES : %d\n ",gyro_frames_req);
                rslt = bmi160_extract_gyro(&gyro_data, &gyro_frames_req, dev);
    
                if (rslt == BMI160_OK) {
                        //nrf_delay_ms(1); //allow printing
                        NRF_LOG_INFO("\n AVAILABLE GYRO DATA FRAMES : %d\n ",gyro_frames_req);
                        
                        /* Print the parsed gyro data from the FIFO buffer */
                        //for (gyro_index = 0 ; gyro_index <gyro_frames_req ; gyro_index++) {
                        //	NRF_LOG_INFO("\nFIFO GYRO FRAME[%d]",gyro_index);
                       	//NRF_LOG_INFO("\nGYRO X-DATA : %d \t Y-DATA : %d \t Z-DATA : %d"
                       	//	,gyro_data[gyro_index].x ,gyro_data[gyro_index].y
                        //		,gyro_data[gyro_index].z);
                        //    //nrf_delay_ms(1); //allow printing
                        //}
                        /*Print last sample as speed is too high*/
                        NRF_LOG_INFO("\nGYRO X-DATA : %d \t Y-DATA : %d \t Z-DATA : %d"
                                          ,gyro_data[32].x ,gyro_data[32].y
                                          ,gyro_data[32].z);
                        /* Print the special FIFO frame data like sensortime */
                        //nrf_delay_ms(2); //allow printing
                        //NRF_LOG_INFO("\n SENSOR TIME DATA : %d \n",dev->fifo->sensor_time);
                        NRF_LOG_INFO("SKIPPED FRAME COUNT : %d",dev->fifo->skipped_frame_count);                                
                } else {
                        NRF_LOG_INFO("\n Gyro data extraction failed");
                }
                /* Parse the FIFO data to extract accel data from the FIFO buffer */
                //nrf_delay_ms(1); //allow printing
                NRF_LOG_INFO("\n REQUESTED ACCEL DATA FRAMES : %d\n ",accel_frames_req);
                rslt = bmi160_extract_accel(&accel_data, &accel_frames_req, dev);
    
                if (rslt == BMI160_OK) {
                        //nrf_delay_ms(1); //allow printing
                        NRF_LOG_INFO("\n AVAILABLE ACCEL DATA FRAMES : %d\n ",accel_frames_req);
                        
                        /* Print the parsed accel data from the FIFO buffer */
                        //for (accel_index = 0; accel_index < accel_frames_req; accel_index++) {
                        //	printf("\nFIFO ACCEL FRAME[%d]",accel_index);
                        //	printf("\nACCEL X-DATA : %d \t Y-DATA : %d \t Z-DATA : %d"
                        //		,accel_data[accel_index].x ,accel_data[accel_index].y
                        //		,accel_data[accel_index].z);
                        //    //nrf_delay_ms(1); //allow printing
                        //}
                        /*Print last sample as speed is too high*/
                        NRF_LOG_INFO("\nACCEL X-DATA : %d \t Y-DATA : %d \t Z-DATA : %d"
                        		,accel_data[32].x ,accel_data[32].y
                        		,accel_data[32].z);
                        /* Print the special FIFO frame data like sensortime */
                        //nrf_delay_ms(2);//allow printing
                        //NRF_LOG_INFO("\n SENSOR TIME DATA : %d \n",dev->fifo->sensor_time);
                        NRF_LOG_INFO("SKIPPED FRAME COUNT : %d",dev->fifo->skipped_frame_count);                                
                } else {
                        NRF_LOG_INFO("\n Accel data extraction failed");
                }
          } else {
                  NRF_LOG_INFO("\n Reading FIFO data failed");
    
          }
    
          return rslt;
    
        //bmi160_set_fifo_flush(dev);
    
    }

     

    void inertial_sensor_interrupt_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
        uint8_t rslt;
        NRF_LOG_INFO("Buffer FULL");
        nrf_gpio_pin_toggle(TOGGLE_PIN);
        struct bmi160_int_settg int_config;
    
        uint8_t data = 0x00;
        rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, &inertial_sensor);  // disable the WM interrupt
        
        /* Read data from the sensor's FIFO and store it the FIFO buffer,"fifo_buff" */
        inertial_sensor_fifo_read(&inertial_sensor);
    
    
        data = BMI160_FIFO_WATERMARK_INT_EN_MASK; //BMI160_FIFO_FULL_INT_EN_MASK;  //BMI160_FIFO_WATERMARK_INT_EN_MASK;
        rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1,  &inertial_sensor);  // enable the WM
        nrf_gpio_pin_clear(TOGGLE_PIN);
    }

    Thanks in advance for your answer. 

    Kind regards, 
    Tom

    5 REPLIES 5

    Hi, 

    Thank you for your message,

    Apparently we ran in to the issue that the i2c burst read could not handle transfers larger than 255 bytes. 
    I would suggest to add this requirement within the Bosch example driver. 
    Now we are able to read out the FIFO data. 

    Thanks for the support.

    Kind regards,
    Tom

    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