1. Regarding the FOC failure: I checked the value of the register and it is equal to zero after the function calls fails. I stepped through the program with a debugger, and the tests passed when stepping through the program, indicating there is a timing issue. In bmi160.c:trigger_foc() I increased the max number of times that the while() loop is executed and added debugging statements. My modified library code looks like this now: static int8_t trigger_foc(struct bmi160_offsets *offset, struct bmi160_dev const *dev)
{
int8_t rslt;
uint8_t foc_status;
uint8_t cmd = BMI160_START_FOC_CMD;
uint8_t timeout = 0;
uint8_t data_array[20];
/* Start the FOC process */
rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &cmd, 1, dev);
if (rslt == BMI160_OK)
{
/* Check the FOC status*/
rslt = get_foc_status(&foc_status, dev);
fprintf(stderr, "Checking foc status: rslt=%d, foc_status=%d\n",rslt, foc_status);
if ((rslt != BMI160_OK) || (foc_status != BMI160_ENABLE))
{
while ((foc_status != BMI160_ENABLE) && (timeout < 32))
{
/* Maximum time of 250ms is given in 10
* steps of 25ms each - 250ms refer datasheet 2.9.1 */
dev->delay_ms(25);
/* Check the FOC status*/
rslt = get_foc_status(&foc_status, dev);
fprintf(stderr, "Checking foc status: rslt=%d, foc_status=%d timeout=%d ts=%lld\n",rslt, foc_status, timeout, get_timestamp_us());
timeout++;
}
if ((rslt == BMI160_OK) && (foc_status == BMI160_ENABLE))
{
/* Get offset values from sensor */
rslt = bmi160_get_offsets(offset, dev);
fprintf(stderr, "Geetting offsets rslt=%d, foc_status=%d ts=%lld\n",rslt, foc_status, get_timestamp_us());
}
else
{
/* FOC failure case */
rslt = BMI160_FOC_FAILURE;
}
}
if (rslt == BMI160_OK)
{
/* Read registers 0x04-0x17 */
rslt = bmi160_get_regs(BMI160_GYRO_DATA_ADDR, data_array, 20, dev);
fprintf(stderr, "read registers %d", rslt);
}
}
return rslt;
} With these modifications, the FOC calibration succeeds on the 20th attempt. The debug output is the following: Checking foc status: rslt=0, foc_status=0 Checking foc status: rslt=0, foc_status=0 timeout=0 ts=1594390337401459 Checking foc status: rslt=0, foc_status=0 timeout=1 ts=1594390337427819 Checking foc status: rslt=0, foc_status=0 timeout=2 ts=1594390337454171 Checking foc status: rslt=0, foc_status=0 timeout=3 ts=1594390337480592 Checking foc status: rslt=0, foc_status=0 timeout=4 ts=1594390337506955 Checking foc status: rslt=0, foc_status=0 timeout=5 ts=1594390337533314 Checking foc status: rslt=0, foc_status=0 timeout=6 ts=1594390337559649 Checking foc status: rslt=0, foc_status=0 timeout=7 ts=1594390337586005 Checking foc status: rslt=0, foc_status=0 timeout=8 ts=1594390337612341 Checking foc status: rslt=0, foc_status=0 timeout=9 ts=1594390337638703 Checking foc status: rslt=0, foc_status=0 timeout=10 ts=1594390337665110 Checking foc status: rslt=0, foc_status=0 timeout=11 ts=1594390337691551 Checking foc status: rslt=0, foc_status=0 timeout=12 ts=1594390337717919 Checking foc status: rslt=0, foc_status=0 timeout=13 ts=1594390337744286 Checking foc status: rslt=0, foc_status=0 timeout=14 ts=1594390337770655 Checking foc status: rslt=0, foc_status=0 timeout=15 ts=1594390337797020 Checking foc status: rslt=0, foc_status=0 timeout=16 ts=1594390337823495 Checking foc status: rslt=0, foc_status=0 timeout=17 ts=1594390337849858 Checking foc status: rslt=0, foc_status=0 timeout=18 ts=1594390337876225 Checking foc status: rslt=0, foc_status=1 timeout=19 ts=1594390337902595 Geetting offsets rslt=0, foc_status=1 ts=1594390337904053 While the calibration succeeds now, I don't understand why. The results of my debugging seem to contradict the datasheet, which states that the FOC routine completes within 250ms. The timestamps above are in epoch time in microseconds and show that my implementation of user_delay_ms() is working as intended. The calibration always seems to require 20 attempts to complete, i.e. it always succeeds after timeout=19 as above. I am running this on Linux on a Raspberry Pi over I2C. 2. I have made no progress with the magnetometer self-test. Both normal and advanced self-tests fail, with BMM150_W_NORMAL_SELF_TEST_XYZ_FAIL.
... View more