zephyr/tests/drivers/sensor/generic/src/main.c
Radoslaw Koppel d1a93c1426 drivers: sensor: Const sensor trigger data in trigger handler
This commit adds const modifier in second argument for
sensor trigger handler.
There is no reason to modify this data and this change
would allow to store trigger configuration also in FLASH.

Fixes: #38929

Signed-off-by: Radoslaw Koppel <radoslaw.koppel@nordicsemi.no>
2021-10-27 15:09:35 -04:00

324 lines
9.3 KiB
C

/*
* Copyright (c) 2020 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @defgroup driver_sensor_subsys_tests sensor_subsys
* @ingroup all_tests
* @{
* @}
*/
#include <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()
*/
void test_sensor_get_channels(void)
{
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 is not match.");
zassert_equal(data.val2, chan_elements[0].data.val2,
"the data is 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 is not match.");
zassert_equal(data.val2, chan_elements[i].data.val2,
"the data is 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()
*/
void test_sensor_handle_triggers(void)
{
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,
"retrived data is not match.");
zassert_equal(data.val2, trigger_elements[i].data.val2,
"retrived data is 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 coversion 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.
*/
void test_sensor_unit_conversion(void)
{
struct sensor_value data;
/* Test acceleration unit conversion */
sensor_g_to_ms2(1, &data);
zassert_equal(data.val1, SENSOR_G/1000000LL,
"the data is not match.");
zassert_equal(data.val2, SENSOR_G%(data.val1 * 1000000LL),
"the data is not match.");
zassert_equal(sensor_ms2_to_g(&data), 1,
"the data is 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 is not match.");
/* Test the conversion between angle and radian */
sensor_degrees_to_rad(180, &data);
zassert_equal(data.val1, SENSOR_PI/1000000LL,
"the data is not match.");
zassert_equal(data.val2, SENSOR_PI%(data.val1 * 1000000LL),
"the data is not match.");
zassert_equal(sensor_rad_to_degrees(&data), 180,
"the data is 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 is not match.");
/* reset test data to positive value */
data.val1 = -data.val1;
data.val2 = -data.val2;
/* Test struct sensor_value to double */
#if defined(CONFIG_FPU)
zassert_equal((long long)(sensor_value_to_double(&data) * 1000000LL),
SENSOR_PI, "the data is not match.");
#endif
}
/*test case main entry*/
void test_main(void)
{
ztest_test_suite(test_sensor_api,
ztest_1cpu_unit_test(test_sensor_get_channels),
ztest_1cpu_unit_test(test_sensor_handle_triggers),
ztest_1cpu_unit_test(test_sensor_unit_conversion));
ztest_run_test_suite(test_sensor_api);
}