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