LCOV - code coverage report
Current view: top level - zephyr/drivers - adc.h Hit Total Coverage
Test: new.info Lines: 53 56 94.6 %
Date: 2024-12-21 18:13:37

          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_ */

Generated by: LCOV version 1.14