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 /** Trigger fires when the FIFO watermark has been reached. */
256 SENSOR_TRIG_FIFO_WATERMARK,
257
258 /** Trigger fires when the FIFO becomes full. */
259 SENSOR_TRIG_FIFO_FULL,
260 /**
261 * Number of all common sensor triggers.
262 */
263 SENSOR_TRIG_COMMON_COUNT,
264
265 /**
266 * This and higher values are sensor specific.
267 * Refer to the sensor header file.
268 */
269 SENSOR_TRIG_PRIV_START = SENSOR_TRIG_COMMON_COUNT,
270
271 /**
272 * Maximum value describing a sensor trigger type.
273 */
274 SENSOR_TRIG_MAX = INT16_MAX,
275 };
276
277 /**
278 * @brief Sensor trigger spec.
279 */
280 struct sensor_trigger {
281 /** Trigger type. */
282 enum sensor_trigger_type type;
283 /** Channel the trigger is set on. */
284 enum sensor_channel chan;
285 };
286
287 /**
288 * @brief Sensor attribute types.
289 */
290 enum sensor_attribute {
291 /**
292 * Sensor sampling frequency, i.e. how many times a second the
293 * sensor takes a measurement.
294 */
295 SENSOR_ATTR_SAMPLING_FREQUENCY,
296 /** Lower threshold for trigger. */
297 SENSOR_ATTR_LOWER_THRESH,
298 /** Upper threshold for trigger. */
299 SENSOR_ATTR_UPPER_THRESH,
300 /** Threshold for any-motion (slope) trigger. */
301 SENSOR_ATTR_SLOPE_TH,
302 /**
303 * Duration for which the slope values needs to be
304 * outside the threshold for the trigger to fire.
305 */
306 SENSOR_ATTR_SLOPE_DUR,
307 /* Hysteresis for trigger thresholds. */
308 SENSOR_ATTR_HYSTERESIS,
309 /** Oversampling factor */
310 SENSOR_ATTR_OVERSAMPLING,
311 /** Sensor range, in SI units. */
312 SENSOR_ATTR_FULL_SCALE,
313 /**
314 * The sensor value returned will be altered by the amount indicated by
315 * offset: final_value = sensor_value + offset.
316 */
317 SENSOR_ATTR_OFFSET,
318 /**
319 * Calibration target. This will be used by the internal chip's
320 * algorithms to calibrate itself on a certain axis, or all of them.
321 */
322 SENSOR_ATTR_CALIB_TARGET,
323 /** Configure the operating modes of a sensor. */
324 SENSOR_ATTR_CONFIGURATION,
325 /** Set a calibration value needed by a sensor. */
326 SENSOR_ATTR_CALIBRATION,
327 /** Enable/disable sensor features */
328 SENSOR_ATTR_FEATURE_MASK,
329 /** Alert threshold or alert enable/disable */
330 SENSOR_ATTR_ALERT,
331 /** Free-fall duration represented in milliseconds.
332 * If the sampling frequency is changed during runtime,
333 * this attribute should be set to adjust freefall duration
334 * to the new sampling frequency.
335 */
336 SENSOR_ATTR_FF_DUR,
337
338 /** Hardware batch duration in ticks */
339 SENSOR_ATTR_BATCH_DURATION,
340
341 /**
342 * Number of all common sensor attributes.
343 */
344 SENSOR_ATTR_COMMON_COUNT,
345
346 /**
347 * This and higher values are sensor specific.
348 * Refer to the sensor header file.
349 */
350 SENSOR_ATTR_PRIV_START = SENSOR_ATTR_COMMON_COUNT,
351
352 /**
353 * Maximum value describing a sensor attribute type.
354 */
355 SENSOR_ATTR_MAX = INT16_MAX,
356 };
357
358 /**
359 * @typedef sensor_trigger_handler_t
360 * @brief Callback API upon firing of a trigger
361 *
362 * @param dev Pointer to the sensor device
363 * @param trigger The trigger
364 */
365 typedef void (*sensor_trigger_handler_t)(const struct device *dev,
366 const struct sensor_trigger *trigger);
367
368 /**
369 * @typedef sensor_attr_set_t
370 * @brief Callback API upon setting a sensor's attributes
371 *
372 * See sensor_attr_set() for argument description
373 */
374 typedef int (*sensor_attr_set_t)(const struct device *dev,
375 enum sensor_channel chan,
376 enum sensor_attribute attr,
377 const struct sensor_value *val);
378
379 /**
380 * @typedef sensor_attr_get_t
381 * @brief Callback API upon getting a sensor's attributes
382 *
383 * See sensor_attr_get() for argument description
384 */
385 typedef int (*sensor_attr_get_t)(const struct device *dev,
386 enum sensor_channel chan,
387 enum sensor_attribute attr,
388 struct sensor_value *val);
389
390 /**
391 * @typedef sensor_trigger_set_t
392 * @brief Callback API for setting a sensor's trigger and handler
393 *
394 * See sensor_trigger_set() for argument description
395 */
396 typedef int (*sensor_trigger_set_t)(const struct device *dev,
397 const struct sensor_trigger *trig,
398 sensor_trigger_handler_t handler);
399 /**
400 * @typedef sensor_sample_fetch_t
401 * @brief Callback API for fetching data from a sensor
402 *
403 * See sensor_sample_fetch() for argument description
404 */
405 typedef int (*sensor_sample_fetch_t)(const struct device *dev,
406 enum sensor_channel chan);
407 /**
408 * @typedef sensor_channel_get_t
409 * @brief Callback API for getting a reading from a sensor
410 *
411 * See sensor_channel_get() for argument description
412 */
413 typedef int (*sensor_channel_get_t)(const struct device *dev,
414 enum sensor_channel chan,
415 struct sensor_value *val);
416
417 /**
418 * @brief Decodes a single raw data buffer
419 *
420 * Data buffers are provided on the @ref rtio context that's supplied to
421 * @ref sensor_read.
422 */
423 struct sensor_decoder_api {
424 /**
425 * @brief Get the number of frames in the current buffer.
426 *
427 * @param[in] buffer The buffer provided on the @ref rtio context.
428 * @param[in] channel The channel to get the count for
429 * @param[in] channel_idx The index of the channel
430 * @param[out] frame_count The number of frames on the buffer (at least 1)
431 * @return 0 on success
432 * @return -ENOTSUP if the channel/channel_idx aren't found
433 */
434 int (*get_frame_count)(const uint8_t *buffer, enum sensor_channel channel,
435 size_t channel_idx, uint16_t *frame_count);
436
437 /**
438 * @brief Get the size required to decode a given channel
439 *
440 * When decoding a single frame, use @p base_size. For every additional frame, add another
441 * @p frame_size. As an example, to decode 3 frames use: 'base_size + 2 * frame_size'.
442 *
443 * @param[in] channel The channel to query
444 * @param[out] base_size The size of decoding the first frame
445 * @param[out] frame_size The additional size of every additional frame
446 * @return 0 on success
447 * @return -ENOTSUP if the channel is not supported
448 */
449 int (*get_size_info)(enum sensor_channel channel, size_t *base_size, size_t *frame_size);
450
451 /**
452 * @brief Decode up to @p max_count samples from the buffer
453 *
454 * Decode samples of channel @ref sensor_channel across multiple frames. If there exist
455 * multiple instances of the same channel, @p channel_index is used to differentiate them.
456 * As an example, assume a sensor provides 2 distance measurements:
457 *
458 * @code{.c}
459 * // Decode the first channel instance of 'distance'
460 * decoder->decode(buffer, SENSOR_CHAN_DISTANCE, 0, &fit, 5, out);
461 * ...
462 *
463 * // Decode the second channel instance of 'distance'
464 * decoder->decode(buffer, SENSOR_CHAN_DISTANCE, 1, &fit, 5, out);
465 * @endcode
466 *
467 * @param[in] buffer The buffer provided on the @ref rtio context
468 * @param[in] channel The channel to decode
469 * @param[in] channel_idx The index of the channel
470 * @param[in,out] fit The current frame iterator
471 * @param[in] max_count The maximum number of channels to decode.
472 * @param[out] data_out The decoded data
473 * @return 0 no more samples to decode
474 * @return >0 the number of decoded frames
475 * @return <0 on error
476 */
477 int (*decode)(const uint8_t *buffer, enum sensor_channel channel, size_t channel_idx,
478 uint32_t *fit, uint16_t max_count, void *data_out);
479
480 /**
481 * @brief Check if the given trigger type is present
482 *
483 * @param[in] buffer The buffer provided on the @ref rtio context
484 * @param[in] trigger The trigger type in question
485 * @return Whether the trigger is present in the buffer
486 */
487 bool (*has_trigger)(const uint8_t *buffer, enum sensor_trigger_type trigger);
488 };
489
490 /**
491 * @brief Used for iterating over the data frames via the sensor_decoder_api.
492 *
493 * Example usage:
494 *
495 * @code(.c)
496 * struct sensor_decode_context ctx = SENSOR_DECODE_CONTEXT_INIT(
497 * decoder, buffer, SENSOR_CHAN_ACCEL_XYZ, 0);
498 *
499 * while (true) {
500 * struct sensor_three_axis_data accel_out_data;
501 *
502 * num_decoded_channels = sensor_decode(ctx, &accel_out_data, 1);
503 *
504 * if (num_decoded_channels <= 0) {
505 * printk("Done decoding buffer\n");
506 * break;
507 * }
508 *
509 * printk("Decoded (%" PRId32 ", %" PRId32 ", %" PRId32 ")\n", accel_out_data.readings[0].x,
510 * accel_out_data.readings[0].y, accel_out_data.readings[0].z);
511 * }
512 * @endcode
513 */
514 struct sensor_decode_context {
515 const struct sensor_decoder_api *decoder;
516 const uint8_t *buffer;
517 enum sensor_channel channel;
518 size_t channel_idx;
519 uint32_t fit;
520 };
521
522 /**
523 * @brief Initialize a sensor_decode_context
524 */
525 #define SENSOR_DECODE_CONTEXT_INIT(decoder_, buffer_, channel_, channel_index_) \
526 { \
527 .decoder = (decoder_), \
528 .buffer = (buffer_), \
529 .channel = (channel_), \
530 .channel_idx = (channel_index_), \
531 .fit = 0, \
532 }
533
534 /**
535 * @brief Decode N frames using a sensor_decode_context
536 *
537 * @param[in,out] ctx The context to use for decoding
538 * @param[out] out The output buffer
539 * @param[in] max_count Maximum number of frames to decode
540 * @return The decode result from sensor_decoder_api's decode function
541 */
sensor_decode(struct sensor_decode_context * ctx,void * out,uint16_t max_count)542 static inline int sensor_decode(struct sensor_decode_context *ctx, void *out, uint16_t max_count)
543 {
544 return ctx->decoder->decode(ctx->buffer, ctx->channel, ctx->channel_idx, &ctx->fit,
545 max_count, out);
546 }
547
548 int sensor_natively_supported_channel_size_info(enum sensor_channel channel, size_t *base_size,
549 size_t *frame_size);
550
551 /**
552 * @typedef sensor_get_decoder_t
553 * @brief Get the decoder associate with the given device
554 *
555 * @see sensor_get_decoder for more details
556 */
557 typedef int (*sensor_get_decoder_t)(const struct device *dev,
558 const struct sensor_decoder_api **api);
559
560 /**
561 * @brief Options for what to do with the associated data when a trigger is consumed
562 */
563 enum sensor_stream_data_opt {
564 /** @brief Include whatever data is associated with the trigger */
565 SENSOR_STREAM_DATA_INCLUDE = 0,
566 /** @brief Do nothing with the associated trigger data, it may be consumed later */
567 SENSOR_STREAM_DATA_NOP = 1,
568 /** @brief Flush/clear whatever data is associated with the trigger */
569 SENSOR_STREAM_DATA_DROP = 2,
570 };
571
572 struct sensor_stream_trigger {
573 enum sensor_trigger_type trigger;
574 enum sensor_stream_data_opt opt;
575 };
576
577 #define SENSOR_STREAM_TRIGGER_PREP(_trigger, _opt) \
578 { \
579 .trigger = (_trigger), .opt = (_opt), \
580 }
581 /*
582 * Internal data structure used to store information about the IODevice for async reading and
583 * streaming sensor data.
584 */
585 struct sensor_read_config {
586 const struct device *sensor;
587 const bool is_streaming;
588 union {
589 enum sensor_channel *const channels;
590 struct sensor_stream_trigger *const triggers;
591 };
592 size_t count;
593 const size_t max;
594 };
595
596 /**
597 * @brief Define a reading instance of a sensor
598 *
599 * Use this macro to generate a @ref rtio_iodev for reading specific channels. Example:
600 *
601 * @code(.c)
602 * SENSOR_DT_READ_IODEV(icm42688_accelgyro, DT_NODELABEL(icm42688),
603 * SENSOR_CHAN_ACCEL_XYZ, SENSOR_CHAN_GYRO_XYZ);
604 *
605 * int main(void) {
606 * sensor_read(&icm42688_accelgyro, &rtio);
607 * }
608 * @endcode
609 */
610 #define SENSOR_DT_READ_IODEV(name, dt_node, ...) \
611 static enum sensor_channel _CONCAT(__channel_array_, name)[] = {__VA_ARGS__}; \
612 static struct sensor_read_config _CONCAT(__sensor_read_config_, name) = { \
613 .sensor = DEVICE_DT_GET(dt_node), \
614 .is_streaming = false, \
615 .channels = _CONCAT(__channel_array_, name), \
616 .count = ARRAY_SIZE(_CONCAT(__channel_array_, name)), \
617 .max = ARRAY_SIZE(_CONCAT(__channel_array_, name)), \
618 }; \
619 RTIO_IODEV_DEFINE(name, &__sensor_iodev_api, _CONCAT(&__sensor_read_config_, name))
620
621 /**
622 * @brief Define a stream instance of a sensor
623 *
624 * Use this macro to generate a @ref rtio_iodev for starting a stream that's triggered by specific
625 * interrupts. Example:
626 *
627 * @code(.c)
628 * SENSOR_DT_STREAM_IODEV(imu_stream, DT_ALIAS(imu),
629 * {SENSOR_TRIG_FIFO_WATERMARK, SENSOR_STREAM_DATA_INCLUDE},
630 * {SENSOR_TRIG_FIFO_FULL, SENSOR_STREAM_DATA_NOP});
631 *
632 * int main(void) {
633 * struct rtio_sqe *handle;
634 * sensor_stream(&imu_stream, &rtio, NULL, &handle);
635 * k_msleep(1000);
636 * rtio_sqe_cancel(handle);
637 * }
638 * @endcode
639 */
640 #define SENSOR_DT_STREAM_IODEV(name, dt_node, ...) \
641 static struct sensor_stream_trigger _CONCAT(__trigger_array_, name)[] = {__VA_ARGS__}; \
642 static struct sensor_read_config _CONCAT(__sensor_read_config_, name) = { \
643 .sensor = DEVICE_DT_GET(dt_node), \
644 .is_streaming = true, \
645 .triggers = _CONCAT(__trigger_array_, name), \
646 .count = ARRAY_SIZE(_CONCAT(__trigger_array_, name)), \
647 .max = ARRAY_SIZE(_CONCAT(__trigger_array_, name)), \
648 }; \
649 RTIO_IODEV_DEFINE(name, &__sensor_iodev_api, &_CONCAT(__sensor_read_config_, name))
650
651 /* Used to submit an RTIO sqe to the sensor's iodev */
652 typedef int (*sensor_submit_t)(const struct device *sensor, struct rtio_iodev_sqe *sqe);
653
654 /* The default decoder API */
655 extern const struct sensor_decoder_api __sensor_default_decoder;
656
657 /* The default sensor iodev API */
658 extern const struct rtio_iodev_api __sensor_iodev_api;
659
660 __subsystem struct sensor_driver_api {
661 sensor_attr_set_t attr_set;
662 sensor_attr_get_t attr_get;
663 sensor_trigger_set_t trigger_set;
664 sensor_sample_fetch_t sample_fetch;
665 sensor_channel_get_t channel_get;
666 sensor_get_decoder_t get_decoder;
667 sensor_submit_t submit;
668 };
669
670 /**
671 * @brief Set an attribute for a sensor
672 *
673 * @param dev Pointer to the sensor device
674 * @param chan The channel the attribute belongs to, if any. Some
675 * attributes may only be set for all channels of a device, depending on
676 * device capabilities.
677 * @param attr The attribute to set
678 * @param val The value to set the attribute to
679 *
680 * @return 0 if successful, negative errno code if failure.
681 */
682 __syscall int sensor_attr_set(const struct device *dev,
683 enum sensor_channel chan,
684 enum sensor_attribute attr,
685 const struct sensor_value *val);
686
z_impl_sensor_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)687 static inline int z_impl_sensor_attr_set(const struct device *dev,
688 enum sensor_channel chan,
689 enum sensor_attribute attr,
690 const struct sensor_value *val)
691 {
692 const struct sensor_driver_api *api =
693 (const struct sensor_driver_api *)dev->api;
694
695 if (api->attr_set == NULL) {
696 return -ENOSYS;
697 }
698
699 return api->attr_set(dev, chan, attr, val);
700 }
701
702 /**
703 * @brief Get an attribute for a sensor
704 *
705 * @param dev Pointer to the sensor device
706 * @param chan The channel the attribute belongs to, if any. Some
707 * attributes may only be set for all channels of a device, depending on
708 * device capabilities.
709 * @param attr The attribute to get
710 * @param val Pointer to where to store the attribute
711 *
712 * @return 0 if successful, negative errno code if failure.
713 */
714 __syscall int sensor_attr_get(const struct device *dev,
715 enum sensor_channel chan,
716 enum sensor_attribute attr,
717 struct sensor_value *val);
718
z_impl_sensor_attr_get(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)719 static inline int z_impl_sensor_attr_get(const struct device *dev,
720 enum sensor_channel chan,
721 enum sensor_attribute attr,
722 struct sensor_value *val)
723 {
724 const struct sensor_driver_api *api =
725 (const struct sensor_driver_api *)dev->api;
726
727 if (api->attr_get == NULL) {
728 return -ENOSYS;
729 }
730
731 return api->attr_get(dev, chan, attr, val);
732 }
733
734 /**
735 * @brief Activate a sensor's trigger and set the trigger handler
736 *
737 * The handler will be called from a thread, so I2C or SPI operations are
738 * safe. However, the thread's stack is limited and defined by the
739 * driver. It is currently up to the caller to ensure that the handler
740 * does not overflow the stack.
741 *
742 * The user-allocated trigger will be stored by the driver as a pointer, rather
743 * than a copy, and passed back to the handler. This enables the handler to use
744 * CONTAINER_OF to retrieve a context pointer when the trigger is embedded in a
745 * larger struct and requires that the trigger is not allocated on the stack.
746 *
747 * @funcprops \supervisor
748 *
749 * @param dev Pointer to the sensor device
750 * @param trig The trigger to activate
751 * @param handler The function that should be called when the trigger
752 * fires
753 *
754 * @return 0 if successful, negative errno code if failure.
755 */
sensor_trigger_set(const struct device * dev,const struct sensor_trigger * trig,sensor_trigger_handler_t handler)756 static inline int sensor_trigger_set(const struct device *dev,
757 const struct sensor_trigger *trig,
758 sensor_trigger_handler_t handler)
759 {
760 const struct sensor_driver_api *api =
761 (const struct sensor_driver_api *)dev->api;
762
763 if (api->trigger_set == NULL) {
764 return -ENOSYS;
765 }
766
767 return api->trigger_set(dev, trig, handler);
768 }
769
770 /**
771 * @brief Fetch a sample from the sensor and store it in an internal
772 * driver buffer
773 *
774 * Read all of a sensor's active channels and, if necessary, perform any
775 * additional operations necessary to make the values useful. The user
776 * may then get individual channel values by calling @ref
777 * sensor_channel_get.
778 *
779 * The function blocks until the fetch operation is complete.
780 *
781 * Since the function communicates with the sensor device, it is unsafe
782 * to call it in an ISR if the device is connected via I2C or SPI.
783 *
784 * @param dev Pointer to the sensor device
785 *
786 * @return 0 if successful, negative errno code if failure.
787 */
788 __syscall int sensor_sample_fetch(const struct device *dev);
789
z_impl_sensor_sample_fetch(const struct device * dev)790 static inline int z_impl_sensor_sample_fetch(const struct device *dev)
791 {
792 const struct sensor_driver_api *api =
793 (const struct sensor_driver_api *)dev->api;
794
795 return api->sample_fetch(dev, SENSOR_CHAN_ALL);
796 }
797
798 /**
799 * @brief Fetch a sample from the sensor and store it in an internal
800 * driver buffer
801 *
802 * Read and compute compensation for one type of sensor data (magnetometer,
803 * accelerometer, etc). The user may then get individual channel values by
804 * calling @ref sensor_channel_get.
805 *
806 * This is mostly implemented by multi function devices enabling reading at
807 * different sampling rates.
808 *
809 * The function blocks until the fetch operation is complete.
810 *
811 * Since the function communicates with the sensor device, it is unsafe
812 * to call it in an ISR if the device is connected via I2C or SPI.
813 *
814 * @param dev Pointer to the sensor device
815 * @param type The channel that needs updated
816 *
817 * @return 0 if successful, negative errno code if failure.
818 */
819 __syscall int sensor_sample_fetch_chan(const struct device *dev,
820 enum sensor_channel type);
821
z_impl_sensor_sample_fetch_chan(const struct device * dev,enum sensor_channel type)822 static inline int z_impl_sensor_sample_fetch_chan(const struct device *dev,
823 enum sensor_channel type)
824 {
825 const struct sensor_driver_api *api =
826 (const struct sensor_driver_api *)dev->api;
827
828 return api->sample_fetch(dev, type);
829 }
830
831 /**
832 * @brief Get a reading from a sensor device
833 *
834 * Return a useful value for a particular channel, from the driver's
835 * internal data. Before calling this function, a sample must be
836 * obtained by calling @ref sensor_sample_fetch or
837 * @ref sensor_sample_fetch_chan. It is guaranteed that two subsequent
838 * calls of this function for the same channels will yield the same
839 * value, if @ref sensor_sample_fetch or @ref sensor_sample_fetch_chan
840 * has not been called in the meantime.
841 *
842 * For vectorial data samples you can request all axes in just one call
843 * by passing the specific channel with _XYZ suffix. The sample will be
844 * returned at val[0], val[1] and val[2] (X, Y and Z in that order).
845 *
846 * @param dev Pointer to the sensor device
847 * @param chan The channel to read
848 * @param val Where to store the value
849 *
850 * @return 0 if successful, negative errno code if failure.
851 */
852 __syscall int sensor_channel_get(const struct device *dev,
853 enum sensor_channel chan,
854 struct sensor_value *val);
855
z_impl_sensor_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)856 static inline int z_impl_sensor_channel_get(const struct device *dev,
857 enum sensor_channel chan,
858 struct sensor_value *val)
859 {
860 const struct sensor_driver_api *api =
861 (const struct sensor_driver_api *)dev->api;
862
863 return api->channel_get(dev, chan, val);
864 }
865
866 #if defined(CONFIG_SENSOR_ASYNC_API) || defined(__DOXYGEN__)
867
868 /*
869 * Generic data structure used for encoding the sample timestamp and number of channels sampled.
870 */
871 struct __attribute__((__packed__)) sensor_data_generic_header {
872 /* The timestamp at which the data was collected from the sensor */
873 uint64_t timestamp_ns;
874
875 /*
876 * The number of channels present in the frame. This will be the true number of elements in
877 * channel_info and in the q31 values that follow the header.
878 */
879 uint32_t num_channels;
880
881 /* Shift value for all samples in the frame */
882 int8_t shift;
883
884 /* This padding is needed to make sure that the 'channels' field is aligned */
885 int8_t _padding[sizeof(enum sensor_channel) - 1];
886
887 /* Channels present in the frame */
888 enum sensor_channel channels[0];
889 };
890
891 /**
892 * @brief checks if a given channel is a 3-axis channel
893 *
894 * @param[in] chan The channel to check
895 * @retval true if @p chan is any of @ref SENSOR_CHAN_ACCEL_XYZ, @ref SENSOR_CHAN_GYRO_XYZ, or
896 * @ref SENSOR_CHAN_MAGN_XYZ
897 * @retval false otherwise
898 */
899 #define SENSOR_CHANNEL_3_AXIS(chan) \
900 ((chan) == SENSOR_CHAN_ACCEL_XYZ || (chan) == SENSOR_CHAN_GYRO_XYZ || \
901 (chan) == SENSOR_CHAN_MAGN_XYZ)
902
903 /**
904 * @brief Get the sensor's decoder API
905 *
906 * @param[in] dev The sensor device
907 * @param[in] decoder Pointer to the decoder which will be set upon success
908 * @return 0 on success
909 * @return < 0 on error
910 */
911 __syscall int sensor_get_decoder(const struct device *dev,
912 const struct sensor_decoder_api **decoder);
913
z_impl_sensor_get_decoder(const struct device * dev,const struct sensor_decoder_api ** decoder)914 static inline int z_impl_sensor_get_decoder(const struct device *dev,
915 const struct sensor_decoder_api **decoder)
916 {
917 const struct sensor_driver_api *api = (const struct sensor_driver_api *)dev->api;
918
919 __ASSERT_NO_MSG(api != NULL);
920
921 if (api->get_decoder == NULL) {
922 *decoder = &__sensor_default_decoder;
923 return 0;
924 }
925
926 return api->get_decoder(dev, decoder);
927 }
928
929 /**
930 * @brief Reconfigure a reading iodev
931 *
932 * Allows a reconfiguration of the iodev associated with reading a sample from a sensor.
933 *
934 * <b>Important</b>: If the iodev is currently servicing a read operation, the data will likely be
935 * invalid. Please be sure the flush or wait for all pending operations to complete before using the
936 * data after a configuration change.
937 *
938 * It is also important that the `data` field of the iodev is a @ref sensor_read_config.
939 *
940 * @param[in] iodev The iodev to reconfigure
941 * @param[in] sensor The sensor to read from
942 * @param[in] channels One or more channels to read
943 * @param[in] num_channels The number of channels in @p channels
944 * @return 0 on success
945 * @return < 0 on error
946 */
947 __syscall int sensor_reconfigure_read_iodev(struct rtio_iodev *iodev, const struct device *sensor,
948 const enum sensor_channel *channels,
949 size_t num_channels);
950
z_impl_sensor_reconfigure_read_iodev(struct rtio_iodev * iodev,const struct device * sensor,const enum sensor_channel * channels,size_t num_channels)951 static inline int z_impl_sensor_reconfigure_read_iodev(struct rtio_iodev *iodev,
952 const struct device *sensor,
953 const enum sensor_channel *channels,
954 size_t num_channels)
955 {
956 struct sensor_read_config *cfg = (struct sensor_read_config *)iodev->data;
957
958 if (cfg->max < num_channels || cfg->is_streaming) {
959 return -ENOMEM;
960 }
961
962 cfg->sensor = sensor;
963 memcpy(cfg->channels, channels, num_channels * sizeof(enum sensor_channel));
964 cfg->count = num_channels;
965 return 0;
966 }
967
sensor_stream(struct rtio_iodev * iodev,struct rtio * ctx,void * userdata,struct rtio_sqe ** handle)968 static inline int sensor_stream(struct rtio_iodev *iodev, struct rtio *ctx, void *userdata,
969 struct rtio_sqe **handle)
970 {
971 if (IS_ENABLED(CONFIG_USERSPACE)) {
972 struct rtio_sqe sqe;
973
974 rtio_sqe_prep_read_multishot(&sqe, iodev, RTIO_PRIO_NORM, userdata);
975 rtio_sqe_copy_in_get_handles(ctx, &sqe, handle, 1);
976 } else {
977 struct rtio_sqe *sqe = rtio_sqe_acquire(ctx);
978
979 if (sqe == NULL) {
980 return -ENOMEM;
981 }
982 if (handle != NULL) {
983 *handle = sqe;
984 }
985 rtio_sqe_prep_read_multishot(sqe, iodev, RTIO_PRIO_NORM, userdata);
986 }
987 rtio_submit(ctx, 0);
988 return 0;
989 }
990
991 /**
992 * @brief Read data from a sensor.
993 *
994 * Using @p cfg, read one snapshot of data from the device by using the provided RTIO context
995 * @p ctx. This call will generate a @ref rtio_sqe that will leverage the RTIO's internal
996 * mempool when the time comes to service the read.
997 *
998 * @param[in] iodev The iodev created by @ref SENSOR_DT_READ_IODEV
999 * @param[in] ctx The RTIO context to service the read
1000 * @param[in] userdata Optional userdata that will be available when the read is complete
1001 * @return 0 on success
1002 * @return < 0 on error
1003 */
sensor_read(struct rtio_iodev * iodev,struct rtio * ctx,void * userdata)1004 static inline int sensor_read(struct rtio_iodev *iodev, struct rtio *ctx, void *userdata)
1005 {
1006 if (IS_ENABLED(CONFIG_USERSPACE)) {
1007 struct rtio_sqe sqe;
1008
1009 rtio_sqe_prep_read_with_pool(&sqe, iodev, RTIO_PRIO_NORM, userdata);
1010 rtio_sqe_copy_in(ctx, &sqe, 1);
1011 } else {
1012 struct rtio_sqe *sqe = rtio_sqe_acquire(ctx);
1013
1014 if (sqe == NULL) {
1015 return -ENOMEM;
1016 }
1017 rtio_sqe_prep_read_with_pool(sqe, iodev, RTIO_PRIO_NORM, userdata);
1018 }
1019 rtio_submit(ctx, 0);
1020 return 0;
1021 }
1022
1023 /**
1024 * @typedef sensor_processing_callback_t
1025 * @brief Callback function used with the helper processing function.
1026 *
1027 * @see sensor_processing_with_callback
1028 *
1029 * @param[in] result The result code of the read (0 being success)
1030 * @param[in] buf The data buffer holding the sensor data
1031 * @param[in] buf_len The length (in bytes) of the @p buf
1032 * @param[in] userdata The optional userdata passed to sensor_read()
1033 */
1034 typedef void (*sensor_processing_callback_t)(int result, uint8_t *buf, uint32_t buf_len,
1035 void *userdata);
1036
1037 /**
1038 * @brief Helper function for common processing of sensor data.
1039 *
1040 * This function can be called in a blocking manner after sensor_read() or in a standalone
1041 * thread dedicated to processing. It will wait for a cqe from the RTIO context, once received, it
1042 * will decode the userdata and call the @p cb. Once the @p cb returns, the buffer will be released
1043 * back into @p ctx's mempool if available.
1044 *
1045 * @param[in] ctx The RTIO context to wait on
1046 * @param[in] cb Callback to call when data is ready for processing
1047 */
1048 void sensor_processing_with_callback(struct rtio *ctx, sensor_processing_callback_t cb);
1049
1050 #endif /* defined(CONFIG_SENSOR_ASYNC_API) || defined(__DOXYGEN__) */
1051
1052 /**
1053 * @brief The value of gravitational constant in micro m/s^2.
1054 */
1055 #define SENSOR_G 9806650LL
1056
1057 /**
1058 * @brief The value of constant PI in micros.
1059 */
1060 #define SENSOR_PI 3141592LL
1061
1062 /**
1063 * @brief Helper function to convert acceleration from m/s^2 to Gs
1064 *
1065 * @param ms2 A pointer to a sensor_value struct holding the acceleration,
1066 * in m/s^2.
1067 *
1068 * @return The converted value, in Gs.
1069 */
sensor_ms2_to_g(const struct sensor_value * ms2)1070 static inline int32_t sensor_ms2_to_g(const struct sensor_value *ms2)
1071 {
1072 int64_t micro_ms2 = ms2->val1 * 1000000LL + ms2->val2;
1073
1074 if (micro_ms2 > 0) {
1075 return (micro_ms2 + SENSOR_G / 2) / SENSOR_G;
1076 } else {
1077 return (micro_ms2 - SENSOR_G / 2) / SENSOR_G;
1078 }
1079 }
1080
1081 /**
1082 * @brief Helper function to convert acceleration from Gs to m/s^2
1083 *
1084 * @param g The G value to be converted.
1085 * @param ms2 A pointer to a sensor_value struct, where the result is stored.
1086 */
sensor_g_to_ms2(int32_t g,struct sensor_value * ms2)1087 static inline void sensor_g_to_ms2(int32_t g, struct sensor_value *ms2)
1088 {
1089 ms2->val1 = ((int64_t)g * SENSOR_G) / 1000000LL;
1090 ms2->val2 = ((int64_t)g * SENSOR_G) % 1000000LL;
1091 }
1092
1093 /**
1094 * @brief Helper function to convert acceleration from m/s^2 to micro Gs
1095 *
1096 * @param ms2 A pointer to a sensor_value struct holding the acceleration,
1097 * in m/s^2.
1098 *
1099 * @return The converted value, in micro Gs.
1100 */
sensor_ms2_to_ug(const struct sensor_value * ms2)1101 static inline int32_t sensor_ms2_to_ug(const struct sensor_value *ms2)
1102 {
1103 int64_t micro_ms2 = (ms2->val1 * INT64_C(1000000)) + ms2->val2;
1104
1105 return (micro_ms2 * 1000000LL) / SENSOR_G;
1106 }
1107
1108 /**
1109 * @brief Helper function to convert acceleration from micro Gs to m/s^2
1110 *
1111 * @param ug The micro G value to be converted.
1112 * @param ms2 A pointer to a sensor_value struct, where the result is stored.
1113 */
sensor_ug_to_ms2(int32_t ug,struct sensor_value * ms2)1114 static inline void sensor_ug_to_ms2(int32_t ug, struct sensor_value *ms2)
1115 {
1116 ms2->val1 = ((int64_t)ug * SENSOR_G / 1000000LL) / 1000000LL;
1117 ms2->val2 = ((int64_t)ug * SENSOR_G / 1000000LL) % 1000000LL;
1118 }
1119
1120 /**
1121 * @brief Helper function for converting radians to degrees.
1122 *
1123 * @param rad A pointer to a sensor_value struct, holding the value in radians.
1124 *
1125 * @return The converted value, in degrees.
1126 */
sensor_rad_to_degrees(const struct sensor_value * rad)1127 static inline int32_t sensor_rad_to_degrees(const struct sensor_value *rad)
1128 {
1129 int64_t micro_rad_s = rad->val1 * 1000000LL + rad->val2;
1130
1131 if (micro_rad_s > 0) {
1132 return (micro_rad_s * 180LL + SENSOR_PI / 2) / SENSOR_PI;
1133 } else {
1134 return (micro_rad_s * 180LL - SENSOR_PI / 2) / SENSOR_PI;
1135 }
1136 }
1137
1138 /**
1139 * @brief Helper function for converting degrees to radians.
1140 *
1141 * @param d The value (in degrees) to be converted.
1142 * @param rad A pointer to a sensor_value struct, where the result is stored.
1143 */
sensor_degrees_to_rad(int32_t d,struct sensor_value * rad)1144 static inline void sensor_degrees_to_rad(int32_t d, struct sensor_value *rad)
1145 {
1146 rad->val1 = ((int64_t)d * SENSOR_PI / 180LL) / 1000000LL;
1147 rad->val2 = ((int64_t)d * SENSOR_PI / 180LL) % 1000000LL;
1148 }
1149
1150 /**
1151 * @brief Helper function for converting radians to 10 micro degrees.
1152 *
1153 * When the unit is 1 micro degree, the range that the int32_t can represent is
1154 * +/-2147.483 degrees. In order to increase this range, here we use 10 micro
1155 * degrees as the unit.
1156 *
1157 * @param rad A pointer to a sensor_value struct, holding the value in radians.
1158 *
1159 * @return The converted value, in 10 micro degrees.
1160 */
sensor_rad_to_10udegrees(const struct sensor_value * rad)1161 static inline int32_t sensor_rad_to_10udegrees(const struct sensor_value *rad)
1162 {
1163 int64_t micro_rad_s = rad->val1 * 1000000LL + rad->val2;
1164
1165 return (micro_rad_s * 180LL * 100000LL) / SENSOR_PI;
1166 }
1167
1168 /**
1169 * @brief Helper function for converting 10 micro degrees to radians.
1170 *
1171 * @param d The value (in 10 micro degrees) to be converted.
1172 * @param rad A pointer to a sensor_value struct, where the result is stored.
1173 */
sensor_10udegrees_to_rad(int32_t d,struct sensor_value * rad)1174 static inline void sensor_10udegrees_to_rad(int32_t d, struct sensor_value *rad)
1175 {
1176 rad->val1 = ((int64_t)d * SENSOR_PI / 180LL / 100000LL) / 1000000LL;
1177 rad->val2 = ((int64_t)d * SENSOR_PI / 180LL / 100000LL) % 1000000LL;
1178 }
1179
1180 /**
1181 * @brief Helper function for converting struct sensor_value to double.
1182 *
1183 * @param val A pointer to a sensor_value struct.
1184 * @return The converted value.
1185 */
sensor_value_to_double(const struct sensor_value * val)1186 static inline double sensor_value_to_double(const struct sensor_value *val)
1187 {
1188 return (double)val->val1 + (double)val->val2 / 1000000;
1189 }
1190
1191 /**
1192 * @brief Helper function for converting struct sensor_value to float.
1193 *
1194 * @param val A pointer to a sensor_value struct.
1195 * @return The converted value.
1196 */
sensor_value_to_float(const struct sensor_value * val)1197 static inline float sensor_value_to_float(const struct sensor_value *val)
1198 {
1199 return (float)val->val1 + (float)val->val2 / 1000000;
1200 }
1201
1202 /**
1203 * @brief Helper function for converting double to struct sensor_value.
1204 *
1205 * @param val A pointer to a sensor_value struct.
1206 * @param inp The converted value.
1207 * @return 0 if successful, negative errno code if failure.
1208 */
sensor_value_from_double(struct sensor_value * val,double inp)1209 static inline int sensor_value_from_double(struct sensor_value *val, double inp)
1210 {
1211 if (inp < INT32_MIN || inp > INT32_MAX) {
1212 return -ERANGE;
1213 }
1214
1215 double val2 = (inp - (int32_t)inp) * 1000000.0;
1216
1217 if (val2 < INT32_MIN || val2 > INT32_MAX) {
1218 return -ERANGE;
1219 }
1220
1221 val->val1 = (int32_t)inp;
1222 val->val2 = (int32_t)val2;
1223
1224 return 0;
1225 }
1226
1227 /**
1228 * @brief Helper function for converting float to struct sensor_value.
1229 *
1230 * @param val A pointer to a sensor_value struct.
1231 * @param inp The converted value.
1232 * @return 0 if successful, negative errno code if failure.
1233 */
sensor_value_from_float(struct sensor_value * val,float inp)1234 static inline int sensor_value_from_float(struct sensor_value *val, float inp)
1235 {
1236 float val2 = (inp - (int32_t)inp) * 1000000.0f;
1237
1238 if (val2 < INT32_MIN || val2 > (float)(INT32_MAX - 1)) {
1239 return -ERANGE;
1240 }
1241
1242 val->val1 = (int32_t)inp;
1243 val->val2 = (int32_t)val2;
1244
1245 return 0;
1246 }
1247
1248 #ifdef CONFIG_SENSOR_INFO
1249
1250 struct sensor_info {
1251 const struct device *dev;
1252 const char *vendor;
1253 const char *model;
1254 const char *friendly_name;
1255 };
1256
1257 #define SENSOR_INFO_INITIALIZER(_dev, _vendor, _model, _friendly_name) \
1258 { \
1259 .dev = _dev, \
1260 .vendor = _vendor, \
1261 .model = _model, \
1262 .friendly_name = _friendly_name, \
1263 }
1264
1265 #define SENSOR_INFO_DEFINE(name, ...) \
1266 static const STRUCT_SECTION_ITERABLE(sensor_info, name) = \
1267 SENSOR_INFO_INITIALIZER(__VA_ARGS__)
1268
1269 #define SENSOR_INFO_DT_NAME(node_id) \
1270 _CONCAT(__sensor_info, DEVICE_DT_NAME_GET(node_id))
1271
1272 #define SENSOR_INFO_DT_DEFINE(node_id) \
1273 SENSOR_INFO_DEFINE(SENSOR_INFO_DT_NAME(node_id), \
1274 DEVICE_DT_GET(node_id), \
1275 DT_NODE_VENDOR_OR(node_id, NULL), \
1276 DT_NODE_MODEL_OR(node_id, NULL), \
1277 DT_PROP_OR(node_id, friendly_name, NULL)) \
1278
1279 #else
1280
1281 #define SENSOR_INFO_DEFINE(name, ...)
1282 #define SENSOR_INFO_DT_DEFINE(node_id)
1283
1284 #endif /* CONFIG_SENSOR_INFO */
1285
1286 /**
1287 * @brief Like DEVICE_DT_DEFINE() with sensor specifics.
1288 *
1289 * @details Defines a device which implements the sensor API. May define an
1290 * element in the sensor info iterable section used to enumerate all sensor
1291 * devices.
1292 *
1293 * @param node_id The devicetree node identifier.
1294 *
1295 * @param init_fn Name of the init function of the driver.
1296 *
1297 * @param pm_device PM device resources reference (NULL if device does not use
1298 * PM).
1299 *
1300 * @param data_ptr Pointer to the device's private data.
1301 *
1302 * @param cfg_ptr The address to the structure containing the configuration
1303 * information for this instance of the driver.
1304 *
1305 * @param level The initialization level. See SYS_INIT() for details.
1306 *
1307 * @param prio Priority within the selected initialization level. See
1308 * SYS_INIT() for details.
1309 *
1310 * @param api_ptr Provides an initial pointer to the API function struct used
1311 * by the driver. Can be NULL.
1312 */
1313 #define SENSOR_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
1314 data_ptr, cfg_ptr, level, prio, \
1315 api_ptr, ...) \
1316 DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
1317 data_ptr, cfg_ptr, level, prio, \
1318 api_ptr, __VA_ARGS__); \
1319 \
1320 SENSOR_INFO_DT_DEFINE(node_id);
1321
1322 /**
1323 * @brief Like SENSOR_DEVICE_DT_DEFINE() for an instance of a DT_DRV_COMPAT
1324 * compatible
1325 *
1326 * @param inst instance number. This is replaced by
1327 * <tt>DT_DRV_COMPAT(inst)</tt> in the call to SENSOR_DEVICE_DT_DEFINE().
1328 *
1329 * @param ... other parameters as expected by SENSOR_DEVICE_DT_DEFINE().
1330 */
1331 #define SENSOR_DEVICE_DT_INST_DEFINE(inst, ...) \
1332 SENSOR_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
1333
1334 /**
1335 * @brief Helper function for converting struct sensor_value to integer milli units.
1336 *
1337 * @param val A pointer to a sensor_value struct.
1338 * @return The converted value.
1339 */
sensor_value_to_milli(const struct sensor_value * val)1340 static inline int64_t sensor_value_to_milli(const struct sensor_value *val)
1341 {
1342 return ((int64_t)val->val1 * 1000) + val->val2 / 1000;
1343 }
1344
1345 /**
1346 * @brief Helper function for converting struct sensor_value to integer micro units.
1347 *
1348 * @param val A pointer to a sensor_value struct.
1349 * @return The converted value.
1350 */
sensor_value_to_micro(const struct sensor_value * val)1351 static inline int64_t sensor_value_to_micro(const struct sensor_value *val)
1352 {
1353 return ((int64_t)val->val1 * 1000000) + val->val2;
1354 }
1355
1356 /**
1357 * @brief Helper function for converting integer milli units to struct sensor_value.
1358 *
1359 * @param val A pointer to a sensor_value struct.
1360 * @param milli The converted value.
1361 * @return 0 if successful, negative errno code if failure.
1362 */
sensor_value_from_milli(struct sensor_value * val,int64_t milli)1363 static inline int sensor_value_from_milli(struct sensor_value *val, int64_t milli)
1364 {
1365 if (milli < ((int64_t)INT32_MIN - 1) * 1000LL ||
1366 milli > ((int64_t)INT32_MAX + 1) * 1000LL) {
1367 return -ERANGE;
1368 }
1369
1370 val->val1 = (int32_t)(milli / 1000);
1371 val->val2 = (int32_t)(milli % 1000) * 1000;
1372
1373 return 0;
1374 }
1375
1376 /**
1377 * @brief Helper function for converting integer micro units to struct sensor_value.
1378 *
1379 * @param val A pointer to a sensor_value struct.
1380 * @param micro The converted value.
1381 * @return 0 if successful, negative errno code if failure.
1382 */
sensor_value_from_micro(struct sensor_value * val,int64_t micro)1383 static inline int sensor_value_from_micro(struct sensor_value *val, int64_t micro)
1384 {
1385 if (micro < ((int64_t)INT32_MIN - 1) * 1000000LL ||
1386 micro > ((int64_t)INT32_MAX + 1) * 1000000LL) {
1387 return -ERANGE;
1388 }
1389
1390 val->val1 = (int32_t)(micro / 1000000LL);
1391 val->val2 = (int32_t)(micro % 1000000LL);
1392
1393 return 0;
1394 }
1395
1396 /**
1397 * @}
1398 */
1399
1400 /**
1401 * @brief Get the decoder name for the current driver
1402 *
1403 * This function depends on `DT_DRV_COMPAT` being defined.
1404 */
1405 #define SENSOR_DECODER_NAME() UTIL_CAT(DT_DRV_COMPAT, __decoder_api)
1406
1407 /**
1408 * @brief Statically get the decoder for a given node
1409 *
1410 * @code{.c}
1411 * static const sensor_decoder_api *decoder = SENSOR_DECODER_DT_GET(DT_ALIAS(accel));
1412 * @endcode
1413 */
1414 #define SENSOR_DECODER_DT_GET(node_id) \
1415 &UTIL_CAT(DT_STRING_TOKEN_BY_IDX(node_id, compatible, 0), __decoder_api)
1416
1417 /**
1418 * @brief Define a decoder API
1419 *
1420 * This macro should be created once per compatible string of a sensor and will create a statically
1421 * referenceable decoder API.
1422 *
1423 * @code{.c}
1424 * SENSOR_DECODER_API_DT_DEFINE() = {
1425 * .get_frame_count = my_driver_get_frame_count,
1426 * .get_timestamp = my_driver_get_timestamp,
1427 * .get_shift = my_driver_get_shift,
1428 * .decode = my_driver_decode,
1429 * };
1430 * @endcode
1431 */
1432 #define SENSOR_DECODER_API_DT_DEFINE() \
1433 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT), (), (static)) \
1434 const STRUCT_SECTION_ITERABLE(sensor_decoder_api, SENSOR_DECODER_NAME())
1435
1436 #define Z_MAYBE_SENSOR_DECODER_DECLARE_INTERNAL_IDX(node_id, prop, idx) \
1437 extern const struct sensor_decoder_api UTIL_CAT( \
1438 DT_STRING_TOKEN_BY_IDX(node_id, prop, idx), __decoder_api);
1439
1440 #define Z_MAYBE_SENSOR_DECODER_DECLARE_INTERNAL(node_id) \
1441 COND_CODE_1(DT_NODE_HAS_PROP(node_id, compatible), \
1442 (DT_FOREACH_PROP_ELEM(node_id, compatible, \
1443 Z_MAYBE_SENSOR_DECODER_DECLARE_INTERNAL_IDX)), \
1444 ())
1445
1446 DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_SENSOR_DECODER_DECLARE_INTERNAL)
1447
1448 #ifdef __cplusplus
1449 }
1450 #endif
1451
1452 #include <syscalls/sensor.h>
1453
1454 #endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_H_ */
1455