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