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