/* * Copyright (c) 2020 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ /** * @defgroup driver_sensor_subsys_tests sensor_subsys * @ingroup all_tests * @{ * @} */ #include #include "dummy_sensor.h" K_SEM_DEFINE(sem, 0, 1); #define RETURN_SUCCESS (0) struct channel_sequence { enum sensor_channel chan; struct sensor_value data; }; struct trigger_sequence { struct sensor_trigger trig; struct sensor_value data; enum sensor_attribute attr; }; static struct channel_sequence chan_elements[] = { { SENSOR_CHAN_LIGHT, { 0, 0 } }, { SENSOR_CHAN_RED, { 1, 1 } }, { SENSOR_CHAN_GREEN, { 2, 4 } }, { SENSOR_CHAN_BLUE, { 3, 9 } }, { SENSOR_CHAN_PROX, { 4, 16 } } }; static struct trigger_sequence trigger_elements[] = { /* trigger for SENSOR_TRIG_THRESHOLD */ { {SENSOR_TRIG_THRESHOLD, SENSOR_CHAN_PROX}, { 127, 0 }, SENSOR_ATTR_UPPER_THRESH }, /* trigger for SENSOR_TRIG_TIMER */ { {SENSOR_TRIG_TIMER, SENSOR_CHAN_PROX}, { 130, 127 }, SENSOR_ATTR_UPPER_THRESH }, /* trigger for SENSOR_TRIG_DATA_READY */ { {SENSOR_TRIG_DATA_READY, SENSOR_CHAN_PROX}, { 150, 130 }, SENSOR_ATTR_UPPER_THRESH }, /* trigger for SENSOR_TRIG_DELTA */ { {SENSOR_TRIG_DELTA, SENSOR_CHAN_PROX}, { 180, 150 }, SENSOR_ATTR_UPPER_THRESH }, /* trigger for SENSOR_TRIG_NEAR_FAR */ { {SENSOR_TRIG_NEAR_FAR, SENSOR_CHAN_PROX}, { 155, 180 }, SENSOR_ATTR_UPPER_THRESH } }; #define TOTAL_CHAN_ELEMENTS (sizeof(chan_elements) / \ sizeof(struct channel_sequence)) #define TOTAL_TRIG_ELEMENTS (sizeof(trigger_elements) / \ sizeof(struct trigger_sequence)) /** * @brief Test get multiple channels values. * * @ingroup driver_sensor_subsys_tests * * @details * Test Objective: * - get multiple channels values consistently in two operations: * fetch sample and get the values of each channel individually. * - check the results with sensor_value type avoids use of * floating point values * * Testing techniques: * - function and block box testing,Interface testing, * Dynamic analysis and testing, Equivalence classes. * * Prerequisite Conditions: * - N/A * * Input Specifications: * - N/A * * Test Procedure: * -# Define a device and bind to dummy sensor. * -# Fetch the sample of dummy senor and check the result. * -# Get SENSOR_CHAN_LIGHT/SENSOR_CHAN_RED/SENSOR_CHAN_GREEN/ * SENSOR_CHAN_BLUE/SENSOR_CHAN_BLUE channels from the sensor, * and check the result. * * Expected Test Result: * - Application can get multiple channels for dummy sensor. * * Pass/Fail Criteria: * - Successful if check points in test procedure are all passed, otherwise failure. * * Assumptions and Constraints: * - N/A * * @see sensor_sample_fetch(), sensor_channel_get() */ ZTEST(sensor_api, test_sensor_get_channels) { const struct device *dev; struct sensor_value data; dev = device_get_binding(DUMMY_SENSOR_NAME); zassert_not_null(dev, "failed: dev is null"); /* test fetch single channel */ zassert_equal(sensor_sample_fetch_chan(dev, chan_elements[0].chan), RETURN_SUCCESS, "fail to fetch sample"); /* Get and check channel 0 value. */ zassert_equal(sensor_channel_get(dev, chan_elements[0].chan, &data), RETURN_SUCCESS, "fail to get channel"); zassert_equal(data.val1, chan_elements[0].data.val1, "the data does not match"); zassert_equal(data.val2, chan_elements[0].data.val2, "the data does not match"); /* test fetch all channel */ zassert_equal(sensor_sample_fetch(dev), RETURN_SUCCESS, "fail to fetch sample"); /* Get and check channels value except for chanel 0. */ for (int i = 1; i < TOTAL_CHAN_ELEMENTS; i++) { zassert_equal(sensor_channel_get(dev, chan_elements[i].chan, &data), RETURN_SUCCESS, "fail to get channel"); zassert_equal(data.val1, chan_elements[i].data.val1, "the data does not match"); zassert_equal(data.val2, chan_elements[i].data.val2, "the data does not match"); } /* Get data with invalid channel. */ zassert_not_equal(sensor_channel_get(dev, SENSOR_CHAN_DISTANCE, &data), RETURN_SUCCESS, "should fail for invalid channel"); } static void trigger_handler(const struct device *dev, const struct sensor_trigger *trigger) { ARG_UNUSED(dev); ARG_UNUSED(trigger); k_sem_give(&sem); } /** * @brief Test sensor multiple triggers. * * @ingroup driver_sensor_subsys_tests * * @details * Test Objective: * Check if sensor subsys can set multiple triggers and * can set/get sensor attribute. * * Testing techniques: * - function and block box testing,Interface testing, * Dynamic analysis and testing. * * Prerequisite Conditions: * - N/A * * Input Specifications: * - N/A * * Test Procedure: * -# Define a device and bind to dummy sensor and * check the result. * -# set multiple triggers for the dummy sensor and no trig sensor. * then check the result. * -# Handle different types of triggers, based on time, data,threshold, * based on a delta value, near/far events and single/double tap and * check the result. * * Expected Test Result: * - Application can get multiple channels for dummy sensor. * * Pass/Fail Criteria: * - Successful if check points in test procedure are all passed, otherwise failure. * * Assumptions and Constraints: * - N/A * * @see sensor_attr_set(), sensor_trigger_set() */ ZTEST(sensor_api, test_sensor_handle_triggers) { const struct device *dev; const struct device *dev_no_trig; struct sensor_value data; dev = device_get_binding(DUMMY_SENSOR_NAME); dev_no_trig = device_get_binding(DUMMY_SENSOR_NAME_NO_TRIG); zassert_not_null(dev, "failed: dev is null"); zassert_equal(sensor_sample_fetch(dev), RETURN_SUCCESS, "fail to fetch sample"); /* setup multiple triggers */ for (int i = 0; i < TOTAL_TRIG_ELEMENTS; i++) { /* set attributes for trigger */ zassert_equal(sensor_attr_set(dev, trigger_elements[i].trig.chan, trigger_elements[i].attr, &trigger_elements[i].data), RETURN_SUCCESS, "fail to set attributes"); /* read-back attributes for trigger */ zassert_equal(sensor_attr_get(dev, trigger_elements[i].trig.chan, trigger_elements[i].attr, &data), RETURN_SUCCESS, "fail to get attributes"); zassert_equal(trigger_elements[i].data.val1, data.val1, "read-back returned wrong val1"); zassert_equal(trigger_elements[i].data.val2, data.val2, "read-back returned wrong val2"); /* setting a sensor's trigger and handler */ zassert_equal(sensor_trigger_set(dev, &trigger_elements[i].trig, trigger_handler), RETURN_SUCCESS, "fail to set trigger"); /* get channels value after trigger fired */ k_sem_take(&sem, K_FOREVER); zassert_equal(sensor_channel_get(dev, trigger_elements[i].trig.chan, &data), RETURN_SUCCESS, "fail to get channel"); /* check the result of the trigger channel */ zassert_equal(data.val1, trigger_elements[i].data.val1, "retrieved data does not match"); zassert_equal(data.val2, trigger_elements[i].data.val2, "retrieved data does not match"); /* set attributes for no trig dev */ zassert_equal(sensor_attr_set(dev_no_trig, trigger_elements[i].trig.chan, trigger_elements[i].attr, &trigger_elements[i].data), -ENOSYS, "fail to set attributes"); /* read-back attributes for no trig dev*/ zassert_equal(sensor_attr_get(dev_no_trig, trigger_elements[i].trig.chan, trigger_elements[i].attr, &data), -ENOSYS, "fail to get attributes"); /* setting a sensor's trigger and handler for no trig dev */ zassert_equal(sensor_trigger_set(dev_no_trig, &trigger_elements[i].trig, trigger_handler), -ENOSYS, "fail to set trigger"); } } /** * @brief Test unit conversion of sensor module * @details Verify helper function to convert acceleration from * Gs to m/s^2 and from m/s^2 to Gs. Verify helper function * to convert radians to degrees and degrees to radians. Verify * helper function for converting struct sensor_value to double. * Verify helper functions for converting to milli and micro prefix * units. */ ZTEST(sensor_api, test_sensor_unit_conversion) { struct sensor_value data; /* Test acceleration unit conversion */ sensor_g_to_ms2(1, &data); zassert_equal(data.val1, SENSOR_G/1000000LL, "the data does not match"); zassert_equal(data.val2, SENSOR_G%(data.val1 * 1000000LL), "the data does not match"); zassert_equal(sensor_ms2_to_g(&data), 1, "the data does not match"); /* set test data to negative value */ data.val1 = -data.val1; data.val2 = -data.val2; zassert_equal(sensor_ms2_to_g(&data), -1, "the data does not match"); /* Test the conversion between angle and radian */ sensor_degrees_to_rad(180, &data); zassert_equal(data.val1, SENSOR_PI/1000000LL, "the data does not match"); zassert_equal(data.val2, SENSOR_PI%(data.val1 * 1000000LL), "the data does not match"); zassert_equal(sensor_rad_to_degrees(&data), 180, "the data does not match"); /* set test data to negative value */ data.val1 = -data.val1; data.val2 = -data.val2; zassert_equal(sensor_rad_to_degrees(&data), -180, "the data does not match"); /* reset test data to positive value */ data.val1 = -data.val1; data.val2 = -data.val2; #if defined(CONFIG_FPU) /* Test struct sensor_value to double and float */ zassert_equal((long long)(sensor_value_to_double(&data) * 1000000LL), SENSOR_PI, "the data does not match"); zassert_equal((long long)(sensor_value_to_float(&data) * 1000000LL), SENSOR_PI, "the data does not match"); /* Test struct sensor_value from double and float */ sensor_value_from_double(&data, (double)(SENSOR_PI) / 1000000.0); zassert_equal(data.val1, SENSOR_PI/1000000LL, "the data does not match"); zassert_equal(data.val2, SENSOR_PI%(data.val1 * 1000000LL), "the data does not match"); sensor_value_from_float(&data, (float)(SENSOR_PI) / 1000000.0f); zassert_equal(data.val1, SENSOR_PI/1000000LL, "the data does not match"); zassert_equal(data.val2, SENSOR_PI%(data.val1 * 1000000LL), "the data does not match"); #endif /* reset test data to positive value */ data.val1 = 3; data.val2 = 300000; zassert_equal(sensor_value_to_milli(&data), 3300LL, "the result does not match"); zassert_equal(sensor_value_to_micro(&data), 3300000LL, "the result does not match"); /* reset test data to negative value */ data.val1 = -data.val1; data.val2 = -data.val2; zassert_equal(sensor_value_to_milli(&data), -3300LL, "the result does not match"); zassert_equal(sensor_value_to_micro(&data), -3300000LL, "the result does not match"); /* Test when result is greater than 32-bit wide */ data.val1 = 5432109; data.val2 = 876543; zassert_equal(sensor_value_to_milli(&data), 5432109876LL, "the result does not match"); zassert_equal(sensor_value_to_micro(&data), 5432109876543LL, "the result does not match"); } ZTEST_SUITE(sensor_api, NULL, NULL, ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);