BMX160: FOC failure and magnetometer self-test failure

Using a BMX160 connected over I2C to a Raspberry Pi I have the following two issues:

1. The magnetometer self-tests fail (both the normal and advanced test). On the contrary, the accelerometer and gyroscope self-tests succeed.

2. The Fast Offset Calibration for the accelerometer and gyroscope fails, with error -11.

Could you please provide any tips as to why this might be? Thank you in advance.


Code for setting up the sensor:

    void calibrate_sensor()
    { 
        struct bmi160_foc_conf foc_conf;
        struct bmi160_offsets offsets;
        
        foc_conf.acc_off_en = BMI160_ENABLE;
        foc_conf.foc_acc_x  = BMI160_FOC_ACCEL_0G;
        foc_conf.foc_acc_y  = BMI160_FOC_ACCEL_0G;
        foc_conf.foc_acc_z  = BMI160_FOC_ACCEL_POSITIVE_G;
       
        foc_conf.foc_gyr_en = BMI160_ENABLE;
        foc_conf.gyro_off_en = BMI160_ENABLE;

//////// FIXME: This fails and returns -11 
        auto rslt = bmi160_start_foc(&foc_conf, &offsets, &m_bmi);
        handle_potential_error(rslt, "bmi160_start_fox");
    }
    
    void test_sensor()
    { 
        auto rslt = bmi160_perform_self_test(BMI160_ACCEL_ONLY, &m_bmi);
        handle_potential_error(rslt, "bmi160_perform_self_test; accelerometer");
        user_delay_ms(100);
        rslt = bmi160_perform_self_test(BMI160_GYRO_ONLY, &m_bmi);
        handle_potential_error(rslt, "bmi160_perform_self_test; gyroscope"); 
        user_delay_ms(100);
////////FIXME: Test fails
        rslt = bmm150_perform_self_test(BMM150_NORMAL_SELF_TEST, &m_bmm);
        handle_potential_error(rslt, "bmm150_perform_self_test: magnetometer");
    }



void setup_sensor()
{        
        int8_t rslt; 
        
        m_bmi.id = BMI160_I2C_ADDR;
        m_bmi.interface = BMI160_I2C_INTF;
        m_bmi.read =  i2c_read;
        m_bmi.write = i2c_write;
        m_bmi.delay_ms = user_delay_ms;
        rslt = bmi160_init(&m_bmi);
        handle_potential_error(rslt, "bmi160_init");

        /* Configure the BMM150 device structure by mapping user_aux_read and user_aux_write */
        m_bmm.read = user_aux_read;
        m_bmm.write = user_aux_write;
        m_bmm.dev_id = BMM150_DEFAULT_I2C_ADDRESS; 
        /* Ensure that sensor.aux_cfg.aux_i2c_addr = bmm150.id for proper sensor operation */
        m_bmm.delay_ms = user_delay_ms;
        m_bmm.intf = BMM150_I2C_INTF;
 
        /* Configure device structure for auxiliary sensor parameter */
        m_bmi.aux_cfg.aux_sensor_enable = BMI160_ENABLE; // auxiliary sensor enable
        m_bmi.aux_cfg.aux_i2c_addr = m_bmm.dev_id; // auxiliary sensor address
        m_bmi.aux_cfg.manual_enable = BMI160_ENABLE; // setup mode enable
        m_bmi.aux_cfg.aux_rd_burst_len = BMI160_AUX_READ_LEN_3 ;// burst read; 8 bytes
        
        /* Initialize the auxiliary sensor interface */
        rslt = bmi160_aux_init(&m_bmi);
        handle_potential_error(rslt, "bmi160_aux_init");
        /* Auxiliary sensor is enabled and can be accessed from this point */
        
        /* Configure the desired settings in auxiliary BMM150 sensor 
         * using the bmm150 APIs */
        /* Initialising the bmm150 sensor */
        rslt = bmm150_init(&m_bmm);
        handle_potential_error(rslt, "bmm150_init");
        
        /* After the above function call, accel and gyro parameters in the device structure 
          are reset with default values, found in the datasheet of the sensor */
        
        m_bmi.accel_cfg.odr     = BMI160_ACCEL_ODR_25HZ;       // Output data rate
        m_bmi.accel_cfg.range   = BMI160_ACCEL_RANGE_2G;        // Range 
        m_bmi.accel_cfg.bw      = BMI160_ACCEL_BW_NORMAL_AVG4;  // Bandwidth 
        m_bmi.accel_cfg.power   = BMI160_ACCEL_NORMAL_MODE;     // Power mode
        
        m_bmi.gyro_cfg.odr      = BMI160_GYRO_ODR_25HZ;        // Output data rate
        m_bmi.gyro_cfg.range    = BMI160_GYRO_RANGE_500_DPS;    // Range 
        m_bmi.gyro_cfg.bw       = BMI160_GYRO_BW_NORMAL_MODE;   // Bandwidth
        m_bmi.gyro_cfg.power    = BMI160_GYRO_NORMAL_MODE;      // Power mode 

        m_bmm.settings.preset_mode= BMM150_PRESETMODE_REGULAR;
        rslt = bmm150_set_presetmode(&m_bmm);
        handle_potential_error(rslt, "bmm150_set_presetmode");
 
        // It is important that the last write to the BMM150 sets the forced mode.
        // This is because the BMI160 writes the last value to the auxiliary sensor 
        // after every read 
        m_bmm.settings.pwr_mode = BMM150_FORCED_MODE;
        rslt = bmm150_set_op_mode(&m_bmm);
        handle_potential_error(rslt, "bmm150_set_op_mode");
               
        m_bmi.aux_cfg.aux_odr = BMI160_AUX_ODR_25HZ; // Aux polling frequency
        rslt = bmi160_config_aux_mode(&m_bmi);
        handle_potential_error(rslt, "bmi160_config_aux_mode");

        uint8_t aux_addr = BMM150_DATA_X_LSB; // BMM150 Mag data starts from register address 0x42 
        rslt = bmi160_set_aux_auto_mode(&aux_addr, &m_bmi);
        handle_potential_error(rslt, "bmi160_set_aux_auto_mode");
         
        rslt = bmi160_set_sens_conf(&m_bmi); // Set configuration
        handle_potential_error(rslt, "bmi160_set_sens_conf");
}

 

I initiate the tests and calibration using the following snippet:

 

       setup_sensor();
       test_sensor();
       setup_sensor();
       calibrate_sensor();

 

6 replies