1 /**
2 * @file drivers/sensor.h
3 *
4 * @brief Public APIs for the sensor driver.
5 */
6
7 /*
8 * Copyright (c) 2016 Intel Corporation
9 *
10 * SPDX-License-Identifier: Apache-2.0
11 */
12 #ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_H_
13 #define ZEPHYR_INCLUDE_DRIVERS_SENSOR_H_
14
15 /**
16 * @brief Sensor Interface
17 * @defgroup sensor_interface Sensor Interface
18 * @ingroup io_interfaces
19 * @{
20 */
21
22 #include <errno.h>
23 #include <stdlib.h>
24
25 #include <zephyr/device.h>
26 #include <zephyr/dsp/types.h>
27 #include <zephyr/rtio/rtio.h>
28 #include <zephyr/sys/iterable_sections.h>
29 #include <zephyr/types.h>
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 /**
36 * @brief Representation of a sensor readout value.
37 *
38 * The value is represented as having an integer and a fractional part,
39 * and can be obtained using the formula val1 + val2 * 10^(-6). Negative
40 * values also adhere to the above formula, but may need special attention.
41 * Here are some examples of the value representation:
42 *
43 * 0.5: val1 = 0, val2 = 500000
44 * -0.5: val1 = 0, val2 = -500000
45 * -1.0: val1 = -1, val2 = 0
46 * -1.5: val1 = -1, val2 = -500000
47 */
48 struct sensor_value {
49 /** Integer part of the value. */
50 int32_t val1;
51 /** Fractional part of the value (in one-millionth parts). */
52 int32_t val2;
53 };
54
55 /**
56 * @brief Sensor channels.
57 */
58 enum sensor_channel {
59 /** Acceleration on the X axis, in m/s^2. */
60 SENSOR_CHAN_ACCEL_X,
61 /** Acceleration on the Y axis, in m/s^2. */
62 SENSOR_CHAN_ACCEL_Y,
63 /** Acceleration on the Z axis, in m/s^2. */
64 SENSOR_CHAN_ACCEL_Z,
65 /** Acceleration on the X, Y and Z axes. */
66 SENSOR_CHAN_ACCEL_XYZ,
67 /** Angular velocity around the X axis, in radians/s. */
68 SENSOR_CHAN_GYRO_X,
69 /** Angular velocity around the Y axis, in radians/s. */
70 SENSOR_CHAN_GYRO_Y,
71 /** Angular velocity around the Z axis, in radians/s. */
72 SENSOR_CHAN_GYRO_Z,
73 /** Angular velocity around the X, Y and Z axes. */
74 SENSOR_CHAN_GYRO_XYZ,
75 /** Magnetic field on the X axis, in Gauss. */
76 SENSOR_CHAN_MAGN_X,
77 /** Magnetic field on the Y axis, in Gauss. */
78 SENSOR_CHAN_MAGN_Y,
79 /** Magnetic field on the Z axis, in Gauss. */
80 SENSOR_CHAN_MAGN_Z,
81 /** Magnetic field on the X, Y and Z axes. */
82 SENSOR_CHAN_MAGN_XYZ,
83 /** Device die temperature in degrees Celsius. */
84 SENSOR_CHAN_DIE_TEMP,
85 /** Ambient temperature in degrees Celsius. */
86 SENSOR_CHAN_AMBIENT_TEMP,
87 /** Pressure in kilopascal. */
88 SENSOR_CHAN_PRESS,
89 /**
90 * Proximity. Adimensional. A value of 1 indicates that an
91 * object is close.
92 */
93 SENSOR_CHAN_PROX,
94 /** Humidity, in percent. */
95 SENSOR_CHAN_HUMIDITY,
96 /** Illuminance in visible spectrum, in lux. */
97 SENSOR_CHAN_LIGHT,
98 /** Illuminance in infra-red spectrum, in lux. */
99 SENSOR_CHAN_IR,
100 /** Illuminance in red spectrum, in lux. */
101 SENSOR_CHAN_RED,
102 /** Illuminance in green spectrum, in lux. */
103 SENSOR_CHAN_GREEN,
104 /** Illuminance in blue spectrum, in lux. */
105 SENSOR_CHAN_BLUE,
106 /** Altitude, in meters */
107 SENSOR_CHAN_ALTITUDE,
108
109 /** 1.0 micro-meters Particulate Matter, in ug/m^3 */
110 SENSOR_CHAN_PM_1_0,
111 /** 2.5 micro-meters Particulate Matter, in ug/m^3 */
112 SENSOR_CHAN_PM_2_5,
113 /** 10 micro-meters Particulate Matter, in ug/m^3 */
114 SENSOR_CHAN_PM_10,
115 /** Distance. From sensor to target, in meters */
116 SENSOR_CHAN_DISTANCE,
117
118 /** CO2 level, in parts per million (ppm) **/
119 SENSOR_CHAN_CO2,
120 /** VOC level, in parts per billion (ppb) **/
121 SENSOR_CHAN_VOC,
122 /** Gas sensor resistance in ohms. */
123 SENSOR_CHAN_GAS_RES,
124
125 /** Voltage, in volts **/
126 SENSOR_CHAN_VOLTAGE,
127 /** Current, in amps **/
128 SENSOR_CHAN_CURRENT,
129 /** Power in watts **/
130 SENSOR_CHAN_POWER,
131
132 /** Resistance , in Ohm **/
133 SENSOR_CHAN_RESISTANCE,
134
135 /** Angular rotation, in degrees */
136 SENSOR_CHAN_ROTATION,
137
138 /** Position change on the X axis, in points. */
139 SENSOR_CHAN_POS_DX,
140 /** Position change on the Y axis, in points. */
141 SENSOR_CHAN_POS_DY,
142 /** Position change on the Z axis, in points. */
143 SENSOR_CHAN_POS_DZ,
144
145 /** Revolutions per minute, in RPM. */
146 SENSOR_CHAN_RPM,
147
148 /** Voltage, in volts **/
149 SENSOR_CHAN_GAUGE_VOLTAGE,
150 /** Average current, in amps **/
151 SENSOR_CHAN_GAUGE_AVG_CURRENT,
152 /** Standby current, in amps **/
153 SENSOR_CHAN_GAUGE_STDBY_CURRENT,
154 /** Max load current, in amps **/
155 SENSOR_CHAN_GAUGE_MAX_LOAD_CURRENT,
156 /** Gauge temperature **/
157 SENSOR_CHAN_GAUGE_TEMP,
158 /** State of charge measurement in % **/
159 SENSOR_CHAN_GAUGE_STATE_OF_CHARGE,
160 /** Full Charge Capacity in mAh **/
161 SENSOR_CHAN_GAUGE_FULL_CHARGE_CAPACITY,
162 /** Remaining Charge Capacity in mAh **/
163 SENSOR_CHAN_GAUGE_REMAINING_CHARGE_CAPACITY,
164 /** Nominal Available Capacity in mAh **/
165 SENSOR_CHAN_GAUGE_NOM_AVAIL_CAPACITY,
166 /** Full Available Capacity in mAh **/
167 SENSOR_CHAN_GAUGE_FULL_AVAIL_CAPACITY,
168 /** Average power in mW **/
169 SENSOR_CHAN_GAUGE_AVG_POWER,
170 /** State of health measurement in % **/
171 SENSOR_CHAN_GAUGE_STATE_OF_HEALTH,
172 /** Time to empty in minutes **/
173 SENSOR_CHAN_GAUGE_TIME_TO_EMPTY,
174 /** Time to full in minutes **/
175 SENSOR_CHAN_GAUGE_TIME_TO_FULL,
176 /** Cycle count (total number of charge/discharge cycles) **/
177 SENSOR_CHAN_GAUGE_CYCLE_COUNT,
178 /** Design voltage of cell in V (max voltage)*/
179 SENSOR_CHAN_GAUGE_DESIGN_VOLTAGE,
180 /** Desired voltage of cell in V (nominal voltage) */
181 SENSOR_CHAN_GAUGE_DESIRED_VOLTAGE,
182 /** Desired charging current in mA */
183 SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT,
184
185 /** All channels. */
186 SENSOR_CHAN_ALL,
187
188 /**
189 * Number of all common sensor channels.
190 */
191 SENSOR_CHAN_COMMON_COUNT,
192
193 /**
194 * This and higher values are sensor specific.
195 * Refer to the sensor header file.
196 */
197 SENSOR_CHAN_PRIV_START = SENSOR_CHAN_COMMON_COUNT,
198
199 /**
200 * Maximum value describing a sensor channel type.
201 */
202 SENSOR_CHAN_MAX = INT16_MAX,
203 };
204
205 /**
206 * @brief Sensor trigger types.
207 */
208 enum sensor_trigger_type {
209 /**
210 * Timer-based trigger, useful when the sensor does not have an
211 * interrupt line.
212 */
213 SENSOR_TRIG_TIMER,
214 /** Trigger fires whenever new data is ready. */
215 SENSOR_TRIG_DATA_READY,
216 /**
217 * Trigger fires when the selected channel varies significantly.
218 * This includes any-motion detection when the channel is
219 * acceleration or gyro. If detection is based on slope between
220 * successive channel readings, the slope threshold is configured
221 * via the @ref SENSOR_ATTR_SLOPE_TH and @ref SENSOR_ATTR_SLOPE_DUR
222 * attributes.
223 */
224 SENSOR_TRIG_DELTA,
225 /** Trigger fires when a near/far event is detected. */
226 SENSOR_TRIG_NEAR_FAR,
227 /**
228 * Trigger fires when channel reading transitions configured
229 * thresholds. The thresholds are configured via the @ref
230 * SENSOR_ATTR_LOWER_THRESH, @ref SENSOR_ATTR_UPPER_THRESH, and
231 * @ref SENSOR_ATTR_HYSTERESIS attributes.
232 */
233 SENSOR_TRIG_THRESHOLD,
234
235 /** Trigger fires when a single tap is detected. */
236 SENSOR_TRIG_TAP,
237
238 /** Trigger fires when a double tap is detected. */
239 SENSOR_TRIG_DOUBLE_TAP,
240
241 /** Trigger fires when a free fall is detected. */
242 SENSOR_TRIG_FREEFALL,
243
244 /** Trigger fires when motion is detected. */
245 SENSOR_TRIG_MOTION,
246
247 /** Trigger fires when no motion has been detected for a while. */
248 SENSOR_TRIG_STATIONARY,
249 /**
250 * Number of all common sensor triggers.
251 */
252 SENSOR_TRIG_COMMON_COUNT,
253
254 /**
255 * This and higher values are sensor specific.
256 * Refer to the sensor header file.
257 */
258 SENSOR_TRIG_PRIV_START = SENSOR_TRIG_COMMON_COUNT,
259
260 /**
261 * Maximum value describing a sensor trigger type.
262 */
263 SENSOR_TRIG_MAX = INT16_MAX,
264 };
265
266 /**
267 * @brief Sensor trigger spec.
268 */
269 struct sensor_trigger {
270 /** Trigger type. */
271 enum sensor_trigger_type type;
272 /** Channel the trigger is set on. */
273 enum sensor_channel chan;
274 };
275
276 /**
277 * @brief Sensor attribute types.
278 */
279 enum sensor_attribute {
280 /**
281 * Sensor sampling frequency, i.e. how many times a second the
282 * sensor takes a measurement.
283 */
284 SENSOR_ATTR_SAMPLING_FREQUENCY,
285 /** Lower threshold for trigger. */
286 SENSOR_ATTR_LOWER_THRESH,
287 /** Upper threshold for trigger. */
288 SENSOR_ATTR_UPPER_THRESH,
289 /** Threshold for any-motion (slope) trigger. */
290 SENSOR_ATTR_SLOPE_TH,
291 /**
292 * Duration for which the slope values needs to be
293 * outside the threshold for the trigger to fire.
294 */
295 SENSOR_ATTR_SLOPE_DUR,
296 /* Hysteresis for trigger thresholds. */
297 SENSOR_ATTR_HYSTERESIS,
298 /** Oversampling factor */
299 SENSOR_ATTR_OVERSAMPLING,
300 /** Sensor range, in SI units. */
301 SENSOR_ATTR_FULL_SCALE,
302 /**
303 * The sensor value returned will be altered by the amount indicated by
304 * offset: final_value = sensor_value + offset.
305 */
306 SENSOR_ATTR_OFFSET,
307 /**
308 * Calibration target. This will be used by the internal chip's
309 * algorithms to calibrate itself on a certain axis, or all of them.
310 */
311 SENSOR_ATTR_CALIB_TARGET,
312 /** Configure the operating modes of a sensor. */
313 SENSOR_ATTR_CONFIGURATION,
314 /** Set a calibration value needed by a sensor. */
315 SENSOR_ATTR_CALIBRATION,
316 /** Enable/disable sensor features */
317 SENSOR_ATTR_FEATURE_MASK,
318 /** Alert threshold or alert enable/disable */
319 SENSOR_ATTR_ALERT,
320 /** Free-fall duration represented in milliseconds.
321 * If the sampling frequency is changed during runtime,
322 * this attribute should be set to adjust freefall duration
323 * to the new sampling frequency.
324 */
325 SENSOR_ATTR_FF_DUR,
326 /**
327 * Number of all common sensor attributes.
328 */
329 SENSOR_ATTR_COMMON_COUNT,
330
331 /**
332 * This and higher values are sensor specific.
333 * Refer to the sensor header file.
334 */
335 SENSOR_ATTR_PRIV_START = SENSOR_ATTR_COMMON_COUNT,
336
337 /**
338 * Maximum value describing a sensor attribute type.
339 */
340 SENSOR_ATTR_MAX = INT16_MAX,
341 };
342
343 /**
344 * @typedef sensor_trigger_handler_t
345 * @brief Callback API upon firing of a trigger
346 *
347 * @param dev Pointer to the sensor device
348 * @param trigger The trigger
349 */
350 typedef void (*sensor_trigger_handler_t)(const struct device *dev,
351 const struct sensor_trigger *trigger);
352
353 /**
354 * @typedef sensor_attr_set_t
355 * @brief Callback API upon setting a sensor's attributes
356 *
357 * See sensor_attr_set() for argument description
358 */
359 typedef int (*sensor_attr_set_t)(const struct device *dev,
360 enum sensor_channel chan,
361 enum sensor_attribute attr,
362 const struct sensor_value *val);
363
364 /**
365 * @typedef sensor_attr_get_t
366 * @brief Callback API upon getting a sensor's attributes
367 *
368 * See sensor_attr_get() for argument description
369 */
370 typedef int (*sensor_attr_get_t)(const struct device *dev,
371 enum sensor_channel chan,
372 enum sensor_attribute attr,
373 struct sensor_value *val);
374
375 /**
376 * @typedef sensor_trigger_set_t
377 * @brief Callback API for setting a sensor's trigger and handler
378 *
379 * See sensor_trigger_set() for argument description
380 */
381 typedef int (*sensor_trigger_set_t)(const struct device *dev,
382 const struct sensor_trigger *trig,
383 sensor_trigger_handler_t handler);
384 /**
385 * @typedef sensor_sample_fetch_t
386 * @brief Callback API for fetching data from a sensor
387 *
388 * See sensor_sample_fetch() for argument description
389 */
390 typedef int (*sensor_sample_fetch_t)(const struct device *dev,
391 enum sensor_channel chan);
392 /**
393 * @typedef sensor_channel_get_t
394 * @brief Callback API for getting a reading from a sensor
395 *
396 * See sensor_channel_get() for argument description
397 */
398 typedef int (*sensor_channel_get_t)(const struct device *dev,
399 enum sensor_channel chan,
400 struct sensor_value *val);
401
402 /**
403 * @typedef sensor_frame_iterator_t
404 * @brief Used for iterating over the data frames via the :c:struct:`sensor_decoder_api`
405 *
406 * Example usage:
407 *
408 * @code(.c)
409 * sensor_frame_iterator_t fit = {0}, fit_last;
410 * sensor_channel_iterator_t cit = {0}, cit_last;
411 *
412 * while (true) {
413 * int num_decoded_channels;
414 * enum sensor_channel channel;
415 * q31_t value;
416 *
417 * fit_last = fit;
418 * num_decoded_channels = decoder->decode(buffer, &fit, &cit, &channel, &value, 1);
419 *
420 * if (num_decoded_channels <= 0) {
421 * printk("Done decoding buffer\n");
422 * break;
423 * }
424 *
425 * printk("Decoded channel (%d) with value %s0.%06" PRIi64 "\n", q < 0 ? "-" : "",
426 * abs(q) * INT64_C(1000000) / (INT64_C(1) << 31));
427 *
428 * if (fit_last != fit) {
429 * printk("Finished decoding frame\n");
430 * }
431 * }
432 * @endcode
433 */
434 typedef uint32_t sensor_frame_iterator_t;
435
436 /**
437 * @typedef sensor_channel_iterator_t
438 * @brief Used for iterating over data channels in the same frame via :c:struct:`sensor_decoder_api`
439 */
440 typedef uint32_t sensor_channel_iterator_t;
441
442 /**
443 * @brief Decodes a single raw data buffer
444 *
445 * Data buffers are provided on the :c:struct:`rtio` context that's supplied to
446 * c:func:`sensor_read`.
447 */
448 struct sensor_decoder_api {
449 /**
450 * @brief Get the number of frames in the current buffer.
451 *
452 * @param[in] buffer The buffer provided on the :c:struct:`rtio` context.
453 * @param[out] frame_count The number of frames on the buffer (at least 1)
454 * @return 0 on success
455 * @return <0 on error
456 */
457 int (*get_frame_count)(const uint8_t *buffer, uint16_t *frame_count);
458
459 /**
460 * @brief Get the timestamp associated with the first frame.
461 *
462 * @param[in] buffer The buffer provided on the :c:struct:`rtio` context.
463 * @param[out] timestamp_ns The closest timestamp for when the first frame was generated
464 * as attained by :c:func:`k_uptime_ticks`.
465 * @return 0 on success
466 * @return <0 on error
467 */
468 int (*get_timestamp)(const uint8_t *buffer, uint64_t *timestamp_ns);
469
470 /**
471 * @brief Get the shift count of a particular channel (multiplier)
472 *
473 * This value can be used by shifting the q31_t value resulting in the SI unit of the
474 * reading. It is guaranteed that the shift for a channel will not change between frames.
475 *
476 * @param[in] buffer The buffer provided on the :c:struct:`rtio` context.
477 * @param[in] channel_type The c:enum:`sensor_channel` to query
478 * @param[out] shift The bit shift of the channel for this data buffer.
479 * @return 0 on success
480 * @return -EINVAL if the @p channel_type doesn't exist in the buffer
481 * @return <0 on error
482 */
483 int (*get_shift)(const uint8_t *buffer, enum sensor_channel channel_type, int8_t *shift);
484
485 /**
486 * @brief Decode up to N samples from the buffer
487 *
488 * This function will never wrap frames. If 1 channel is available in the current frame and
489 * @p max_count is 2, only 1 channel will be decoded and the frame iterator will be modified
490 * so that the next call to decode will begin at the next frame.
491 *
492 * @param[in] buffer The buffer provided on the :c:struct:`rtio` context
493 * @param[in,out] fit The current frame iterator
494 * @param[in,out] cit The current channel iterator
495 * @param[out] channels The channels that were decoded
496 * @param[out] values The scaled data that was decoded
497 * @param[in] max_count The maximum number of channels to decode.
498 * @return
499 */
500 int (*decode)(const uint8_t *buffer, sensor_frame_iterator_t *fit,
501 sensor_channel_iterator_t *cit, enum sensor_channel *channels, q31_t *values,
502 uint8_t max_count);
503 };
504
505 /**
506 * @typedef sensor_get_decoder_t
507 * @brief Get the decoder associate with the given device
508 *
509 * @see sensor_get_decoder for more details
510 */
511 typedef int (*sensor_get_decoder_t)(const struct device *dev,
512 const struct sensor_decoder_api **api);
513
514 /*
515 * Internal data structure used to store information about the IODevice for async reading and
516 * streaming sensor data.
517 */
518 struct sensor_read_config {
519 const struct device *sensor;
520 enum sensor_channel *const channels;
521 size_t count;
522 const size_t max;
523 };
524
525 /**
526 * @brief Define a reading instance of a sensor
527 *
528 * Use this macro to generate a :c:struct:`rtio_iodev` for reading specific channels. Example:
529 *
530 * @code(.c)
531 * SENSOR_DT_READ_IODEV(icm42688_accelgyro, DT_NODELABEL(icm42688),
532 * SENSOR_CHAN_ACCEL_XYZ, SENSOR_CHAN_GYRO_XYZ);
533 *
534 * int main(void) {
535 * sensor_read(&icm42688_accelgyro, &rtio);
536 * }
537 * @endcode
538 */
539 #define SENSOR_DT_READ_IODEV(name, dt_node, ...) \
540 static enum sensor_channel __channel_array_##name[] = {__VA_ARGS__}; \
541 static struct sensor_read_config __sensor_read_config_##name = { \
542 .sensor = DEVICE_DT_GET(dt_node), \
543 .channels = __channel_array_##name, \
544 .count = ARRAY_SIZE(__channel_array_##name), \
545 .max = ARRAY_SIZE(__channel_array_##name), \
546 }; \
547 RTIO_IODEV_DEFINE(name, &__sensor_iodev_api, &__sensor_read_config_##name)
548
549 /* Used to submit an RTIO sqe to the sensor's iodev */
550 typedef int (*sensor_submit_t)(const struct device *sensor, struct rtio_iodev_sqe *sqe);
551
552 /* The default decoder API */
553 extern const struct sensor_decoder_api __sensor_default_decoder;
554
555 /* The default sensor iodev API */
556 extern const struct rtio_iodev_api __sensor_iodev_api;
557
558 __subsystem struct sensor_driver_api {
559 sensor_attr_set_t attr_set;
560 sensor_attr_get_t attr_get;
561 sensor_trigger_set_t trigger_set;
562 sensor_sample_fetch_t sample_fetch;
563 sensor_channel_get_t channel_get;
564 sensor_get_decoder_t get_decoder;
565 sensor_submit_t submit;
566 };
567
568 /**
569 * @brief Set an attribute for a sensor
570 *
571 * @param dev Pointer to the sensor device
572 * @param chan The channel the attribute belongs to, if any. Some
573 * attributes may only be set for all channels of a device, depending on
574 * device capabilities.
575 * @param attr The attribute to set
576 * @param val The value to set the attribute to
577 *
578 * @return 0 if successful, negative errno code if failure.
579 */
580 __syscall int sensor_attr_set(const struct device *dev,
581 enum sensor_channel chan,
582 enum sensor_attribute attr,
583 const struct sensor_value *val);
584
z_impl_sensor_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)585 static inline int z_impl_sensor_attr_set(const struct device *dev,
586 enum sensor_channel chan,
587 enum sensor_attribute attr,
588 const struct sensor_value *val)
589 {
590 const struct sensor_driver_api *api =
591 (const struct sensor_driver_api *)dev->api;
592
593 if (api->attr_set == NULL) {
594 return -ENOSYS;
595 }
596
597 return api->attr_set(dev, chan, attr, val);
598 }
599
600 /**
601 * @brief Get an attribute for a sensor
602 *
603 * @param dev Pointer to the sensor device
604 * @param chan The channel the attribute belongs to, if any. Some
605 * attributes may only be set for all channels of a device, depending on
606 * device capabilities.
607 * @param attr The attribute to get
608 * @param val Pointer to where to store the attribute
609 *
610 * @return 0 if successful, negative errno code if failure.
611 */
612 __syscall int sensor_attr_get(const struct device *dev,
613 enum sensor_channel chan,
614 enum sensor_attribute attr,
615 struct sensor_value *val);
616
z_impl_sensor_attr_get(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)617 static inline int z_impl_sensor_attr_get(const struct device *dev,
618 enum sensor_channel chan,
619 enum sensor_attribute attr,
620 struct sensor_value *val)
621 {
622 const struct sensor_driver_api *api =
623 (const struct sensor_driver_api *)dev->api;
624
625 if (api->attr_get == NULL) {
626 return -ENOSYS;
627 }
628
629 return api->attr_get(dev, chan, attr, val);
630 }
631
632 /**
633 * @brief Activate a sensor's trigger and set the trigger handler
634 *
635 * The handler will be called from a thread, so I2C or SPI operations are
636 * safe. However, the thread's stack is limited and defined by the
637 * driver. It is currently up to the caller to ensure that the handler
638 * does not overflow the stack.
639 *
640 * The user-allocated trigger will be stored by the driver as a pointer, rather
641 * than a copy, and passed back to the handler. This enables the handler to use
642 * CONTAINER_OF to retrieve a context pointer when the trigger is embedded in a
643 * larger struct and requires that the trigger is not allocated on the stack.
644 *
645 * @funcprops \supervisor
646 *
647 * @param dev Pointer to the sensor device
648 * @param trig The trigger to activate
649 * @param handler The function that should be called when the trigger
650 * fires
651 *
652 * @return 0 if successful, negative errno code if failure.
653 */
sensor_trigger_set(const struct device * dev,const struct sensor_trigger * trig,sensor_trigger_handler_t handler)654 static inline int sensor_trigger_set(const struct device *dev,
655 const struct sensor_trigger *trig,
656 sensor_trigger_handler_t handler)
657 {
658 const struct sensor_driver_api *api =
659 (const struct sensor_driver_api *)dev->api;
660
661 if (api->trigger_set == NULL) {
662 return -ENOSYS;
663 }
664
665 return api->trigger_set(dev, trig, handler);
666 }
667
668 /**
669 * @brief Fetch a sample from the sensor and store it in an internal
670 * driver buffer
671 *
672 * Read all of a sensor's active channels and, if necessary, perform any
673 * additional operations necessary to make the values useful. The user
674 * may then get individual channel values by calling @ref
675 * sensor_channel_get.
676 *
677 * The function blocks until the fetch operation is complete.
678 *
679 * Since the function communicates with the sensor device, it is unsafe
680 * to call it in an ISR if the device is connected via I2C or SPI.
681 *
682 * @param dev Pointer to the sensor device
683 *
684 * @return 0 if successful, negative errno code if failure.
685 */
686 __syscall int sensor_sample_fetch(const struct device *dev);
687
z_impl_sensor_sample_fetch(const struct device * dev)688 static inline int z_impl_sensor_sample_fetch(const struct device *dev)
689 {
690 const struct sensor_driver_api *api =
691 (const struct sensor_driver_api *)dev->api;
692
693 return api->sample_fetch(dev, SENSOR_CHAN_ALL);
694 }
695
696 /**
697 * @brief Fetch a sample from the sensor and store it in an internal
698 * driver buffer
699 *
700 * Read and compute compensation for one type of sensor data (magnetometer,
701 * accelerometer, etc). The user may then get individual channel values by
702 * calling @ref sensor_channel_get.
703 *
704 * This is mostly implemented by multi function devices enabling reading at
705 * different sampling rates.
706 *
707 * The function blocks until the fetch operation is complete.
708 *
709 * Since the function communicates with the sensor device, it is unsafe
710 * to call it in an ISR if the device is connected via I2C or SPI.
711 *
712 * @param dev Pointer to the sensor device
713 * @param type The channel that needs updated
714 *
715 * @return 0 if successful, negative errno code if failure.
716 */
717 __syscall int sensor_sample_fetch_chan(const struct device *dev,
718 enum sensor_channel type);
719
z_impl_sensor_sample_fetch_chan(const struct device * dev,enum sensor_channel type)720 static inline int z_impl_sensor_sample_fetch_chan(const struct device *dev,
721 enum sensor_channel type)
722 {
723 const struct sensor_driver_api *api =
724 (const struct sensor_driver_api *)dev->api;
725
726 return api->sample_fetch(dev, type);
727 }
728
729 /**
730 * @brief Get a reading from a sensor device
731 *
732 * Return a useful value for a particular channel, from the driver's
733 * internal data. Before calling this function, a sample must be
734 * obtained by calling @ref sensor_sample_fetch or
735 * @ref sensor_sample_fetch_chan. It is guaranteed that two subsequent
736 * calls of this function for the same channels will yield the same
737 * value, if @ref sensor_sample_fetch or @ref sensor_sample_fetch_chan
738 * has not been called in the meantime.
739 *
740 * For vectorial data samples you can request all axes in just one call
741 * by passing the specific channel with _XYZ suffix. The sample will be
742 * returned at val[0], val[1] and val[2] (X, Y and Z in that order).
743 *
744 * @param dev Pointer to the sensor device
745 * @param chan The channel to read
746 * @param val Where to store the value
747 *
748 * @return 0 if successful, negative errno code if failure.
749 */
750 __syscall int sensor_channel_get(const struct device *dev,
751 enum sensor_channel chan,
752 struct sensor_value *val);
753
z_impl_sensor_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)754 static inline int z_impl_sensor_channel_get(const struct device *dev,
755 enum sensor_channel chan,
756 struct sensor_value *val)
757 {
758 const struct sensor_driver_api *api =
759 (const struct sensor_driver_api *)dev->api;
760
761 return api->channel_get(dev, chan, val);
762 }
763
764 #if defined(CONFIG_SENSOR_ASYNC_API) || defined(__DOXYGEN__)
765
766 /*
767 * Generic data structure used for encoding the sample timestamp and number of channels sampled.
768 */
769 struct __attribute__((__packed__)) sensor_data_generic_header {
770 /* The timestamp at which the data was collected from the sensor */
771 uint64_t timestamp_ns;
772
773 /*
774 * The number of channels present in the frame. This will be the true number of elements in
775 * channel_info and in the q31 values that follow the header.
776 */
777 size_t num_channels;
778
779 /* Shift value for all samples in the frame */
780 int8_t shift;
781
782 /* Channels present in the frame */
783 enum sensor_channel channels[0];
784 };
785
786 /**
787 * @brief checks if a given channel is a 3-axis channel
788 *
789 * @param[in] chan The channel to check
790 * @return true if @p chan is :c:enum:`SENSOR_CHAN_ACCEL_XYZ`
791 * @return true if @p chan is :c:enum:`SENSOR_CHAN_GYRO_XYZ`
792 * @return true if @p chan is :c:enum:`SENSOR_CHAN_MAGN_XYZ`
793 * @return false otherwise
794 */
795 #define SENSOR_CHANNEL_3_AXIS(chan) \
796 ((chan) == SENSOR_CHAN_ACCEL_XYZ || (chan) == SENSOR_CHAN_GYRO_XYZ || \
797 (chan) == SENSOR_CHAN_MAGN_XYZ)
798
799 /**
800 * @brief Get the sensor's decoder API
801 *
802 * @param[in] dev The sensor device
803 * @param[in] decoder Pointer to the decoder which will be set upon success
804 * @return 0 on success
805 * @return < 0 on error
806 */
807 __syscall int sensor_get_decoder(const struct device *dev,
808 const struct sensor_decoder_api **decoder);
809
z_impl_sensor_get_decoder(const struct device * dev,const struct sensor_decoder_api ** decoder)810 static inline int z_impl_sensor_get_decoder(const struct device *dev,
811 const struct sensor_decoder_api **decoder)
812 {
813 const struct sensor_driver_api *api = (const struct sensor_driver_api *)dev->api;
814
815 __ASSERT_NO_MSG(api != NULL);
816
817 if (api->get_decoder == NULL) {
818 *decoder = &__sensor_default_decoder;
819 return 0;
820 }
821
822 return api->get_decoder(dev, decoder);
823 }
824
825 /**
826 * @brief Reconfigure a reading iodev
827 *
828 * Allows a reconfiguration of the iodev associated with reading a sample from a sensor.
829 *
830 * <b>Important</b>: If the iodev is currently servicing a read operation, the data will likely be
831 * invalid. Please be sure the flush or wait for all pending operations to complete before using the
832 * data after a configuration change.
833 *
834 * It is also important that the `data` field of the iodev is a :c:struct:`sensor_read_config`.
835 *
836 * @param[in] iodev The iodev to reconfigure
837 * @param[in] sensor The sensor to read from
838 * @param[in] channels One or more channels to read
839 * @param[in] num_channels The number of channels in @p channels
840 * @return 0 on success
841 * @return < 0 on error
842 */
843 __syscall int sensor_reconfigure_read_iodev(struct rtio_iodev *iodev, const struct device *sensor,
844 const enum sensor_channel *channels,
845 size_t num_channels);
846
z_impl_sensor_reconfigure_read_iodev(struct rtio_iodev * iodev,const struct device * sensor,const enum sensor_channel * channels,size_t num_channels)847 static inline int z_impl_sensor_reconfigure_read_iodev(struct rtio_iodev *iodev,
848 const struct device *sensor,
849 const enum sensor_channel *channels,
850 size_t num_channels)
851 {
852 struct sensor_read_config *cfg = (struct sensor_read_config *)iodev->data;
853
854 if (cfg->max < num_channels) {
855 return -ENOMEM;
856 }
857
858 cfg->sensor = sensor;
859 memcpy(cfg->channels, channels, num_channels * sizeof(enum sensor_channel));
860 cfg->count = num_channels;
861 return 0;
862 return 0;
863 }
864
865 /**
866 * @brief Read data from a sensor.
867 *
868 * Using @p cfg, read one snapshot of data from the device by using the provided RTIO context
869 * @p ctx. This call will generate a :c:struct:`rtio_sqe` that will leverage the RTIO's internal
870 * mempool when the time comes to service the read.
871 *
872 * @param[in] iodev The iodev created by :c:macro:`SENSOR_DT_READ_IODEV`
873 * @param[in] ctx The RTIO context to service the read
874 * @param[in] userdata Optional userdata that will be available when the read is complete
875 * @return 0 on success
876 * @return < 0 on error
877 */
sensor_read(struct rtio_iodev * iodev,struct rtio * ctx,void * userdata)878 static inline int sensor_read(struct rtio_iodev *iodev, struct rtio *ctx, void *userdata)
879 {
880 if (IS_ENABLED(CONFIG_USERSPACE)) {
881 struct rtio_sqe sqe;
882
883 rtio_sqe_prep_read_with_pool(&sqe, iodev, RTIO_PRIO_NORM, userdata);
884 rtio_sqe_copy_in(ctx, &sqe, 1);
885 } else {
886 struct rtio_sqe *sqe = rtio_sqe_acquire(ctx);
887
888 if (sqe == NULL) {
889 return -ENOMEM;
890 }
891 rtio_sqe_prep_read_with_pool(sqe, iodev, RTIO_PRIO_NORM, userdata);
892 }
893 rtio_submit(ctx, 0);
894 return 0;
895 }
896
897 /**
898 * @typedef sensor_processing_callback_t
899 * @brief Callback function used with the helper processing function.
900 *
901 * @see sensor_processing_with_callback
902 *
903 * @param[in] result The result code of the read (0 being success)
904 * @param[in] buf The data buffer holding the sensor data
905 * @param[in] buf_len The length (in bytes) of the @p buf
906 * @param[in] userdata The optional userdata passed to :c:func:`sensor_read`
907 */
908 typedef void (*sensor_processing_callback_t)(int result, uint8_t *buf, uint32_t buf_len,
909 void *userdata);
910
911 /**
912 * @brief Helper function for common processing of sensor data.
913 *
914 * This function can be called in a blocking manner after :c:func:`sensor_read` or in a standalone
915 * thread dedicated to processing. It will wait for a cqe from the RTIO context, once received, it
916 * will decode the userdata and call the @p cb. Once the @p cb returns, the buffer will be released
917 * back into @p ctx's mempool if available.
918 *
919 * @param[in] ctx The RTIO context to wait on
920 * @param[in] cb Callback to call when data is ready for processing
921 */
922 void sensor_processing_with_callback(struct rtio *ctx, sensor_processing_callback_t cb);
923
924 #endif /* defined(CONFIG_SENSOR_ASYNC_API) || defined(__DOXYGEN__) */
925
926 /**
927 * @brief The value of gravitational constant in micro m/s^2.
928 */
929 #define SENSOR_G 9806650LL
930
931 /**
932 * @brief The value of constant PI in micros.
933 */
934 #define SENSOR_PI 3141592LL
935
936 /**
937 * @brief Helper function to convert acceleration from m/s^2 to Gs
938 *
939 * @param ms2 A pointer to a sensor_value struct holding the acceleration,
940 * in m/s^2.
941 *
942 * @return The converted value, in Gs.
943 */
sensor_ms2_to_g(const struct sensor_value * ms2)944 static inline int32_t sensor_ms2_to_g(const struct sensor_value *ms2)
945 {
946 int64_t micro_ms2 = ms2->val1 * 1000000LL + ms2->val2;
947
948 if (micro_ms2 > 0) {
949 return (micro_ms2 + SENSOR_G / 2) / SENSOR_G;
950 } else {
951 return (micro_ms2 - SENSOR_G / 2) / SENSOR_G;
952 }
953 }
954
955 /**
956 * @brief Helper function to convert acceleration from Gs to m/s^2
957 *
958 * @param g The G value to be converted.
959 * @param ms2 A pointer to a sensor_value struct, where the result is stored.
960 */
sensor_g_to_ms2(int32_t g,struct sensor_value * ms2)961 static inline void sensor_g_to_ms2(int32_t g, struct sensor_value *ms2)
962 {
963 ms2->val1 = ((int64_t)g * SENSOR_G) / 1000000LL;
964 ms2->val2 = ((int64_t)g * SENSOR_G) % 1000000LL;
965 }
966
967 /**
968 * @brief Helper function to convert acceleration from m/s^2 to micro Gs
969 *
970 * @param ms2 A pointer to a sensor_value struct holding the acceleration,
971 * in m/s^2.
972 *
973 * @return The converted value, in micro Gs.
974 */
sensor_ms2_to_ug(const struct sensor_value * ms2)975 static inline int32_t sensor_ms2_to_ug(const struct sensor_value *ms2)
976 {
977 int64_t micro_ms2 = (ms2->val1 * INT64_C(1000000)) + ms2->val2;
978
979 return (micro_ms2 * 1000000LL) / SENSOR_G;
980 }
981
982 /**
983 * @brief Helper function to convert acceleration from micro Gs to m/s^2
984 *
985 * @param ug The micro G value to be converted.
986 * @param ms2 A pointer to a sensor_value struct, where the result is stored.
987 */
sensor_ug_to_ms2(int32_t ug,struct sensor_value * ms2)988 static inline void sensor_ug_to_ms2(int32_t ug, struct sensor_value *ms2)
989 {
990 ms2->val1 = ((int64_t)ug * SENSOR_G / 1000000LL) / 1000000LL;
991 ms2->val2 = ((int64_t)ug * SENSOR_G / 1000000LL) % 1000000LL;
992 }
993
994 /**
995 * @brief Helper function for converting radians to degrees.
996 *
997 * @param rad A pointer to a sensor_value struct, holding the value in radians.
998 *
999 * @return The converted value, in degrees.
1000 */
sensor_rad_to_degrees(const struct sensor_value * rad)1001 static inline int32_t sensor_rad_to_degrees(const struct sensor_value *rad)
1002 {
1003 int64_t micro_rad_s = rad->val1 * 1000000LL + rad->val2;
1004
1005 if (micro_rad_s > 0) {
1006 return (micro_rad_s * 180LL + SENSOR_PI / 2) / SENSOR_PI;
1007 } else {
1008 return (micro_rad_s * 180LL - SENSOR_PI / 2) / SENSOR_PI;
1009 }
1010 }
1011
1012 /**
1013 * @brief Helper function for converting degrees to radians.
1014 *
1015 * @param d The value (in degrees) to be converted.
1016 * @param rad A pointer to a sensor_value struct, where the result is stored.
1017 */
sensor_degrees_to_rad(int32_t d,struct sensor_value * rad)1018 static inline void sensor_degrees_to_rad(int32_t d, struct sensor_value *rad)
1019 {
1020 rad->val1 = ((int64_t)d * SENSOR_PI / 180LL) / 1000000LL;
1021 rad->val2 = ((int64_t)d * SENSOR_PI / 180LL) % 1000000LL;
1022 }
1023
1024 /**
1025 * @brief Helper function for converting radians to 10 micro degrees.
1026 *
1027 * When the unit is 1 micro degree, the range that the int32_t can represent is
1028 * +/-2147.483 degrees. In order to increase this range, here we use 10 micro
1029 * degrees as the unit.
1030 *
1031 * @param rad A pointer to a sensor_value struct, holding the value in radians.
1032 *
1033 * @return The converted value, in 10 micro degrees.
1034 */
sensor_rad_to_10udegrees(const struct sensor_value * rad)1035 static inline int32_t sensor_rad_to_10udegrees(const struct sensor_value *rad)
1036 {
1037 int64_t micro_rad_s = rad->val1 * 1000000LL + rad->val2;
1038
1039 return (micro_rad_s * 180LL * 100000LL) / SENSOR_PI;
1040 }
1041
1042 /**
1043 * @brief Helper function for converting 10 micro degrees to radians.
1044 *
1045 * @param d The value (in 10 micro degrees) to be converted.
1046 * @param rad A pointer to a sensor_value struct, where the result is stored.
1047 */
sensor_10udegrees_to_rad(int32_t d,struct sensor_value * rad)1048 static inline void sensor_10udegrees_to_rad(int32_t d, struct sensor_value *rad)
1049 {
1050 rad->val1 = ((int64_t)d * SENSOR_PI / 180LL / 100000LL) / 1000000LL;
1051 rad->val2 = ((int64_t)d * SENSOR_PI / 180LL / 100000LL) % 1000000LL;
1052 }
1053
1054 /**
1055 * @brief Helper function for converting struct sensor_value to double.
1056 *
1057 * @param val A pointer to a sensor_value struct.
1058 * @return The converted value.
1059 */
sensor_value_to_double(const struct sensor_value * val)1060 static inline double sensor_value_to_double(const struct sensor_value *val)
1061 {
1062 return (double)val->val1 + (double)val->val2 / 1000000;
1063 }
1064
1065 /**
1066 * @brief Helper function for converting struct sensor_value to float.
1067 *
1068 * @param val A pointer to a sensor_value struct.
1069 * @return The converted value.
1070 */
sensor_value_to_float(const struct sensor_value * val)1071 static inline float sensor_value_to_float(const struct sensor_value *val)
1072 {
1073 return (float)val->val1 + (float)val->val2 / 1000000;
1074 }
1075
1076 /**
1077 * @brief Helper function for converting double to struct sensor_value.
1078 *
1079 * @param val A pointer to a sensor_value struct.
1080 * @param inp The converted value.
1081 * @return 0 if successful, negative errno code if failure.
1082 */
sensor_value_from_double(struct sensor_value * val,double inp)1083 static inline int sensor_value_from_double(struct sensor_value *val, double inp)
1084 {
1085 if (inp < INT32_MIN || inp > INT32_MAX) {
1086 return -ERANGE;
1087 }
1088
1089 double val2 = (inp - (int32_t)inp) * 1000000.0;
1090
1091 if (val2 < INT32_MIN || val2 > INT32_MAX) {
1092 return -ERANGE;
1093 }
1094
1095 val->val1 = (int32_t)inp;
1096 val->val2 = (int32_t)val2;
1097
1098 return 0;
1099 }
1100
1101 /**
1102 * @brief Helper function for converting float to struct sensor_value.
1103 *
1104 * @param val A pointer to a sensor_value struct.
1105 * @param inp The converted value.
1106 * @return 0 if successful, negative errno code if failure.
1107 */
sensor_value_from_float(struct sensor_value * val,float inp)1108 static inline int sensor_value_from_float(struct sensor_value *val, float inp)
1109 {
1110 float val2 = (inp - (int32_t)inp) * 1000000.0;
1111
1112 if (val2 < INT32_MIN || val2 > (float)(INT32_MAX - 1)) {
1113 return -ERANGE;
1114 }
1115
1116 val->val1 = (int32_t)inp;
1117 val->val2 = (int32_t)val2;
1118
1119 return 0;
1120 }
1121
1122 #ifdef CONFIG_SENSOR_INFO
1123
1124 struct sensor_info {
1125 const struct device *dev;
1126 const char *vendor;
1127 const char *model;
1128 const char *friendly_name;
1129 };
1130
1131 #define SENSOR_INFO_INITIALIZER(_dev, _vendor, _model, _friendly_name) \
1132 { \
1133 .dev = _dev, \
1134 .vendor = _vendor, \
1135 .model = _model, \
1136 .friendly_name = _friendly_name, \
1137 }
1138
1139 #define SENSOR_INFO_DEFINE(name, ...) \
1140 static const STRUCT_SECTION_ITERABLE(sensor_info, name) = \
1141 SENSOR_INFO_INITIALIZER(__VA_ARGS__)
1142
1143 #define SENSOR_INFO_DT_NAME(node_id) \
1144 _CONCAT(__sensor_info, DEVICE_DT_NAME_GET(node_id))
1145
1146 #define SENSOR_INFO_DT_DEFINE(node_id) \
1147 SENSOR_INFO_DEFINE(SENSOR_INFO_DT_NAME(node_id), \
1148 DEVICE_DT_GET(node_id), \
1149 DT_NODE_VENDOR_OR(node_id, NULL), \
1150 DT_NODE_MODEL_OR(node_id, NULL), \
1151 DT_PROP_OR(node_id, friendly_name, NULL)) \
1152
1153 #else
1154
1155 #define SENSOR_INFO_DEFINE(name, ...)
1156 #define SENSOR_INFO_DT_DEFINE(node_id)
1157
1158 #endif /* CONFIG_SENSOR_INFO */
1159
1160 /**
1161 * @brief Like DEVICE_DT_DEFINE() with sensor specifics.
1162 *
1163 * @details Defines a device which implements the sensor API. May define an
1164 * element in the sensor info iterable section used to enumerate all sensor
1165 * devices.
1166 *
1167 * @param node_id The devicetree node identifier.
1168 *
1169 * @param init_fn Name of the init function of the driver.
1170 *
1171 * @param pm_device PM device resources reference (NULL if device does not use
1172 * PM).
1173 *
1174 * @param data_ptr Pointer to the device's private data.
1175 *
1176 * @param cfg_ptr The address to the structure containing the configuration
1177 * information for this instance of the driver.
1178 *
1179 * @param level The initialization level. See SYS_INIT() for details.
1180 *
1181 * @param prio Priority within the selected initialization level. See
1182 * SYS_INIT() for details.
1183 *
1184 * @param api_ptr Provides an initial pointer to the API function struct used
1185 * by the driver. Can be NULL.
1186 */
1187 #define SENSOR_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
1188 data_ptr, cfg_ptr, level, prio, \
1189 api_ptr, ...) \
1190 DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
1191 data_ptr, cfg_ptr, level, prio, \
1192 api_ptr, __VA_ARGS__); \
1193 \
1194 SENSOR_INFO_DT_DEFINE(node_id);
1195
1196 /**
1197 * @brief Like SENSOR_DEVICE_DT_DEFINE() for an instance of a DT_DRV_COMPAT
1198 * compatible
1199 *
1200 * @param inst instance number. This is replaced by
1201 * <tt>DT_DRV_COMPAT(inst)</tt> in the call to SENSOR_DEVICE_DT_DEFINE().
1202 *
1203 * @param ... other parameters as expected by SENSOR_DEVICE_DT_DEFINE().
1204 */
1205 #define SENSOR_DEVICE_DT_INST_DEFINE(inst, ...) \
1206 SENSOR_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
1207
1208 /**
1209 * @brief Helper function for converting struct sensor_value to integer milli units.
1210 *
1211 * @param val A pointer to a sensor_value struct.
1212 * @return The converted value.
1213 */
sensor_value_to_milli(struct sensor_value * val)1214 static inline int64_t sensor_value_to_milli(struct sensor_value *val)
1215 {
1216 return ((int64_t)val->val1 * 1000) + val->val2 / 1000;
1217 }
1218
1219 /**
1220 * @brief Helper function for converting struct sensor_value to integer micro units.
1221 *
1222 * @param val A pointer to a sensor_value struct.
1223 * @return The converted value.
1224 */
sensor_value_to_micro(struct sensor_value * val)1225 static inline int64_t sensor_value_to_micro(struct sensor_value *val)
1226 {
1227 return ((int64_t)val->val1 * 1000000) + val->val2;
1228 }
1229
1230 /**
1231 * @}
1232 */
1233
1234 #if defined(CONFIG_HAS_DTS) || defined(__DOXYGEN__)
1235
1236 /**
1237 * @brief Get the decoder name for the current driver
1238 *
1239 * This function depends on `DT_DRV_COMPAT` being defined.
1240 */
1241 #define SENSOR_DECODER_NAME() UTIL_CAT(DT_DRV_COMPAT, __decoder_api)
1242
1243 /**
1244 * @brief Statically get the decoder for a given node
1245 *
1246 * @code{.c}
1247 * static const sensor_decoder_api *decoder = SENSOR_DECODER_DT_GET(DT_ALIAS(accel));
1248 * @endcode
1249 */
1250 #define SENSOR_DECODER_DT_GET(node_id) \
1251 &UTIL_CAT(DT_STRING_TOKEN_BY_IDX(node_id, compatible, 0), __decoder_api)
1252
1253 /**
1254 * @brief Define a decoder API
1255 *
1256 * This macro should be created once per compatible string of a sensor and will create a statically
1257 * referenceable decoder API.
1258 *
1259 * @code{.c}
1260 * SENSOR_DECODER_API_DT_DEFINE() = {
1261 * .get_frame_count = my_driver_get_frame_count,
1262 * .get_timestamp = my_driver_get_timestamp,
1263 * .get_shift = my_driver_get_shift,
1264 * .decode = my_driver_decode,
1265 * };
1266 * @endcode
1267 */
1268 #define SENSOR_DECODER_API_DT_DEFINE() \
1269 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT), (), (static)) \
1270 const STRUCT_SECTION_ITERABLE(sensor_decoder_api, SENSOR_DECODER_NAME())
1271
1272 #define Z_MAYBE_SENSOR_DECODER_DECLARE_INTERNAL_IDX(node_id, prop, idx) \
1273 extern const struct sensor_decoder_api UTIL_CAT( \
1274 DT_STRING_TOKEN_BY_IDX(node_id, prop, idx), __decoder_api);
1275
1276 #define Z_MAYBE_SENSOR_DECODER_DECLARE_INTERNAL(node_id) \
1277 COND_CODE_1(DT_NODE_HAS_PROP(node_id, compatible), \
1278 (DT_FOREACH_PROP_ELEM(node_id, compatible, \
1279 Z_MAYBE_SENSOR_DECODER_DECLARE_INTERNAL_IDX)), \
1280 ())
1281
1282 DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_SENSOR_DECODER_DECLARE_INTERNAL)
1283 #endif /* defined(CONFIG_HAS_DTS) || defined(__DOXYGEN__) */
1284
1285 #ifdef __cplusplus
1286 }
1287 #endif
1288
1289 #include <syscalls/sensor.h>
1290
1291 #endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_H_ */
1292