Zephyr Project API  3.4.0
A Scalable Open Source RTOS
adc.h
Go to the documentation of this file.
1
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>
18#include <zephyr/kernel.h>
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
53};
54
72 int32_t *value);
73
83};
84
91
94
105
129
132
133#ifdef CONFIG_ADC_CONFIGURABLE_INPUTS
139 uint8_t input_positive;
140
146 uint8_t input_negative;
147#endif /* CONFIG_ADC_CONFIGURABLE_INPUTS */
148
149#ifdef CONFIG_ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN
150 uint8_t current_source_pin_set : 1;
157 uint8_t current_source_pin[2];
158#endif /* CONFIG_ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN */
159};
160
225#define ADC_CHANNEL_CFG_DT(node_id) { \
226 .gain = DT_STRING_TOKEN(node_id, zephyr_gain), \
227 .reference = DT_STRING_TOKEN(node_id, zephyr_reference), \
228 .acquisition_time = DT_PROP(node_id, zephyr_acquisition_time), \
229 .channel_id = DT_REG_ADDR(node_id), \
230IF_ENABLED(CONFIG_ADC_CONFIGURABLE_INPUTS, \
231 (.differential = DT_NODE_HAS_PROP(node_id, zephyr_input_negative), \
232 .input_positive = DT_PROP_OR(node_id, zephyr_input_positive, 0), \
233 .input_negative = DT_PROP_OR(node_id, zephyr_input_negative, 0),)) \
234IF_ENABLED(CONFIG_ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN, \
235 (.current_source_pin_set = DT_NODE_HAS_PROP(node_id, zephyr_current_source_pin), \
236 .current_source_pin = DT_PROP_OR(node_id, zephyr_current_source_pin, {0}),)) \
237}
238
250 const struct device *dev;
251
254
261
268
276
283
290};
291
294#define ADC_DT_SPEC_STRUCT(ctlr, input) { \
295 .dev = DEVICE_DT_GET(ctlr), \
296 .channel_id = input, \
297 ADC_CHANNEL_CFG_FROM_DT_NODE(\
298 ADC_CHANNEL_DT_NODE(ctlr, input)) \
299 }
300
301#define ADC_CHANNEL_DT_NODE(ctlr, input) \
302 DT_FOREACH_CHILD_VARGS(ctlr, ADC_FOREACH_INPUT, input)
303
304#define ADC_FOREACH_INPUT(node, input) \
305 IF_ENABLED(IS_EQ(DT_REG_ADDR(node), input), (node))
306
307#define ADC_CHANNEL_CFG_FROM_DT_NODE(node_id) \
308 IF_ENABLED(DT_NODE_EXISTS(node_id), \
309 (.channel_cfg_dt_node_exists = true, \
310 .channel_cfg = ADC_CHANNEL_CFG_DT(node_id), \
311 .vref_mv = DT_PROP_OR(node_id, zephyr_vref_mv, 0), \
312 .resolution = DT_PROP_OR(node_id, zephyr_resolution, 0), \
313 .oversampling = DT_PROP_OR(node_id, zephyr_oversampling, 0),))
314
386#define ADC_DT_SPEC_GET_BY_IDX(node_id, idx) \
387 ADC_DT_SPEC_STRUCT(DT_IO_CHANNELS_CTLR_BY_IDX(node_id, idx), \
388 DT_IO_CHANNELS_INPUT_BY_IDX(node_id, idx))
389
400#define ADC_DT_SPEC_INST_GET_BY_IDX(inst, idx) \
401 ADC_DT_SPEC_GET_BY_IDX(DT_DRV_INST(inst), idx)
402
412#define ADC_DT_SPEC_GET(node_id) ADC_DT_SPEC_GET_BY_IDX(node_id, 0)
413
422#define ADC_DT_SPEC_INST_GET(inst) ADC_DT_SPEC_GET(DT_DRV_INST(inst))
423
424/* Forward declaration of the adc_sequence structure. */
425struct adc_sequence;
426
433
439
442};
443
463typedef enum adc_action (*adc_sequence_callback)(const struct device *dev,
464 const struct adc_sequence *sequence,
465 uint16_t sampling_index);
466
481
487
493
499};
500
510
519
531 void *buffer;
532
540
549
557
567};
568
569
574typedef int (*adc_api_channel_setup)(const struct device *dev,
575 const struct adc_channel_cfg *channel_cfg);
576
581typedef int (*adc_api_read)(const struct device *dev,
582 const struct adc_sequence *sequence);
583
589typedef int (*adc_api_read_async)(const struct device *dev,
590 const struct adc_sequence *sequence,
591 struct k_poll_signal *async);
592
598__subsystem struct adc_driver_api {
601#ifdef CONFIG_ADC_ASYNC
602 adc_api_read_async read_async;
603#endif
605};
606
619__syscall int adc_channel_setup(const struct device *dev,
620 const struct adc_channel_cfg *channel_cfg);
621
622static inline int z_impl_adc_channel_setup(const struct device *dev,
623 const struct adc_channel_cfg *channel_cfg)
624{
625 const struct adc_driver_api *api =
626 (const struct adc_driver_api *)dev->api;
627
628 return api->channel_setup(dev, channel_cfg);
629}
630
640static inline int adc_channel_setup_dt(const struct adc_dt_spec *spec)
641{
642 if (!spec->channel_cfg_dt_node_exists) {
643 return -ENOTSUP;
644 }
645
646 return adc_channel_setup(spec->dev, &spec->channel_cfg);
647}
648
670__syscall int adc_read(const struct device *dev,
671 const struct adc_sequence *sequence);
672
673static inline int z_impl_adc_read(const struct device *dev,
674 const struct adc_sequence *sequence)
675{
676 const struct adc_driver_api *api =
677 (const struct adc_driver_api *)dev->api;
678
679 return api->read(dev, sequence);
680}
681
702__syscall int adc_read_async(const struct device *dev,
703 const struct adc_sequence *sequence,
704 struct k_poll_signal *async);
705
706
707#ifdef CONFIG_ADC_ASYNC
708static inline int z_impl_adc_read_async(const struct device *dev,
709 const struct adc_sequence *sequence,
710 struct k_poll_signal *async)
711{
712 const struct adc_driver_api *api =
713 (const struct adc_driver_api *)dev->api;
714
715 return api->read_async(dev, sequence, async);
716}
717#endif /* CONFIG_ADC_ASYNC */
718
728static inline uint16_t adc_ref_internal(const struct device *dev)
729{
730 const struct adc_driver_api *api =
731 (const struct adc_driver_api *)dev->api;
732
733 return api->ref_internal;
734}
735
759static inline int adc_raw_to_millivolts(int32_t ref_mv,
760 enum adc_gain gain,
761 uint8_t resolution,
762 int32_t *valp)
763{
764 int32_t adc_mv = *valp * ref_mv;
765 int ret = adc_gain_invert(gain, &adc_mv);
766
767 if (ret == 0) {
768 *valp = (adc_mv >> resolution);
769 }
770
771 return ret;
772}
773
787static inline int adc_raw_to_millivolts_dt(const struct adc_dt_spec *spec,
788 int32_t *valp)
789{
790 int32_t vref_mv;
791 uint8_t resolution;
792
793 if (!spec->channel_cfg_dt_node_exists) {
794 return -ENOTSUP;
795 }
796
798 vref_mv = (int32_t)adc_ref_internal(spec->dev);
799 } else {
800 vref_mv = spec->vref_mv;
801 }
802
803 resolution = spec->resolution;
804
805 /*
806 * For differential channels, one bit less needs to be specified
807 * for resolution to achieve correct conversion.
808 */
809 if (spec->channel_cfg.differential) {
810 resolution -= 1U;
811 }
812
813 return adc_raw_to_millivolts(vref_mv, spec->channel_cfg.gain,
814 resolution, valp);
815}
816
835static inline int adc_sequence_init_dt(const struct adc_dt_spec *spec,
836 struct adc_sequence *seq)
837{
838 if (!spec->channel_cfg_dt_node_exists) {
839 return -ENOTSUP;
840 }
841
842 seq->channels = BIT(spec->channel_id);
843 seq->resolution = spec->resolution;
844 seq->oversampling = spec->oversampling;
845
846 return 0;
847}
848
853#ifdef __cplusplus
854}
855#endif
856
857#include <syscalls/adc.h>
858
859#endif /* ZEPHYR_INCLUDE_DRIVERS_ADC_H_ */
int adc_read_async(const struct device *dev, const struct adc_sequence *sequence, struct k_poll_signal *async)
Set an asynchronous read request.
static int adc_raw_to_millivolts_dt(const struct adc_dt_spec *spec, int32_t *valp)
Convert a raw ADC value to millivolts using information stored in a struct adc_dt_spec.
Definition: adc.h:787
adc_gain
ADC channel gain factors.
Definition: adc.h:32
int(* adc_api_read)(const struct device *dev, const struct adc_sequence *sequence)
Type definition of ADC API function for setting a read request. See adc_read() for argument descripti...
Definition: adc.h:581
static int adc_sequence_init_dt(const struct adc_dt_spec *spec, struct adc_sequence *seq)
Initialize a struct adc_sequence from information stored in struct adc_dt_spec.
Definition: adc.h:835
int adc_gain_invert(enum adc_gain gain, int32_t *value)
Invert the application of gain to a measurement value.
int adc_read(const struct device *dev, const struct adc_sequence *sequence)
Set a read request.
int adc_channel_setup(const struct device *dev, const struct adc_channel_cfg *channel_cfg)
Configure an ADC channel.
int(* adc_api_channel_setup)(const struct device *dev, const struct adc_channel_cfg *channel_cfg)
Type definition of ADC API function for configuring a channel. See adc_channel_setup() for argument d...
Definition: adc.h:574
adc_action
Action to be performed after a sampling is done.
Definition: adc.h:430
enum adc_action(* adc_sequence_callback)(const struct device *dev, const struct adc_sequence *sequence, uint16_t sampling_index)
Type definition of the optional callback function to be called after a requested sampling is done.
Definition: adc.h:463
adc_reference
ADC references.
Definition: adc.h:75
int(* adc_api_read_async)(const struct device *dev, const struct adc_sequence *sequence, struct k_poll_signal *async)
Type definition of ADC API function for setting an asynchronous read request. See adc_read_async() fo...
Definition: adc.h:589
static uint16_t adc_ref_internal(const struct device *dev)
Get the internal reference voltage.
Definition: adc.h:728
static int adc_channel_setup_dt(const struct adc_dt_spec *spec)
Configure an ADC channel from a struct adc_dt_spec.
Definition: adc.h:640
static int adc_raw_to_millivolts(int32_t ref_mv, enum adc_gain gain, uint8_t resolution, int32_t *valp)
Convert a raw ADC value to millivolts.
Definition: adc.h:759
@ ADC_GAIN_64
Definition: adc.h:51
@ ADC_GAIN_3
Definition: adc.h:43
@ ADC_GAIN_4
Definition: adc.h:44
@ ADC_GAIN_1_5
Definition: adc.h:34
@ ADC_GAIN_128
Definition: adc.h:52
@ ADC_GAIN_1_2
Definition: adc.h:38
@ ADC_GAIN_12
Definition: adc.h:47
@ ADC_GAIN_2_5
Definition: adc.h:37
@ ADC_GAIN_16
Definition: adc.h:48
@ ADC_GAIN_24
Definition: adc.h:49
@ ADC_GAIN_1
Definition: adc.h:41
@ ADC_GAIN_6
Definition: adc.h:45
@ ADC_GAIN_1_6
Definition: adc.h:33
@ ADC_GAIN_32
Definition: adc.h:50
@ ADC_GAIN_2_3
Definition: adc.h:39
@ ADC_GAIN_4_5
Definition: adc.h:40
@ ADC_GAIN_8
Definition: adc.h:46
@ ADC_GAIN_1_3
Definition: adc.h:36
@ ADC_GAIN_1_4
Definition: adc.h:35
@ ADC_GAIN_2
Definition: adc.h:42
@ ADC_ACTION_FINISH
Definition: adc.h:441
@ ADC_ACTION_REPEAT
Definition: adc.h:438
@ ADC_ACTION_CONTINUE
Definition: adc.h:432
@ ADC_REF_INTERNAL
Definition: adc.h:80
@ ADC_REF_EXTERNAL1
Definition: adc.h:82
@ ADC_REF_VDD_1_2
Definition: adc.h:77
@ ADC_REF_VDD_1_3
Definition: adc.h:78
@ ADC_REF_VDD_1_4
Definition: adc.h:79
@ ADC_REF_VDD_1
Definition: adc.h:76
@ ADC_REF_EXTERNAL0
Definition: adc.h:81
#define BIT(n)
Unsigned integer with bit position n set (signed in assembly language).
Definition: util_macro.h:44
#define ENOTSUP
Definition: errno.h:115
Public kernel APIs.
static ZTEST_BMEM volatile int ret
Definition: k_float_disable.c:29
__UINT32_TYPE__ uint32_t
Definition: stdint.h:90
__INT32_TYPE__ int32_t
Definition: stdint.h:74
__UINT8_TYPE__ uint8_t
Definition: stdint.h:88
__UINT16_TYPE__ uint16_t
Definition: stdint.h:89
Structure for specifying the configuration of an ADC channel.
Definition: adc.h:88
enum adc_gain gain
Definition: adc.h:90
uint8_t differential
Definition: adc.h:131
uint16_t acquisition_time
Definition: adc.h:104
enum adc_reference reference
Definition: adc.h:93
uint8_t channel_id
Definition: adc.h:128
ADC driver API.
Definition: adc.h:598
adc_api_read read
Definition: adc.h:600
uint16_t ref_internal
Definition: adc.h:604
adc_api_channel_setup channel_setup
Definition: adc.h:599
Container for ADC channel information specified in devicetree.
Definition: adc.h:245
struct adc_channel_cfg channel_cfg
Definition: adc.h:267
uint8_t channel_id
Definition: adc.h:253
uint16_t vref_mv
Definition: adc.h:275
const struct device * dev
Definition: adc.h:250
uint8_t oversampling
Definition: adc.h:289
bool channel_cfg_dt_node_exists
Definition: adc.h:260
uint8_t resolution
Definition: adc.h:282
Structure defining additional options for an ADC sampling sequence.
Definition: adc.h:470
void * user_data
Definition: adc.h:492
uint16_t extra_samplings
Definition: adc.h:498
adc_sequence_callback callback
Definition: adc.h:486
uint32_t interval_us
Definition: adc.h:480
Structure defining an ADC sampling sequence.
Definition: adc.h:504
uint8_t oversampling
Definition: adc.h:556
const struct adc_sequence_options * options
Definition: adc.h:509
uint32_t channels
Definition: adc.h:518
void * buffer
Definition: adc.h:531
bool calibrate
Definition: adc.h:566
size_t buffer_size
Definition: adc.h:539
uint8_t resolution
Definition: adc.h:548
Runtime device structure (in ROM) per driver instance.
Definition: device.h:380
const void * api
Definition: device.h:386
Definition: kernel.h:5517