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