1 /**
2 * @file
3 * @brief ADC public API header file.
4 */
5
6 /*
7 * Copyright (c) 2018 Nordic Semiconductor ASA
8 * Copyright (c) 2015 Intel Corporation
9 *
10 * SPDX-License-Identifier: Apache-2.0
11 */
12
13 #ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_H_
14 #define ZEPHYR_INCLUDE_DRIVERS_ADC_H_
15
16 #include <zephyr/device.h>
17 #include <zephyr/dt-bindings/adc/adc.h>
18 #include <zephyr/kernel.h>
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
24 /**
25 * @brief ADC driver APIs
26 * @defgroup adc_interface ADC driver APIs
27 * @ingroup io_interfaces
28 * @{
29 */
30
31 /** @brief ADC channel gain factors. */
32 enum adc_gain {
33 ADC_GAIN_1_6, /**< x 1/6. */
34 ADC_GAIN_1_5, /**< x 1/5. */
35 ADC_GAIN_1_4, /**< x 1/4. */
36 ADC_GAIN_1_3, /**< x 1/3. */
37 ADC_GAIN_2_5, /**< x 2/5. */
38 ADC_GAIN_1_2, /**< x 1/2. */
39 ADC_GAIN_2_3, /**< x 2/3. */
40 ADC_GAIN_4_5, /**< x 4/5. */
41 ADC_GAIN_1, /**< x 1. */
42 ADC_GAIN_2, /**< x 2. */
43 ADC_GAIN_3, /**< x 3. */
44 ADC_GAIN_4, /**< x 4. */
45 ADC_GAIN_6, /**< x 6. */
46 ADC_GAIN_8, /**< x 8. */
47 ADC_GAIN_12, /**< x 12. */
48 ADC_GAIN_16, /**< x 16. */
49 ADC_GAIN_24, /**< x 24. */
50 ADC_GAIN_32, /**< x 32. */
51 ADC_GAIN_64, /**< x 64. */
52 ADC_GAIN_128, /**< x 128. */
53 };
54
55 /**
56 * @brief Invert the application of gain to a measurement value.
57 *
58 * For example, if the gain passed in is ADC_GAIN_1_6 and the
59 * referenced value is 10, the value after the function returns is 60.
60 *
61 * @param gain the gain used to amplify the input signal.
62 *
63 * @param value a pointer to a value that initially has the effect of
64 * the applied gain but has that effect removed when this function
65 * successfully returns. If the gain cannot be reversed the value
66 * remains unchanged.
67 *
68 * @retval 0 if the gain was successfully reversed
69 * @retval -EINVAL if the gain could not be interpreted
70 */
71 int adc_gain_invert(enum adc_gain gain,
72 int32_t *value);
73
74 /** @brief ADC references. */
75 enum adc_reference {
76 ADC_REF_VDD_1, /**< VDD. */
77 ADC_REF_VDD_1_2, /**< VDD/2. */
78 ADC_REF_VDD_1_3, /**< VDD/3. */
79 ADC_REF_VDD_1_4, /**< VDD/4. */
80 ADC_REF_INTERNAL, /**< Internal. */
81 ADC_REF_EXTERNAL0, /**< External, input 0. */
82 ADC_REF_EXTERNAL1, /**< External, input 1. */
83 };
84
85 /**
86 * @brief Structure for specifying the configuration of an ADC channel.
87 */
88 struct adc_channel_cfg {
89 /** Gain selection. */
90 enum adc_gain gain;
91
92 /** Reference selection. */
93 enum adc_reference reference;
94
95 /**
96 * Acquisition time.
97 * Use the ADC_ACQ_TIME macro to compose the value for this field or
98 * pass ADC_ACQ_TIME_DEFAULT to use the default setting for a given
99 * hardware (e.g. when the hardware does not allow to configure the
100 * acquisition time).
101 * Particular drivers do not necessarily support all the possible units.
102 * Value range is 0-16383 for a given unit.
103 */
104 uint16_t acquisition_time;
105
106 /**
107 * Channel identifier.
108 * This value primarily identifies the channel within the ADC API - when
109 * a read request is done, the corresponding bit in the "channels" field
110 * of the "adc_sequence" structure must be set to include this channel
111 * in the sampling.
112 * For hardware that does not allow selection of analog inputs for given
113 * channels, but rather have dedicated ones, this value also selects the
114 * physical ADC input to be used in the sampling. Otherwise, when it is
115 * needed to explicitly select an analog input for the channel, or two
116 * inputs when the channel is a differential one, the selection is done
117 * in "input_positive" and "input_negative" fields.
118 * Particular drivers indicate which one of the above two cases they
119 * support by selecting or not a special hidden Kconfig option named
120 * ADC_CONFIGURABLE_INPUTS. If this option is not selected, the macro
121 * CONFIG_ADC_CONFIGURABLE_INPUTS is not defined and consequently the
122 * mentioned two fields are not present in this structure.
123 * While this API allows identifiers from range 0-31, particular drivers
124 * may support only a limited number of channel identifiers (dependent
125 * on the underlying hardware capabilities or configured via a dedicated
126 * Kconfig option).
127 */
128 uint8_t channel_id : 5;
129
130 /** Channel type: single-ended or differential. */
131 uint8_t differential : 1;
132
133 #ifdef CONFIG_ADC_CONFIGURABLE_INPUTS
134 /**
135 * Positive ADC input.
136 * This is a driver dependent value that identifies an ADC input to be
137 * associated with the channel.
138 */
139 uint8_t input_positive;
140
141 /**
142 * Negative ADC input (used only for differential channels).
143 * This is a driver dependent value that identifies an ADC input to be
144 * associated with the channel.
145 */
146 uint8_t input_negative;
147 #endif /* CONFIG_ADC_CONFIGURABLE_INPUTS */
148
149 #ifdef CONFIG_ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN
150 uint8_t current_source_pin_set : 1;
151 /**
152 * Output pin for the current sources.
153 * This is only available if the driver enables this feature
154 * via the hidden configuration option ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN.
155 * The meaning itself is then defined by the driver itself.
156 */
157 uint8_t current_source_pin[2];
158 #endif /* CONFIG_ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN */
159 };
160
161 /**
162 * @brief Get ADC channel configuration from a given devicetree node.
163 *
164 * This returns a static initializer for a <tt>struct adc_channel_cfg</tt>
165 * filled with data from a given devicetree node.
166 *
167 * Example devicetree fragment:
168 *
169 * @code{.dts}
170 * &adc {
171 * #address-cells = <1>;
172 * #size-cells = <0>;
173 *
174 * channel@0 {
175 * reg = <0>;
176 * zephyr,gain = "ADC_GAIN_1_6";
177 * zephyr,reference = "ADC_REF_INTERNAL";
178 * zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 20)>;
179 * zephyr,input-positive = <NRF_SAADC_AIN6>;
180 * zephyr,input-negative = <NRF_SAADC_AIN7>;
181 * };
182 *
183 * channel@1 {
184 * reg = <1>;
185 * zephyr,gain = "ADC_GAIN_1_6";
186 * zephyr,reference = "ADC_REF_INTERNAL";
187 * zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
188 * zephyr,input-positive = <NRF_SAADC_AIN0>;
189 * };
190 * };
191 * @endcode
192 *
193 * Example usage:
194 *
195 * @code{.c}
196 * static const struct adc_channel_cfg ch0_cfg_dt =
197 * ADC_CHANNEL_CFG_DT(DT_CHILD(DT_NODELABEL(adc), channel_0));
198 * static const struct adc_channel_cfg ch1_cfg_dt =
199 * ADC_CHANNEL_CFG_DT(DT_CHILD(DT_NODELABEL(adc), channel_1));
200 *
201 * // Initializes 'ch0_cfg_dt' to:
202 * // {
203 * // .channel_id = 0,
204 * // .gain = ADC_GAIN_1_6,
205 * // .reference = ADC_REF_INTERNAL,
206 * // .acquisition_time = ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 20),
207 * // .differential = true,
208 * // .input_positive = NRF_SAADC_AIN6,
209 * // .input-negative = NRF_SAADC_AIN7,
210 * // }
211 * // and 'ch1_cfg_dt' to:
212 * // {
213 * // .channel_id = 1,
214 * // .gain = ADC_GAIN_1_6,
215 * // .reference = ADC_REF_INTERNAL,
216 * // .acquisition_time = ADC_ACQ_TIME_DEFAULT,
217 * // .input_positive = NRF_SAADC_AIN0,
218 * // }
219 * @endcode
220 *
221 * @param node_id Devicetree node identifier.
222 *
223 * @return Static initializer for an adc_channel_cfg structure.
224 */
225 #define ADC_CHANNEL_CFG_DT(node_id) { \
226 .gain = DT_STRING_TOKEN(node_id, zephyr_gain), \
227 .reference = DT_STRING_TOKEN(node_id, zephyr_reference), \
228 .acquisition_time = DT_PROP(node_id, zephyr_acquisition_time), \
229 .channel_id = DT_REG_ADDR(node_id), \
230 IF_ENABLED(CONFIG_ADC_CONFIGURABLE_INPUTS, \
231 (.differential = DT_NODE_HAS_PROP(node_id, zephyr_input_negative), \
232 .input_positive = DT_PROP_OR(node_id, zephyr_input_positive, 0), \
233 .input_negative = DT_PROP_OR(node_id, zephyr_input_negative, 0),)) \
234 IF_ENABLED(DT_PROP(node_id, zephyr_differential), \
235 (.differential = true,)) \
236 IF_ENABLED(CONFIG_ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN, \
237 (.current_source_pin_set = DT_NODE_HAS_PROP(node_id, zephyr_current_source_pin), \
238 .current_source_pin = DT_PROP_OR(node_id, zephyr_current_source_pin, {0}),)) \
239 }
240
241 /**
242 * @brief Container for ADC channel information specified in devicetree.
243 *
244 * @see ADC_DT_SPEC_GET_BY_IDX
245 * @see ADC_DT_SPEC_GET
246 */
247 struct adc_dt_spec {
248 /**
249 * Pointer to the device structure for the ADC driver instance
250 * used by this io-channel.
251 */
252 const struct device *dev;
253
254 /** ADC channel identifier used by this io-channel. */
255 uint8_t channel_id;
256
257 /**
258 * Flag indicating whether configuration of the associated ADC channel
259 * is provided as a child node of the corresponding ADC controller in
260 * devicetree.
261 */
262 bool channel_cfg_dt_node_exists;
263
264 /**
265 * Configuration of the associated ADC channel specified in devicetree.
266 * This field is valid only when @a channel_cfg_dt_node_exists is set
267 * to @a true.
268 */
269 struct adc_channel_cfg channel_cfg;
270
271 /**
272 * Voltage of the reference selected for the channel or 0 if this
273 * value is not provided in devicetree.
274 * This field is valid only when @a channel_cfg_dt_node_exists is set
275 * to @a true.
276 */
277 uint16_t vref_mv;
278
279 /**
280 * ADC resolution to be used for that channel.
281 * This field is valid only when @a channel_cfg_dt_node_exists is set
282 * to @a true.
283 */
284 uint8_t resolution;
285
286 /**
287 * Oversampling setting to be used for that channel.
288 * This field is valid only when @a channel_cfg_dt_node_exists is set
289 * to @a true.
290 */
291 uint8_t oversampling;
292 };
293
294 /** @cond INTERNAL_HIDDEN */
295
296 #define ADC_DT_SPEC_STRUCT(ctlr, input) { \
297 .dev = DEVICE_DT_GET(ctlr), \
298 .channel_id = input, \
299 ADC_CHANNEL_CFG_FROM_DT_NODE(\
300 ADC_CHANNEL_DT_NODE(ctlr, input)) \
301 }
302
303 #define ADC_CHANNEL_DT_NODE(ctlr, input) \
304 DT_FOREACH_CHILD_VARGS(ctlr, ADC_FOREACH_INPUT, input)
305
306 #define ADC_FOREACH_INPUT(node, input) \
307 IF_ENABLED(IS_EQ(DT_REG_ADDR(node), input), (node))
308
309 #define ADC_CHANNEL_CFG_FROM_DT_NODE(node_id) \
310 IF_ENABLED(DT_NODE_EXISTS(node_id), \
311 (.channel_cfg_dt_node_exists = true, \
312 .channel_cfg = ADC_CHANNEL_CFG_DT(node_id), \
313 .vref_mv = DT_PROP_OR(node_id, zephyr_vref_mv, 0), \
314 .resolution = DT_PROP_OR(node_id, zephyr_resolution, 0), \
315 .oversampling = DT_PROP_OR(node_id, zephyr_oversampling, 0),))
316
317 /** @endcond */
318
319 /**
320 * @brief Get ADC io-channel information from devicetree.
321 *
322 * This returns a static initializer for an @p adc_dt_spec structure
323 * given a devicetree node and a channel index. The node must have
324 * the "io-channels" property defined.
325 *
326 * Example devicetree fragment:
327 *
328 * @code{.dts}
329 * / {
330 * zephyr,user {
331 * io-channels = <&adc0 1>, <&adc0 3>;
332 * };
333 * };
334 *
335 * &adc0 {
336 * #address-cells = <1>;
337 * #size-cells = <0>;
338 *
339 * channel@3 {
340 * reg = <3>;
341 * zephyr,gain = "ADC_GAIN_1_5";
342 * zephyr,reference = "ADC_REF_VDD_1_4";
343 * zephyr,vref-mv = <750>;
344 * zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
345 * zephyr,resolution = <12>;
346 * zephyr,oversampling = <4>;
347 * };
348 * };
349 * @endcode
350 *
351 * Example usage:
352 *
353 * @code{.c}
354 * static const struct adc_dt_spec adc_chan0 =
355 * ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), 0);
356 * static const struct adc_dt_spec adc_chan1 =
357 * ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), 1);
358 *
359 * // Initializes 'adc_chan0' to:
360 * // {
361 * // .dev = DEVICE_DT_GET(DT_NODELABEL(adc0)),
362 * // .channel_id = 1,
363 * // }
364 * // and 'adc_chan1' to:
365 * // {
366 * // .dev = DEVICE_DT_GET(DT_NODELABEL(adc0)),
367 * // .channel_id = 3,
368 * // .channel_cfg_dt_node_exists = true,
369 * // .channel_cfg = {
370 * // .channel_id = 3,
371 * // .gain = ADC_GAIN_1_5,
372 * // .reference = ADC_REF_VDD_1_4,
373 * // .acquisition_time = ADC_ACQ_TIME_DEFAULT,
374 * // },
375 * // .vref_mv = 750,
376 * // .resolution = 12,
377 * // .oversampling = 4,
378 * // }
379 * @endcode
380 *
381 * @see ADC_DT_SPEC_GET()
382 *
383 * @param node_id Devicetree node identifier.
384 * @param idx Channel index.
385 *
386 * @return Static initializer for an adc_dt_spec structure.
387 */
388 #define ADC_DT_SPEC_GET_BY_IDX(node_id, idx) \
389 ADC_DT_SPEC_STRUCT(DT_IO_CHANNELS_CTLR_BY_IDX(node_id, idx), \
390 DT_IO_CHANNELS_INPUT_BY_IDX(node_id, idx))
391
392 /** @brief Get ADC io-channel information from a DT_DRV_COMPAT devicetree
393 * instance.
394 *
395 * @see ADC_DT_SPEC_GET_BY_IDX()
396 *
397 * @param inst DT_DRV_COMPAT instance number
398 * @param idx Channel index.
399 *
400 * @return Static initializer for an adc_dt_spec structure.
401 */
402 #define ADC_DT_SPEC_INST_GET_BY_IDX(inst, idx) \
403 ADC_DT_SPEC_GET_BY_IDX(DT_DRV_INST(inst), idx)
404
405 /**
406 * @brief Equivalent to ADC_DT_SPEC_GET_BY_IDX(node_id, 0).
407 *
408 * @see ADC_DT_SPEC_GET_BY_IDX()
409 *
410 * @param node_id Devicetree node identifier.
411 *
412 * @return Static initializer for an adc_dt_spec structure.
413 */
414 #define ADC_DT_SPEC_GET(node_id) ADC_DT_SPEC_GET_BY_IDX(node_id, 0)
415
416 /** @brief Equivalent to ADC_DT_SPEC_INST_GET_BY_IDX(inst, 0).
417 *
418 * @see ADC_DT_SPEC_GET()
419 *
420 * @param inst DT_DRV_COMPAT instance number
421 *
422 * @return Static initializer for an adc_dt_spec structure.
423 */
424 #define ADC_DT_SPEC_INST_GET(inst) ADC_DT_SPEC_GET(DT_DRV_INST(inst))
425
426 /* Forward declaration of the adc_sequence structure. */
427 struct adc_sequence;
428
429 /**
430 * @brief Action to be performed after a sampling is done.
431 */
432 enum adc_action {
433 /** The sequence should be continued normally. */
434 ADC_ACTION_CONTINUE = 0,
435
436 /**
437 * The sampling should be repeated. New samples or sample should be
438 * read from the ADC and written in the same place as the recent ones.
439 */
440 ADC_ACTION_REPEAT,
441
442 /** The sequence should be finished immediately. */
443 ADC_ACTION_FINISH,
444 };
445
446 /**
447 * @brief Type definition of the optional callback function to be called after
448 * a requested sampling is done.
449 *
450 * @param dev Pointer to the device structure for the driver
451 * instance.
452 * @param sequence Pointer to the sequence structure that triggered
453 * the sampling. This parameter points to a copy of
454 * the structure that was supplied to the call that
455 * started the sampling sequence, thus it cannot be
456 * used with the CONTAINER_OF() macro to retrieve
457 * some other data associated with the sequence.
458 * Instead, the adc_sequence_options::user_data field
459 * should be used for such purpose.
460 *
461 * @param sampling_index Index (0-65535) of the sampling done.
462 *
463 * @returns Action to be performed by the driver. See @ref adc_action.
464 */
465 typedef enum adc_action (*adc_sequence_callback)(const struct device *dev,
466 const struct adc_sequence *sequence,
467 uint16_t sampling_index);
468
469 /**
470 * @brief Structure defining additional options for an ADC sampling sequence.
471 */
472 struct adc_sequence_options {
473 /**
474 * Interval between consecutive samplings (in microseconds), 0 means
475 * sample as fast as possible, without involving any timer.
476 * The accuracy of this interval is dependent on the implementation of
477 * a given driver. The default routine that handles the intervals uses
478 * a kernel timer for this purpose, thus, it has the accuracy of the
479 * kernel's system clock. Particular drivers may use some dedicated
480 * hardware timers and achieve a better precision.
481 */
482 uint32_t interval_us;
483
484 /**
485 * Callback function to be called after each sampling is done.
486 * Optional - set to NULL if it is not needed.
487 */
488 adc_sequence_callback callback;
489
490 /**
491 * Pointer to user data. It can be used to associate the sequence
492 * with any other data that is needed in the callback function.
493 */
494 void *user_data;
495
496 /**
497 * Number of extra samplings to perform (the total number of samplings
498 * is 1 + extra_samplings).
499 */
500 uint16_t extra_samplings;
501 };
502
503 /**
504 * @brief Structure defining an ADC sampling sequence.
505 */
506 struct adc_sequence {
507 /**
508 * Pointer to a structure defining additional options for the sequence.
509 * If NULL, the sequence consists of a single sampling.
510 */
511 const struct adc_sequence_options *options;
512
513 /**
514 * Bit-mask indicating the channels to be included in each sampling
515 * of this sequence.
516 * All selected channels must be configured with adc_channel_setup()
517 * before they are used in a sequence.
518 * The least significant bit corresponds to channel 0.
519 */
520 uint32_t channels;
521
522 /**
523 * Pointer to a buffer where the samples are to be written. Samples
524 * from subsequent samplings are written sequentially in the buffer.
525 * The number of samples written for each sampling is determined by
526 * the number of channels selected in the "channels" field.
527 * The values written to the buffer represent a sample from each
528 * selected channel starting from the one with the lowest ID.
529 * The buffer must be of an appropriate size, taking into account
530 * the number of selected channels and the ADC resolution used,
531 * as well as the number of samplings contained in the sequence.
532 */
533 void *buffer;
534
535 /**
536 * Specifies the actual size of the buffer pointed by the "buffer"
537 * field (in bytes). The driver must ensure that samples are not
538 * written beyond the limit and it must return an error if the buffer
539 * turns out to be not large enough to hold all the requested samples.
540 */
541 size_t buffer_size;
542
543 /**
544 * ADC resolution.
545 * For single-ended channels the sample values are from range:
546 * 0 .. 2^resolution - 1,
547 * for differential ones:
548 * - 2^(resolution-1) .. 2^(resolution-1) - 1.
549 */
550 uint8_t resolution;
551
552 /**
553 * Oversampling setting.
554 * Each sample is averaged from 2^oversampling conversion results.
555 * This feature may be unsupported by a given ADC hardware, or in
556 * a specific mode (e.g. when sampling multiple channels).
557 */
558 uint8_t oversampling;
559
560 /**
561 * Perform calibration before the reading is taken if requested.
562 *
563 * The impact of channel configuration on the calibration
564 * process is specific to the underlying hardware. ADC
565 * implementations that do not support calibration should
566 * ignore this flag.
567 */
568 bool calibrate;
569 };
570
571
572 /**
573 * @brief Type definition of ADC API function for configuring a channel.
574 * See adc_channel_setup() for argument descriptions.
575 */
576 typedef int (*adc_api_channel_setup)(const struct device *dev,
577 const struct adc_channel_cfg *channel_cfg);
578
579 /**
580 * @brief Type definition of ADC API function for setting a read request.
581 * See adc_read() for argument descriptions.
582 */
583 typedef int (*adc_api_read)(const struct device *dev,
584 const struct adc_sequence *sequence);
585
586 /**
587 * @brief Type definition of ADC API function for setting an asynchronous
588 * read request.
589 * See adc_read_async() for argument descriptions.
590 */
591 typedef int (*adc_api_read_async)(const struct device *dev,
592 const struct adc_sequence *sequence,
593 struct k_poll_signal *async);
594
595 /**
596 * @brief ADC driver API
597 *
598 * This is the mandatory API any ADC driver needs to expose.
599 */
600 __subsystem struct adc_driver_api {
601 adc_api_channel_setup channel_setup;
602 adc_api_read read;
603 #ifdef CONFIG_ADC_ASYNC
604 adc_api_read_async read_async;
605 #endif
606 uint16_t ref_internal; /* mV */
607 };
608
609 /**
610 * @brief Configure an ADC channel.
611 *
612 * It is required to call this function and configure each channel before it is
613 * selected for a read request.
614 *
615 * @param dev Pointer to the device structure for the driver instance.
616 * @param channel_cfg Channel configuration.
617 *
618 * @retval 0 On success.
619 * @retval -EINVAL If a parameter with an invalid value has been provided.
620 */
621 __syscall int adc_channel_setup(const struct device *dev,
622 const struct adc_channel_cfg *channel_cfg);
623
z_impl_adc_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)624 static inline int z_impl_adc_channel_setup(const struct device *dev,
625 const struct adc_channel_cfg *channel_cfg)
626 {
627 const struct adc_driver_api *api =
628 (const struct adc_driver_api *)dev->api;
629
630 return api->channel_setup(dev, channel_cfg);
631 }
632
633 /**
634 * @brief Configure an ADC channel from a struct adc_dt_spec.
635 *
636 * @param spec ADC specification from Devicetree.
637 *
638 * @return A value from adc_channel_setup() or -ENOTSUP if information from
639 * Devicetree is not valid.
640 * @see adc_channel_setup()
641 */
adc_channel_setup_dt(const struct adc_dt_spec * spec)642 static inline int adc_channel_setup_dt(const struct adc_dt_spec *spec)
643 {
644 if (!spec->channel_cfg_dt_node_exists) {
645 return -ENOTSUP;
646 }
647
648 return adc_channel_setup(spec->dev, &spec->channel_cfg);
649 }
650
651 /**
652 * @brief Set a read request.
653 *
654 * @param dev Pointer to the device structure for the driver instance.
655 * @param sequence Structure specifying requested sequence of samplings.
656 *
657 * If invoked from user mode, any sequence struct options for callback must
658 * be NULL.
659 *
660 * @retval 0 On success.
661 * @retval -EINVAL If a parameter with an invalid value has been provided.
662 * @retval -ENOMEM If the provided buffer is to small to hold the results
663 * of all requested samplings.
664 * @retval -ENOTSUP If the requested mode of operation is not supported.
665 * @retval -EBUSY If another sampling was triggered while the previous one
666 * was still in progress. This may occur only when samplings
667 * are done with intervals, and it indicates that the selected
668 * interval was too small. All requested samples are written
669 * in the buffer, but at least some of them were taken with
670 * an extra delay compared to what was scheduled.
671 */
672 __syscall int adc_read(const struct device *dev,
673 const struct adc_sequence *sequence);
674
z_impl_adc_read(const struct device * dev,const struct adc_sequence * sequence)675 static inline int z_impl_adc_read(const struct device *dev,
676 const struct adc_sequence *sequence)
677 {
678 const struct adc_driver_api *api =
679 (const struct adc_driver_api *)dev->api;
680
681 return api->read(dev, sequence);
682 }
683
684 /**
685 * @brief Set a read request from a struct adc_dt_spec.
686 *
687 * @param spec ADC specification from Devicetree.
688 * @param sequence Structure specifying requested sequence of samplings.
689 *
690 * @return A value from adc_read().
691 * @see adc_read()
692 */
adc_read_dt(const struct adc_dt_spec * spec,const struct adc_sequence * sequence)693 static inline int adc_read_dt(const struct adc_dt_spec *spec,
694 const struct adc_sequence *sequence)
695 {
696 return adc_read(spec->dev, sequence);
697 }
698
699 /**
700 * @brief Set an asynchronous read request.
701 *
702 * @note This function is available only if @kconfig{CONFIG_ADC_ASYNC}
703 * is selected.
704 *
705 * If invoked from user mode, any sequence struct options for callback must
706 * be NULL.
707 *
708 * @param dev Pointer to the device structure for the driver instance.
709 * @param sequence Structure specifying requested sequence of samplings.
710 * @param async Pointer to a valid and ready to be signaled struct
711 * k_poll_signal. (Note: if NULL this function will not notify
712 * the end of the transaction, and whether it went successfully
713 * or not).
714 *
715 * @returns 0 on success, negative error code otherwise.
716 * See adc_read() for a list of possible error codes.
717 *
718 */
719 __syscall int adc_read_async(const struct device *dev,
720 const struct adc_sequence *sequence,
721 struct k_poll_signal *async);
722
723
724 #ifdef CONFIG_ADC_ASYNC
z_impl_adc_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)725 static inline int z_impl_adc_read_async(const struct device *dev,
726 const struct adc_sequence *sequence,
727 struct k_poll_signal *async)
728 {
729 const struct adc_driver_api *api =
730 (const struct adc_driver_api *)dev->api;
731
732 return api->read_async(dev, sequence, async);
733 }
734 #endif /* CONFIG_ADC_ASYNC */
735
736 /**
737 * @brief Get the internal reference voltage.
738 *
739 * Returns the voltage corresponding to @ref ADC_REF_INTERNAL,
740 * measured in millivolts.
741 *
742 * @return a positive value is the reference voltage value. Returns
743 * zero if reference voltage information is not available.
744 */
adc_ref_internal(const struct device * dev)745 static inline uint16_t adc_ref_internal(const struct device *dev)
746 {
747 const struct adc_driver_api *api =
748 (const struct adc_driver_api *)dev->api;
749
750 return api->ref_internal;
751 }
752
753 /**
754 * @brief Convert a raw ADC value to millivolts.
755 *
756 * This function performs the necessary conversion to transform a raw
757 * ADC measurement to a voltage in millivolts.
758 *
759 * @param ref_mv the reference voltage used for the measurement, in
760 * millivolts. This may be from adc_ref_internal() or a known
761 * external reference.
762 *
763 * @param gain the ADC gain configuration used to sample the input
764 *
765 * @param resolution the number of bits in the absolute value of the
766 * sample. For differential sampling this needs to be one less than the
767 * resolution in struct adc_sequence.
768 *
769 * @param valp pointer to the raw measurement value on input, and the
770 * corresponding millivolt value on successful conversion. If
771 * conversion fails the stored value is left unchanged.
772 *
773 * @retval 0 on successful conversion
774 * @retval -EINVAL if the gain is not reversible
775 */
adc_raw_to_millivolts(int32_t ref_mv,enum adc_gain gain,uint8_t resolution,int32_t * valp)776 static inline int adc_raw_to_millivolts(int32_t ref_mv,
777 enum adc_gain gain,
778 uint8_t resolution,
779 int32_t *valp)
780 {
781 int32_t adc_mv = *valp * ref_mv;
782 int ret = adc_gain_invert(gain, &adc_mv);
783
784 if (ret == 0) {
785 *valp = (adc_mv >> resolution);
786 }
787
788 return ret;
789 }
790
791 /**
792 * @brief Convert a raw ADC value to millivolts using information stored
793 * in a struct adc_dt_spec.
794 *
795 * @param[in] spec ADC specification from Devicetree.
796 * @param[in,out] valp Pointer to the raw measurement value on input, and the
797 * corresponding millivolt value on successful conversion. If conversion fails
798 * the stored value is left unchanged.
799 *
800 * @return A value from adc_raw_to_millivolts() or -ENOTSUP if information from
801 * Devicetree is not valid.
802 * @see adc_raw_to_millivolts()
803 */
adc_raw_to_millivolts_dt(const struct adc_dt_spec * spec,int32_t * valp)804 static inline int adc_raw_to_millivolts_dt(const struct adc_dt_spec *spec,
805 int32_t *valp)
806 {
807 int32_t vref_mv;
808 uint8_t resolution;
809
810 if (!spec->channel_cfg_dt_node_exists) {
811 return -ENOTSUP;
812 }
813
814 if (spec->channel_cfg.reference == ADC_REF_INTERNAL) {
815 vref_mv = (int32_t)adc_ref_internal(spec->dev);
816 } else {
817 vref_mv = spec->vref_mv;
818 }
819
820 resolution = spec->resolution;
821
822 /*
823 * For differential channels, one bit less needs to be specified
824 * for resolution to achieve correct conversion.
825 */
826 if (spec->channel_cfg.differential) {
827 resolution -= 1U;
828 }
829
830 return adc_raw_to_millivolts(vref_mv, spec->channel_cfg.gain,
831 resolution, valp);
832 }
833
834 /**
835 * @brief Initialize a struct adc_sequence from information stored in
836 * struct adc_dt_spec.
837 *
838 * Note that this function only initializes the following fields:
839 *
840 * - @ref adc_sequence.channels
841 * - @ref adc_sequence.resolution
842 * - @ref adc_sequence.oversampling
843 *
844 * Other fields should be initialized by the caller.
845 *
846 * @param[in] spec ADC specification from Devicetree.
847 * @param[out] seq Sequence to initialize.
848 *
849 * @retval 0 On success
850 * @retval -ENOTSUP If @p spec does not have valid channel configuration
851 */
adc_sequence_init_dt(const struct adc_dt_spec * spec,struct adc_sequence * seq)852 static inline int adc_sequence_init_dt(const struct adc_dt_spec *spec,
853 struct adc_sequence *seq)
854 {
855 if (!spec->channel_cfg_dt_node_exists) {
856 return -ENOTSUP;
857 }
858
859 seq->channels = BIT(spec->channel_id);
860 seq->resolution = spec->resolution;
861 seq->oversampling = spec->oversampling;
862
863 return 0;
864 }
865
866 /**
867 * @brief Validate that the ADC device is ready.
868 *
869 * @param spec ADC specification from devicetree
870 *
871 * @retval true if the ADC device is ready for use and false otherwise.
872 */
adc_is_ready_dt(const struct adc_dt_spec * spec)873 static inline bool adc_is_ready_dt(const struct adc_dt_spec *spec)
874 {
875 return device_is_ready(spec->dev);
876 }
877
878 /**
879 * @}
880 */
881
882 #ifdef __cplusplus
883 }
884 #endif
885
886 #include <syscalls/adc.h>
887
888 #endif /* ZEPHYR_INCLUDE_DRIVERS_ADC_H_ */
889