LCOV - code coverage report
Current view: top level - zephyr/drivers - adc.h Coverage Total Hit
Test: new.info Lines: 95.1 % 61 58
Test Date: 2025-09-05 20:47:19

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

Generated by: LCOV version 2.0-1