b249535093
Use a structured channel specifier rather than a single enum when specifying channels to read in the new read/decoder API. Replaces usages of a seperate channel and channel_index parameter where previously used with a struct sensor_chan_spec. Signed-off-by: Tom Burdick <thomas.burdick@intel.com>
185 lines
6.3 KiB
C
185 lines
6.3 KiB
C
/*
|
|
* Copyright (c) 2023 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/drivers/emul.h>
|
|
#include <zephyr/drivers/sensor.h>
|
|
#include <zephyr/drivers/sensor_attribute_types.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
/**
|
|
* @brief Sensor emulator backend API
|
|
* @defgroup sensor_emulator_backend Sensor emulator backend API
|
|
* @ingroup io_interfaces
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @cond INTERNAL_HIDDEN
|
|
*
|
|
* These are for internal use only, so skip these in public documentation.
|
|
*/
|
|
|
|
/**
|
|
* @brief Collection of function pointers implementing a common backend API for sensor emulators
|
|
*/
|
|
__subsystem struct emul_sensor_driver_api {
|
|
/** Sets a given fractional value for a given sensor channel. */
|
|
int (*set_channel)(const struct emul *target, struct sensor_chan_spec ch,
|
|
const q31_t *value, int8_t shift);
|
|
/** Retrieve a range of sensor values to use with test. */
|
|
int (*get_sample_range)(const struct emul *target, struct sensor_chan_spec ch, q31_t *lower,
|
|
q31_t *upper, q31_t *epsilon, int8_t *shift);
|
|
/** Set the attribute value(s) of a given chanel. */
|
|
int (*set_attribute)(const struct emul *target, struct sensor_chan_spec ch,
|
|
enum sensor_attribute attribute, const void *value);
|
|
/** Get metadata about an attribute. */
|
|
int (*get_attribute_metadata)(const struct emul *target, struct sensor_chan_spec ch,
|
|
enum sensor_attribute attribute, q31_t *min, q31_t *max,
|
|
q31_t *increment, int8_t *shift);
|
|
};
|
|
/**
|
|
* @endcond
|
|
*/
|
|
|
|
/**
|
|
* @brief Check if a given sensor emulator supports the backend API
|
|
*
|
|
* @param target Pointer to emulator instance to query
|
|
*
|
|
* @return True if supported, false if unsupported or if \p target is NULL.
|
|
*/
|
|
static inline bool emul_sensor_backend_is_supported(const struct emul *target)
|
|
{
|
|
return target && target->backend_api;
|
|
}
|
|
|
|
/**
|
|
* @brief Set an expected value for a given channel on a given sensor emulator
|
|
*
|
|
* @param target Pointer to emulator instance to operate on
|
|
* @param ch Sensor channel to set expected value for
|
|
* @param value Expected value in fixed-point format using standard SI unit for sensor type
|
|
* @param shift Shift value (scaling factor) applied to \p value
|
|
*
|
|
* @return 0 if successful
|
|
* @return -ENOTSUP if no backend API or if channel not supported by emul
|
|
* @return -ERANGE if provided value is not in the sensor's supported range
|
|
*/
|
|
static inline int emul_sensor_backend_set_channel(const struct emul *target,
|
|
struct sensor_chan_spec ch, const q31_t *value,
|
|
int8_t shift)
|
|
{
|
|
if (!target || !target->backend_api) {
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
struct emul_sensor_driver_api *api = (struct emul_sensor_driver_api *)target->backend_api;
|
|
|
|
if (api->set_channel) {
|
|
return api->set_channel(target, ch, value, shift);
|
|
}
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
/**
|
|
* @brief Query an emulator for a channel's supported sample value range and tolerance
|
|
*
|
|
* @param target Pointer to emulator instance to operate on
|
|
* @param ch The channel to request info for. If \p ch is unsupported, return `-ENOTSUP`
|
|
* @param[out] lower Minimum supported sample value in SI units, fixed-point format
|
|
* @param[out] upper Maximum supported sample value in SI units, fixed-point format
|
|
* @param[out] epsilon Tolerance to use comparing expected and actual values to account for rounding
|
|
* and sensor precision issues. This can usually be set to the minimum sample value step
|
|
* size. Uses SI units and fixed-point format.
|
|
* @param[out] shift The shift value (scaling factor) associated with \p lower, \p upper, and
|
|
* \p epsilon.
|
|
*
|
|
* @return 0 if successful
|
|
* @return -ENOTSUP if no backend API or if channel not supported by emul
|
|
*
|
|
*/
|
|
static inline int emul_sensor_backend_get_sample_range(const struct emul *target,
|
|
struct sensor_chan_spec ch, q31_t *lower,
|
|
q31_t *upper, q31_t *epsilon, int8_t *shift)
|
|
{
|
|
if (!target || !target->backend_api) {
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
struct emul_sensor_driver_api *api = (struct emul_sensor_driver_api *)target->backend_api;
|
|
|
|
if (api->get_sample_range) {
|
|
return api->get_sample_range(target, ch, lower, upper, epsilon, shift);
|
|
}
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the emulator's attribute values
|
|
*
|
|
* @param[in] target Pointer to emulator instance to operate on
|
|
* @param[in] ch The channel to request info for. If \p ch is unsupported, return `-ENOTSUP`
|
|
* @param[in] attribute The attribute to set
|
|
* @param[in] value the value to use (cast according to the channel/attribute pair)
|
|
* @return 0 is successful
|
|
* @return < 0 on error
|
|
*/
|
|
static inline int emul_sensor_backend_set_attribute(const struct emul *target,
|
|
struct sensor_chan_spec ch,
|
|
enum sensor_attribute attribute,
|
|
const void *value)
|
|
{
|
|
if (!target || !target->backend_api) {
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
struct emul_sensor_driver_api *api = (struct emul_sensor_driver_api *)target->backend_api;
|
|
|
|
if (api->set_attribute == NULL) {
|
|
return -ENOTSUP;
|
|
}
|
|
return api->set_attribute(target, ch, attribute, value);
|
|
}
|
|
|
|
/**
|
|
* @brief Get metadata about an attribute.
|
|
*
|
|
* Information provided by this function includes the minimum/maximum values of the attribute as
|
|
* well as the increment (value per LSB) which can be used as an epsilon when comparing results.
|
|
*
|
|
* @param[in] target Pointer to emulator instance to operate on
|
|
* @param[in] ch The channel to request info for. If \p ch is unsupported, return '-ENOTSUP'
|
|
* @param[in] attribute The attribute to request info for. If \p attribute is unsupported, return
|
|
* '-ENOTSUP'
|
|
* @param[out] min The minimum value the attribute can be set to
|
|
* @param[out] max The maximum value the attribute can be set to
|
|
* @param[out] increment The value that the attribute increses by for every LSB
|
|
* @param[out] shift The shift for \p min, \p max, and \p increment
|
|
* @return 0 on SUCCESS
|
|
* @return < 0 on error
|
|
*/
|
|
static inline int emul_sensor_backend_get_attribute_metadata(const struct emul *target,
|
|
struct sensor_chan_spec ch,
|
|
enum sensor_attribute attribute,
|
|
q31_t *min, q31_t *max,
|
|
q31_t *increment, int8_t *shift)
|
|
{
|
|
if (!target || !target->backend_api) {
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
struct emul_sensor_driver_api *api = (struct emul_sensor_driver_api *)target->backend_api;
|
|
|
|
if (api->get_attribute_metadata == NULL) {
|
|
return -ENOTSUP;
|
|
}
|
|
return api->get_attribute_metadata(target, ch, attribute, min, max, increment, shift);
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|