mbed library sources

Fork of mbed-src by mbed official

Revision:
579:53297373a894
Child:
592:a274ee790e56
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_Atmel/TARGET_SAM21/drivers/adc/adc.h	Wed Jul 01 09:45:11 2015 +0100
@@ -0,0 +1,1083 @@
+/**
+ * \file
+ *
+ * \brief SAM Peripheral Analog-to-Digital Converter Driver
+ *
+ * Copyright (C) 2012-2014 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_H_INCLUDED
+#define ADC_H_INCLUDED
+
+/**
+ * \defgroup asfdoc_sam0_adc_group SAM Analog to Digital Converter Driver (ADC)
+ *
+ * This driver for Atmel庐 | SMART SAM devices provides an interface for the configuration
+ * and management of the device's Analog to Digital Converter functionality, for
+ * the conversion of analog voltages into a corresponding digital form.
+ * The following driver API modes are covered by this manual:
+ * - Polled APIs
+ * \if ADC_CALLBACK_MODE
+ * - Callback APIs
+ * \endif
+ *
+ * The following peripherals are used by this module:
+ *  - ADC (Analog to Digital Converter)
+ *
+ * The following devices can use this module:
+ * \if DEVICE_SAML21_SUPPORT
+ *  - Atmel | SMART SAM L21
+ * \else
+ *  - Atmel | SMART SAM D20/D21
+ *  - Atmel | SMART SAM R21
+ *  - Atmel | SMART SAM D10/D11
+ * \endif
+ *
+ * The outline of this documentation is as follows:
+ *  - \ref asfdoc_sam0_adc_prerequisites
+ *  - \ref asfdoc_sam0_adc_module_overview
+ *  - \ref asfdoc_sam0_adc_special_considerations
+ *  - \ref asfdoc_sam0_adc_extra_info
+ *  - \ref asfdoc_sam0_adc_examples
+ *  - \ref asfdoc_sam0_adc_api_overview
+ *
+ *
+ * \section asfdoc_sam0_adc_prerequisites Prerequisites
+ *
+ * There are no prerequisites for this module.
+ *
+ *
+ * \section asfdoc_sam0_adc_module_overview Module Overview
+ *
+ * This driver provides an interface for the Analog-to-Digital conversion
+ * functions on the device, to convert analog voltages to a corresponding
+ * digital value. The ADC has up to 12-bit resolution, and is capable of
+ * \if DEVICE_SAML21_SUPPORT
+ * converting up to 1,000,000 samples per second (1 Msps).
+ * \else
+ * converting up to 500K samples per second (Ksps).
+ * \endif
+ *
+ * The ADC has a compare function for accurate monitoring of user defined
+ * thresholds with minimum software intervention required.
+ * The ADC may be configured for 8-, 10-, or 12-bit result, reducing the
+ * conversion time. ADC conversion results are provided left or right adjusted
+ * which eases calculation when the result is represented as a signed integer.
+ *
+ * The input selection is flexible, and both single-ended and differential
+ * measurements can be made. For differential measurements, an optional gain
+ * stage is available to increase the dynamic range. In addition, several
+ * internal signal inputs are available. The ADC can provide both signed and
+ * unsigned results.
+ *
+ * The ADC measurements can either be started by application software or an
+ * incoming event from another peripheral in the device, and both internal and
+ * external reference voltages can be selected.
+ *
+ * \note Internal references will be enabled by the driver, but not disabled.
+ *       Any reference not used by the application should be disabled by the application.
+ *
+ * A simplified block diagram of the ADC can be seen in
+ * \ref asfdoc_sam0_adc_module_block_diagram "the figure below".
+ *
+ * \anchor asfdoc_sam0_adc_module_block_diagram
+ * \dot
+ * digraph overview {
+ * splines = false;
+ * rankdir=LR;
+ *
+ * mux1 [label="Positive input", shape=box];
+ * mux2 [label="Negative input", shape=box];
+ *
+ *
+ * mux3 [label="Reference", shape=box];
+ *
+ * adc [label="ADC", shape=polygon, sides=5, orientation=90, distortion=-0.6, style=filled, fillcolor=darkolivegreen1, height=1, width=1];
+ * prescaler [label="PRESCALER", shape=box, style=filled, fillcolor=lightblue];
+ *
+ * mux1 -> adc;
+ * mux2 -> adc;
+ * mux3 -> adc:sw;
+ * prescaler -> adc;
+ *
+ * postproc [label="Post processing", shape=box];
+ * result [label="RESULT", shape=box, style=filled, fillcolor=lightblue];
+ *
+ * adc:e -> postproc:w;
+ * postproc:e -> result:w;
+ *
+ * {rank=same; mux1 mux2}
+ * {rank=same; prescaler adc}
+ *
+ * }
+ * \enddot
+ *
+ *
+ * \subsection asfdoc_sam0_adc_module_overview_prescaler Sample Clock Prescaler
+ * The ADC features a prescaler, which enables conversion at lower clock rates
+ * than the input Generic Clock to the ADC module. This feature can be used to
+ * lower the synchronization time of the digital interface to the ADC module
+ * via a high speed Generic Clock frequency, while still allowing the ADC
+ * sampling rate to be reduced.
+ *
+ * \subsection asfdoc_sam0_adc_module_overview_resolution ADC Resolution
+ * The ADC supports full 8-bit, 10-bit, or 12-bit resolution. Hardware
+ * oversampling and decimation can be used to increase the
+ * effective resolution at the expense of throughput. Using oversampling and
+ * decimation mode the ADC resolution is increased from 12-bit to an effective
+ * 13-, 14-, 15-, or 16-bit. In these modes the conversion rate is reduced, as
+ * a greater number of samples is used to achieve the increased resolution. The
+ * available resolutions and effective conversion rate is listed in
+ * \ref asfdoc_sam0_adc_module_conversion_rate "the table below".
+ *
+ * \anchor asfdoc_sam0_adc_module_conversion_rate
+ * <table>
+ *	<caption>Effective ADC Conversion Speed Using Oversampling</caption>
+ *	<tr>
+ *		<th>Resolution</th>
+ *		<th>Effective conversion rate</th>
+ *	</tr>
+ *	<tr>
+ *		<td>13-bit</td>
+ *		<td>Conversion rate divided by 4</td>
+ *	</tr>
+ *	<tr>
+ *		<td>14-bit</td>
+ *		<td>Conversion rate divided by 16</td>
+ *	</tr>
+ *	<tr>
+ *		<td>15-bit</td>
+ *		<td>Conversion rate divided by 64</td>
+ *	</tr>
+ *	<tr>
+ *		<td>16-bit</td>
+ *		<td>Conversion rate divided by 256</td>
+ *	</tr>
+ * </table>
+ *
+ * \subsection asfdoc_sam0_adc_module_overview_conversion Conversion Modes
+ * ADC conversions can be software triggered on demand by the user application,
+ * if continuous sampling is not required. It is also possible to configure the
+ * ADC in free-running mode, where new conversions are started as soon as the
+ * previous conversion is completed, or configure the ADC to scan across a
+ * number of input pins (see \ref asfdoc_sam0_adc_module_overview_pin_scan).
+ *
+ * \subsection asfdoc_sam0_adc_module_overview_diff_mode Differential and Single-Ended Conversion
+ * The ADC has two conversion modes; differential and single-ended. When
+ * measuring signals where the positive input pin is always at a higher voltage
+ * than the negative input pin, the single-ended conversion mode should be used
+ * in order to achieve a full 12-bit output resolution.
+ *
+ * If however the positive input pin voltage may drop below the negative input
+ * pin the signed differential mode should be used.
+ *
+ * \subsection asfdoc_sam0_adc_module_overview_sample_time Sample Time
+ * The sample time for each ADC conversion is configurable as a number of half
+ * prescaled ADC clock cycles (depending on the prescaler value), allowing the
+ * user application to achieve faster or slower sampling depending on the
+ * source impedance of the ADC input channels. For applications with high
+ * impedance inputs the sample time can be increased to give the ADC an adequate
+ * time to sample and convert the input channel.
+ *
+ * The resulting sampling time is given by the following equation:
+ * \f[
+ * t_{SAMPLE} = (sample\_length+1) \times \frac{ADC_{CLK}} {2}
+ * \f]
+ *
+ * \subsection asfdoc_sam0_adc_module_overview_averaging Averaging
+ * The ADC can be configured to trade conversion speed for accuracy by averaging
+ * multiple samples in hardware. This feature is suitable when operating in
+ * noisy conditions.
+ *
+ * You can specify any number of samples to accumulate (up to 1024) and the
+ * divide ratio to use (up to divide by 128). To modify these settings the
+ * ADC_RESOLUTION_CUSTOM needs to be set as the resolution. When this is set
+ * the number of samples to accumulate and the division ratio can be set by
+ * the configuration struct members \ref adc_config.accumulate_samples and
+ * \ref adc_config.divide_result. When using this mode the ADC result register
+ * will be set to be 16-bit wide to accommodate the larger result sizes
+ * produced by the accumulator.
+ *
+ * The effective ADC conversion rate will be reduced by a factor of the number
+ * of accumulated samples;
+ * however the effective resolution will be increased according to
+ * \ref asfdoc_sam0_adc_module_hw_av_resolution "the table below".
+ *
+ * \anchor asfdoc_sam0_adc_module_hw_av_resolution
+ * <table>
+ *   <caption>Effective ADC Resolution From Various Hardware Averaging Modes</caption>
+ *   <tr>
+ *     <th>Number of samples</tr>
+ *     <th>Final result</tr>
+ *   </tr>
+ *   <tr>
+ *     <td>1</td>
+ *     <td>12-bit</td>
+ *   </tr>
+ *   <tr>
+ *      <td>2</td>
+ *      <td>13-bit</td>
+ *   </tr>
+ *   <tr>
+ *      <td>4</td>
+ *      <td>14-bit</td>
+ *   </tr>
+ *   <tr>
+ *      <td>8</td>
+ *      <td>15-bit</td>
+ *   </tr>
+ *   <tr>
+ *      <td>16</td>
+ *      <td>16-bit</td>
+ *   </tr>
+ *   <tr>
+ *      <td>32</td>
+ *      <td>16-bit</td>
+ *   </tr>
+ *   <tr>
+ *      <td>64</td>
+ *      <td>16-bit</td>
+ *   </tr>
+ *   <tr>
+ *      <td>128</td>
+ *      <td>16-bit</td>
+ *   </tr>
+ *   <tr>
+ *      <td>256</td>
+ *      <td>16-bit</td>
+ *   </tr>
+ *   <tr>
+ *      <td>512</td>
+ *      <td>16-bit</td>
+ *   </tr>
+ *   <tr>
+ *      <td>1024</td>
+ *      <td>16-bit</td>
+ *   </tr>
+ * </table>
+ *
+ *
+ * \subsection asfdoc_sam0_adc_module_overview_offset_corr Offset and Gain Correction
+ * Inherent gain and offset errors affect the absolute accuracy of the ADC.
+ *
+ * The offset error is defined as the deviation of the ADC鈥檚 actual transfer
+ * function from ideal straight line at zero input voltage.
+ *
+ * The gain error is defined as the deviation of the last output step's
+ * midpoint from the ideal straight line, after compensating for offset error.
+ *
+ * The offset correction value is subtracted from the converted data before the
+ * result is ready. The gain correction value is multiplied with the offset
+ * corrected value.
+ *
+ * The equation for both offset and gain error compensation is shown below:
+ * \f[
+ * ADC_{RESULT} = (VALUE_{CONV} + CORR_{OFFSET}) \times CORR_{GAIN}
+ * \f]
+ *
+ * When enabled, a given set of offset and gain correction values can be applied
+ * to the sampled data in hardware, giving a corrected stream of sample data to
+ * the user application at the cost of an increased sample latency.
+ *
+ * In single conversion, a latency of 13 ADC Generic Clock cycles is added for
+ * the final sample result availability. As the correction time is always less
+ * than the propagation delay, in free running mode this latency appears only
+ * during the first conversion. After the first conversion is complete future
+ * conversion results are available at the defined sampling rate.
+ *
+ * \subsection asfdoc_sam0_adc_module_overview_pin_scan Pin Scan
+ * In pin scan mode, the first ADC conversion will begin from the configured
+ * positive channel, plus the requested starting offset. When the first
+ * conversion is completed, the next conversion will start at the next positive
+ * input channel and so on, until all requested pins to scan have been sampled
+ * and converted.
+ * SAM L21 has automatic sequences feature instead of pin scan mode. In automatic
+ * sequence mode, all of 32 positives inputs can be included in a sequence. The
+ * sequence starts from the lowest input, and go to the next enabled input
+ * automatically.
+ *
+ * Pin scanning gives a simple mechanism to sample a large number of physical
+ * input channel samples, using a single physical ADC channel.
+ *
+ * \subsection asfdoc_sam0_adc_module_overview_window_monitor Window Monitor
+ * The ADC module window monitor function can be used to automatically compare
+ * the conversion result against a preconfigured pair of upper and lower
+ * threshold values.
+ *
+ * The threshold values are evaluated differently, depending on whether
+ * differential or single-ended mode is selected. In differential mode, the
+ * upper and lower thresholds are evaluated as signed values for the comparison,
+ * while in single-ended mode the comparisons are made as a set of unsigned
+ * values.
+ *
+ * The significant bits of the lower window monitor threshold and upper window
+ * monitor threshold values are user-configurable, and follow the overall ADC
+ * sampling bit precision set when the ADC is configured by the user application.
+ * For example, only the eight lower bits of the window threshold values will be
+ * compares to the sampled data whilst the ADC is configured in 8-bit mode.
+ * In addition, if using differential mode, the 8<SUP>th</SUP> bit will be considered as
+ * the sign bit even if bit 9 is zero.
+ *
+ * \subsection asfdoc_sam0_adc_module_overview_events Events
+ * Event generation and event actions are configurable in the ADC.
+ *
+ * The ADC has two actions that can be triggered upon event reception:
+ * \li Start conversion
+ * \li Flush pipeline and start conversion
+ *
+ * The ADC can generate two events:
+ * \li Window monitor
+ * \li Result ready
+ *
+ * If the event actions are enabled in the configuration, any incoming event
+ * will trigger the action.
+ *
+ * If the window monitor event is enabled, an event will be generated
+ * when the configured window condition is detected.
+ *
+ * If the result ready event is enabled, an event will be generated when a
+ * conversion is completed.
+ *
+ * \note The connection of events between modules requires the use of the
+ *       \ref asfdoc_sam0_events_group "SAM Event System Driver (EVENTS)"
+ *       to route output event of one module to the the input event of another.
+ *       For more information on event routing, refer to the event driver
+ *       documentation.
+ *
+ *
+ * \section asfdoc_sam0_adc_special_considerations Special Considerations
+ *
+ * An integrated analog temperature sensor is available for use with the ADC.
+ * The bandgap voltage, as well as the scaled I/O and core voltages can also be
+ * measured by the ADC. For internal ADC inputs, the internal source(s) may need
+ * to be manually enabled by the user application before they can be measured.
+ *
+ *
+ * \section asfdoc_sam0_adc_extra_info Extra Information
+ *
+ * For extra information, see \ref asfdoc_sam0_adc_extra. This includes:
+ *  - \ref asfdoc_sam0_adc_extra_acronyms
+ *  - \ref asfdoc_sam0_adc_extra_dependencies
+ *  - \ref asfdoc_sam0_adc_extra_errata
+ *  - \ref asfdoc_sam0_adc_extra_history
+ *
+ *
+ * \section asfdoc_sam0_adc_examples Examples
+ *
+ * For a list of examples related to this driver, see
+ * \ref asfdoc_sam0_adc_exqsg.
+ *
+ *
+ * \section asfdoc_sam0_adc_api_overview API Overview
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <compiler.h>
+#include <system.h>
+#include <adc_feature.h>
+
+/**
+ * \name Module Status Flags
+ *
+ * ADC status flags, returned by \ref adc_get_status() and cleared by
+ * \ref adc_clear_status().
+ *
+ * @{
+ */
+
+/** ADC result ready. */
+#define ADC_STATUS_RESULT_READY  (1UL << 0)
+/** Window monitor match. */
+#define ADC_STATUS_WINDOW        (1UL << 1)
+/** ADC result overwritten before read. */
+#define ADC_STATUS_OVERRUN       (1UL << 2)
+
+/** @} */
+
+/**
+ * \name Driver Initialization and Configuration
+ * @{
+ */
+enum status_code adc_init(
+    struct adc_module *const module_inst,
+    Adc *hw,
+    struct adc_config *config);
+
+void adc_get_config_defaults(
+    struct adc_config *const config);
+/** @} */
+
+/**
+ * \name Status Management
+ * @{
+ */
+
+/**
+ * \brief Retrieves the current module status.
+ *
+ * Retrieves the status of the module, giving overall state information.
+ *
+ * \param[in] module_inst  Pointer to the ADC software instance struct
+ *
+ * \return Bitmask of \c ADC_STATUS_* flags.
+ *
+ * \retval ADC_STATUS_RESULT_READY  ADC Result is ready to be read
+ * \retval ADC_STATUS_WINDOW        ADC has detected a value inside the set
+ *                                  window range
+ * \retval ADC_STATUS_OVERRUN       ADC result has overrun
+ */
+static inline uint32_t adc_get_status(
+    struct adc_module *const module_inst)
+{
+    /* Sanity check arguments */
+    Assert(module_inst);
+    Assert(module_inst->hw);
+
+    Adc *const adc_module = module_inst->hw;
+
+    uint32_t int_flags = adc_module->INTFLAG.reg;
+
+    uint32_t status_flags = 0;
+
+    /* Check for ADC Result Ready */
+    if (int_flags & ADC_INTFLAG_RESRDY) {
+        status_flags |= ADC_STATUS_RESULT_READY;
+    }
+
+    /* Check for ADC Window Match */
+    if (int_flags & ADC_INTFLAG_WINMON) {
+        status_flags |= ADC_STATUS_WINDOW;
+    }
+
+    /* Check for ADC Overrun */
+    if (int_flags & ADC_INTFLAG_OVERRUN) {
+        status_flags |= ADC_STATUS_OVERRUN;
+    }
+
+    return status_flags;
+}
+
+/**
+ * \brief Clears a module status flag.
+ *
+ * Clears the given status flag of the module.
+ *
+ * \param[in] module_inst   Pointer to the ADC software instance struct
+ * \param[in] status_flags  Bitmask of \c ADC_STATUS_* flags to clear
+ */
+static inline void adc_clear_status(
+    struct adc_module *const module_inst,
+    const uint32_t status_flags)
+{
+    /* Sanity check arguments */
+    Assert(module_inst);
+    Assert(module_inst->hw);
+
+    Adc *const adc_module = module_inst->hw;
+
+    uint32_t int_flags = 0;
+
+    /* Check for ADC Result Ready */
+    if (status_flags & ADC_STATUS_RESULT_READY) {
+        int_flags |= ADC_INTFLAG_RESRDY;
+    }
+
+    /* Check for ADC Window Match */
+    if (status_flags & ADC_STATUS_WINDOW) {
+        int_flags |= ADC_INTFLAG_WINMON;
+    }
+
+    /* Check for ADC Overrun */
+    if (status_flags & ADC_STATUS_OVERRUN) {
+        int_flags |= ADC_INTFLAG_OVERRUN;
+    }
+
+    /* Clear interrupt flag */
+    adc_module->INTFLAG.reg = int_flags;
+}
+/** @} */
+
+/**
+ * \name Enable, Disable and Reset ADC Module, Start Conversion and Read Result
+ * @{
+ */
+
+/**
+ * \brief Enables the ADC module.
+ *
+ * Enables an ADC module that has previously been configured. If any internal reference
+ * is selected it will be enabled.
+ *
+ * \param[in] module_inst  Pointer to the ADC software instance struct
+ */
+static inline enum status_code adc_enable(
+    struct adc_module *const module_inst)
+{
+    Assert(module_inst);
+    Assert(module_inst->hw);
+
+    Adc *const adc_module = module_inst->hw;
+
+    while (adc_is_syncing(module_inst)) {
+        /* Wait for synchronization */
+    }
+
+#if ADC_CALLBACK_MODE == true
+    system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_ADC);
+#endif
+
+    adc_module->CTRLA.reg |= ADC_CTRLA_ENABLE;
+
+    while (adc_is_syncing(module_inst)) {
+        /* Wait for synchronization */
+    }
+    return STATUS_OK;
+}
+
+/**
+ * \brief Disables the ADC module.
+ *
+ * Disables an ADC module that was previously enabled.
+ *
+ * \param[in] module_inst Pointer to the ADC software instance struct
+ */
+static inline enum status_code adc_disable(
+    struct adc_module *const module_inst)
+{
+    Assert(module_inst);
+    Assert(module_inst->hw);
+
+    Adc *const adc_module = module_inst->hw;
+
+#if ADC_CALLBACK_MODE == true
+    system_interrupt_disable(SYSTEM_INTERRUPT_MODULE_ADC);
+#endif
+
+    while (adc_is_syncing(module_inst)) {
+        /* Wait for synchronization */
+    }
+
+    adc_module->CTRLA.reg &= ~ADC_CTRLA_ENABLE;
+
+    while (adc_is_syncing(module_inst)) {
+        /* Wait for synchronization */
+    }
+    return STATUS_OK;
+}
+
+/**
+ * \brief Resets the ADC module.
+ *
+ * Resets an ADC module, clearing all module state and registers to their
+ * default values.
+ *
+ * \param[in] module_inst  Pointer to the ADC software instance struct
+ */
+static inline enum status_code adc_reset(
+    struct adc_module *const module_inst)
+{
+    /* Sanity check arguments */
+    Assert(module_inst);
+    Assert(module_inst->hw);
+
+    Adc *const adc_module = module_inst->hw;
+
+    /* Disable to make sure the pipeline is flushed before reset */
+    adc_disable(module_inst);
+
+    /* Software reset the module */
+    adc_module->CTRLA.reg |= ADC_CTRLA_SWRST;
+
+    while (adc_is_syncing(module_inst)) {
+        /* Wait for synchronization */
+    }
+    return STATUS_OK;
+}
+
+
+/**
+ * \brief Enables an ADC event input or output.
+ *
+ *  Enables one or more input or output events to or from the ADC module. See
+ *  \ref adc_events "here" for a list of events this module supports.
+ *
+ *  \note Events cannot be altered while the module is enabled.
+ *
+ *  \param[in] module_inst  Software instance for the ADC peripheral
+ *  \param[in] events       Struct containing flags of events to enable
+ */
+static inline void adc_enable_events(
+    struct adc_module *const module_inst,
+    struct adc_events *const events)
+{
+    /* Sanity check arguments */
+    Assert(module_inst);
+    Assert(module_inst->hw);
+    Assert(events);
+
+    Adc *const adc_module = module_inst->hw;
+
+    uint32_t event_mask = 0;
+
+    /* Configure Window Monitor event */
+    if (events->generate_event_on_window_monitor) {
+        event_mask |= ADC_EVCTRL_WINMONEO;
+    }
+
+    /* Configure Result Ready event */
+    if (events->generate_event_on_conversion_done) {
+        event_mask |= ADC_EVCTRL_RESRDYEO;
+    }
+
+    adc_module->EVCTRL.reg |= event_mask;
+}
+
+/**
+ * \brief Disables an ADC event input or output.
+ *
+ *  Disables one or more input or output events to or from the ADC module. See
+ *  \ref adc_events "here" for a list of events this module supports.
+ *
+ *  \note Events cannot be altered while the module is enabled.
+ *
+ *  \param[in] module_inst  Software instance for the ADC peripheral
+ *  \param[in] events       Struct containing flags of events to disable
+ */
+static inline void adc_disable_events(
+    struct adc_module *const module_inst,
+    struct adc_events *const events)
+{
+    /* Sanity check arguments */
+    Assert(module_inst);
+    Assert(module_inst->hw);
+    Assert(events);
+
+    Adc *const adc_module = module_inst->hw;
+
+    uint32_t event_mask = 0;
+
+    /* Configure Window Monitor event */
+    if (events->generate_event_on_window_monitor) {
+        event_mask |= ADC_EVCTRL_WINMONEO;
+    }
+
+    /* Configure Result Ready event */
+    if (events->generate_event_on_conversion_done) {
+        event_mask |= ADC_EVCTRL_RESRDYEO;
+    }
+
+    adc_module->EVCTRL.reg &= ~event_mask;
+}
+
+/**
+ * \brief Starts an ADC conversion.
+ *
+ * Starts a new ADC conversion.
+ *
+ * \param[in] module_inst  Pointer to the ADC software instance struct
+ */
+static inline void adc_start_conversion(
+    struct adc_module *const module_inst)
+{
+    Assert(module_inst);
+    Assert(module_inst->hw);
+
+    Adc *const adc_module = module_inst->hw;
+
+    while (adc_is_syncing(module_inst)) {
+        /* Wait for synchronization */
+    }
+
+    adc_module->SWTRIG.reg |= ADC_SWTRIG_START;
+
+    while (adc_is_syncing(module_inst)) {
+        /* Wait for synchronization */
+    }
+}
+
+/**
+ * \brief Reads the ADC result.
+ *
+ * Reads the result from an ADC conversion that was previously started.
+ *
+ * \param[in]  module_inst  Pointer to the ADC software instance struct
+ * \param[out] result       Pointer to store the result value in
+ *
+ * \return Status of the ADC read request.
+ * \retval STATUS_OK           The result was retrieved successfully
+ * \retval STATUS_BUSY         A conversion result was not ready
+ * \retval STATUS_ERR_OVERFLOW The result register has been overwritten by the
+ *                             ADC module before the result was read by the software
+ */
+static inline enum status_code adc_read(
+    struct adc_module *const module_inst,
+    uint16_t *result)
+{
+    Assert(module_inst);
+    Assert(module_inst->hw);
+    Assert(result);
+
+    if (!(adc_get_status(module_inst) & ADC_STATUS_RESULT_READY)) {
+        /* Result not ready */
+        return STATUS_BUSY;
+    }
+
+    Adc *const adc_module = module_inst->hw;
+
+    while (adc_is_syncing(module_inst)) {
+        /* Wait for synchronization */
+    }
+
+    /* Get ADC result */
+    *result = adc_module->RESULT.reg;
+
+    /* Reset ready flag */
+    adc_clear_status(module_inst, ADC_STATUS_RESULT_READY);
+
+    if (adc_get_status(module_inst) & ADC_STATUS_OVERRUN) {
+        adc_clear_status(module_inst, ADC_STATUS_OVERRUN);
+        return STATUS_ERR_OVERFLOW;
+    }
+
+    return STATUS_OK;
+}
+
+/** @} */
+
+/**
+ * \name Runtime Changes of ADC Module
+ * @{
+ */
+
+/**
+ * \brief Flushes the ADC pipeline.
+ *
+ * Flushes the pipeline and restart the ADC clock on the next peripheral clock
+ * edge. All conversions in progress will be lost. When flush is complete, the
+ * module will resume where it left off.
+ *
+ * \param[in] module_inst  Pointer to the ADC software instance struct
+ */
+static inline void adc_flush(
+    struct adc_module *const module_inst)
+{
+    Assert(module_inst);
+    Assert(module_inst->hw);
+
+    Adc *const adc_module = module_inst->hw;
+
+    while (adc_is_syncing(module_inst)) {
+        /* Wait for synchronization */
+    }
+
+    adc_module->SWTRIG.reg |= ADC_SWTRIG_FLUSH;
+
+    while (adc_is_syncing(module_inst)) {
+        /* Wait for synchronization */
+    }
+}
+void adc_set_window_mode(
+    struct adc_module *const module_inst,
+    const enum adc_window_mode window_mode,
+    const int16_t window_lower_value,
+    const int16_t window_upper_value);
+
+/**
+ * \brief Sets positive ADC input pin.
+ *
+ * Sets the positive ADC input pin selection.
+ *
+ * \param[in] module_inst     Pointer to the ADC software instance struct
+ * \param[in] positive_input  Positive input pin
+ */
+static inline void adc_set_positive_input(
+    struct adc_module *const module_inst,
+    const enum adc_positive_input positive_input)
+{
+    /* Sanity check arguments */
+    Assert(module_inst);
+    Assert(module_inst->hw);
+
+    Adc *const adc_module = module_inst->hw;
+
+    while (adc_is_syncing(module_inst)) {
+        /* Wait for synchronization */
+    }
+
+    /* Set positive input pin */
+    adc_module->INPUTCTRL.reg =
+        (adc_module->INPUTCTRL.reg & ~ADC_INPUTCTRL_MUXPOS_Msk) |
+        (positive_input);
+
+    while (adc_is_syncing(module_inst)) {
+        /* Wait for synchronization */
+    }
+}
+
+
+/**
+ * \brief Sets negative ADC input pin for differential mode.
+ *
+ * Sets the negative ADC input pin, when the ADC is configured in differential
+ * mode.
+ *
+ * \param[in] module_inst     Pointer to the ADC software instance struct
+ * \param[in] negative_input  Negative input pin
+ */
+static inline void adc_set_negative_input(
+    struct adc_module *const module_inst,
+    const enum adc_negative_input negative_input)
+{
+    /* Sanity check arguments */
+    Assert(module_inst);
+    Assert(module_inst->hw);
+
+    Adc *const adc_module = module_inst->hw;
+
+    while (adc_is_syncing(module_inst)) {
+        /* Wait for synchronization */
+    }
+
+    /* Set negative input pin */
+    adc_module->INPUTCTRL.reg =
+        (adc_module->INPUTCTRL.reg & ~ADC_INPUTCTRL_MUXNEG_Msk) |
+        (negative_input);
+
+    while (adc_is_syncing(module_inst)) {
+        /* Wait for synchronization */
+    }
+}
+
+/** @} */
+
+#if ADC_CALLBACK_MODE == true
+/**
+ * \name Enable and Disable Interrupts
+ * @{
+ */
+
+/**
+ * \brief Enable interrupt.
+ *
+ * Enable the given interrupt request from the ADC module.
+ *
+ * \param[in] module_inst Pointer to the ADC software instance struct
+ * \param[in] interrupt Interrupt to enable
+ */
+static inline void adc_enable_interrupt(struct adc_module *const module_inst,
+                                        enum adc_interrupt_flag interrupt)
+{
+    /* Sanity check arguments */
+    Assert(module_inst);
+    Assert(module_inst->hw);
+
+    Adc *const adc_module = module_inst->hw;
+    /* Enable interrupt */
+    adc_module->INTENSET.reg = interrupt;
+}
+
+/**
+ * \brief Disable interrupt.
+ *
+ * Disable the given interrupt request from the ADC module.
+ *
+ * \param[in] module_inst Pointer to the ADC software instance struct
+ * \param[in] interrupt Interrupt to disable
+ */
+static inline void adc_disable_interrupt(struct adc_module *const module_inst,
+        enum adc_interrupt_flag interrupt)
+{
+    /* Sanity check arguments */
+    Assert(module_inst);
+    Assert(module_inst->hw);
+
+    Adc *const adc_module = module_inst->hw;
+    /* Enable interrupt */
+    adc_module->INTENCLR.reg = interrupt;
+}
+
+/** @} */
+#endif /* ADC_CALLBACK_MODE == true */
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+
+/**
+ * \page asfdoc_sam0_adc_extra Extra Information for ADC Driver
+ *
+ * \section asfdoc_sam0_adc_extra_acronyms Acronyms
+ * Below is a table listing the acronyms used in this module, along with their
+ * intended meanings.
+ *
+ * <table>
+ *	<tr>
+ *		<th>Acronym</th>
+ *		<th>Description</th>
+ *	</tr>
+ *  <tr>
+ *		<td>ADC</td>
+ *		<td>Analog-to-Digital Converter</td>
+ *	</tr>
+ *  <tr>
+ *		<td>DAC</td>
+ *		<td>Digital-to-Analog Converter</td>
+ *	</tr>
+ *	<tr>
+ *		<td>LSB</td>
+ *		<td>Least Significant Bit</td>
+ *	</tr>
+ *	<tr>
+ *		<td>MSB</td>
+ *		<td>Most Significant Bit</td>
+ *	</tr>
+ *	<tr>
+ *		<td>DMA</td>
+ *		<td>Direct Memory Access</td>
+ *	</tr>
+ * </table>
+ *
+ *
+ * \section asfdoc_sam0_adc_extra_dependencies Dependencies
+ * This driver has the following dependencies:
+ *
+ *  - \ref asfdoc_sam0_system_pinmux_group "System Pin Multiplexer Driver"
+ *
+ *
+ * \section asfdoc_sam0_adc_extra_errata Errata
+ * There are no errata related to this driver.
+ *
+ *
+ * \section asfdoc_sam0_adc_extra_history Module History
+ * An overview of the module history is presented in the table below, with
+ * details on the enhancements and fixes made to the module since its first
+ * release. The current version of this corresponds to the newest version in
+ * the table.
+ *
+ * <table>
+ *	<tr>
+ *		<th>Changelog</th>
+ *	</tr>
+ * \if DEVICE_SAML21_SUPPORT
+ *  <tr>
+ *		<td>Initial Release</td>
+ * </tr>
+ * \else
+ *	<tr>
+ *		<td>Added support for SAMR21</td>
+ *	</tr>
+ *	<tr>
+ *		<td>Added support for SAMD21 and new DMA quick start guide</td>
+ *	</tr>
+ *	<tr>
+ *		<td>Added ADC calibration constant loading from the device signature
+ *          row when the module is initialized</td>
+ *	</tr>
+ *	<tr>
+ *		<td>Initial Release</td>
+ *	</tr>
+ * \endif
+ * </table>
+ */
+
+/**
+ * \page asfdoc_sam0_adc_exqsg Examples for ADC Driver
+ *
+ * This is a list of the available Quick Start guides (QSGs) and example
+ * applications for \ref asfdoc_sam0_adc_group. QSGs are simple examples with
+ * step-by-step instructions to configure and use this driver in a selection of
+ * use cases. Note that QSGs can be compiled as a standalone application or be
+ * added to the user application.
+ *
+ *  - \subpage asfdoc_sam0_adc_basic_use_case
+ * \if ADC_CALLBACK_MODE
+ *  - \subpage asfdoc_sam0_adc_basic_use_case_callback
+ * \endif
+ *  - \subpage asfdoc_sam0_adc_dma_use_case
+ *
+ * \page asfdoc_sam0_adc_document_revision_history Document Revision History
+ *
+ * <table>
+ *	<tr>
+ *		<th>Doc. Rev.</td>
+ *		<th>Date</td>
+ *		<th>Comments</td>
+ *	</tr>
+ * \if DEVICE_SAML21_SUPPORT
+ *  <tr>
+ *      <td>A</td>
+ *      <td>11/2014</td>
+ *      <td>Initial release.</td>
+ * </tr>
+ * \else
+ *	<tr>
+ *		<td>D</td>
+ *		<td>12/2014</td>
+ *		<td>Added support for SAMR21 and SAMD10/D11.</td>
+ *	</tr>
+ *	<tr>
+ *		<td>C</td>
+ *		<td>01/2014</td>
+ *		<td>Added support for SAMD21.</td>
+ *	</tr>
+ *	<tr>
+ *		<td>B</td>
+ *		<td>06/2013</td>
+ *		<td>Added additional documentation on the event system. Corrected
+ *          documentation typos.</td>
+ *	</tr>
+ *	<tr>
+ *		<td>A</td>
+ *		<td>06/2013</td>
+ *		<td>Initial release</td>
+ *	</tr>
+ * \endif
+ * </table>
+ */
+
+#endif /* ADC_H_INCLUDED */