Post Go back to editing

Self Test fails intermittently fails

Thread Summary

The user is experiencing ADXL367 self-test failures (diff > max or diff < min) in an embedded design. The final answer suggests adding a 100ms delay after entering Measure mode and averaging multiple samples to reduce noise. The user confirmed the issue persists with diff = 0 (x_axis_1 = 0xFFFF, x_axis_2 = 0xFFFF) and will verify if this is due to communication issues or other environmental factors. The ADXL367 is used in the design, and the self-test function is based on the Analog Devices reference code.
AI Generated Content
Category: Hardware
Product Number: ADXL367

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:

  1. 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;
	}
}