09-08-2021 03:27 PM - edited 09-09-2021 04:35 AM
Hi,
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:
https://github.com/piMagpie/IoT/blob/2fd729ea7dd2e3afe2a169f9798d4ef98656b70b/last Project/ble_app_uart/main.c
https://community.bosch-sensortec.com/t5/Knowledge-base/BMI160-FIFO-Advanced-Usage/ta-p/8957
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:
https://gist.github.com/ttn115/82ab37c0e0acf89587ca60dbee63d51a
Please help me to fix the problem, thanks.
Solved! Go to Solution.
09-08-2021 04:46 PM
Hello TTN,
1.Did you refer BMI160 driver code in github "https://github.com/BoschSensortec/BMI160_driver"?
2.For FIFO reading way: poll mode or FIFO watermark interrupt?
09-09-2021 04:29 AM - edited 09-09-2021 04:33 AM
Hi Robin,
1.Did you refer BMI160 driver code in github "https://github.com/BoschSensortec/BMI160_driver"?
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: https://gist.github.com/ttn115/82ab37c0e0acf89587ca60dbee63d51a
static void Spi_sensor_fifo_init( void ) {
/* You may assign a chip select identifier to be handled later */
s_spi_bmi160_sensor.id = 0 ;
s_spi_bmi160_sensor.interface = BMI160_SPI_INTF ;
s_spi_bmi160_sensor.read = 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
else
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 ;
s_spi_bmi160_sensor.accel_cfg.bw = 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 ;
s_spi_bmi160_sensor.gyro_cfg.bw = 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);
nrf_delay_ms(200);
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_frame.data = 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()
09-09-2021 07:10 AM
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.
09-09-2021 01:27 PM - edited 09-09-2021 01:33 PM
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 fifo_frame.data is the snap below.
Data in the fifo_frame.data
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:
https://gist.github.com/ttn115/82ab37c0e0acf89587ca60dbee63d51a