Line data Source code
1 0 : /*
2 : * Copyright (c) 2022-2023 Intel Corporation.
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #ifndef ZEPHYR_INCLUDE_SENSING_SENSOR_H_
8 : #define ZEPHYR_INCLUDE_SENSING_SENSOR_H_
9 :
10 : #include <stdbool.h>
11 : #include <zephyr/device.h>
12 : #include <zephyr/drivers/sensor.h>
13 : #include <zephyr/sensing/sensing.h>
14 :
15 : /**
16 : * @brief Interfaces to manipulate sensors in the sensing subsystem
17 : * @defgroup sensing_sensor Sensors (Sensing)
18 : * @ingroup sensing_api
19 : * @{
20 : */
21 :
22 : #ifdef __cplusplus
23 : extern "C" {
24 : #endif
25 :
26 : /**
27 : * @brief Sensor registration information
28 : *
29 : */
30 1 : struct sensing_sensor_register_info {
31 : /**
32 : * Sensor flags
33 : */
34 1 : uint16_t flags;
35 :
36 : /**
37 : * Sample size in bytes for a single sample of the registered sensor.
38 : * sensing runtime need this information for internal buffer allocation.
39 : */
40 1 : uint16_t sample_size;
41 :
42 : /**
43 : * The number of sensor sensitivities
44 : */
45 1 : uint8_t sensitivity_count;
46 :
47 : /**
48 : * Sensor version.
49 : * Version can be used to identify different versions of sensor implementation.
50 : */
51 1 : struct sensing_sensor_version version;
52 : };
53 :
54 : /** @cond INTERNAL_HIDDEN */
55 :
56 : /**
57 : * @brief Enumeration for sensing subsystem event.
58 : *
59 : * This enumeration defines the various events used by the sensing subsystem.
60 : */
61 : enum {
62 : EVENT_CONFIG_READY, /**< Configuration is ready. */
63 : };
64 :
65 : /**
66 : * @brief Enumeration for sensor flag bit.
67 : *
68 : * This enumeration defines the bit for sensor flag.
69 : */
70 : enum {
71 : SENSOR_LATER_CFG_BIT, /**< Indicates if there is a configuration request pending. */
72 : };
73 :
74 : /**
75 : * @brief Connection between a source and sink of sensor data
76 : */
77 : struct sensing_connection {
78 : sys_snode_t snode; /**< Node in the singly-linked list of connections. */
79 : struct sensing_sensor *source; /**< Source sensor of the connection. */
80 : struct sensing_sensor *sink; /**< Sink sensor of the connection. */
81 : uint32_t interval; /**< Report interval in micro seconds. */
82 : /** Sensitivity of the connection. */
83 : int sensitivity[CONFIG_SENSING_MAX_SENSITIVITY_COUNT];
84 : void *data; /**< Pointer to sensor sample data of the connection. */
85 : /** Next consume time of the connection. Unit is micro seconds. */
86 : uint64_t next_consume_time;
87 : struct sensing_callback_list *callback_list; /**< Callback list of the connection. */
88 : };
89 :
90 : /**
91 : * @brief Internal sensor instance data structure.
92 : *
93 : * Each sensor instance will have its unique data structure for storing all
94 : * it's related information.
95 : *
96 : * Sensor management will enumerate all these instance data structures,
97 : * build report relationship model base on them, etc.
98 : */
99 : struct sensing_sensor {
100 : const struct device *dev; /**< Device of the sensor instance. */
101 : const struct sensing_sensor_info *info; /**< Info of the sensor instance. */
102 : /** Register info of the sensor instance. */
103 : const struct sensing_sensor_register_info *register_info;
104 : const uint16_t reporter_num; /**< Reporter number of the sensor instance. */
105 : sys_slist_t client_list; /**< List of the sensor clients. */
106 : uint32_t interval; /**< Report interval of the sensor sample in micro seconds. */
107 : uint8_t sensitivity_count; /**< Sensitivity count of the sensor instance. */
108 : /** Sensitivity array of the sensor instance. */
109 : int sensitivity[CONFIG_SENSING_MAX_SENSITIVITY_COUNT];
110 : enum sensing_sensor_state state; /**< State of the sensor instance. */
111 : struct rtio_iodev *iodev; /**< Pointer to RTIO device of the sensor instance. */
112 : struct k_timer timer; /**< Timer for non streaming mode */
113 : struct rtio_sqe *stream_sqe; /**< Sqe for streaming mode. */
114 : atomic_t flag; /**< Sensor flag of the sensor instance. */
115 : struct sensing_connection *conns; /**< Pointer to sensor connections. */
116 : };
117 :
118 : /**
119 : * @brief Macro to generate a name for a sensor info structure.
120 : *
121 : * This macro generates a name for a sensor info structure based on a node and an index.
122 : *
123 : * @param node The devicetree node identifier.
124 : * @param idx Logical index into the sensor-types array.
125 : */
126 : #define SENSING_SENSOR_INFO_NAME(node, idx) \
127 : _CONCAT(_CONCAT(__sensing_sensor_info_, idx), DEVICE_DT_NAME_GET(node))
128 :
129 : /**
130 : * @brief Macro to define a sensor info structure.
131 : *
132 : * This macro defines a sensor info structure based on a node and an index.
133 : * The structure includes the type, name, friendly name, vendor, model, and minimal interval of the
134 : * sensor.
135 : *
136 : * @param node The devicetree node identifier.
137 : * @param idx Logical index into the sensor-types array.
138 : */
139 : #define SENSING_SENSOR_INFO_DEFINE(node, idx) \
140 : const static STRUCT_SECTION_ITERABLE(sensing_sensor_info, \
141 : SENSING_SENSOR_INFO_NAME(node, idx)) = { \
142 : .type = DT_PROP_BY_IDX(node, sensor_types, idx), \
143 : .name = DT_NODE_FULL_NAME(node), \
144 : .friendly_name = DT_PROP(node, friendly_name), \
145 : .vendor = DT_NODE_VENDOR_OR(node, NULL), \
146 : .model = DT_NODE_MODEL_OR(node, NULL), \
147 : .minimal_interval = DT_PROP(node, minimal_interval), \
148 : };
149 :
150 : /**
151 : * @brief Macro to generate a name for a connections array.
152 : *
153 : * This macro generates a name for a connections array based on a node.
154 : *
155 : * @param node The devicetree node identifier.
156 : */
157 : #define SENSING_CONNECTIONS_NAME(node) \
158 : _CONCAT(__sensing_connections_, DEVICE_DT_NAME_GET(node))
159 :
160 : /**
161 : * @brief Macro to generate a name for a sensor source.
162 : *
163 : * This macro generates a name for a sensor source based on an index and a node.
164 : *
165 : * @param idx Logical index into the reporters array.
166 : * @param node The devicetree node identifier.
167 : */
168 : #define SENSING_SENSOR_SOURCE_NAME(idx, node) \
169 : SENSING_SENSOR_NAME(DT_PHANDLE_BY_IDX(node, reporters, idx), \
170 : DT_PROP_BY_IDX(node, reporters_index, idx))
171 :
172 : /**
173 : * @brief Macro to declare an external sensor source.
174 : *
175 : * This macro declares an external sensor source based on an index and a node.
176 : *
177 : * @param idx Logical index into the reporters array.
178 : * @param node The devicetree node identifier.
179 : */
180 : #define SENSING_SENSOR_SOURCE_EXTERN(idx, node) \
181 : extern struct sensing_sensor SENSING_SENSOR_SOURCE_NAME(idx, node);
182 :
183 : /**
184 : * @brief Macro to initialize a connection.
185 : *
186 : * This macro initializes a connection with a source name and a callback list pointer.
187 : *
188 : * @param source_name The name of struct sensing_sensor for source sensor.
189 : * @param cb_list_ptr Pointer to sensing callback list.
190 : */
191 : #define SENSING_CONNECTION_INITIALIZER(source_name, cb_list_ptr) \
192 : { \
193 : .callback_list = cb_list_ptr, \
194 : .source = &source_name, \
195 : }
196 :
197 : /**
198 : * @brief Macro to define a connection.
199 : *
200 : * This macro defines a connection based on an index, a node, and a callback list pointer.
201 : *
202 : * @param idx Logical index into the reporters array.
203 : * @param node The devicetree node identifier.
204 : * @param cb_list_ptr Pointer to sensing callback list.
205 : */
206 : #define SENSING_CONNECTION_DEFINE(idx, node, cb_list_ptr) \
207 : SENSING_CONNECTION_INITIALIZER(SENSING_SENSOR_SOURCE_NAME(idx, node), \
208 : cb_list_ptr)
209 :
210 : /**
211 : * @brief Macro to define an array of connections.
212 : *
213 : * This macro defines an array of connections based on a node, a number, and a callback list
214 : * pointer.
215 : *
216 : * @param node The devicetree node identifier.
217 : * @param num The number of the connections.
218 : * @param cb_list_ptr Pointer to sensing callback list.
219 : */
220 : #define SENSING_CONNECTIONS_DEFINE(node, num, cb_list_ptr) \
221 : LISTIFY(num, SENSING_SENSOR_SOURCE_EXTERN, \
222 : (), node) \
223 : static struct sensing_connection \
224 : SENSING_CONNECTIONS_NAME(node)[(num)] = { \
225 : LISTIFY(num, SENSING_CONNECTION_DEFINE, \
226 : (,), node, cb_list_ptr) \
227 : };
228 :
229 : /**
230 : * @brief Structure for sensor submit configuration.
231 : *
232 : * This structure represents a sensor submit configuration. It includes the channel, info index, and
233 : * streaming flag.
234 : */
235 : struct sensing_submit_config {
236 : enum sensor_channel chan; /**< Channel of the sensor to submit. */
237 : const int info_index; /**< Logical index into the sensor-types array. */
238 : const bool is_streaming; /**< Working in streaming mode or not. */
239 : };
240 :
241 : /**
242 : * @brief External declaration for the sensing I/O device API.
243 : *
244 : * This external declaration represents the sensing I/O device API.
245 : */
246 : extern const struct rtio_iodev_api __sensing_iodev_api;
247 :
248 : /**
249 : * @brief Macro to generate a name for a submit configuration.
250 : *
251 : * This macro generates a name for a submit configuration based on a node and an index.
252 : *
253 : * @param node The devicetree node identifier.
254 : * @param idx Logical index into the sensor-types array.
255 : */
256 : #define SENSING_SUBMIT_CFG_NAME(node, idx) \
257 : _CONCAT(_CONCAT(__sensing_submit_cfg_, idx), DEVICE_DT_NAME_GET(node))
258 :
259 : /**
260 : * @brief Macro to generate a name for a sensor I/O device.
261 : *
262 : * This macro generates a name for a sensor I/O device based on a node and an index.
263 : *
264 : * @param node The devicetree node identifier.
265 : * @param idx Logical index into the sensor-types array.
266 : */
267 : #define SENSING_SENSOR_IODEV_NAME(node, idx) \
268 : _CONCAT(_CONCAT(__sensing_iodev_, idx), DEVICE_DT_NAME_GET(node))
269 :
270 : /**
271 : * @brief Macro to define a sensor I/O device.
272 : *
273 : * This macro defines a sensor I/O device based on a node and an index.
274 : * The device includes a submit configuration with a streaming flag and an info index.
275 : *
276 : * @param node The devicetree node identifier.
277 : * @param idx Logical index into the sensor-types array.
278 : */
279 : #define SENSING_SENSOR_IODEV_DEFINE(node, idx) \
280 : static struct sensing_submit_config SENSING_SUBMIT_CFG_NAME(node, idx) = { \
281 : .is_streaming = DT_PROP(node, stream_mode), \
282 : .info_index = idx, \
283 : }; \
284 : RTIO_IODEV_DEFINE(SENSING_SENSOR_IODEV_NAME(node, idx), \
285 : &__sensing_iodev_api, \
286 : &SENSING_SUBMIT_CFG_NAME(node, idx));
287 :
288 : /**
289 : * @brief Macro to generate a name for a sensor.
290 : *
291 : * This macro generates a name for a sensor based on a node and an index.
292 : *
293 : * @param node The devicetree node identifier.
294 : * @param idx Logical index into the sensor-types array.
295 : */
296 : #define SENSING_SENSOR_NAME(node, idx) \
297 : _CONCAT(_CONCAT(__sensing_sensor_, idx), DEVICE_DT_NAME_GET(node))
298 :
299 : /**
300 : * @brief Macro to define a sensor.
301 : *
302 : * This macro defines a sensor based on a node, a property, an index, a register info pointer, and a
303 : * callback list pointer. The sensor includes a device, info, register info, reporter number,
304 : * connections, and an I/O device.
305 : *
306 : * @param node The devicetree node identifier.
307 : * @param prop property name.
308 : * @param idx Logical index into the sensor-types array.
309 : * @param reg_ptr Pointer to the device's sensing_sensor_register_info.
310 : * @param cb_list_ptr Pointer to sensing callback list.
311 : */
312 : #define SENSING_SENSOR_DEFINE(node, prop, idx, reg_ptr, cb_list_ptr) \
313 : SENSING_SENSOR_INFO_DEFINE(node, idx) \
314 : SENSING_SENSOR_IODEV_DEFINE(node, idx) \
315 : STRUCT_SECTION_ITERABLE(sensing_sensor, \
316 : SENSING_SENSOR_NAME(node, idx)) = { \
317 : .dev = DEVICE_DT_GET(node), \
318 : .info = &SENSING_SENSOR_INFO_NAME(node, idx), \
319 : .register_info = reg_ptr, \
320 : .reporter_num = DT_PROP_LEN_OR(node, reporters, 0), \
321 : .conns = SENSING_CONNECTIONS_NAME(node), \
322 : .iodev = &SENSING_SENSOR_IODEV_NAME(node, idx), \
323 : };
324 :
325 : /**
326 : * @brief Macro to define sensors.
327 : *
328 : * This macro defines sensors based on a node, a register info pointer, and a callback list pointer.
329 : * It uses the DT_FOREACH_PROP_ELEM_VARGS macro to define each sensor.
330 : *
331 : * @param node The devicetree node identifier.
332 : * @param reg_ptr Pointer to the device's sensing_sensor_register_info.
333 : * @param cb_list_ptr Pointer to sensing callback list.
334 : */
335 : #define SENSING_SENSORS_DEFINE(node, reg_ptr, cb_list_ptr) \
336 : DT_FOREACH_PROP_ELEM_VARGS(node, sensor_types, \
337 : SENSING_SENSOR_DEFINE, reg_ptr, cb_list_ptr)
338 :
339 : /** @endcond */
340 :
341 : /**
342 : * @brief Like SENSOR_DEVICE_DT_DEFINE() with sensing specifics.
343 : *
344 : * @details Defines a sensor which implements the sensor API. May define an
345 : * element in the sensing sensor iterable section used to enumerate all sensing
346 : * sensors.
347 : *
348 : * @param node The devicetree node identifier.
349 : * @param reg_ptr Pointer to the device's sensing_sensor_register_info.
350 : * @param cb_list_ptr Pointer to sensing callback list.
351 : * @param init_fn Name of the init function of the driver.
352 : * @param pm_device PM device resources reference (NULL if device does not use
353 : * PM).
354 : * @param data_ptr Pointer to the device's private data.
355 : * @param cfg_ptr The address to the structure containing the configuration
356 : * information for this instance of the driver.
357 : * @param level The initialization level. See SYS_INIT() for details.
358 : * @param prio Priority within the selected initialization level. See
359 : * SYS_INIT() for details.
360 : * @param api_ptr Provides an initial pointer to the API function struct used
361 : * by the driver. Can be NULL.
362 : */
363 : #define SENSING_SENSORS_DT_DEFINE(node, reg_ptr, cb_list_ptr, \
364 : init_fn, pm_device, \
365 : data_ptr, cfg_ptr, level, prio, \
366 1 : api_ptr, ...) \
367 : SENSOR_DEVICE_DT_DEFINE(node, init_fn, pm_device, \
368 : data_ptr, cfg_ptr, level, prio, \
369 : api_ptr, __VA_ARGS__); \
370 : SENSING_CONNECTIONS_DEFINE(node, \
371 : DT_PROP_LEN_OR(node, reporters, 0), \
372 : cb_list_ptr); \
373 : SENSING_SENSORS_DEFINE(node, reg_ptr, cb_list_ptr);
374 :
375 : /**
376 : * @brief Like SENSING_SENSORS_DT_DEFINE() for an instance of a DT_DRV_COMPAT
377 : * compatible
378 : *
379 : * @param inst instance number. This is replaced by
380 : * <tt>DT_DRV_COMPAT(inst)</tt> in the call to SENSING_SENSORS_DT_DEFINE().
381 : * @param ... other parameters as expected by SENSING_SENSORS_DT_DEFINE().
382 : */
383 1 : #define SENSING_SENSORS_DT_INST_DEFINE(inst, ...) \
384 : SENSING_SENSORS_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
385 :
386 : /**
387 : * @brief Get reporter handles of a given sensor instance by sensor type.
388 : *
389 : * @param dev The sensor instance device structure.
390 : * @param type The given type, \ref SENSING_SENSOR_TYPE_ALL to get reporters
391 : * with all types.
392 : * @param max_handles The max count of the \p reporter_handles array input. Can
393 : * get real count number via \ref sensing_sensor_get_reporters_count
394 : * @param reporter_handles Input handles array for receiving found reporter
395 : * sensor instances
396 : * @return number of reporters found, 0 returned if not found.
397 : */
398 1 : int sensing_sensor_get_reporters(
399 : const struct device *dev, int type,
400 : sensing_sensor_handle_t *reporter_handles, int max_handles);
401 :
402 : /**
403 : * @brief Get reporters count of a given sensor instance by sensor type.
404 : *
405 : * @param dev The sensor instance device structure.
406 : * @param type The sensor type for checking, \ref SENSING_SENSOR_TYPE_ALL
407 : * @return Count of reporters by \p type, 0 returned if no reporters by \p type.
408 : */
409 1 : int sensing_sensor_get_reporters_count(
410 : const struct device *dev, int type);
411 :
412 : /**
413 : * @brief Get this sensor's state
414 : *
415 : * @param dev The sensor instance device structure.
416 : * @param state Returned sensor state value
417 : * @return 0 on success or negative error value on failure.
418 : */
419 1 : int sensing_sensor_get_state(
420 : const struct device *dev,
421 : enum sensing_sensor_state *state);
422 :
423 : /**
424 : * @}
425 : */
426 :
427 : #ifdef __cplusplus
428 : }
429 : #endif
430 :
431 : #endif /*ZEPHYR_INCLUDE_SENSING_SENSOR_H_*/
|