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