Bosch Sensortec Community

    Showing results for 
    Search instead for 
    Did you mean: 

    Can not read from bmi160's fifo

    Can not read from bmi160's fifo

    New Poster


    We have design a custom board that can read single frame from bmi160 without problems,

    Now we want to read more imu data, so we modify the bmi160 and mcu setting.

    Using WM trigger to triiger bmi160_get_fifo_data() function, but i got an error return 11(Hex).

    which is #define BMI160_FOC_FAILURE INT8_C(-11), but the error can't be fix by calling rslt = start_foc(&s_spi_bmi160_sensor);

    i read the datasheet and the repo from github: Project/ble_app_uart/main.c 

    and compare the setting with these github repo with my code, still can't figure out why and how to fix it.

    here is snip from my code: 

    Please help me to fix the problem, thanks.




    8 REPLIES 8

    Community Moderator
    Community Moderator

    Hello TTN,

    1.Did you refer BMI160 driver code in github ""?

    2.For FIFO reading way: poll mode or FIFO watermark interrupt?

    Hi Robin,

    1.Did you refer BMI160 driver code in github ""?

    Yes, i use the lastest version of bmi160 driver.

    I remember there were examples of fifo settings.

    But now there are 3 examples, so  the code of fifo setting i refer, is from other github repo.


    2.For FIFO reading way: poll mode or FIFO watermark interrupt?

    I want to use FIFO watermark interrupt mode. 

    The fifo setting function refer to below snap, more detail can refer: 



    static void Spi_sensor_fifo_init( void ) {
        /* You may assign a chip select identifier to be handled later */ = 0 ;
        s_spi_bmi160_sensor.interface = BMI160_SPI_INTF ; = Spi_read_transfer ;
        s_spi_bmi160_sensor.write = Spi_write_transfer ;
        s_spi_bmi160_sensor.delay_ms = Spi_delay_ms ;
        int8_t rslt = BMI160_OK ;
        rslt = bmi160_init( &s_spi_bmi160_sensor ) ;
        if ( rslt == 0 ) {
                SEGGER_RTT_printf( 0,"Get bmi160 data success ! \n", rslt ) ; 	
        } // if
                SEGGER_RTT_printf( 0,"Error : Get bmi160 data fail ! \n", rslt ) ; 
        /* After the above function call, accel_cfg and gyro_cfg parameters in the device 
        structure are set with default values, found in the datasheet of the sensor */
        rslt = BMI160_OK ;
        /* Select the Output data rate, range of accelerometer sensor */
        s_spi_bmi160_sensor.accel_cfg.odr = BMI160_ACCEL_ODR_50HZ ;
        s_spi_bmi160_sensor.accel_cfg.range = BMI160_ACCEL_RANGE_2G ; = BMI160_ACCEL_BW_OSR4_AVG1 ;
        /* Select the power mode of accelerometer sensor */
        s_spi_bmi160_sensor.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE ;
        /* Select the Output data rate, range of Gyroscope sensor */
        s_spi_bmi160_sensor.gyro_cfg.odr = BMI160_GYRO_ODR_25HZ ;
        s_spi_bmi160_sensor.gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS ; = BMI160_GYRO_BW_NORMAL_MODE ;
        /* Select the power mode of Gyroscope sensor */
        s_spi_bmi160_sensor.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE ;
        /* Set the sensor configuration */
        rslt = bmi160_set_sens_conf( &s_spi_bmi160_sensor ) ;
        /* Select the power mode */
        s_spi_bmi160_sensor.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE ;
        s_spi_bmi160_sensor.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE ;  
        /*  Set the Power mode  */
        rslt = bmi160_set_power_mode( &s_spi_bmi160_sensor ) ;
        nrf_delay_ms( 10 ) ; // delay_10ms
        rslt = start_foc(&s_spi_bmi160_sensor);		
        SEGGER_RTT_printf(0,"foc rslt=%d\n",rslt);
        struct bmi160_offsets sensor_offset;
        rslt = bmi160_get_offsets(&sensor_offset,&s_spi_bmi160_sensor);	//
        SEGGER_RTT_printf(0,"calibration value: ax=%d,ay=%d,az=%d,gx=%d,gy=%d,gz=%d\n",sensor_offset.off_acc_x,sensor_offset.off_acc_y,sensor_offset.off_acc_z,sensor_offset.off_gyro_x,sensor_offset.off_gyro_y,sensor_offset.off_gyro_z);
        /* Link the FIFO memory location */ = FIFO_BUFF;
        fifo_frame.length = FIFO_LEN;
        s_spi_bmi160_sensor.fifo = &fifo_frame;
        /*Enable fifo*/
        uint8_t fifo_config = BMI160_FIFO_HEADER | BMI160_FIFO_ACCEL | BMI160_FIFO_GYRO;
        rslt = bmi160_set_fifo_config(fifo_config, BMI160_ENABLE, &s_spi_bmi160_sensor);
        if (rslt != BMI160_OK)
            SEGGER_RTT_printf(0,"BMI160 failed FIFO setting");
        // instance for interrupt settings
        struct bmi160_int_settg int_config;
        int_config.int_channel = BMI160_INT_CHANNEL_1;
        int_config.int_type = BMI160_ACC_GYRO_FIFO_WATERMARK_INT; // choose FIFO watermark IRQ (fires when a certain level of fullness is reached)
        rslt = bmi160_set_fifo_wm((uint8_t) (FIFO_LEN - 20), &s_spi_bmi160_sensor);
        if (rslt != BMI160_OK)
            SEGGER_RTT_printf(0,"BMI160 failed FIFO wm setting");
        int_config.int_pin_settg.output_en = BMI160_ENABLE; // enable output via INT_1 and INT_2 on BMI160
        int_config.int_pin_settg.output_mode = BMI160_DISABLE; // push-pull mode
        int_config.int_pin_settg.output_type = BMI160_ENABLE; // active high
        int_config.int_pin_settg.edge_ctrl = BMI160_ENABLE; // edge-triggered
        int_config.int_pin_settg.input_en = BMI160_DISABLE; // don't act as input
        int_config.int_pin_settg.latch_dur = BMI160_LATCH_DUR_NONE; // non-latched output (no need to clear manually)
        int_config.fifo_WTM_int_en = BMI160_ENABLE; // enable FIFO WM IRQ
        rslt = bmi160_set_int_config(&int_config, &s_spi_bmi160_sensor);
        if (rslt != BMI160_OK)
            SEGGER_RTT_printf(0,"BMI160 failed IRQ config,rslt =%d\n",rslt);
    } // Spi_sensor_fifo_init()




    New Poster

    Hi Robin,

    I simplify the project in to poll mode, and the mcu can read the fifo now.😅

    Still turning the fifo get function but it works.

    So the problem maybe in the wm interupt setting.



    New Poster

    Hi Robin,

    According to the doucument in the Knowledge-base  BMI160-FIFO-Advanced-Usage .

    I change the fifo into poll mode to check the fifo functions,

    Now i can't understand the sensortime of the data, the Data in the is the snap below.

    Data in the


    According to the


    fifo_time_en defines if sensortime frame in FIFO is enabled. When fifo_time_en = 0, no sensortime frame will be returned. When fifo_time_en = 1, a sensortime frame will be returned after the last valid frame when the number of data that are read is greater than that of valid frames in the FIFO. When reading from FIFO with burst read, the AP/MCU should read more than the bytes (FIFO byte counter + 4 bytes). These four bytes contain one frame header that indicates the Sensortime frame and 3 bytes for the real sensor time.    FIFO data register (0x24)


    in this case  is the sensortime can be repesent as  0xff(header)+0x002001(sensortime)?

    Is this sensortime is the sensortime of the last frame? or the first frame?

    If the answer is yes, can i reverse the frame[N-1]'s sensortime by minusing 0.01s(if the sensor both set in 100Hz)?

    which is 8193(0x002001)*0.39us-0.01s=0.319527-0.01=0.318527 (?

    here is snip from my code: