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