Line data Source code
1 0 : /*
2 : * Copyright (c) 2023 Google LLC
3 : * SPDX-License-Identifier: Apache-2.0
4 : */
5 :
6 : #include <zephyr/drivers/emul.h>
7 : #include <zephyr/drivers/sensor.h>
8 : #include <zephyr/drivers/sensor_attribute_types.h>
9 :
10 : #include <stdint.h>
11 :
12 : /**
13 : * @brief Sensor emulator backend API
14 : * @defgroup sensor_emulator_backend Sensor emulator backend API
15 : * @ingroup io_emulators
16 : * @ingroup sensor_interface
17 : * @{
18 : */
19 :
20 : /**
21 : * @cond INTERNAL_HIDDEN
22 : *
23 : * These are for internal use only, so skip these in public documentation.
24 : */
25 :
26 : /**
27 : * @brief Collection of function pointers implementing a common backend API for sensor emulators
28 : */
29 : __subsystem struct emul_sensor_driver_api {
30 : /** Sets a given fractional value for a given sensor channel. */
31 : int (*set_channel)(const struct emul *target, struct sensor_chan_spec ch,
32 : const q31_t *value, int8_t shift);
33 : /** Retrieve a range of sensor values to use with test. */
34 : int (*get_sample_range)(const struct emul *target, struct sensor_chan_spec ch, q31_t *lower,
35 : q31_t *upper, q31_t *epsilon, int8_t *shift);
36 : /** Set the attribute value(s) of a given channel. */
37 : int (*set_attribute)(const struct emul *target, struct sensor_chan_spec ch,
38 : enum sensor_attribute attribute, const void *value);
39 : /** Get metadata about an attribute. */
40 : int (*get_attribute_metadata)(const struct emul *target, struct sensor_chan_spec ch,
41 : enum sensor_attribute attribute, q31_t *min, q31_t *max,
42 : q31_t *increment, int8_t *shift);
43 : };
44 : /**
45 : * @endcond
46 : */
47 :
48 : /**
49 : * @brief Check if a given sensor emulator supports the backend API
50 : *
51 : * @param target Pointer to emulator instance to query
52 : *
53 : * @return True if supported, false if unsupported or if \p target is NULL.
54 : */
55 1 : static inline bool emul_sensor_backend_is_supported(const struct emul *target)
56 : {
57 : return target && target->backend_api;
58 : }
59 :
60 : /**
61 : * @brief Set an expected value for a given channel on a given sensor emulator
62 : *
63 : * @param target Pointer to emulator instance to operate on
64 : * @param ch Sensor channel to set expected value for
65 : * @param value Expected value in fixed-point format using standard SI unit for sensor type
66 : * @param shift Shift value (scaling factor) applied to \p value
67 : *
68 : * @return 0 if successful
69 : * @return -ENOTSUP if no backend API or if channel not supported by emul
70 : * @return -ERANGE if provided value is not in the sensor's supported range
71 : */
72 1 : static inline int emul_sensor_backend_set_channel(const struct emul *target,
73 : struct sensor_chan_spec ch, const q31_t *value,
74 : int8_t shift)
75 : {
76 : if (!target || !target->backend_api) {
77 : return -ENOTSUP;
78 : }
79 :
80 : struct emul_sensor_driver_api *api = (struct emul_sensor_driver_api *)target->backend_api;
81 :
82 : if (api->set_channel) {
83 : return api->set_channel(target, ch, value, shift);
84 : }
85 : return -ENOTSUP;
86 : }
87 :
88 : /**
89 : * @brief Query an emulator for a channel's supported sample value range and tolerance
90 : *
91 : * @param target Pointer to emulator instance to operate on
92 : * @param ch The channel to request info for. If \p ch is unsupported, return `-ENOTSUP`
93 : * @param[out] lower Minimum supported sample value in SI units, fixed-point format
94 : * @param[out] upper Maximum supported sample value in SI units, fixed-point format
95 : * @param[out] epsilon Tolerance to use comparing expected and actual values to account for rounding
96 : * and sensor precision issues. This can usually be set to the minimum sample value step
97 : * size. Uses SI units and fixed-point format.
98 : * @param[out] shift The shift value (scaling factor) associated with \p lower, \p upper, and
99 : * \p epsilon.
100 : *
101 : * @return 0 if successful
102 : * @return -ENOTSUP if no backend API or if channel not supported by emul
103 : *
104 : */
105 1 : static inline int emul_sensor_backend_get_sample_range(const struct emul *target,
106 : struct sensor_chan_spec ch, q31_t *lower,
107 : q31_t *upper, q31_t *epsilon, int8_t *shift)
108 : {
109 : if (!target || !target->backend_api) {
110 : return -ENOTSUP;
111 : }
112 :
113 : struct emul_sensor_driver_api *api = (struct emul_sensor_driver_api *)target->backend_api;
114 :
115 : if (api->get_sample_range) {
116 : return api->get_sample_range(target, ch, lower, upper, epsilon, shift);
117 : }
118 : return -ENOTSUP;
119 : }
120 :
121 : /**
122 : * @brief Set the emulator's attribute values
123 : *
124 : * @param[in] target Pointer to emulator instance to operate on
125 : * @param[in] ch The channel to request info for. If \p ch is unsupported, return `-ENOTSUP`
126 : * @param[in] attribute The attribute to set
127 : * @param[in] value the value to use (cast according to the channel/attribute pair)
128 : * @return 0 is successful
129 : * @return < 0 on error
130 : */
131 1 : static inline int emul_sensor_backend_set_attribute(const struct emul *target,
132 : struct sensor_chan_spec ch,
133 : enum sensor_attribute attribute,
134 : const void *value)
135 : {
136 : if (!target || !target->backend_api) {
137 : return -ENOTSUP;
138 : }
139 :
140 : struct emul_sensor_driver_api *api = (struct emul_sensor_driver_api *)target->backend_api;
141 :
142 : if (api->set_attribute == NULL) {
143 : return -ENOTSUP;
144 : }
145 : return api->set_attribute(target, ch, attribute, value);
146 : }
147 :
148 : /**
149 : * @brief Get metadata about an attribute.
150 : *
151 : * Information provided by this function includes the minimum/maximum values of the attribute as
152 : * well as the increment (value per LSB) which can be used as an epsilon when comparing results.
153 : *
154 : * @param[in] target Pointer to emulator instance to operate on
155 : * @param[in] ch The channel to request info for. If \p ch is unsupported, return '-ENOTSUP'
156 : * @param[in] attribute The attribute to request info for. If \p attribute is unsupported, return
157 : * '-ENOTSUP'
158 : * @param[out] min The minimum value the attribute can be set to
159 : * @param[out] max The maximum value the attribute can be set to
160 : * @param[out] increment The value that the attribute increases by for every LSB
161 : * @param[out] shift The shift for \p min, \p max, and \p increment
162 : * @return 0 on SUCCESS
163 : * @return < 0 on error
164 : */
165 1 : static inline int emul_sensor_backend_get_attribute_metadata(const struct emul *target,
166 : struct sensor_chan_spec ch,
167 : enum sensor_attribute attribute,
168 : q31_t *min, q31_t *max,
169 : q31_t *increment, int8_t *shift)
170 : {
171 : if (!target || !target->backend_api) {
172 : return -ENOTSUP;
173 : }
174 :
175 : struct emul_sensor_driver_api *api = (struct emul_sensor_driver_api *)target->backend_api;
176 :
177 : if (api->get_attribute_metadata == NULL) {
178 : return -ENOTSUP;
179 : }
180 : return api->get_attribute_metadata(target, ch, attribute, min, max, increment, shift);
181 : }
182 :
183 : /**
184 : * @}
185 : */
|