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