Double promotion warnings are generated with the flag -Wdouble-promotion Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
353 lines
11 KiB
C
353 lines
11 KiB
C
/*
|
|
* Copyright (c) 2020 Intel Corporation.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* @defgroup driver_sensor_subsys_tests sensor_subsys
|
|
* @ingroup all_tests
|
|
* @{
|
|
* @}
|
|
*/
|
|
|
|
#include <zephyr/ztest.h>
|
|
#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);
|