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