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 <zephyr/types.h>
23 #include <device.h>
24 #include <errno.h>
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
30 /**
31 * @brief Representation of a sensor readout value.
32 *
33 * The value is represented as having an integer and a fractional part,
34 * and can be obtained using the formula val1 + val2 * 10^(-6). Negative
35 * values also adhere to the above formula, but may need special attention.
36 * Here are some examples of the value representation:
37 *
38 * 0.5: val1 = 0, val2 = 500000
39 * -0.5: val1 = 0, val2 = -500000
40 * -1.0: val1 = -1, val2 = 0
41 * -1.5: val1 = -1, val2 = -500000
42 */
43 struct sensor_value {
44 /** Integer part of the value. */
45 int32_t val1;
46 /** Fractional part of the value (in one-millionth parts). */
47 int32_t val2;
48 };
49
50 /**
51 * @brief Sensor channels.
52 */
53 enum sensor_channel {
54 /** Acceleration on the X axis, in m/s^2. */
55 SENSOR_CHAN_ACCEL_X,
56 /** Acceleration on the Y axis, in m/s^2. */
57 SENSOR_CHAN_ACCEL_Y,
58 /** Acceleration on the Z axis, in m/s^2. */
59 SENSOR_CHAN_ACCEL_Z,
60 /** Acceleration on the X, Y and Z axes. */
61 SENSOR_CHAN_ACCEL_XYZ,
62 /** Angular velocity around the X axis, in radians/s. */
63 SENSOR_CHAN_GYRO_X,
64 /** Angular velocity around the Y axis, in radians/s. */
65 SENSOR_CHAN_GYRO_Y,
66 /** Angular velocity around the Z axis, in radians/s. */
67 SENSOR_CHAN_GYRO_Z,
68 /** Angular velocity around the X, Y and Z axes. */
69 SENSOR_CHAN_GYRO_XYZ,
70 /** Magnetic field on the X axis, in Gauss. */
71 SENSOR_CHAN_MAGN_X,
72 /** Magnetic field on the Y axis, in Gauss. */
73 SENSOR_CHAN_MAGN_Y,
74 /** Magnetic field on the Z axis, in Gauss. */
75 SENSOR_CHAN_MAGN_Z,
76 /** Magnetic field on the X, Y and Z axes. */
77 SENSOR_CHAN_MAGN_XYZ,
78 /** Device die temperature in degrees Celsius. */
79 SENSOR_CHAN_DIE_TEMP,
80 /** Ambient temperature in degrees Celsius. */
81 SENSOR_CHAN_AMBIENT_TEMP,
82 /** Pressure in kilopascal. */
83 SENSOR_CHAN_PRESS,
84 /**
85 * Proximity. Adimensional. A value of 1 indicates that an
86 * object is close.
87 */
88 SENSOR_CHAN_PROX,
89 /** Humidity, in percent. */
90 SENSOR_CHAN_HUMIDITY,
91 /** Illuminance in visible spectrum, in lux. */
92 SENSOR_CHAN_LIGHT,
93 /** Illuminance in infra-red spectrum, in lux. */
94 SENSOR_CHAN_IR,
95 /** Illuminance in red spectrum, in lux. */
96 SENSOR_CHAN_RED,
97 /** Illuminance in green spectrum, in lux. */
98 SENSOR_CHAN_GREEN,
99 /** Illuminance in blue spectrum, in lux. */
100 SENSOR_CHAN_BLUE,
101 /** Altitude, in meters */
102 SENSOR_CHAN_ALTITUDE,
103
104 /** 1.0 micro-meters Particulate Matter, in ug/m^3 */
105 SENSOR_CHAN_PM_1_0,
106 /** 2.5 micro-meters Particulate Matter, in ug/m^3 */
107 SENSOR_CHAN_PM_2_5,
108 /** 10 micro-meters Particulate Matter, in ug/m^3 */
109 SENSOR_CHAN_PM_10,
110 /** Distance. From sensor to target, in meters */
111 SENSOR_CHAN_DISTANCE,
112
113 /** CO2 level, in parts per million (ppm) **/
114 SENSOR_CHAN_CO2,
115 /** VOC level, in parts per billion (ppb) **/
116 SENSOR_CHAN_VOC,
117 /** Gas sensor resistance in ohms. */
118 SENSOR_CHAN_GAS_RES,
119
120 /** Voltage, in volts **/
121 SENSOR_CHAN_VOLTAGE,
122 /** Current, in amps **/
123 SENSOR_CHAN_CURRENT,
124 /** Power in watts **/
125 SENSOR_CHAN_POWER,
126
127 /** Resistance , in Ohm **/
128 SENSOR_CHAN_RESISTANCE,
129
130 /** Angular rotation, in degrees */
131 SENSOR_CHAN_ROTATION,
132
133 /** Position change on the X axis, in points. */
134 SENSOR_CHAN_POS_DX,
135 /** Position change on the Y axis, in points. */
136 SENSOR_CHAN_POS_DY,
137 /** Position change on the Z axis, in points. */
138 SENSOR_CHAN_POS_DZ,
139
140 /** Revolutions per minute, in RPM. */
141 SENSOR_CHAN_RPM,
142
143 /** Voltage, in volts **/
144 SENSOR_CHAN_GAUGE_VOLTAGE,
145 /** Average current, in amps **/
146 SENSOR_CHAN_GAUGE_AVG_CURRENT,
147 /** Standy current, in amps **/
148 SENSOR_CHAN_GAUGE_STDBY_CURRENT,
149 /** Max load current, in amps **/
150 SENSOR_CHAN_GAUGE_MAX_LOAD_CURRENT,
151 /** Gauge temperature **/
152 SENSOR_CHAN_GAUGE_TEMP,
153 /** State of charge measurement in % **/
154 SENSOR_CHAN_GAUGE_STATE_OF_CHARGE,
155 /** Full Charge Capacity in mAh **/
156 SENSOR_CHAN_GAUGE_FULL_CHARGE_CAPACITY,
157 /** Remaining Charge Capacity in mAh **/
158 SENSOR_CHAN_GAUGE_REMAINING_CHARGE_CAPACITY,
159 /** Nominal Available Capacity in mAh **/
160 SENSOR_CHAN_GAUGE_NOM_AVAIL_CAPACITY,
161 /** Full Available Capacity in mAh **/
162 SENSOR_CHAN_GAUGE_FULL_AVAIL_CAPACITY,
163 /** Average power in mW **/
164 SENSOR_CHAN_GAUGE_AVG_POWER,
165 /** State of health measurement in % **/
166 SENSOR_CHAN_GAUGE_STATE_OF_HEALTH,
167 /** Time to empty in minutes **/
168 SENSOR_CHAN_GAUGE_TIME_TO_EMPTY,
169 /** Time to full in minutes **/
170 SENSOR_CHAN_GAUGE_TIME_TO_FULL,
171 /** Cycle count (total number of charge/discharge cycles) **/
172 SENSOR_CHAN_GAUGE_CYCLE_COUNT,
173 /** Design voltage of cell in V (max voltage)*/
174 SENSOR_CHAN_GAUGE_DESIGN_VOLTAGE,
175 /** Desired voltage of cell in V (nominal voltage) */
176 SENSOR_CHAN_GAUGE_DESIRED_VOLTAGE,
177 /** Desired charging current in mA */
178 SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT,
179
180 /** All channels. */
181 SENSOR_CHAN_ALL,
182
183 /**
184 * Number of all common sensor channels.
185 */
186 SENSOR_CHAN_COMMON_COUNT,
187
188 /**
189 * This and higher values are sensor specific.
190 * Refer to the sensor header file.
191 */
192 SENSOR_CHAN_PRIV_START = SENSOR_CHAN_COMMON_COUNT,
193
194 /**
195 * Maximum value describing a sensor channel type.
196 */
197 SENSOR_CHAN_MAX = INT16_MAX,
198 };
199
200 /**
201 * @brief Sensor trigger types.
202 */
203 enum sensor_trigger_type {
204 /**
205 * Timer-based trigger, useful when the sensor does not have an
206 * interrupt line.
207 */
208 SENSOR_TRIG_TIMER,
209 /** Trigger fires whenever new data is ready. */
210 SENSOR_TRIG_DATA_READY,
211 /**
212 * Trigger fires when the selected channel varies significantly.
213 * This includes any-motion detection when the channel is
214 * acceleration or gyro. If detection is based on slope between
215 * successive channel readings, the slope threshold is configured
216 * via the @ref SENSOR_ATTR_SLOPE_TH and @ref SENSOR_ATTR_SLOPE_DUR
217 * attributes.
218 */
219 SENSOR_TRIG_DELTA,
220 /** Trigger fires when a near/far event is detected. */
221 SENSOR_TRIG_NEAR_FAR,
222 /**
223 * Trigger fires when channel reading transitions configured
224 * thresholds. The thresholds are configured via the @ref
225 * SENSOR_ATTR_LOWER_THRESH, @ref SENSOR_ATTR_UPPER_THRESH, and
226 * @ref SENSOR_ATTR_HYSTERESIS attributes.
227 */
228 SENSOR_TRIG_THRESHOLD,
229
230 /** Trigger fires when a single tap is detected. */
231 SENSOR_TRIG_TAP,
232
233 /** Trigger fires when a double tap is detected. */
234 SENSOR_TRIG_DOUBLE_TAP,
235
236 /** Trigger fires when a free fall is detected. */
237 SENSOR_TRIG_FREEFALL,
238
239 /**
240 * Number of all common sensor triggers.
241 */
242 SENSOR_TRIG_COMMON_COUNT,
243
244 /**
245 * This and higher values are sensor specific.
246 * Refer to the sensor header file.
247 */
248 SENSOR_TRIG_PRIV_START = SENSOR_TRIG_COMMON_COUNT,
249
250 /**
251 * Maximum value describing a sensor trigger type.
252 */
253 SENSOR_TRIG_MAX = INT16_MAX,
254 };
255
256 /**
257 * @brief Sensor trigger spec.
258 */
259 struct sensor_trigger {
260 /** Trigger type. */
261 enum sensor_trigger_type type;
262 /** Channel the trigger is set on. */
263 enum sensor_channel chan;
264 };
265
266 /**
267 * @brief Sensor attribute types.
268 */
269 enum sensor_attribute {
270 /**
271 * Sensor sampling frequency, i.e. how many times a second the
272 * sensor takes a measurement.
273 */
274 SENSOR_ATTR_SAMPLING_FREQUENCY,
275 /** Lower threshold for trigger. */
276 SENSOR_ATTR_LOWER_THRESH,
277 /** Upper threshold for trigger. */
278 SENSOR_ATTR_UPPER_THRESH,
279 /** Threshold for any-motion (slope) trigger. */
280 SENSOR_ATTR_SLOPE_TH,
281 /**
282 * Duration for which the slope values needs to be
283 * outside the threshold for the trigger to fire.
284 */
285 SENSOR_ATTR_SLOPE_DUR,
286 /* Hysteresis for trigger thresholds. */
287 SENSOR_ATTR_HYSTERESIS,
288 /** Oversampling factor */
289 SENSOR_ATTR_OVERSAMPLING,
290 /** Sensor range, in SI units. */
291 SENSOR_ATTR_FULL_SCALE,
292 /**
293 * The sensor value returned will be altered by the amount indicated by
294 * offset: final_value = sensor_value + offset.
295 */
296 SENSOR_ATTR_OFFSET,
297 /**
298 * Calibration target. This will be used by the internal chip's
299 * algorithms to calibrate itself on a certain axis, or all of them.
300 */
301 SENSOR_ATTR_CALIB_TARGET,
302 /** Configure the operating modes of a sensor. */
303 SENSOR_ATTR_CONFIGURATION,
304 /** Set a calibration value needed by a sensor. */
305 SENSOR_ATTR_CALIBRATION,
306 /** Enable/disable sensor features */
307 SENSOR_ATTR_FEATURE_MASK,
308 /** Alert threshold or alert enable/disable */
309 SENSOR_ATTR_ALERT,
310
311 /**
312 * Number of all common sensor attributes.
313 */
314 SENSOR_ATTR_COMMON_COUNT,
315
316 /**
317 * This and higher values are sensor specific.
318 * Refer to the sensor header file.
319 */
320 SENSOR_ATTR_PRIV_START = SENSOR_ATTR_COMMON_COUNT,
321
322 /**
323 * Maximum value describing a sensor attribute type.
324 */
325 SENSOR_ATTR_MAX = INT16_MAX,
326 };
327
328 /**
329 * @typedef sensor_trigger_handler_t
330 * @brief Callback API upon firing of a trigger
331 *
332 * @param dev Pointer to the sensor device
333 * @param trigger The trigger
334 */
335 typedef void (*sensor_trigger_handler_t)(const struct device *dev,
336 struct sensor_trigger *trigger);
337
338 /**
339 * @typedef sensor_attr_set_t
340 * @brief Callback API upon setting a sensor's attributes
341 *
342 * See sensor_attr_set() for argument description
343 */
344 typedef int (*sensor_attr_set_t)(const struct device *dev,
345 enum sensor_channel chan,
346 enum sensor_attribute attr,
347 const struct sensor_value *val);
348
349 /**
350 * @typedef sensor_attr_get_t
351 * @brief Callback API upon getting a sensor's attributes
352 *
353 * See sensor_attr_get() for argument description
354 */
355 typedef int (*sensor_attr_get_t)(const struct device *dev,
356 enum sensor_channel chan,
357 enum sensor_attribute attr,
358 struct sensor_value *val);
359
360 /**
361 * @typedef sensor_trigger_set_t
362 * @brief Callback API for setting a sensor's trigger and handler
363 *
364 * See sensor_trigger_set() for argument description
365 */
366 typedef int (*sensor_trigger_set_t)(const struct device *dev,
367 const struct sensor_trigger *trig,
368 sensor_trigger_handler_t handler);
369 /**
370 * @typedef sensor_sample_fetch_t
371 * @brief Callback API for fetching data from a sensor
372 *
373 * See sensor_sample_fetch() for argument description
374 */
375 typedef int (*sensor_sample_fetch_t)(const struct device *dev,
376 enum sensor_channel chan);
377 /**
378 * @typedef sensor_channel_get_t
379 * @brief Callback API for getting a reading from a sensor
380 *
381 * See sensor_channel_get() for argument description
382 */
383 typedef int (*sensor_channel_get_t)(const struct device *dev,
384 enum sensor_channel chan,
385 struct sensor_value *val);
386
387 __subsystem struct sensor_driver_api {
388 sensor_attr_set_t attr_set;
389 sensor_attr_get_t attr_get;
390 sensor_trigger_set_t trigger_set;
391 sensor_sample_fetch_t sample_fetch;
392 sensor_channel_get_t channel_get;
393 };
394
395 /**
396 * @brief Set an attribute for a sensor
397 *
398 * @param dev Pointer to the sensor device
399 * @param chan The channel the attribute belongs to, if any. Some
400 * attributes may only be set for all channels of a device, depending on
401 * device capabilities.
402 * @param attr The attribute to set
403 * @param val The value to set the attribute to
404 *
405 * @return 0 if successful, negative errno code if failure.
406 */
407 __syscall int sensor_attr_set(const struct device *dev,
408 enum sensor_channel chan,
409 enum sensor_attribute attr,
410 const struct sensor_value *val);
411
z_impl_sensor_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)412 static inline int z_impl_sensor_attr_set(const struct device *dev,
413 enum sensor_channel chan,
414 enum sensor_attribute attr,
415 const struct sensor_value *val)
416 {
417 const struct sensor_driver_api *api =
418 (const struct sensor_driver_api *)dev->api;
419
420 if (api->attr_set == NULL) {
421 return -ENOSYS;
422 }
423
424 return api->attr_set(dev, chan, attr, val);
425 }
426
427 /**
428 * @brief Get an attribute for a sensor
429 *
430 * @param dev Pointer to the sensor device
431 * @param chan The channel the attribute belongs to, if any. Some
432 * attributes may only be set for all channels of a device, depending on
433 * device capabilities.
434 * @param attr The attribute to get
435 * @param val Pointer to where to store the attribute
436 *
437 * @return 0 if successful, negative errno code if failure.
438 */
439 __syscall int sensor_attr_get(const struct device *dev,
440 enum sensor_channel chan,
441 enum sensor_attribute attr,
442 struct sensor_value *val);
443
z_impl_sensor_attr_get(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)444 static inline int z_impl_sensor_attr_get(const struct device *dev,
445 enum sensor_channel chan,
446 enum sensor_attribute attr,
447 struct sensor_value *val)
448 {
449 const struct sensor_driver_api *api =
450 (const struct sensor_driver_api *)dev->api;
451
452 if (api->attr_get == NULL) {
453 return -ENOSYS;
454 }
455
456 return api->attr_get(dev, chan, attr, val);
457 }
458
459 /**
460 * @brief Activate a sensor's trigger and set the trigger handler
461 *
462 * The handler will be called from a thread, so I2C or SPI operations are
463 * safe. However, the thread's stack is limited and defined by the
464 * driver. It is currently up to the caller to ensure that the handler
465 * does not overflow the stack.
466 *
467 * @funcprops \supervisor
468 *
469 * @param dev Pointer to the sensor device
470 * @param trig The trigger to activate
471 * @param handler The function that should be called when the trigger
472 * fires
473 *
474 * @return 0 if successful, negative errno code if failure.
475 */
sensor_trigger_set(const struct device * dev,struct sensor_trigger * trig,sensor_trigger_handler_t handler)476 static inline int sensor_trigger_set(const struct device *dev,
477 struct sensor_trigger *trig,
478 sensor_trigger_handler_t handler)
479 {
480 const struct sensor_driver_api *api =
481 (const struct sensor_driver_api *)dev->api;
482
483 if (api->trigger_set == NULL) {
484 return -ENOSYS;
485 }
486
487 return api->trigger_set(dev, trig, handler);
488 }
489
490 /**
491 * @brief Fetch a sample from the sensor and store it in an internal
492 * driver buffer
493 *
494 * Read all of a sensor's active channels and, if necessary, perform any
495 * additional operations necessary to make the values useful. The user
496 * may then get individual channel values by calling @ref
497 * sensor_channel_get.
498 *
499 * Since the function communicates with the sensor device, it is unsafe
500 * to call it in an ISR if the device is connected via I2C or SPI.
501 *
502 * @param dev Pointer to the sensor device
503 *
504 * @return 0 if successful, negative errno code if failure.
505 */
506 __syscall int sensor_sample_fetch(const struct device *dev);
507
z_impl_sensor_sample_fetch(const struct device * dev)508 static inline int z_impl_sensor_sample_fetch(const struct device *dev)
509 {
510 const struct sensor_driver_api *api =
511 (const struct sensor_driver_api *)dev->api;
512
513 return api->sample_fetch(dev, SENSOR_CHAN_ALL);
514 }
515
516 /**
517 * @brief Fetch a sample from the sensor and store it in an internal
518 * driver buffer
519 *
520 * Read and compute compensation for one type of sensor data (magnetometer,
521 * accelerometer, etc). The user may then get individual channel values by
522 * calling @ref sensor_channel_get.
523 *
524 * This is mostly implemented by multi function devices enabling reading at
525 * different sampling rates.
526 *
527 * Since the function communicates with the sensor device, it is unsafe
528 * to call it in an ISR if the device is connected via I2C or SPI.
529 *
530 * @param dev Pointer to the sensor device
531 * @param type The channel that needs updated
532 *
533 * @return 0 if successful, negative errno code if failure.
534 */
535 __syscall int sensor_sample_fetch_chan(const struct device *dev,
536 enum sensor_channel type);
537
z_impl_sensor_sample_fetch_chan(const struct device * dev,enum sensor_channel type)538 static inline int z_impl_sensor_sample_fetch_chan(const struct device *dev,
539 enum sensor_channel type)
540 {
541 const struct sensor_driver_api *api =
542 (const struct sensor_driver_api *)dev->api;
543
544 return api->sample_fetch(dev, type);
545 }
546
547 /**
548 * @brief Get a reading from a sensor device
549 *
550 * Return a useful value for a particular channel, from the driver's
551 * internal data. Before calling this function, a sample must be
552 * obtained by calling @ref sensor_sample_fetch or
553 * @ref sensor_sample_fetch_chan. It is guaranteed that two subsequent
554 * calls of this function for the same channels will yield the same
555 * value, if @ref sensor_sample_fetch or @ref sensor_sample_fetch_chan
556 * has not been called in the meantime.
557 *
558 * For vectorial data samples you can request all axes in just one call
559 * by passing the specific channel with _XYZ suffix. The sample will be
560 * returned at val[0], val[1] and val[2] (X, Y and Z in that order).
561 *
562 * @param dev Pointer to the sensor device
563 * @param chan The channel to read
564 * @param val Where to store the value
565 *
566 * @return 0 if successful, negative errno code if failure.
567 */
568 __syscall int sensor_channel_get(const struct device *dev,
569 enum sensor_channel chan,
570 struct sensor_value *val);
571
z_impl_sensor_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)572 static inline int z_impl_sensor_channel_get(const struct device *dev,
573 enum sensor_channel chan,
574 struct sensor_value *val)
575 {
576 const struct sensor_driver_api *api =
577 (const struct sensor_driver_api *)dev->api;
578
579 return api->channel_get(dev, chan, val);
580 }
581
582 /**
583 * @brief The value of gravitational constant in micro m/s^2.
584 */
585 #define SENSOR_G 9806650LL
586
587 /**
588 * @brief The value of constant PI in micros.
589 */
590 #define SENSOR_PI 3141592LL
591
592 /**
593 * @brief Helper function to convert acceleration from m/s^2 to Gs
594 *
595 * @param ms2 A pointer to a sensor_value struct holding the acceleration,
596 * in m/s^2.
597 *
598 * @return The converted value, in Gs.
599 */
sensor_ms2_to_g(const struct sensor_value * ms2)600 static inline int32_t sensor_ms2_to_g(const struct sensor_value *ms2)
601 {
602 int64_t micro_ms2 = ms2->val1 * 1000000LL + ms2->val2;
603
604 if (micro_ms2 > 0) {
605 return (micro_ms2 + SENSOR_G / 2) / SENSOR_G;
606 } else {
607 return (micro_ms2 - SENSOR_G / 2) / SENSOR_G;
608 }
609 }
610
611 /**
612 * @brief Helper function to convert acceleration from Gs to m/s^2
613 *
614 * @param g The G value to be converted.
615 * @param ms2 A pointer to a sensor_value struct, where the result is stored.
616 */
sensor_g_to_ms2(int32_t g,struct sensor_value * ms2)617 static inline void sensor_g_to_ms2(int32_t g, struct sensor_value *ms2)
618 {
619 ms2->val1 = ((int64_t)g * SENSOR_G) / 1000000LL;
620 ms2->val2 = ((int64_t)g * SENSOR_G) % 1000000LL;
621 }
622
623 /**
624 * @brief Helper function for converting radians to degrees.
625 *
626 * @param rad A pointer to a sensor_value struct, holding the value in radians.
627 *
628 * @return The converted value, in degrees.
629 */
sensor_rad_to_degrees(const struct sensor_value * rad)630 static inline int32_t sensor_rad_to_degrees(const struct sensor_value *rad)
631 {
632 int64_t micro_rad_s = rad->val1 * 1000000LL + rad->val2;
633
634 if (micro_rad_s > 0) {
635 return (micro_rad_s * 180LL + SENSOR_PI / 2) / SENSOR_PI;
636 } else {
637 return (micro_rad_s * 180LL - SENSOR_PI / 2) / SENSOR_PI;
638 }
639 }
640
641 /**
642 * @brief Helper function for converting degrees to radians.
643 *
644 * @param d The value (in degrees) to be converted.
645 * @param rad A pointer to a sensor_value struct, where the result is stored.
646 */
sensor_degrees_to_rad(int32_t d,struct sensor_value * rad)647 static inline void sensor_degrees_to_rad(int32_t d, struct sensor_value *rad)
648 {
649 rad->val1 = ((int64_t)d * SENSOR_PI / 180LL) / 1000000LL;
650 rad->val2 = ((int64_t)d * SENSOR_PI / 180LL) % 1000000LL;
651 }
652
653 /**
654 * @brief Helper function for converting struct sensor_value to double.
655 *
656 * @param val A pointer to a sensor_value struct.
657 * @return The converted value.
658 */
sensor_value_to_double(const struct sensor_value * val)659 static inline double sensor_value_to_double(const struct sensor_value *val)
660 {
661 return (double)val->val1 + (double)val->val2 / 1000000;
662 }
663
664 /**
665 * @brief Helper function for converting double to struct sensor_value.
666 *
667 * @param val A pointer to a sensor_value struct.
668 * @param inp The converted value.
669 */
sensor_value_from_double(struct sensor_value * val,double inp)670 static inline void sensor_value_from_double(struct sensor_value *val, double inp)
671 {
672 val->val1 = (int32_t) inp;
673 val->val2 = (int32_t)(inp * 1000000) % 1000000;
674 }
675
676 /**
677 * @}
678 */
679
680 #ifdef __cplusplus
681 }
682 #endif
683
684 #include <syscalls/sensor.h>
685
686 #endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_H_ */
687