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