mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Revision:
18:da299f395b9e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_Atmel/TARGET_SAM_CortexM0P/drivers/adc/TARGET_SAML21/adc_feature.h	Mon Nov 09 13:30:11 2015 +0000
@@ -0,0 +1,726 @@
+/**
+ * \file
+ *
+ * \brief SAM ADC functionality
+ *
+ * Copyright (C) 2014-2015 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ *    Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+/*
+ * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
+ */
+#ifndef ADC_FEATURE_H_INCLUDED
+#define ADC_FEATURE_H_INCLUDED
+
+/**
+ * \addtogroup asfdoc_sam0_adc_group
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*@{*/
+#if (SAMC20) || (SAMC21) || defined(__DOXYGEN__)
+/** Output Driver Strength Selection feature support. */
+#  define FEATURE_ADC_SUPPORT_MASTER_SLAVE
+#endif
+/*@}*/
+
+#if ADC_CALLBACK_MODE == true
+#  include <system_interrupt.h>
+
+#if !defined(__DOXYGEN__)
+extern struct adc_module *_adc_instances[ADC_INST_NUM];
+#endif
+
+/** Forward definition of the device instance. */
+struct adc_module;
+
+/** Type of the callback functions. */
+typedef void (*adc_callback_t)(struct adc_module *const module);
+
+/**
+ * \brief ADC callback enum.
+ *
+ * Callback types for ADC callback driver.
+ *
+ */
+enum adc_callback {
+    /** Callback for buffer received */
+    ADC_CALLBACK_READ_BUFFER,
+    /** Callback when window is hit */
+    ADC_CALLBACK_WINDOW,
+    /** Callback for error */
+    ADC_CALLBACK_ERROR,
+#  if !defined(__DOXYGEN__)
+    /** Number of available callbacks */
+    ADC_CALLBACK_N,
+#  endif
+};
+
+#endif
+
+/**
+ * \brief ADC reference voltage enum.
+ *
+ * Enum for the possible reference voltages for the ADC.
+ *
+ */
+enum adc_reference {
+    /** Internal Bandgap Reference */
+    ADC_REFERENCE_INTREF  = ADC_REFCTRL_REFSEL_INTREF,
+    /** 1/1.48V<SUB>CC</SUB> reference */
+    ADC_REFERENCE_INTVCC0 = ADC_REFCTRL_REFSEL_INTVCC0,
+    /** 1/2V<SUB>CC</SUB> (only for internal V<SUB>CC</SUB> > 2.1V) */
+    ADC_REFERENCE_INTVCC1 = ADC_REFCTRL_REFSEL_INTVCC1,
+    /** External reference A */
+    ADC_REFERENCE_AREFA   = ADC_REFCTRL_REFSEL_AREFA,
+#if (SAML21)
+    /** External reference B. */
+    ADC_REFERENCE_AREFB   = ADC_REFCTRL_REFSEL_AREFB,
+#endif
+#if (SAMC20) || (SAMC21)
+    /** DAC. */
+    ADC_REFERENCE_DAC     = ADC_REFCTRL_REFSEL_DAC,
+#endif
+    /** VDDANA. */
+    ADC_REFERENCE_INTVCC2 = ADC_REFCTRL_REFSEL_INTVCC2,
+};
+
+/**
+ * \brief ADC clock prescaler enum.
+ *
+ * Enum for the possible clock prescaler values for the ADC.
+ *
+ */
+enum adc_clock_prescaler {
+    /** ADC clock division factor 2 */
+    ADC_CLOCK_PRESCALER_DIV2   = ADC_CTRLB_PRESCALER_DIV2,
+    /** ADC clock division factor 4 */
+    ADC_CLOCK_PRESCALER_DIV4   = ADC_CTRLB_PRESCALER_DIV4,
+    /** ADC clock division factor 8 */
+    ADC_CLOCK_PRESCALER_DIV8   = ADC_CTRLB_PRESCALER_DIV8,
+    /** ADC clock division factor 16 */
+    ADC_CLOCK_PRESCALER_DIV16  = ADC_CTRLB_PRESCALER_DIV16,
+    /** ADC clock division factor 32 */
+    ADC_CLOCK_PRESCALER_DIV32  = ADC_CTRLB_PRESCALER_DIV32,
+    /** ADC clock division factor 64 */
+    ADC_CLOCK_PRESCALER_DIV64  = ADC_CTRLB_PRESCALER_DIV64,
+    /** ADC clock division factor 128 */
+    ADC_CLOCK_PRESCALER_DIV128 = ADC_CTRLB_PRESCALER_DIV128,
+    /** ADC clock division factor 256 */
+    ADC_CLOCK_PRESCALER_DIV256 = ADC_CTRLB_PRESCALER_DIV256,
+};
+
+/**
+ * \brief ADC resolution enum.
+ *
+ * Enum for the possible resolution values for the ADC.
+ *
+ */
+enum adc_resolution {
+    /** ADC 12-bit resolution */
+    ADC_RESOLUTION_12BIT = ADC_CTRLC_RESSEL_12BIT,
+    /** ADC 16-bit resolution using oversampling and decimation */
+    ADC_RESOLUTION_16BIT = ADC_CTRLC_RESSEL_16BIT,
+    /** ADC 10-bit resolution */
+    ADC_RESOLUTION_10BIT = ADC_CTRLC_RESSEL_10BIT,
+    /** ADC 8-bit resolution */
+    ADC_RESOLUTION_8BIT  = ADC_CTRLC_RESSEL_8BIT,
+    /** ADC 13-bit resolution using oversampling and decimation */
+    ADC_RESOLUTION_13BIT,
+    /** ADC 14-bit resolution using oversampling and decimation */
+    ADC_RESOLUTION_14BIT,
+    /** ADC 15-bit resolution using oversampling and decimation */
+    ADC_RESOLUTION_15BIT,
+    /** ADC 16-bit result register for use with averaging. When using this mode
+      * the ADC result register will be set to 16-bit wide, and the number of
+      * samples to accumulate and the division factor is configured by the
+      * \ref adc_config.accumulate_samples and \ref adc_config.divide_result
+      * members in the configuration struct.
+      */
+    ADC_RESOLUTION_CUSTOM,
+};
+
+/**
+ * \brief ADC window monitor mode enum.
+ *
+ * Enum for the possible window monitor modes for the ADC.
+ *
+ */
+enum adc_window_mode {
+    /** No window mode */
+    ADC_WINDOW_MODE_DISABLE          = ADC_CTRLC_WINMODE_DISABLE,
+    /** RESULT > WINLT */
+    ADC_WINDOW_MODE_ABOVE_LOWER      = ADC_CTRLC_WINMODE_MODE1,
+    /** RESULT < WINUT */
+    ADC_WINDOW_MODE_BELOW_UPPER      = ADC_CTRLC_WINMODE_MODE2,
+    /** WINLT < RESULT < WINUT */
+    ADC_WINDOW_MODE_BETWEEN          = ADC_CTRLC_WINMODE_MODE3,
+    /** !(WINLT < RESULT < WINUT) */
+    ADC_WINDOW_MODE_BETWEEN_INVERTED = ADC_CTRLC_WINMODE_MODE4,
+};
+
+/**
+ * \brief ADC event action enum.
+ *
+ * Enum for the possible actions to take on an incoming event.
+ *
+ */
+enum adc_event_action {
+    /** Event action disabled */
+    ADC_EVENT_ACTION_DISABLED         = 0,
+    /** Flush ADC and start conversion */
+    ADC_EVENT_ACTION_FLUSH_START_CONV = ADC_EVCTRL_FLUSHEI,
+    /** Start conversion */
+    ADC_EVENT_ACTION_START_CONV       = ADC_EVCTRL_STARTEI,
+};
+
+/**
+ * \brief ADC positive MUX input selection enum.
+ *
+ * Enum for the possible positive MUX input selections for the ADC.
+ *
+ */
+enum adc_positive_input {
+    /** ADC0 pin */
+    ADC_POSITIVE_INPUT_PIN0          = ADC_INPUTCTRL_MUXPOS_AIN0,
+    /** ADC1 pin */
+    ADC_POSITIVE_INPUT_PIN1          = ADC_INPUTCTRL_MUXPOS_AIN1,
+    /** ADC2 pin */
+    ADC_POSITIVE_INPUT_PIN2          = ADC_INPUTCTRL_MUXPOS_AIN2,
+    /** ADC3 pin */
+    ADC_POSITIVE_INPUT_PIN3          = ADC_INPUTCTRL_MUXPOS_AIN3,
+    /** ADC4 pin */
+    ADC_POSITIVE_INPUT_PIN4          = ADC_INPUTCTRL_MUXPOS_AIN4,
+    /** ADC5 pin */
+    ADC_POSITIVE_INPUT_PIN5          = ADC_INPUTCTRL_MUXPOS_AIN5,
+    /** ADC6 pin */
+    ADC_POSITIVE_INPUT_PIN6          = ADC_INPUTCTRL_MUXPOS_AIN6,
+    /** ADC7 pin */
+    ADC_POSITIVE_INPUT_PIN7          = ADC_INPUTCTRL_MUXPOS_AIN7,
+    /** ADC8 pin */
+    ADC_POSITIVE_INPUT_PIN8          = ADC_INPUTCTRL_MUXPOS_AIN8,
+    /** ADC9 pin */
+    ADC_POSITIVE_INPUT_PIN9          = ADC_INPUTCTRL_MUXPOS_AIN9,
+    /** ADC10 pin */
+    ADC_POSITIVE_INPUT_PIN10         = ADC_INPUTCTRL_MUXPOS_AIN10,
+    /** ADC11 pin */
+    ADC_POSITIVE_INPUT_PIN11         = ADC_INPUTCTRL_MUXPOS_AIN11,
+#if !(SAMC20) && !(SAMC21)
+    /** ADC12 pin. */
+    ADC_POSITIVE_INPUT_PIN12         = ADC_INPUTCTRL_MUXPOS_AIN12,
+    /** ADC13 pin */
+    ADC_POSITIVE_INPUT_PIN13         = ADC_INPUTCTRL_MUXPOS_AIN13,
+    /** ADC14 pin */
+    ADC_POSITIVE_INPUT_PIN14         = ADC_INPUTCTRL_MUXPOS_AIN14,
+    /** ADC15 pin */
+    ADC_POSITIVE_INPUT_PIN15         = ADC_INPUTCTRL_MUXPOS_AIN15,
+    /** ADC16 pin */
+    ADC_POSITIVE_INPUT_PIN16         = ADC_INPUTCTRL_MUXPOS_AIN16,
+    /** ADC17 pin */
+    ADC_POSITIVE_INPUT_PIN17         = ADC_INPUTCTRL_MUXPOS_AIN17,
+    /** ADC18 pin */
+    ADC_POSITIVE_INPUT_PIN18         = ADC_INPUTCTRL_MUXPOS_AIN18,
+    /** ADC19 pin */
+    ADC_POSITIVE_INPUT_PIN19         = ADC_INPUTCTRL_MUXPOS_AIN19,
+    /** ADC20 pin */
+    ADC_POSITIVE_INPUT_PIN20         = ADC_INPUTCTRL_MUXPOS_AIN20,
+    /** ADC21 pin */
+    ADC_POSITIVE_INPUT_PIN21         = ADC_INPUTCTRL_MUXPOS_AIN21,
+    /** ADC22 pin */
+    ADC_POSITIVE_INPUT_PIN22         = ADC_INPUTCTRL_MUXPOS_AIN22,
+    /** ADC23 pin */
+    ADC_POSITIVE_INPUT_PIN23         = ADC_INPUTCTRL_MUXPOS_AIN23,
+    /** Temperature reference */
+    ADC_POSITIVE_INPUT_TEMP          = ADC_INPUTCTRL_MUXPOS_TEMP,
+#endif
+    /** Bandgap voltage. */
+    ADC_POSITIVE_INPUT_BANDGAP       = ADC_INPUTCTRL_MUXPOS_BANDGAP,
+    /** 1/4 scaled core supply */
+    ADC_POSITIVE_INPUT_SCALEDCOREVCC = ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC,
+    /** 1/4 scaled I/O supply */
+    ADC_POSITIVE_INPUT_SCALEDIOVCC   = ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC,
+    /** DAC input */
+    ADC_POSITIVE_INPUT_DAC           = ADC_INPUTCTRL_MUXPOS_DAC,
+#if !(SAMC20) && !(SAMC21)
+    /** SCALEDVBAT. */
+    ADC_POSITIVE_INPUT_SCALEDVBAT    = ADC_INPUTCTRL_MUXPOS_SCALEDVBAT,
+    /** OPAMP01 */
+    ADC_POSITIVE_INPUT_OPAMP01       = ADC_INPUTCTRL_MUXPOS_OPAMP01,
+    /** OPAMP02 */
+    ADC_POSITIVE_INPUT_OPAMP2        = ADC_INPUTCTRL_MUXPOS_OPAMP2,
+#endif
+};
+
+/**
+ * \brief ADC negative MUX input selection enum.
+ *
+ * Enum for the possible negative MUX input selections for the ADC.
+ *
+ */
+enum adc_negative_input {
+    /** ADC0 pin */
+    ADC_NEGATIVE_INPUT_PIN0          = ADC_INPUTCTRL_MUXNEG_AIN0,
+    /** ADC1 pin */
+    ADC_NEGATIVE_INPUT_PIN1          = ADC_INPUTCTRL_MUXNEG_AIN1,
+    /** ADC2 pin */
+    ADC_NEGATIVE_INPUT_PIN2          = ADC_INPUTCTRL_MUXNEG_AIN2,
+    /** ADC3 pin */
+    ADC_NEGATIVE_INPUT_PIN3          = ADC_INPUTCTRL_MUXNEG_AIN3,
+    /** ADC4 pin */
+    ADC_NEGATIVE_INPUT_PIN4          = ADC_INPUTCTRL_MUXNEG_AIN4,
+    /** ADC5 pin */
+    ADC_NEGATIVE_INPUT_PIN5          = ADC_INPUTCTRL_MUXNEG_AIN5,
+#if !(SAMC20) && !(SAMC21)
+    /** ADC6 pin. */
+    ADC_NEGATIVE_INPUT_PIN6          = ADC_INPUTCTRL_MUXNEG_AIN6,
+    /** ADC7 pin */
+    ADC_NEGATIVE_INPUT_PIN7          = ADC_INPUTCTRL_MUXNEG_AIN7,
+#endif
+    /** Internal ground. */
+    ADC_NEGATIVE_INPUT_GND           = ADC_INPUTCTRL_MUXNEG(0x18u),
+};
+
+/**
+ * \brief ADC number of accumulated samples enum.
+ *
+ * Enum for the possible numbers of ADC samples to accumulate.
+ * This setting is only used when the \ref ADC_RESOLUTION_CUSTOM
+ * resolution setting is used.
+ *
+ */
+enum adc_accumulate_samples {
+    /** No averaging */
+    ADC_ACCUMULATE_DISABLE      = ADC_AVGCTRL_SAMPLENUM_1,
+    /** Average 2 samples */
+    ADC_ACCUMULATE_SAMPLES_2    = ADC_AVGCTRL_SAMPLENUM_2,
+    /** Average 4 samples */
+    ADC_ACCUMULATE_SAMPLES_4    = ADC_AVGCTRL_SAMPLENUM_4,
+    /** Average 8 samples */
+    ADC_ACCUMULATE_SAMPLES_8    = ADC_AVGCTRL_SAMPLENUM_8,
+    /** Average 16 samples */
+    ADC_ACCUMULATE_SAMPLES_16   = ADC_AVGCTRL_SAMPLENUM_16,
+    /** Average 32 samples */
+    ADC_ACCUMULATE_SAMPLES_32   = ADC_AVGCTRL_SAMPLENUM_32,
+    /** Average 64 samples */
+    ADC_ACCUMULATE_SAMPLES_64   = ADC_AVGCTRL_SAMPLENUM_64,
+    /** Average 128 samples */
+    ADC_ACCUMULATE_SAMPLES_128  = ADC_AVGCTRL_SAMPLENUM_128,
+    /** Average 256 samples */
+    ADC_ACCUMULATE_SAMPLES_256  = ADC_AVGCTRL_SAMPLENUM_256,
+    /** Average 512 samples */
+    ADC_ACCUMULATE_SAMPLES_512  = ADC_AVGCTRL_SAMPLENUM_512,
+    /** Average 1024 samples */
+    ADC_ACCUMULATE_SAMPLES_1024 = ADC_AVGCTRL_SAMPLENUM_1024,
+};
+
+/**
+ * \brief ADC possible dividers for the result register.
+ *
+ * Enum for the possible division factors to use when accumulating
+ * multiple samples. To keep the same resolution for the averaged
+ * result and the actual input value, the division factor must
+ * be equal to the number of samples accumulated. This setting is only
+ * used when the \ref ADC_RESOLUTION_CUSTOM resolution setting is used.
+ */
+enum adc_divide_result {
+    /** Don't divide result register after accumulation */
+    ADC_DIVIDE_RESULT_DISABLE = 0,
+    /** Divide result register by 2 after accumulation */
+    ADC_DIVIDE_RESULT_2       = 1,
+    /** Divide result register by 4 after accumulation */
+    ADC_DIVIDE_RESULT_4       = 2,
+    /** Divide result register by 8 after accumulation */
+    ADC_DIVIDE_RESULT_8       = 3,
+    /** Divide result register by 16 after accumulation */
+    ADC_DIVIDE_RESULT_16      = 4,
+    /** Divide result register by 32 after accumulation */
+    ADC_DIVIDE_RESULT_32      = 5,
+    /** Divide result register by 64 after accumulation */
+    ADC_DIVIDE_RESULT_64      = 6,
+    /** Divide result register by 128 after accumulation */
+    ADC_DIVIDE_RESULT_128     = 7,
+};
+
+#if ADC_CALLBACK_MODE == true
+/**
+ * Enum for the possible ADC interrupt flags.
+ */
+enum adc_interrupt_flag {
+    /** ADC result ready */
+    ADC_INTERRUPT_RESULT_READY = ADC_INTFLAG_RESRDY,
+    /** Window monitor match */
+    ADC_INTERRUPT_WINDOW       = ADC_INTFLAG_WINMON,
+    /** ADC result overwritten before read */
+    ADC_INTERRUPT_OVERRUN      = ADC_INTFLAG_OVERRUN,
+};
+#endif
+
+/**
+ * \brief ADC oversampling and decimation enum.
+ *
+ * Enum for the possible numbers of bits resolution can be increased by when
+ * using oversampling and decimation.
+ *
+ */
+enum adc_oversampling_and_decimation {
+    /** Don't use oversampling and decimation mode */
+    ADC_OVERSAMPLING_AND_DECIMATION_DISABLE = 0,
+    /** 1 bit resolution increase */
+    ADC_OVERSAMPLING_AND_DECIMATION_1BIT,
+    /** 2 bits resolution increase */
+    ADC_OVERSAMPLING_AND_DECIMATION_2BIT,
+    /** 3 bits resolution increase */
+    ADC_OVERSAMPLING_AND_DECIMATION_3BIT,
+    /** 4 bits resolution increase */
+    ADC_OVERSAMPLING_AND_DECIMATION_4BIT
+};
+
+#ifdef FEATURE_ADC_SUPPORT_MASTER_SLAVE
+/**
+ * Enum for the trigger selection in dual mode.
+ */
+enum adc_dual_mode_trigger_selection {
+    /** Start event or software trigger will start a conversion on both ADCs. */
+    ADC_DUAL_MODE_BOTH         = ADC_CTRLC_DUALSEL_BOTH,
+    /** START event or software trigger will alternatingly start a conversion on ADC0 and ADC1. */
+    ADC_DUAL_MODE_INTERLEAVE   = ADC_CTRLC_DUALSEL_INTERLEAVE,
+};
+#endif
+
+/**
+ * \brief Window monitor configuration structure.
+ *
+ * Window monitor configuration structure.
+ */
+struct adc_window_config {
+    /** Selected window mode */
+    enum adc_window_mode window_mode;
+    /** Lower window value */
+    int32_t window_lower_value;
+    /** Upper window value */
+    int32_t window_upper_value;
+};
+
+/**
+ * \brief ADC event enable/disable structure.
+ *
+ * Event flags for the ADC module. This is used to enable and
+ * disable events via \ref adc_enable_events() and \ref adc_disable_events().
+ */
+struct adc_events {
+    /** Enable event generation on conversion done */
+    bool generate_event_on_conversion_done;
+    /** Enable event generation on window monitor */
+    bool generate_event_on_window_monitor;
+};
+
+/**
+ * \brief Gain and offset correction configuration structure.
+ *
+ * Gain and offset correction configuration structure.
+ * Part of the \ref adc_config struct and will  be initialized by
+ * \ref adc_get_config_defaults.
+ */
+struct adc_correction_config {
+    /**
+     * Enables correction for gain and offset based on values of gain_correction and
+     * offset_correction if set to true
+     */
+    bool correction_enable;
+    /**
+     * This value defines how the ADC conversion result is compensated for gain
+     * error before written to the result register. This is a fractional value,
+     * 1-bit integer plus an 11-bit fraction, therefore
+     * 1/2 ¡Ü gain_correction < 2. Valid \c gain_correction values ranges from
+     * \c 0b010000000000 to \c 0b111111111111.
+     */
+    uint16_t gain_correction;
+    /**
+     * This value defines how the ADC conversion result is compensated for
+     * offset error before written to the result register. This is a 12-bit
+     * value in two's complement format.
+     */
+    int16_t offset_correction;
+};
+
+/**
+ * \brief ADC configuration structure.
+ *
+ * Configuration structure for an ADC instance. This structure should be
+ * initialized by the \ref adc_get_config_defaults()
+ * function before being modified by the user application.
+ */
+struct adc_config {
+    /** GCLK generator used to clock the peripheral */
+    enum gclk_generator clock_source;
+    /** Voltage reference */
+    enum adc_reference reference;
+    /** Clock prescaler */
+    enum adc_clock_prescaler clock_prescaler;
+    /** Result resolution */
+    enum adc_resolution resolution;
+    /** Positive MUX input */
+    enum adc_positive_input positive_input;
+    /** Negative MUX input */
+    enum adc_negative_input negative_input;
+    /** Number of ADC samples to accumulate when using the
+     *  \c ADC_RESOLUTION_CUSTOM mode
+     */
+    enum adc_accumulate_samples accumulate_samples;
+    /** Division ration when using the ADC_RESOLUTION_CUSTOM mode */
+    enum adc_divide_result divide_result;
+    /** Left adjusted result */
+    bool left_adjust;
+    /** Enables differential mode if true */
+    bool differential_mode;
+    /** Enables free running mode if true */
+    bool freerunning;
+    /** ADC run in standby control */
+    bool run_in_standby;
+    /** ADC On demand control */
+    bool on_demand;
+    /**
+     * Enables sampling period offset compensation if true
+     */
+    bool sampling_time_compensation_enable;
+    /**
+     * Positive input enabled mask for conversion sequence.
+     * The sequence start from the lowest input, and go to the next enabled input
+     * automatically when the conversion is done. If no bits are set the
+     * sequence is disabled.
+     */
+    uint32_t positive_input_sequence_mask_enable;
+    /**
+     * Enables reference buffer offset compensation if true.
+     * This will increase the accuracy of the gain stage, but decreases the input
+     * impedance; therefore the startup time of the reference must be increased.
+     */
+    bool reference_compensation_enable;
+    /**
+     * This value (0-63) control the ADC sampling time in number of half ADC
+     * prescaled clock cycles (depends of \c ADC_PRESCALER value), thus
+     * controlling the ADC input impedance. Sampling time is set according to
+     * the formula:
+     * Sample time = (sample_length+1) * (ADCclk / 2).
+     */
+    uint8_t sample_length;
+    /** Window monitor configuration structure */
+    struct adc_window_config window;
+    /** Gain and offset correction configuration structure */
+    struct adc_correction_config correction;
+    /** Event action to take on incoming event */
+    enum adc_event_action event_action;
+};
+
+/**
+ * \brief ADC software device instance structure.
+ *
+ * ADC software instance structure, used to retain software state information
+ * of an associated hardware module instance.
+ *
+ * \note The fields of this structure should not be altered by the user
+ *       application; they are reserved for module-internal use only.
+ */
+struct adc_module {
+#if !defined(__DOXYGEN__)
+    /** Pointer to ADC hardware module */
+    Adc *hw;
+    /** Keep reference configuration so we know when enable is called */
+    enum adc_reference reference;
+#  if ADC_CALLBACK_MODE == true
+    /** Array to store callback functions */
+    adc_callback_t callback[ADC_CALLBACK_N];
+    /** Pointer to buffer used for ADC results */
+    volatile uint16_t *job_buffer;
+    /** Remaining number of conversions in current job */
+    volatile uint16_t remaining_conversions;
+    /** Bit mask for callbacks registered */
+    uint8_t registered_callback_mask;
+    /** Bit mask for callbacks enabled */
+    uint8_t enabled_callback_mask;
+    /** Holds the status of the ongoing or last conversion job */
+    volatile enum status_code job_status;
+    /** If software triggering is needed */
+    bool software_trigger;
+#  endif
+#endif
+};
+
+#if !defined(__DOXYGEN__)
+
+/**
+ * \brief Determines if the hardware module(s) are currently synchronizing to the bus.
+ *
+ * Checks to see if the underlying hardware peripheral module(s) are currently
+ * synchronizing across multiple clock domains to the hardware bus. This
+ * function can be used to delay further operations on a module until such time
+ * that it is ready, to prevent blocking delays for synchronization in the
+ * user application.
+ *
+ * \param[in] module_inst  Pointer to the ADC software instance struct
+ *
+ * \return Synchronization status of the underlying hardware module(s).
+ *
+ * \retval true if the module synchronization is ongoing
+ * \retval false if the module has completed synchronization
+ */
+static inline bool adc_is_syncing(
+    struct adc_module *const module_inst)
+{
+    /* Sanity check arguments */
+    Assert(module_inst);
+
+    Adc *const adc_module = module_inst->hw;
+
+    if (adc_module->SYNCBUSY.reg) {
+        return true;
+    }
+
+    return false;
+}
+#endif
+
+/**
+ * \name  Positive Input Sequence
+ * @{
+ */
+
+/**
+ * \brief Enable positive input sequence mask for conversion.
+ *
+ * The sequence start from the lowest input, and go to the next enabled input
+ * automatically when the conversion is done. If no bits are set the
+ * sequence is disabled.
+ *
+ * \param[in] module_inst  Pointer to the ADC software instance struct
+ * \param[in] eanble_seq_mask  Sequence mask
+ */
+static inline void adc_enable_positive_input_sequence(
+    struct adc_module *const module_inst,
+    uint32_t positive_input_sequence_mask_enable)
+{
+    /* Sanity check arguments */
+    Assert(module_inst);
+
+    Adc *const adc_module = module_inst->hw;
+    adc_module->SEQCTRL.reg = positive_input_sequence_mask_enable;
+}
+
+/**
+ * \brief Disable positive input in the sequence.
+ *
+ * Disable positive input in the sequence.
+ *
+ * \param[in] module_inst  Pointer to the ADC software instance struct
+ */
+static inline void adc_disable_positive_input_sequence(
+    struct adc_module *const module_inst)
+{
+    /* Sanity check arguments */
+    Assert(module_inst);
+
+    Adc *const adc_module = module_inst->hw;
+    adc_module->SEQCTRL.reg = 0;
+}
+
+/**
+ * \brief Get ADC sequence status.
+ *
+ * Check if a sequence is done and get last conversion done in the sequence.
+ *
+ * \param[in] module_inst  Pointer to the ADC software instance struct
+ * \param[out] is_sequence_busy  Sequence busy status
+ * \param[out] sequence_state This value identifies the last conversion
+ *             done in the sequence
+ */
+static inline void adc_get_sequence_status(
+    struct adc_module *const module_inst,
+    bool  * is_sequence_busy,
+    uint8_t *sequence_state)
+{
+    /* Sanity check arguments */
+    Assert(module_inst);
+    uint8_t temp = false;
+    Adc *const adc_module = module_inst->hw;
+    temp = adc_module->SEQSTATUS.reg;
+    if(temp & ADC_SEQSTATUS_SEQBUSY) {
+        *is_sequence_busy = true;
+    }
+    *sequence_state = temp & ADC_SEQSTATUS_SEQSTATE_Msk;
+}
+
+/** @} */
+
+#ifdef FEATURE_ADC_SUPPORT_MASTER_SLAVE
+/**
+ * \brief Set ADC master and slave mode.
+ *
+ * Enable ADC module Master-Slave Operation and select dual mode trigger.
+ *
+ * \param[in] master_inst  Pointer to the master ADC software instance struct
+ * \param[in] slave_inst   Pointer to the slave ADC software instance struct
+ * \param[in] dualsel      Dual mode trigger selection
+ *
+ */
+static inline void adc_set_master_slave_mode(
+    struct adc_module *const master_inst,
+    struct adc_module *const slave_inst,
+    enum adc_dual_mode_trigger_selection dualsel)
+{
+    /* Sanity check arguments */
+    Assert(master_inst);
+    Assert(slave_inst);
+
+    slave_inst->hw->CTRLA.reg |= ADC_CTRLA_SLAVEEN;
+    master_inst->hw->CTRLC.reg |= dualsel;
+
+};
+#endif
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif /* ADC_FEATURE_H_INCLUDED */
+