Hello,
We are using ADXL367 in our design interfacing to our embedded microcontroller.
We have implented ADXL367 Self Test during initialization, but have seen cases where the test fails (diff > max OR diff < min). We have followed the Analog devices reference source code here, https://github.com/analogdevicesinc/no-OS/blob/main/drivers/accel/adxl367/adxl367.c
Max = 1080
Min = 360
Dif = ~700-800 (Happy Case)
Dif = 1678 (Failure Case, only failure data point I have for now)
Questions:
- Do you have any insight on what could cause these types of failures?
Our Self Test Function:
/***************************************************************************//**
* @brief Performs self test.
*
* @param dev - The device structure.
*
* @return 0 in case of success, negative error code otherwise.
*******************************************************************************/
int adxl367_self_test(struct adxl367_dev *dev, int16_t* p_result)
{
int ret;
int16_t x_axis_1, x_axis_2, dif, min, max;
uint8_t read_val;
uint32_t st_delay_ms;
// 4 / ODR value in ms
/* TO give sensor enoug warm up time giving 500 ms delay. with 80 ms
* delay self test failing all time.
*/
st_delay_ms = 500;
/*
switch (dev->odr) {
case ADXL367_ODR_12P5HZ:
st_delay_ms = 320;
case ADXL367_ODR_25HZ:
st_delay_ms = 160;
case ADXL367_ODR_50HZ:
st_delay_ms = 80;
case ADXL367_ODR_100HZ:
st_delay_ms = 40;
case ADXL367_ODR_200HZ:
st_delay_ms = 20;
case ADXL367_ODR_400HZ:
st_delay_ms = 10;
break;
default:
return -EINVAL;
}
*/
ret = adxl367_set_power_mode(dev, ADXL367_OP_MEASURE);
if (ret)
return ret;
ret = adxl367_reg_write_msk(dev, ADXL367_REG_SELF_TEST, ADXL367_SELF_TEST_ST,
ADXL367_SELF_TEST_ST);
if (ret)
return ret;
// 4 / ODR delay
OsDelayMs(st_delay_ms, OS_OPT_TIME_DLY);
ret = adxl367_get_register_value(dev, &read_val, ADXL367_REG_XDATA_H, 1);
if (ret)
return ret;
x_axis_1 = read_val << 6;
ret = adxl367_get_register_value(dev, &read_val, ADXL367_REG_XDATA_L, 1);
if (ret)
return ret;
x_axis_1 += read_val >> 2;
// extend sign to 16 bits
if (x_axis_1 & NO_OS_BIT(13))
x_axis_1 |= NO_OS_GENMASK(15, 14);
ret = adxl367_reg_write_msk(dev, ADXL367_REG_SELF_TEST,
ADXL367_SELF_TEST_ST_FORCE, ADXL367_SELF_TEST_ST_FORCE);
if (ret)
return ret;
// 4 / ODR delay
OsDelayMs(st_delay_ms, OS_OPT_TIME_DLY);
ret = adxl367_get_register_value(dev, &read_val, ADXL367_REG_XDATA_H, 1);
if (ret)
return ret;
x_axis_2 = read_val << 6;
ret = adxl367_get_register_value(dev, &read_val, ADXL367_REG_XDATA_L, 1);
if (ret)
return ret;
x_axis_2 += read_val >> 2;
// extend sign to 16 bits
if (x_axis_2 & NO_OS_BIT(13))
x_axis_2 |= NO_OS_GENMASK(15, 14);
ret = adxl367_set_power_mode(dev, ADXL367_OP_STANDBY);
if (ret)
return ret;
ret = adxl367_reg_write_msk(dev, ADXL367_REG_SELF_TEST, 0,
ADXL367_SELF_TEST_ST_FORCE | ADXL367_SELF_TEST_ST);
if (ret)
return ret;
dif = x_axis_2 - x_axis_1;
min = ADXL367_SELF_TEST_MIN * adxl367_scale_mul[dev->range];
max = ADXL367_SELF_TEST_MAX * adxl367_scale_mul[dev->range];
#if RTT_XL_DEBUG_OUTPUT
SEGGER_RTT_printf(0, " dif: %d\n", dif);
SEGGER_RTT_printf(0, " min: %d\n", min);
SEGGER_RTT_printf(0, " max: %d\n", max);
#endif
// Copy result to output parameter
*p_result = dif;
if ((dif >= min) && (dif <= max)) {
return 0;
} else {
return -1;
}
}