http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac.h ---------------------------------------------------------------------- diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac.h b/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac.h deleted file mode 100755 index f6741d0..0000000 --- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac.h +++ /dev/null @@ -1,1430 +0,0 @@ -/** - * \file - * - * \brief SAM Analog Comparator Driver - * - * Copyright (c) 2012-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 AC_H_INCLUDED -#define AC_H_INCLUDED - -/** - * \defgroup asfdoc_sam0_ac_group SAM Analog Comparator (AC) Driver - * - * This driver for Atmel® | SMART ARM®-based microcontrollers - * provides an interface for the configuration - * and management of the device's Analog Comparator functionality, for the - * comparison of analog voltages against a known reference voltage to determine - * its relative level. The following driver API modes are covered by this - * manual: - * - Polled APIs - * \if AC_CALLBACK_MODE - * - Callback APIs - * \endif - * - * The following peripherals are used by this module: - * - AC (Analog Comparator) - * - * The following devices can use this module: - * - Atmel | SMART SAM D20/D21 - * - Atmel | SMART SAM R21 - * - Atmel | SMART SAM D10/D11 - * - Atmel | SMART SAM L21/L22 - * - Atmel | SMART SAM DA1 - * - Atmel | SMART SAM C20/C21 - * - * The outline of this documentation is as follows: - * - \ref asfdoc_sam0_ac_prerequisites - * - \ref asfdoc_sam0_ac_module_overview - * - \ref asfdoc_sam0_ac_special_considerations - * - \ref asfdoc_sam0_ac_extra_info - * - \ref asfdoc_sam0_ac_examples - * - \ref asfdoc_sam0_ac_api_overview - * - * - * \section asfdoc_sam0_ac_prerequisites Prerequisites - * - * There are no prerequisites for this module. - * - * - * \section asfdoc_sam0_ac_module_overview Module Overview - * - * The Analog Comparator module provides an interface for the comparison of one - * or more analog voltage inputs (sourced from external or internal inputs) - * against a known reference voltage, to determine if the unknown voltage is - * higher or lower than the reference. Additionally, window functions are - * provided so that two comparators can be connected together to determine if - * an input is below, inside, above, or outside the two reference points of the - * window. - * - * Each comparator requires two analog input voltages, a positive and negative - * channel input. The result of the comparison is a binary \c true if the - * comparator's positive channel input is higher than the comparator's negative - * input channel, and \c false if otherwise. - * - * - * \subsection asfdoc_sam0_ac_module_features Driver Feature Macro Definition - * <table> - * <tr> - * <th>Driver Feature Macro</th> - * <th>Supported devices</th> - * </tr> - * <tr> - * <td>FEATURE_AC_HYSTERESIS_LEVEL</td> - * <td>SAM L21/L22/C20/C21</td> - * </tr> - * <tr> - * <td>FEATURE_AC_SYNCBUSY_SCHEME_VERSION_2</td> - * <td>SAM L21/L22/C20/C21</td> - * </tr> - * <tr> - * <td>FEATURE_AC_RUN_IN_STANDY_EACH_COMPARATOR</td> - * <td>SAM L21/L22/C20/C21</td> - * </tr> - * <tr> - * <td>FEATURE_AC_RUN_IN_STANDY_PAIR_COMPARATOR</td> - * <td>SAM D20/L22/D21/D10/D11/R21/DAx</td> - * </tr> - * </table> - * \note The specific features are only available in the driver when the - * selected device supports those features. - * - * \subsection asfdoc_sam0_ac_module_overview_pairs Window Comparators and Comparator Pairs - * Each comparator module contains one or more comparator pairs, a set of two - * distinct comparators which can be used independently or linked together for - * Window Comparator mode. In this latter mode, the two comparator units in a - * comparator pair are linked together to allow the module to detect if an input - * voltage is below, inside, above, or outside a window set by the upper and - * lower threshold voltages set by the two comparators. If not required, window - * comparison mode can be turned off and the two comparator units can be - * configured and used separately. - * - * \subsection asfdoc_sam0_ac_module_overview_pos_neg_mux Positive and Negative Input MUXes - * Each comparator unit requires two input voltages, a positive and a negative - * channel (note that these names refer to the logical operation that the unit - * performs, and both voltages should be above GND), which are then compared with - * one another. Both the positive and the negative channel inputs are connected to - * a pair of multiplexers (MUXes), which allows one of several possible inputs to be - * selected for each comparator channel. - * - * The exact channels available for each comparator differ for the positive and - * the negative inputs, but the same MUX choices are available for all comparator - * units (i.e. all positive MUXes are identical, all negative MUXes are - * identical). This allows the user application to select which voltages are - * compared to one another. - * - * When used in window mode, both comparators in the window pair should have - * their positive channel input MUXes configured to the same input channel, with - * the negative channel input MUXes used to set the lower and upper window - * bounds. - * - * \subsection asfdoc_sam0_ac_module_overview_output_filtering Output Filtering - * The output of each comparator unit can either be used directly with no - * filtering (giving a lower latency signal, with potentially more noise around - * the comparison threshold) or be passed through a multiple stage - * digital majority filter. Several filter lengths are available, with the - * longer stages producing a more stable result, at the expense of a higher - * latency. - * - * When output filtering is used in single shot mode, a single trigger of the - * comparator will automatically perform the required number of samples to - * produce a correctly filtered result. - * - * \subsection asfdoc_sam0_ac_module_overview_input_hysteresis Input Hysteresis - * To prevent unwanted noise around the threshold where the comparator unit's - * positive and negative input channels are close in voltage to one another, an - * optional hysteresis can be used to widen the point at which the output result - * flips. This mode will prevent a change in the comparison output unless the - * inputs cross one another beyond the hysteresis gap introduces by this mode. - * - * \subsection asfdoc_sam0_ac_module_overview_sampling Single Shot and Continuous Sampling Modes - * Comparators can be configured to run in either Single Shot or Continuous - * sampling modes; when in Single Shot mode, the comparator will only perform a - * comparison (and any resulting filtering, see - * \ref asfdoc_sam0_ac_module_overview_output_filtering) when triggered via a - * software or event trigger. This mode improves the power efficiency of the - * system by only performing comparisons when actually required by the - * application. - * - * For systems requiring a lower latency or more frequent comparisons, - * continuous mode will place the comparator into continuous sampling mode, - * which increases the module's power consumption, but decreases the latency - * between each comparison result by automatically performing a comparison on - * every cycle of the module's clock. - * - * \subsection asfdoc_sam0_ac_module_overview_events Events - * Each comparator unit is capable of being triggered by both software and - * hardware triggers. Hardware input events allow for other peripherals to - * automatically trigger a comparison on demand - for example, a timer output - * event could be used to trigger comparisons at a desired regular interval. - * - * The module's output events can similarly be used to trigger other hardware - * modules each time a new comparison result is available. This scheme allows - * for reduced levels of CPU usage in an application and lowers the overall - * system response latency by directly triggering hardware peripherals from one - * another without requiring software intervention. - * - * \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 input event of another. - * For more information on event routing, refer to the event driver - * documentation. - * - * \subsection asfdoc_sam0_ac_module_overview_physical Physical Connection - * Physically, the modules are interconnected within the device as shown in - * \ref asfdoc_sam0_ac_module_int_connections "the diagram below". - * - * \anchor asfdoc_sam0_ac_module_int_connections - * \dot - * digraph overview { - * rankdir = LR; - * splines = false; - * - * pos_src1_1 [label="GPIO Pins", shape=none, height=0]; - * neg_src1_1 [label="GPIO Pins", shape=none, height=0]; - * neg_src1_2 [label="Internal DAC", shape=none, height=0]; - * neg_src1_3 [label="Internal Refs", shape=none, height=0]; - * pos_src2_1 [label="GPIO Pins", shape=none, height=0]; - * neg_src2_1 [label="GPIO Pins", shape=none, height=0]; - * neg_src2_2 [label="Internal DAC", shape=none, height=0]; - * neg_src2_3 [label="Internal Refs", shape=none, height=0]; - * res_out1 [label="", style=invisible]; - * res_out2 [label="", style=invisible]; - * res_window [label="", style=invisible]; - * - * mux_pos1 [label="", shape=polygon, sides=4, distortion=0.6, orientation=90, style=filled, fillcolor=black, height=0.9, width=0.2]; - * mux_neg1 [label="", shape=polygon, sides=4, distortion=0.6, orientation=90, style=filled, fillcolor=black, height=0.9, width=0.2]; - * mux_neg2 [label="", shape=polygon, sides=4, distortion=0.6, orientation=90, style=filled, fillcolor=black, height=0.9, width=0.2]; - * mux_pos2 [label="", shape=polygon, sides=4, distortion=0.6, orientation=90, style=filled, fillcolor=black, height=0.9, width=0.2]; - * ac1 [label="AC 1", shape=triangle, orientation=-90, style=filled, fillcolor=darkolivegreen1, height=1, width=1]; - * ac2 [label="AC 2", shape=triangle, orientation=-90, style=filled, fillcolor=darkolivegreen1, height=1, width=1]; - * - * window_comp [label="Window\nLogic", shape=rectangle style=filled fillcolor=lightgray]; - * - * edge [dir="forward"]; - * - * pos_src1_1:e -> mux_pos1:w; - * mux_pos1:e -> ac1:nw [label="+"]; - * neg_src1_1:e -> mux_neg1:nw; - * neg_src1_2:e -> mux_neg1:w; - * neg_src1_3:e -> mux_neg1:sw; - * mux_neg1:e -> ac1:sw [label="-"]; - * ac1:e -> res_out1 [label="Comparator 1 Result"]; - * - * pos_src2_1:e -> mux_pos2:w; - * mux_pos2:e -> ac2:sw [label="+"]; - * neg_src2_1:e -> mux_neg2:nw; - * neg_src2_2:e -> mux_neg2:w; - * neg_src2_3:e -> mux_neg2:sw; - * mux_neg2:e -> ac2:nw [label="-"]; - * ac2:e -> res_out2 [label="Comparator 2 Result"]; - * - * ac1:e -> window_comp:nw; - * ac2:e -> window_comp:sw; - * window_comp:e -> res_window:w [label="Window Result"]; - * - * {rank=same; pos_src1_1 neg_src1_1 neg_src1_2 neg_src1_3 pos_src2_1 neg_src2_1 neg_src2_2 neg_src2_3 } - * {rank=same; mux_pos1 mux_neg1 mux_pos2 mux_neg2 } - * {rank=same; ac1 ac2 } - * {rank=same; res_out1 res_out2 res_window } - * } - * \enddot - * - * - * \section asfdoc_sam0_ac_special_considerations Special Considerations - * - * The number of comparator pairs (and, thus, window comparators) within a - * single hardware instance of the Analog Comparator module is device-specific. - * Some devices will contain a single comparator pair, while others may have two - * pairs; refer to your device specific datasheet for details. - * - * - * \section asfdoc_sam0_ac_extra_info Extra Information - * - * For extra information, see \ref asfdoc_sam0_ac_extra. This includes: - * - \ref asfdoc_sam0_ac_extra_acronyms - * - \ref asfdoc_sam0_ac_extra_dependencies - * - \ref asfdoc_sam0_ac_extra_errata - * - \ref asfdoc_sam0_ac_extra_history - * - * - * \section asfdoc_sam0_ac_examples Examples - * - * For a list of examples related to this driver, see - * \ref asfdoc_sam0_ac_exqsg. - * - * - * \section asfdoc_sam0_ac_api_overview API Overview - * @{ - */ - -#include <compiler.h> -#include <clock.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name Driver Feature Definition - * Define AC driver feature set according to different device family. - * @{ - */ -#if (SAML21) || (SAML22) || (SAMC20) || (SAMC21) || defined(__DOXYGEN__) - /** Setting of hysteresis level */ -# define FEATURE_AC_HYSTERESIS_LEVEL - /** SYNCBUSY scheme version 2 */ -# define FEATURE_AC_SYNCBUSY_SCHEME_VERSION_2 -#endif - -#if (SAML21) || (SAML22) || (SAMC20) || (SAMC21) || defined(__DOXYGEN__) - /** Run in standby feature for each comparator */ -# define FEATURE_AC_RUN_IN_STANDY_EACH_COMPARATOR -#else - /** Run in standby feature for comparator pair */ -# define FEATURE_AC_RUN_IN_STANDY_PAIR_COMPARATOR -#endif -/* @} */ - -#if !defined(__DOXYGEN__) -/* Forward declaration of struct */ -struct ac_module; - -extern struct ac_module *_ac_instance[AC_INST_NUM]; -#endif - - -/** - * \name AC Window Channel Status Flags - * - * AC window channel status flags, returned by \ref ac_win_get_status(). - * - * @{ - */ - - /** Unknown output state; the comparator window channel was not ready. */ -#define AC_WIN_STATUS_UNKNOWN (1UL << 0) -/** Window Comparator's input voltage is above the window */ -#define AC_WIN_STATUS_ABOVE (1UL << 1) -/** Window Comparator's input voltage is inside the window */ -#define AC_WIN_STATUS_INSIDE (1UL << 2) -/** Window Comparator's input voltage is below the window */ -#define AC_WIN_STATUS_BELOW (1UL << 3) -/** - * This state reflects the window interrupt flag. When the interrupt flag - * should be set is configured in \ref ac_win_set_config(). This state needs - * to be cleared by the of \ref ac_win_clear_status(). - */ -#define AC_WIN_STATUS_INTERRUPT_SET (1UL << 4) -/** @} */ - -/** - * \name AC Channel Status Flags - * - * AC channel status flags, returned by \ref ac_chan_get_status(). - * - * @{ - */ - -/** Unknown output state; the comparator channel was not ready. */ -#define AC_CHAN_STATUS_UNKNOWN (1UL << 0) -/** Comparator's negative input pin is higher in voltage than the positive - * input pin. */ -#define AC_CHAN_STATUS_NEG_ABOVE_POS (1UL << 1) -/** Comparator's positive input pin is higher in voltage than the negative - * input pin. */ -#define AC_CHAN_STATUS_POS_ABOVE_NEG (1UL << 2) -/** - * This state reflects the channel interrupt flag. When the interrupt flag - * should be set is configured in ac_chan_set_config(). This state needs - * to be cleared by the of ac_chan_clear_status(). - */ -#define AC_CHAN_STATUS_INTERRUPT_SET (1UL << 3) -/** @} */ - -/** Type definition for a AC module callback function. */ -typedef void (*ac_callback_t)(struct ac_module *const module_inst); - -/** Enum for possible callback types for the AC module. */ -enum ac_callback { - /** Callback for comparator 0 */ - AC_CALLBACK_COMPARATOR_0 = 0, - /** Callback for comparator 1 */ - AC_CALLBACK_COMPARATOR_1 = 1, - /** Callback for window 0 */ - AC_CALLBACK_WINDOW_0 = 4, -#if (AC_NUM_CMP > 2) - /** Callback for comparator 2 */ - AC_CALLBACK_COMPARATOR_2 = 2, - /** Callback for comparator 3 */ - AC_CALLBACK_COMPARATOR_3 = 3, - /** Callback for window 1 */ - AC_CALLBACK_WINDOW_1 = 5, - /** Number of available callbacks */ -#endif /* (AC_NUM_CMP == 2) */ -#if !defined(__DOXYGEN__) - AC_CALLBACK_N, -#endif /* !defined(__DOXYGEN__) */ -}; - -#ifdef FEATURE_AC_HYSTERESIS_LEVEL -/** Enum for possible hysteresis level types for AC module. */ -enum ac_hysteresis_level { - /** Hysteresis level of 50mV */ - AC_HYSTERESIS_LEVEL_50 = 0, - /** Hysteresis level of 70mV */ - AC_HYSTERESIS_LEVEL_70, - /** Hysteresis level of 90mV */ - AC_HYSTERESIS_LEVEL_90, - /** Hysteresis level of 110mV */ - AC_HYSTERESIS_LEVEL_110 -}; -#endif - -/** - * \brief AC comparator channel selection enum. - * - * Enum for the possible comparator channels. - */ -enum ac_chan_channel { - /** Comparator channel 0 (Pair 0, Comparator 0) */ - AC_CHAN_CHANNEL_0 = 0, - /** Comparator channel 1 (Pair 0, Comparator 1) */ - AC_CHAN_CHANNEL_1 = 1, -#if defined(__DOXYGEN__) || (AC_NUM_CMP > 2) - /** Comparator channel 2 (Pair 1, Comparator 0) */ - AC_CHAN_CHANNEL_2 = 2, - /** Comparator channel 3 (Pair 1, Comparator 1) */ - AC_CHAN_CHANNEL_3 = 3, -#endif -}; - -/** - * \brief AC channel input sampling mode configuration enum. - * - * Enum for the possible channel sampling modes of an Analog Comparator channel. - */ -enum ac_chan_sample_mode { - /** Continuous sampling mode; when the channel is enabled the comparator - * output is available for reading at any time */ - AC_CHAN_MODE_CONTINUOUS = 0, - /** Single shot mode; when used the comparator channel must be triggered to - * perform a comparison before reading the result */ - AC_CHAN_MODE_SINGLE_SHOT = AC_COMPCTRL_SINGLE, -}; - -/** - * \brief AC channel positive comparator pin input configuration enum. - * - * Enum for the possible channel positive pin input of an Analog Comparator - * channel. - */ -enum ac_chan_pos_mux { - /** Positive comparator input is connected to physical AC input pin 0 */ - AC_CHAN_POS_MUX_PIN0 = AC_COMPCTRL_MUXPOS_PIN0, - /** Positive comparator input is connected to physical AC input pin 1 */ - AC_CHAN_POS_MUX_PIN1 = AC_COMPCTRL_MUXPOS_PIN1, - /** Positive comparator input is connected to physical AC input pin 2 */ - AC_CHAN_POS_MUX_PIN2 = AC_COMPCTRL_MUXPOS_PIN2, - /** Positive comparator input is connected to physical AC input pin 3 */ - AC_CHAN_POS_MUX_PIN3 = AC_COMPCTRL_MUXPOS_PIN3, -}; - -/** - * \brief AC channel negative comparator pin input configuration enum. - * - * Enum for the possible channel negative pin input of an Analog Comparator - * channel. - */ -enum ac_chan_neg_mux { - /** Negative comparator input is connected to physical AC input pin 0 */ - AC_CHAN_NEG_MUX_PIN0 = AC_COMPCTRL_MUXNEG_PIN0, - /** Negative comparator input is connected to physical AC input pin 1 */ - AC_CHAN_NEG_MUX_PIN1 = AC_COMPCTRL_MUXNEG_PIN1, - /** Negative comparator input is connected to physical AC input pin 2 */ - AC_CHAN_NEG_MUX_PIN2 = AC_COMPCTRL_MUXNEG_PIN2, - /** Negative comparator input is connected to physical AC input pin 3 */ - AC_CHAN_NEG_MUX_PIN3 = AC_COMPCTRL_MUXNEG_PIN3, - /** Negative comparator input is connected to the internal ground plane */ - AC_CHAN_NEG_MUX_GND = AC_COMPCTRL_MUXNEG_GND, - /** Negative comparator input is connected to the channel's internal V<SUB>CC</SUB> - * plane voltage scalar */ - AC_CHAN_NEG_MUX_SCALED_VCC = AC_COMPCTRL_MUXNEG_VSCALE, - /** Negative comparator input is connected to the internal band gap voltage - * reference */ - AC_CHAN_NEG_MUX_BANDGAP = AC_COMPCTRL_MUXNEG_BANDGAP, -#if !(SAML22) - /** - * For SAM D20/D21/D10/D11/R21/DA1: - * Negative comparator input is connected to the channel's internal DAC - * channel 0 output. - * For SAM L21/C20/C21: - * Negative comparator input is connected to the channel's internal DAC - * channel 0 output for Comparator 0 or OPAMP output for Comparator 1. - */ - AC_CHAN_NEG_MUX_DAC0 = AC_COMPCTRL_MUXNEG_DAC, -#endif -}; - -/** - * \brief AC channel output filtering configuration enum. - * - * Enum for the possible channel output filtering configurations of an Analog - * Comparator channel. - */ -enum ac_chan_filter { - /** No output filtering is performed on the comparator channel */ - AC_CHAN_FILTER_NONE = AC_COMPCTRL_FLEN_OFF, - /** Comparator channel output is passed through a Majority-of-Three - * filter */ - AC_CHAN_FILTER_MAJORITY_3 = AC_COMPCTRL_FLEN_MAJ3, - /** Comparator channel output is passed through a Majority-of-Five - * filter */ - AC_CHAN_FILTER_MAJORITY_5 = AC_COMPCTRL_FLEN_MAJ5, -}; - -/** - * \brief AC channel GPIO output routing configuration enum. - * - * Enum for the possible channel GPIO output routing configurations of an Analog - * Comparator channel. - */ -enum ac_chan_output { - /** Comparator channel output is not routed to a physical GPIO pin, and is - * used internally only */ - AC_CHAN_OUTPUT_INTERNAL = AC_COMPCTRL_OUT_OFF, - /** Comparator channel output is routed to its matching physical GPIO pin, - * via an asynchronous path */ - AC_CHAN_OUTPUT_ASYNCRONOUS = AC_COMPCTRL_OUT_ASYNC, - /** Comparator channel output is routed to its matching physical GPIO pin, - * via a synchronous path */ - AC_CHAN_OUTPUT_SYNCHRONOUS = AC_COMPCTRL_OUT_SYNC, -}; - -/** - * \brief AC window channel selection enum. - * - * Enum for the possible window comparator channels. - */ -enum ac_win_channel { - /** Window channel 0 (Pair 0, Comparators 0 and 1) */ - AC_WIN_CHANNEL_0 = 0, -#if defined(__DOXYGEN__) || (AC_PAIRS > 1) - /** Window channel 1 (Pair 1, Comparators 2 and 3) */ - AC_WIN_CHANNEL_1 = 1, -#endif -}; - -/** - * \brief Channel interrupt selection enum. - * - * This enum is used to select when a channel interrupt should occur. - */ -enum ac_chan_interrupt_selection { - /** An interrupt will be generated when the comparator level is passed */ - AC_CHAN_INTERRUPT_SELECTION_TOGGLE = AC_COMPCTRL_INTSEL_TOGGLE, - /** An interrupt will be generated when the measurement goes above the - * compare level - */ - AC_CHAN_INTERRUPT_SELECTION_RISING = AC_COMPCTRL_INTSEL_RISING, - /** An interrupt will be generated when the measurement goes below the - * compare level - */ - AC_CHAN_INTERRUPT_SELECTION_FALLING = AC_COMPCTRL_INTSEL_FALLING, - /** - * An interrupt will be generated when a new measurement is complete. - * Interrupts will only be generated in single shot mode. This state needs - * to be cleared by the use of ac_chan_cleare_status() - */ - AC_CHAN_INTERRUPT_SELECTION_END_OF_COMPARE = AC_COMPCTRL_INTSEL_EOC, -}; - -/** - * \brief Window interrupt selection enum. - * - * This enum is used to select when a window interrupt should occur. - */ -enum ac_win_interrupt_selection { - /** Interrupt is generated when the compare value goes above the window */ - AC_WIN_INTERRUPT_SELECTION_ABOVE = AC_WINCTRL_WINTSEL0_ABOVE, - /** Interrupt is generated when the compare value goes inside the window */ - AC_WIN_INTERRUPT_SELECTION_INSIDE = AC_WINCTRL_WINTSEL0_INSIDE, - /** Interrupt is generated when the compare value goes below the window */ - AC_WIN_INTERRUPT_SELECTION_BELOW = AC_WINCTRL_WINTSEL0_BELOW, - /** Interrupt is generated when the compare value goes outside the window */ - AC_WIN_INTERRUPT_SELECTION_OUTSIDE = AC_WINCTRL_WINTSEL0_OUTSIDE, -}; - -/** - * \brief AC software device instance structure. - * - * AC 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 ac_module { -#if !defined(__DOXYGEN__) - /** Hardware module pointer of the associated Analog Comparator peripheral. */ - Ac *hw; -# if AC_CALLBACK_MODE == true - /** Array of callbacks */ - ac_callback_t callback[AC_CALLBACK_N]; - /** Bit mask for callbacks registered */ - uint8_t register_callback_mask; - /** Bit mask for callbacks enabled */ - uint8_t enable_callback_mask; -# endif -#endif -}; - -/** - * \brief AC event enable/disable structure. - * - * Event flags for the Analog Comparator module. This is used to enable and - * disable events via \ref ac_enable_events() and \ref ac_disable_events(). - */ -struct ac_events { - /** If \c true, an event will be generated when a comparator window state - * changes */ - bool generate_event_on_window[AC_PAIRS]; - - /** If \c true, an event will be generated when a comparator state - * changes */ - bool generate_event_on_state[AC_NUM_CMP]; - - /** If \c true, a comparator will be sampled each time an event is - * received */ - bool on_event_sample[AC_NUM_CMP]; -}; - -/** - * \brief Analog Comparator module configuration structure. - * - * Configuration structure for a comparator channel, to configure the input and - * output settings of the comparator. - */ -struct ac_config { -#ifdef FEATURE_AC_RUN_IN_STANDY_PAIR_COMPARATOR - /** If \c true, the comparator pairs will continue to sample during sleep - * mode when triggered */ - bool run_in_standby[AC_PAIRS]; -#endif - -#if (SAMD) || (SAMR21) - /** Digital source generator for AC GCLK */ - enum gclk_generator dig_source_generator; - /** Analog source generator for AC GCLK */ - enum gclk_generator ana_source_generator; -#else - /** Source generator for AC GCLK */ - enum gclk_generator source_generator; -#endif -}; - -/** - * \brief Analog Comparator Comparator channel configuration structure. - * - * Configuration structure for a comparator channel, to configure the input and - * output settings of the comparator. - */ -struct ac_chan_config { - /** Sampling mode of the comparator channel */ - enum ac_chan_sample_mode sample_mode; - /** Filtering mode for the comparator output, when the comparator is used - * in a supported mode */ - enum ac_chan_filter filter; - /** When \c true, hysteresis mode is enabled on the comparator inputs */ - bool enable_hysteresis; -#ifdef FEATURE_AC_RUN_IN_STANDY_EACH_COMPARATOR - /** If \c true, the comparator will continue to sample during sleep - * mode when triggered */ - bool run_in_standby; -#endif -#ifdef FEATURE_AC_HYSTERESIS_LEVEL - /** Hysteresis level of the comparator channel */ - enum ac_hysteresis_level hysteresis_level; -#endif - /** Output mode of the comparator, whether it should be available for - * internal use, or asynchronously/synchronously linked to a - * general-purpose input/output (GPIO) pin */ - enum ac_chan_output output_mode; - /** Input multiplexer selection for the comparator's positive input pin */ - enum ac_chan_pos_mux positive_input; - /** Input multiplexer selection for the comparator's negative input pin. - * Any internal reference source, such as a bandgap reference voltage or - * the DAC, must be configured and enabled prior to its use as a - * comparator input.*/ - enum ac_chan_neg_mux negative_input; - /** Scaled VCC voltage division factor for the channel, when a comparator - * pin is connected to the V<SUB>CC</SUB> voltage scalar input. The formular is: - * Vscale = Vdd * vcc_scale_factor / 64. - * If the V<SUB>CC</SUB> voltage scalar is not selected as a comparator - * channel pin's input, this value will be ignored. */ - uint8_t vcc_scale_factor; - /** Interrupt criteria for the comparator channel, to select the condition - * that will trigger a callback */ - enum ac_chan_interrupt_selection interrupt_selection; -}; - -/** - * \brief Analog Comparator Window configuration structure. - */ -struct ac_win_config { - /** Interrupt criteria for the comparator window channel, to select the - * condition that will trigger a callback */ - enum ac_win_interrupt_selection interrupt_selection; -}; - -/** - * \name Configuration and Initialization - * @{ - */ - -enum status_code ac_reset( - struct ac_module *const module_inst); - -enum status_code ac_init( - struct ac_module *const module_inst, - Ac *const hw, - struct ac_config *const config); - -#if (AC_INST_NUM > 1) && !defined(__DOXYGEN__) -/** - * \internal Find the index of given AC module instance. - * - * \param[in] AC module instance pointer. - * - * \return Index of the given AC module instance. - */ -static uint8_t _ac_get_inst_index( - Ac *const hw) -{ - /* List of available AC modules. */ - static Ac *const ac_modules[AC_INST_NUM] = AC_INSTS; - - /* Find index for AC instance. */ - for (uint32_t i = 0; i < AC_INST_NUM; i++) { - if (hw == ac_modules[i]) { - return i; - } - } - - /* Invalid data given. */ - Assert(false); - return 0; -} -#endif /* (AC_INST_NUM > 1) && !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 AC software instance struct - * - * \return Synchronization status of the underlying hardware module(s). - * - * \retval false If the module has completed synchronization - * \retval ture If the module synchronization is ongoing - */ -static inline bool ac_is_syncing( - struct ac_module *const module_inst) -{ - /* Sanity check arguments */ - Assert(module_inst); - - Ac *const ac_module = module_inst->hw; - -#ifdef FEATURE_AC_SYNCBUSY_SCHEME_VERSION_2 - if (ac_module->SYNCBUSY.reg & AC_SYNCBUSY_MASK) { - return true; - } - - return false; -#else - if (ac_module->STATUSB.reg & AC_STATUSB_SYNCBUSY) { - return true; - } - - return false; -#endif -} - -/** - * \brief Initializes all members of an Analog Comparator configuration - * structure to safe defaults. - * - * Initializes all members of a given Analog Comparator configuration - * structure to safe known default values. This function should be called on - * all new instances of these configuration structures before being modified - * by the user application. - * - * The default configuration is as follows: - * \li All comparator pairs disabled during sleep mode (if has this feature) - * \li Generator 0 is the default GCLK generator - * - * \param[out] config Configuration structure to initialize to default values - */ -static inline void ac_get_config_defaults( - struct ac_config *const config) -{ - /* Sanity check arguments */ - Assert(config); -#ifdef FEATURE_AC_RUN_IN_STANDY_PAIR_COMPARATOR - /* Default configuration values */ - for (uint32_t i = 0; i < AC_PAIRS; i++) { - config->run_in_standby[i] = false; - } -#endif -#if (SAMD) || (SAMR21) - config->dig_source_generator = GCLK_GENERATOR_0; - config->ana_source_generator = GCLK_GENERATOR_3; -#else - config->source_generator = GCLK_GENERATOR_0; -#endif -} - -/** - * \brief Enables an Analog Comparator that was previously configured. - * - * Enables an Analog Comparator that was previously configured via a - * call to \ref ac_init(). - * - * \param[in] module_inst Software instance for the Analog Comparator peripheral - */ -static inline void ac_enable( - struct ac_module *const module_inst) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - Ac *const ac_module = module_inst->hw; - - while (ac_is_syncing(module_inst)) { - /* Wait until synchronization is complete */ - } - - /* Write the new comparator module control configuration */ - ac_module->CTRLA.reg |= AC_CTRLA_ENABLE; -} - -/** - * \brief Disables an Analog Comparator that was previously enabled. - * - * Disables an Analog Comparator that was previously started via a call to - * \ref ac_enable(). - * - * \param[in] module_inst Software instance for the Analog Comparator peripheral - */ -static inline void ac_disable( - struct ac_module *const module_inst) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - Ac *const ac_module = module_inst->hw; - - while (ac_is_syncing(module_inst)) { - /* Wait until synchronization is complete */ - } - - /* Write the new comparator module control configuration */ - ac_module->CTRLA.reg &= ~AC_CTRLA_ENABLE; -} - -/** - * \brief Enables an Analog Comparator event input or output. - * - * Enables one or more input or output events to or from the Analog Comparator - * module. See \ref ac_events 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 Analog Comparator peripheral - * \param[in] events Struct containing flags of events to enable - */ -static inline void ac_enable_events( - struct ac_module *const module_inst, - struct ac_events *const events) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - Assert(events); - - Ac *const ac_module = module_inst->hw; - - uint32_t event_mask = 0; - - /* Configure window output events for each comparator pair */ - for (uint8_t i = 0; i < AC_PAIRS; i++) { - if (events->generate_event_on_window[i] == true) { - event_mask |= (AC_EVCTRL_WINEO0 << i); - } - } - - /* Configure sample input/output events for each comparator */ - for (uint8_t i = 0; i < AC_NUM_CMP; i++) { - if (events->on_event_sample[i] == true) { - event_mask |= (AC_EVCTRL_COMPEI0 << i); - } - - if (events->generate_event_on_state[i] == true) { - event_mask |= (AC_EVCTRL_COMPEO0 << i); - } - } - - ac_module->EVCTRL.reg |= event_mask; -} - -/** - * \brief Disables an Analog Comparator event input or output. - * - * Disables one or more input or output events to or from the Analog Comparator - * module. See \ref ac_events 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 Analog Comparator peripheral - * \param[in] events Struct containing flags of events to disable - */ -static inline void ac_disable_events( - struct ac_module *const module_inst, - struct ac_events *const events) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - Assert(events); - - Ac *const ac_module = module_inst->hw; - - uint32_t event_mask = 0; - - /* Configure window output events for each comparator pair */ - for (uint8_t i = 0; i < AC_PAIRS; i++) { - if (events->generate_event_on_window[i] == true) { - event_mask |= (AC_EVCTRL_WINEO0 << i); - } - } - - /* Configure sample input/output events for each comparator */ - for (uint8_t i = 0; i < AC_NUM_CMP; i++) { - if (events->on_event_sample[i] == true) { - event_mask |= (AC_EVCTRL_COMPEI0 << i); - } - - if (events->generate_event_on_state[i] == true) { - event_mask |= (AC_EVCTRL_COMPEO0 << i); - } - } - - ac_module->EVCTRL.reg &= ~event_mask; -} - -/** @} */ - - -/** - * \name Channel Configuration and Initialization - * @{ - */ - -/** - * \brief Initializes all members of an Analog Comparator channel configuration - * structure to safe defaults. - * - * Initializes all members of an Analog Comparator channel configuration - * structure to safe defaults. This function should be called on all new - * instances of these configuration structures before being modified by the - * user application. - * - * The default configuration is as follows: - * \li Continuous sampling mode - * \li Majority of five sample output filter - * \li Comparator disabled during sleep mode (if has this feature) - * \li Hysteresis enabled on the input pins - * \li Hysteresis level of 50mV if having this feature - * \li Internal comparator output mode - * \li Comparator pin multiplexer 0 selected as the positive input - * \li Scaled V<SUB>CC</SUB> voltage selected as the negative input - * \li V<SUB>CC</SUB> voltage scaler set for a division factor of two - * \li Channel interrupt set to occur when the compare threshold is passed - * - * \param[out] config Channel configuration structure to initialize to - * default values - */ -static inline void ac_chan_get_config_defaults( - struct ac_chan_config *const config) -{ - /* Sanity check arguments */ - Assert(config); - - /* Default configuration values */ - config->sample_mode = AC_CHAN_MODE_CONTINUOUS; - config->filter = AC_CHAN_FILTER_MAJORITY_5; - config->enable_hysteresis = true; -#ifdef FEATURE_AC_RUN_IN_STANDY_EACH_COMPARATOR - config->run_in_standby = false; -#endif -#ifdef FEATURE_AC_HYSTERESIS_LEVEL - config->hysteresis_level = AC_HYSTERESIS_LEVEL_50; -#endif - config->output_mode = AC_CHAN_OUTPUT_INTERNAL; - config->positive_input = AC_CHAN_POS_MUX_PIN0; - config->negative_input = AC_CHAN_NEG_MUX_SCALED_VCC; - config->vcc_scale_factor = 32; - config->interrupt_selection = AC_CHAN_INTERRUPT_SELECTION_TOGGLE; -} - -enum status_code ac_chan_set_config( - struct ac_module *const module_inst, - const enum ac_chan_channel channel, - struct ac_chan_config *const config); - -/** - * \brief Enables an Analog Comparator channel that was previously configured. - * - * Enables an Analog Comparator channel that was previously - * configured via a call to \ref ac_chan_set_config(). - * - * \param[in] module_inst Software instance for the Analog Comparator peripheral - * \param[in] channel Comparator channel to enable - */ -static inline void ac_chan_enable( - struct ac_module *const module_inst, - const enum ac_chan_channel channel) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - Ac *const ac_module = module_inst->hw; - - while (ac_is_syncing(module_inst)) { - /* Wait until synchronization is complete */ - } - - /* Write the new comparator module control configuration */ - ac_module->COMPCTRL[(uint8_t)channel].reg |= AC_COMPCTRL_ENABLE; -} - -/** - * \brief Disables an Analog Comparator channel that was previously enabled. - * - * Stops an Analog Comparator channel that was previously started via a call to - * \ref ac_chan_enable(). - * - * \param[in] module_inst Software instance for the Analog Comparator peripheral - * \param[in] channel Comparator channel to disable - */ -static inline void ac_chan_disable( - struct ac_module *const module_inst, - const enum ac_chan_channel channel) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - Ac *const ac_module = module_inst->hw; - - while (ac_is_syncing(module_inst)) { - /* Wait until synchronization is complete */ - } - - /* Write the new comparator module control configuration */ - ac_module->COMPCTRL[(uint8_t)channel].reg &= ~AC_COMPCTRL_ENABLE; -} - -/** @} */ - - -/** - * \name Channel Control - * @{ - */ - -/** - * \brief Triggers a comparison on a comparator that is configured in single shot mode. - * - * Triggers a single conversion on a comparator configured to compare on demand - * (single shot mode) rather than continuously. - * - * \param[in] module_inst Software instance for the Analog Comparator peripheral - * \param[in] channel Comparator channel to trigger - */ -static inline void ac_chan_trigger_single_shot( - struct ac_module *const module_inst, - const enum ac_chan_channel channel) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - Ac *const ac_module = module_inst->hw; - - /* Write the new comparator module control configuration */ - ac_module->CTRLB.reg |= (AC_CTRLB_START0 << (uint8_t)channel); -} - -/** - * \brief Determines if a given comparator channel is ready for comparisons. - * - * Checks a comparator channel to see if the comparator is currently ready to - * begin comparisons. - * - * \param[in] module_inst Software instance for the Analog Comparator peripheral - * \param[in] channel Comparator channel to test - * - * \return Comparator channel readiness state. - */ -static inline bool ac_chan_is_ready( - struct ac_module *const module_inst, - const enum ac_chan_channel channel) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - Ac *const ac_module = module_inst->hw; - - return (ac_module->STATUSB.reg & (AC_STATUSB_READY0 << (uint8_t)channel)); -} - -/** - * \brief Determines the output state of a comparator channel. - * - * Retrieves the last comparison value (after filtering) of a given comparator. - * If the comparator was not ready at the time of the check, the comparison - * result will be indicated as being unknown. - * - * \param[in] module_inst Software instance for the Analog Comparator peripheral - * \param[in] channel Comparator channel to test - * - * \return Bit mask of comparator channel status flags. - */ -static inline uint8_t ac_chan_get_status( - struct ac_module *const module_inst, - const enum ac_chan_channel channel) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - Ac *const ac_module = module_inst->hw; - - uint8_t status_mask = 0; - - if (ac_module->INTFLAG.reg & (1 << channel)) { - status_mask = AC_CHAN_STATUS_INTERRUPT_SET; - } - - if (ac_chan_is_ready(module_inst, channel) == false) { - status_mask |= AC_CHAN_STATUS_UNKNOWN; - return status_mask; - } - - if (ac_module->STATUSA.reg & (AC_STATUSA_STATE0 << (uint8_t)channel)) { - status_mask |= AC_CHAN_STATUS_POS_ABOVE_NEG; - } else { - status_mask |= AC_CHAN_STATUS_NEG_ABOVE_POS; - } - return status_mask; -} - -/** - * \brief Clears an interrupt status flag. - * - * This function is used to clear the AC_CHAN_STATUS_INTERRUPT_SET flag - * it will clear the flag for the channel indicated by the channel argument. - * - * \param[in] module_inst Software instance for the Analog Comparator peripheral - * \param[in] channel Comparator channel to clear - */ -static inline void ac_chan_clear_status( - struct ac_module *const module_inst, - const enum ac_chan_channel channel) -{ - Assert(module_inst); - Assert(module_inst->hw); - - module_inst->hw->INTFLAG.reg = (1 << channel); -} -/** @} */ - - -/** - * \name Window Mode Configuration and Initialization - * @{ - */ - -/** - * \brief Initializes an Analog Comparator window configuration structure to defaults. - * - * Initializes a given Analog Comparator channel configuration structure to a - * set of known default values. This function should be called if window interrupts - * are needed and before ac_win_set_config(). - * - * The default configuration is as follows: - * \li Channel interrupt set to occur when the measurement is above the window - * - * \param[out] config Window configuration structure to initialize to - * default values - */ -static inline void ac_win_get_config_defaults( - struct ac_win_config *const config) -{ - /* Sanity check arguments */ - Assert(config); - - /* Default configuration values */ - config->interrupt_selection = AC_WIN_INTERRUPT_SELECTION_ABOVE; -} - -enum status_code ac_win_set_config( - struct ac_module *const module_inst, - enum ac_win_channel const win_channel, - struct ac_win_config *const config); - -enum status_code ac_win_enable( - struct ac_module *const module_inst, - const enum ac_win_channel win_channel); - -void ac_win_disable( - struct ac_module *const module_inst, - const enum ac_win_channel win_channel); - -/** @} */ - - -/** - * \name Window Mode Control - * @{ - */ - -/** - * \brief Determines if a given Window Comparator is ready for comparisons. - * - * Checks a Window Comparator to see if the both comparators used for window - * detection is currently ready to begin comparisons. - * - * \param[in] module_inst Software instance for the Analog Comparator peripheral - * \param[in] win_channel Window Comparator channel to test - * - * \return Window Comparator channel readiness state. - */ -static inline bool ac_win_is_ready( - struct ac_module *const module_inst, - const enum ac_win_channel win_channel) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - /* Convert a window channel index to the individual comparator channels */ - enum ac_chan_channel win_pair_comp0 = - (enum ac_chan_channel)((uint8_t)win_channel * 2); - enum ac_chan_channel win_pair_comp1 = - (enum ac_chan_channel)(((uint8_t)win_channel * 2) + 1); - - /* Check if the two comparators used in the window are ready */ - bool win_pair_comp0_ready = ac_chan_is_ready(module_inst, win_pair_comp0); - bool win_pair_comp1_ready = ac_chan_is_ready(module_inst, win_pair_comp1); - - /* If one or both window comparators not ready, return failure */ - if ((win_pair_comp0_ready == false) || (win_pair_comp1_ready == false)) { - return false; - } - - return true; -} - -uint8_t ac_win_get_status( - struct ac_module *const module_inst, - const enum ac_win_channel win_channel); - -/** - * \brief Clears an interrupt status flag. - * - * This function is used to clear the AC_WIN_STATUS_INTERRUPT_SET flag - * it will clear the flag for the channel indicated by the win_channel argument. - * - * \param[in] module_inst Software instance for the Analog Comparator peripheral - * \param[in] win_channel Window channel to clear - */ -static inline void ac_win_clear_status( - struct ac_module *const module_inst, - const enum ac_win_channel win_channel) -{ - Assert(module_inst); - Assert(module_inst->hw); - - module_inst->hw->INTFLAG.reg = (1 << (win_channel + AC_INTFLAG_WIN0_Pos)); -} -/** @} */ - -#ifdef __cplusplus -} -#endif - -/** @} */ - - -/** - * \page asfdoc_sam0_ac_extra Extra Information for AC Driver - * - * \section asfdoc_sam0_ac_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>AC</td> - * <td>Analog Comparator</td> - * </tr> - * <tr> - * <td>DAC</td> - * <td>Digital-to-Analog Converter</td> - * </tr> - * <tr> - * <td>MUX</td> - * <td>Multiplexer</td> - * </tr> - * </table> - * - * - * \section asfdoc_sam0_ac_extra_dependencies Dependencies - * This driver has the following dependencies: - * - * - \ref asfdoc_sam0_system_pinmux_group "System Pin Multiplexer Driver" - * - * - * \section asfdoc_sam0_ac_extra_errata Errata - * There are no errata related to this driver. - * - * - * \section asfdoc_sam0_ac_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> - * <tr> - * <td>Initial Release</td> - * </tr> - * </table> - */ - -/** - * \page asfdoc_sam0_ac_exqsg Examples for AC Driver - * - * This is a list of the available Quick Start guides (QSGs) and example - * applications for \ref asfdoc_sam0_ac_group. QSGs are simple examples with - * step-by-step instructions to configure and use this driver in a selection of - * use cases. Note that a QSG can be compiled as a standalone application or be - * added to the user application. - * - * - \subpage asfdoc_sam0_ac_basic_use_case - * \if AC_CALLBACK_MODE - * - \subpage asfdoc_sam0_ac_callback_use_case - * \endif - * - * \page asfdoc_sam0_ac_document_revision_history Document Revision History - * - * <table> - * <tr> - * <th>Doc. Rev.</th> - * <th>Date</th> - * <th>Comments</th> - * </tr> - * <tr> - * <td>42106F</td> - * <td>12/2015</td> - * <td>Fixed typos and legal disclaimer</td> - * </tr> - * <tr> - * <td>42106E</td> - * <td>08/2015</td> - * <td>Added support for SAM L21, SAM C20/C21, and SAM DA1</td> - * </tr> - * <tr> - * <td>42106D</td> - * <td>12/2014</td> - * <td>Added support for SAM R21 and SAM D10/D11</td> - * </tr> - * <tr> - * <td>42106C</td> - * <td>01/2014</td> - * <td>Added support for SAM D21</td> - * </tr> - * <tr> - * <td>42106B</td> - * <td>06/2013</td> - * <td>Added additional documentation on the event system. Corrected - * documentation typos.</td> - * </tr> - * <tr> - * <td>42106A</td> - * <td>06/2013</td> - * <td>Initial release</td> - * </tr> - * </table> - */ - -#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac_callback.c ---------------------------------------------------------------------- diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac_callback.c b/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac_callback.c deleted file mode 100755 index 4f1fc7d..0000000 --- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac_callback.c +++ /dev/null @@ -1,206 +0,0 @@ -/** - * \file - * - * \brief SAM AC - Analog Comparator Callback Driver - * - * Copyright (C) 2013-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> - */ - -#include "ac_callback.h" - -struct ac_module *_ac_instance[AC_INST_NUM]; - -void _ac_interrupt_handler(const uint32_t instance_index); - -/** - * \brief Registers a callback. - * - * Registers a callback function which is implemented by the user. - * - * \note The callback must be enabled by \ref ac_enable_callback, - * in order for the interrupt handler to call it when the conditions for the - * callback type is met. - * - * \param[in] module Pointer to software instance struct - * \param[in] callback_func Pointer to callback function - * \param[in] callback_type Callback type given by an enum - * - * \retval STATUS_OK The function exited successfully - */ -enum status_code ac_register_callback( - struct ac_module *const module, - ac_callback_t callback_func, - const enum ac_callback callback_type) -{ - /* Sanity check arguments */ - Assert(module); - Assert(callback_func); - - /* Register callback function */ - module->callback[callback_type] = callback_func; - - /* Set software flag for callback */ - module->register_callback_mask |= (1 << callback_type); - - return STATUS_OK; -} - -/** - * \brief Unregisters a callback. - * - * Unregisters a callback function implemented by the user. - * - * \param[in] module Pointer to AC software instance struct - * \param[in] callback_type Callback type given by an enum - * - * \retval STATUS_OK The function exited successfully - */ -enum status_code ac_unregister_callback( - struct ac_module *const module, - const enum ac_callback callback_type) -{ - /* Sanity check arguments */ - Assert(module); - /* Unregister callback function */ - module->callback[callback_type] = NULL; - - /* Clear software flag for callback */ - module->register_callback_mask &= ~(1 << callback_type); - - return STATUS_OK; -} - -/** - * \internal ISR handler for AC - */ -#if (AC_INST_NUM == 1) -void AC_Handler(void) -{ - _ac_interrupt_handler(0); -} -#elif (AC_INST_NUM == 2) -void AC_Handler(void) -{ - _ac_interrupt_handler(0); -} - -void AC1_Handler(void) -{ - _ac_interrupt_handler(1); -} -#else -# error This driver is not support more than three AC instances. -#endif - -/** - * \brief Interrupt Handler for AC module. - * - * Handles interrupts as they occur, it will run the callback functions - * that are registered and enabled. - * - * \param [in] instance_index Default value 0 - */ -void _ac_interrupt_handler(const uint32_t instance_index) -{ - /* Temporary variable */ - uint8_t interrupt_and_callback_status_mask; - - /* Get device instance from the look-up table */ - - struct ac_module *module = _ac_instance[instance_index]; - - /* Read and mask interrupt flag register */ - interrupt_and_callback_status_mask = - _ac_instance[instance_index]->hw->INTFLAG.reg & - (module->register_callback_mask & module->enable_callback_mask); - - /* Check if comparator channel 0 needs to be serviced */ - if (interrupt_and_callback_status_mask & AC_INTFLAG_COMP0) { - /* Invoke registered and enabled callback function */ - (module->callback[AC_CALLBACK_COMPARATOR_0])(module); - /* Clear interrupt flag */ - module->hw->INTFLAG.reg = AC_INTFLAG_COMP0; - } - - /* Check if comparator channel 1 needs to be serviced */ - if (interrupt_and_callback_status_mask & AC_INTFLAG_COMP1) { - /* Invoke registered and enabled callback function */ - (module->callback[AC_CALLBACK_COMPARATOR_1])(module); - /* Clear interrupt flag */ - module->hw->INTFLAG.reg = AC_INTFLAG_COMP1; - } - - /* Check if window 0 needs to be serviced */ - if (interrupt_and_callback_status_mask & AC_INTFLAG_WIN0) { - /* Invoke registered and enabled callback function */ - (module->callback[AC_CALLBACK_WINDOW_0])(module); - /* Clear interrupt flag */ - module->hw->INTFLAG.reg = AC_INTFLAG_WIN0; - } - -#if (AC_NUM_CMP > 2) - /* Check if comparator channel 2 needs to be serviced */ - if (interrupt_and_callback_status_mask & AC_INTFLAG_COMP2) { - /* Invoke registered and enabled callback function */ - (module->callback[AC_CALLBACK_COMPARATOR_2])(module); - /* Clear interrupt flag */ - module->hw->INTFLAG.reg = AC_INTFLAG_COMP2; - } - - /* Check if comparator channel 3 needs to be serviced */ - if (interrupt_and_callback_status_mask & AC_INTFLAG_COMP3) { - /* Invoke registered and enabled callback function */ - (module->callback[AC_CALLBACK_COMPARATOR_3])(module); - /* Clear interrupt flag */ - module->hw->INTFLAG.reg = AC_INTFLAG_COMP3; - } - -# if !(SAMC20) - /* Check if window 1 needs to be serviced */ - if (interrupt_and_callback_status_mask & AC_INTFLAG_WIN1) { - /* Invoke registered and enabled callback function */ - (module->callback[AC_CALLBACK_WINDOW_1])(module); - /* Clear interrupt flag */ - module->hw->INTFLAG.reg = AC_INTFLAG_WIN1; - } -# endif -#endif /* (AC_NUM_CMP > 2) */ -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac_callback.h ---------------------------------------------------------------------- diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac_callback.h b/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac_callback.h deleted file mode 100755 index fa48a7c..0000000 --- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac_callback.h +++ /dev/null @@ -1,223 +0,0 @@ -/** - * \file - * - * \brief SAM AC - Analog Comparator Callback Driver - * - * Copyright (C) 2013-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 AC_CALLBACK_H_INCLUDED -#define AC_CALLBACK_H_INCLUDED - -#include <compiler.h> -#include <system_interrupt.h> -#include "ac.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if (AC_INST_NUM > 1) && !defined(__DOXYGEN__) -/** - * \internal Get the interrupt vector for the given device instance - * - * \param[in] TC module instance number - * - * \return Interrupt vector for of the given TC module instance. - */ -static enum system_interrupt_vector _ac_interrupt_get_interrupt_vector( - uint32_t inst_num) -{ - static uint8_t ac_interrupt_vectors[AC_INST_NUM] = - { - SYSTEM_INTERRUPT_MODULE_AC, -#if (AC_INST_NUM == 2) - SYSTEM_INTERRUPT_MODULE_AC1, -#endif -#if (AC_INST_NUM >= 3) -# error This driver is not support more than three AC instances. -#endif - }; - - return ac_interrupt_vectors[inst_num]; -} -#endif /* (AC_INST_NUM > 1) !defined(__DOXYGEN__)*/ - -/** - * \name Callback Management - * {@ - */ - -enum status_code ac_register_callback( - struct ac_module *const module, - ac_callback_t callback_func, - const enum ac_callback callback_type); - -enum status_code ac_unregister_callback( - struct ac_module *const module, - const enum ac_callback callback_type); - -/** - * \brief Enables callback. - * - * Enables the callback function registered by the \ref - * ac_register_callback. The callback function will be called from the - * interrupt handler when the conditions for the callback type are - * met. This function will also enable the appropriate interrupts. - * - * \param[in] module Pointer to AC software instance struct - * \param[in] callback_type Callback type given by an enum - */ -static inline void ac_enable_callback( - struct ac_module *const module, - const enum ac_callback callback_type) -{ - /* Sanity check arguments */ - Assert(module); - - /* Set software flag for the callback */ - module->enable_callback_mask |= (1 << callback_type); - - uint32_t inenset_temp = 0; - - switch (callback_type) - { - case AC_CALLBACK_COMPARATOR_0: - inenset_temp |= AC_INTFLAG_COMP0; - break; - case AC_CALLBACK_COMPARATOR_1: - inenset_temp |= AC_INTFLAG_COMP1; - break; - case AC_CALLBACK_WINDOW_0: - inenset_temp |= AC_INTFLAG_WIN0; - break; -#if (AC_NUM_CMP > 2) - case AC_CALLBACK_COMPARATOR_2: - inenset_temp |= AC_INTFLAG_COMP2; - break; - case AC_CALLBACK_COMPARATOR_3: - inenset_temp |= AC_INTFLAG_COMP3; - break; -# if !(SAMC20) - case AC_CALLBACK_WINDOW_1: - inenset_temp |= AC_INTFLAG_WIN1; - break; -# endif -#endif - default: - break; - } - - /* Enable the interrupt for the callback */ - module->hw->INTENSET.reg = inenset_temp; - -#if (AC_INST_NUM == 1) - /* Enable interrupts for AC module */ - system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_AC); -#elif (AC_INST_NUM > 1) - system_interrupt_enable(_ac_interrupt_get_interrupt_vector(_ac_get_inst_index(module->hw))); -#endif /* (AC_INST_NUM > 1) */ -} - -/** - * \brief Disables callback. - * - * Disables the callback function registered by the \ref - * ac_register_callback, and the callback will not be called from the - * interrupt routine. The function will also disable the appropriate - * interrupts. - * - * \param[in] module Pointer to AC software instance struct - * \param[in] callback_type Callback type given by an enum - */ -static inline void ac_disable_callback( - struct ac_module *const module, - const enum ac_callback callback_type) -{ - /* Sanity check arguments */ - Assert(module); - - /* Clear software flag for the callback */ - module->enable_callback_mask &= ~(1 << callback_type); - - uint32_t inenclr_temp = 0; - - switch (callback_type) - { - case AC_CALLBACK_COMPARATOR_0: - inenclr_temp |= AC_INTFLAG_COMP0; - break; - case AC_CALLBACK_COMPARATOR_1: - inenclr_temp |= AC_INTFLAG_COMP1; - break; - case AC_CALLBACK_WINDOW_0: - inenclr_temp |= AC_INTFLAG_WIN0; - break; -#if (AC_NUM_CMP > 2) - case AC_CALLBACK_COMPARATOR_2: - inenclr_temp |= AC_INTFLAG_COMP2; - break; - case AC_CALLBACK_COMPARATOR_3: - inenclr_temp |= AC_INTFLAG_COMP3; - break; -# if !(SAMC20) - case AC_CALLBACK_WINDOW_1: - inenclr_temp |= AC_INTFLAG_WIN1; - break; -# endif -#endif - default: - break; - } - - /* Disable the interrupt for the callback */ - module->hw->INTENCLR.reg = inenclr_temp; -} - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* AC_CALLBACK_H_INCLUDED */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac_sam_d_r/ac.c ---------------------------------------------------------------------- diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac_sam_d_r/ac.c b/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac_sam_d_r/ac.c deleted file mode 100755 index 171d8cf..0000000 --- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/ac/ac_sam_d_r/ac.c +++ /dev/null @@ -1,440 +0,0 @@ -/** - * \file - * - * \brief SAM Analog Comparator Driver - * - * Copyright (C) 2012-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> - */ -#include "ac.h" - -static enum status_code _ac_set_config( - struct ac_module *const module_inst, - struct ac_config *const config) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - Assert(config); - - Ac *const ac_module = module_inst->hw; - - /* Use a temporary register for computing the control bits */ - uint32_t ctrla_temp = 0; - - /* Check if the comparators should be enabled during sleep */ - for (uint32_t i = 0; i < AC_PAIRS; i++) { - if (config->run_in_standby[i] == true) { - ctrla_temp |= (AC_CTRLA_RUNSTDBY_Msk << i); - } - } - - while (ac_is_syncing(module_inst)) { - /* Wait until synchronization is complete */ - } - - /* Write the new comparator module control configuration */ - ac_module->CTRLA.reg = ctrla_temp; - - return STATUS_OK; -} - -/** \brief Resets and disables the Analog Comparator driver. - * - * Resets and disables the Analog Comparator driver, resets the internal - * states and registers of the hardware module to their power-on defaults. - * - * \param[out] module_inst Pointer to the AC software instance struct - */ -enum status_code ac_reset( - struct ac_module *const module_inst) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - Ac *const ac_module = module_inst->hw; - - /* Disable the hardware module */ - ac_disable(module_inst); - - while (ac_is_syncing(module_inst)) { - /* Wait until synchronization is complete */ - } - - /* Software reset the module */ - ac_module->CTRLA.reg |= AC_CTRLA_SWRST; - - return STATUS_OK; -} - -/** \brief Initializes and configures the Analog Comparator driver. - * - * Initializes the Analog Comparator driver, configuring it to the user - * supplied configuration parameters, ready for use. This function should be - * called before enabling the Analog Comparator. - * - * \note Once called the Analog Comparator will not be running; to start the - * Analog Comparator call \ref ac_enable() after configuring the module. - * - * \param[out] module_inst Pointer to the AC software instance struct - * \param[in] hw Pointer to the AC module instance - * \param[in] config Pointer to the config struct, created by the user - * application - */ -enum status_code ac_init( - struct ac_module *const module_inst, - Ac *const hw, - struct ac_config *const config) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(hw); - Assert(config); - - /* Initialize device instance */ - module_inst->hw = hw; - - /* Turn on the digital interface clock and GCLK */ - struct system_gclk_chan_config gclk_chan_conf; - system_gclk_chan_get_config_defaults(&gclk_chan_conf); - - if (hw == AC) { - system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_AC); - gclk_chan_conf.source_generator = config->dig_source_generator; - system_gclk_chan_set_config(AC_GCLK_ID_DIG, &gclk_chan_conf); - system_gclk_chan_enable(AC_GCLK_ID_DIG); - gclk_chan_conf.source_generator = config->ana_source_generator; - system_gclk_chan_set_config(AC_GCLK_ID_ANA, &gclk_chan_conf); - system_gclk_chan_enable(AC_GCLK_ID_ANA); - } -#if (AC_INST_NUM == 2) - else if (hw == AC1) { - system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_AC1); - gclk_chan_conf.source_generator = config->dig_source_generator; - system_gclk_chan_set_config(AC1_GCLK_ID_DIG, &gclk_chan_conf); - system_gclk_chan_enable(AC1_GCLK_ID_DIG); - gclk_chan_conf.source_generator = config->ana_source_generator; - system_gclk_chan_set_config(AC1_GCLK_ID_ANA, &gclk_chan_conf); - system_gclk_chan_enable(AC1_GCLK_ID_ANA); - } -#elif (AC_INST_NUM >= 3) -# error This driver is not support more than three AC instances. -#endif - -#if AC_CALLBACK_MODE == true - /* Initialize parameters */ - for (uint8_t i = 0; i < AC_CALLBACK_N; i++) { - module_inst->callback[i] = NULL; - } - - /* Initialize software flags*/ - module_inst->register_callback_mask = 0x00; - module_inst->enable_callback_mask = 0x00; - -# if (AC_INST_NUM == 1) - _ac_instance[0] = module_inst; -# else - /* Register this instance for callbacks*/ - _ac_instance[_ac_get_inst_index(hw)] = module_inst; -# endif -#endif - - /* Write configuration to module */ - return _ac_set_config(module_inst, config); -} - -/** \brief Writes an Analog Comparator channel configuration to the hardware module. - * - * Writes a given Analog Comparator channel configuration to the hardware - * module. - * - * \param[in] module_inst Software instance for the Analog Comparator peripheral - * \param[in] channel Analog Comparator channel to configure - * \param[in] config Pointer to the channel configuration struct - */ -enum status_code ac_chan_set_config( - struct ac_module *const module_inst, - const enum ac_chan_channel channel, - struct ac_chan_config *const config) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - Assert(config); - - Ac *const ac_module = module_inst->hw; - - /* Use a temporary variable to compute the comparator configuration */ - uint32_t compctrl_temp = 0; - - /* Enable output filter mode */ - compctrl_temp |= config->filter; - - /* Enable output hysteresis if required */ - if (config->enable_hysteresis == true) { - compctrl_temp |= AC_COMPCTRL_HYST; - } - - /* Set output signal routing mode */ - compctrl_temp |= config->output_mode; - - /* Configure comparator positive and negative pin MUX configurations */ - compctrl_temp |= - (uint32_t)config->positive_input | - (uint32_t)config->negative_input; - - /* Set sampling mode (single shot or continuous) */ - compctrl_temp |= config->sample_mode; - - /* Set channel interrupt selection */ - compctrl_temp |= config->interrupt_selection; - - while (ac_is_syncing(module_inst)) { - /* Wait until synchronization is complete */ - } - - /* Write the final configuration to the module's control register */ - ac_module->COMPCTRL[(uint8_t)channel].reg = compctrl_temp; - - /* Configure VCC voltage scaling for the comparator */ - ac_module->SCALER[(uint8_t)channel].reg = config->vcc_scale_factor - 1; - - return STATUS_OK; -} - -/** - * \brief Function used to setup interrupt selection of a window - * - * This function is used to setup when an interrupt should occur - * for a given window. - * - * \note This must be done before enabling the channel. - * - * \param[in] module_inst Pointer to software instance struct - * \param[in] win_channel Window channel to setup - * \param[in] config Configuration for the given window channel - * - * \retval STATUS_OK Function exited successful - * \retval STATUS_ERR_INVALID_ARG win_channel argument incorrect - */ -enum status_code ac_win_set_config( - struct ac_module *const module_inst, - enum ac_win_channel const win_channel, - struct ac_win_config *const config) -{ - Assert(module_inst); - Assert(module_inst->hw); - Assert(config); - - uint8_t winctrl_mask; - - winctrl_mask = module_inst->hw->WINCTRL.reg; - - if (win_channel == AC_WIN_CHANNEL_0) { - winctrl_mask &= ~AC_WINCTRL_WINTSEL0_Msk; - winctrl_mask |= config->interrupt_selection; - } -#if (AC_PAIRS > 1) - else if (win_channel == AC_WIN_CHANNEL_1) { - winctrl_mask &= ~AC_WINCTRL_WINTSEL1_Msk; - winctrl_mask = (config->interrupt_selection << (AC_WINCTRL_WINTSEL1_Pos - - AC_WINCTRL_WINTSEL0_Pos); - } -#endif /* (AC_PAIRS > 1) */ - else { - return STATUS_ERR_INVALID_ARG ; - } - - module_inst->hw->WINCTRL.reg = winctrl_mask; - - return STATUS_OK; -} - -/** \brief Enables an Analog Comparator window channel that was previously configured. - * - * Enables and starts an Analog Comparator window channel. - * - * \note The comparator channels used by the window channel must be configured - * and enabled before calling this function. The two comparator channels - * forming each window comparator pair must have identical configurations - * other than the negative pin multiplexer setting. - * - * \param[in] module_inst Software instance for the Analog Comparator peripheral - * \param[in] win_channel Comparator window channel to enable - * - * \return Status of the window enable procedure. - * - * \retval STATUS_OK The window comparator was enabled - * \retval STATUS_ERR_IO One or both comparators in the window - * comparator pair is disabled - * \retval STATUS_ERR_BAD_FORMAT The comparator channels in the window pair - * were not configured correctly - */ -enum status_code ac_win_enable( - struct ac_module *const module_inst, - const enum ac_win_channel win_channel) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - Ac *const ac_module = module_inst->hw; - - /* Load the configurations of the two comparators used in the window */ - uint32_t win_pair_comp0_conf = ac_module->COMPCTRL[win_channel * 2].reg; - uint32_t win_pair_comp1_conf = ac_module->COMPCTRL[win_channel * 2 + 1].reg; - - /* Make sure both comparators in the window comparator pair are enabled */ - if (!(win_pair_comp0_conf & AC_COMPCTRL_ENABLE) || - !(win_pair_comp1_conf & AC_COMPCTRL_ENABLE)) { - return STATUS_ERR_IO; - } - - /* Make sure the comparators are configured in the same way, other than the - * negative pin multiplexers */ - if ((win_pair_comp0_conf & ~AC_COMPCTRL_MUXNEG_Msk) != - (win_pair_comp1_conf & ~AC_COMPCTRL_MUXNEG_Msk)) { - return STATUS_ERR_BAD_FORMAT; - } - - while (ac_is_syncing(module_inst)) { - /* Wait until synchronization is complete */ - } - - /* Enable the requested window comparator */ - switch (win_channel) - { - case AC_WIN_CHANNEL_0: - ac_module->WINCTRL.reg |= AC_WINCTRL_WEN0; - break; - -#if (AC_PAIRS > 1) - case AC_WIN_CHANNEL_1: - ac_module->WINCTRL.reg |= AC_WINCTRL_WEN1; - break; -#endif - } - - return STATUS_OK; -} - -/** \brief Disables an Analog Comparator window channel that was previously enabled. - * - * Stops an Analog Comparator window channel that was previously started via a - * call to \ref ac_win_enable(). - * - * \param[in] module_inst Software instance for the Analog Comparator peripheral - * \param[in] win_channel Comparator window channel to disable - */ -void ac_win_disable( - struct ac_module *const module_inst, - const enum ac_win_channel win_channel) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - Ac *const ac_module = module_inst->hw; - - while (ac_is_syncing(module_inst)) { - /* Wait until synchronization is complete */ - } - - /* Disable the requested window comparator */ - switch (win_channel) - { - case AC_WIN_CHANNEL_0: - ac_module->WINCTRL.reg &= ~AC_WINCTRL_WEN0; - break; - -#if (AC_PAIRS > 1) - case AC_WIN_CHANNEL_1: - ac_module->WINCTRL.reg &= ~AC_WINCTRL_WEN1; - break; -#endif - } -} - -/** \brief Determines the state of a specified Window Comparator. - * - * Retrieves the current window detection state, indicating what the input - * signal is currently comparing to relative to the window boundaries. - * - * \param[in] module_inst Software instance for the Analog Comparator peripheral - * \param[in] win_channel Comparator Window channel to test - * - * \return Bit mask of Analog Comparator window channel status flags. - */ -uint8_t ac_win_get_status( - struct ac_module *const module_inst, - const enum ac_win_channel win_channel) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - Ac *const ac_module = module_inst->hw; - - uint32_t win_status = 0; - - /* Check if interrupt flag is set */ - if (ac_module->INTFLAG.reg & (AC_INTFLAG_WIN0 << win_channel)) { - win_status |= AC_WIN_STATUS_INTERRUPT_SET; - } - - /* If one or both window comparators not ready, return unknown result */ - if (ac_win_is_ready(module_inst, win_channel) == false) { - win_status |= AC_WIN_STATUS_UNKNOWN; - return win_status; - } - - uint8_t statusa_tmp = ac_module->STATUSA.reg; - - /* Map hardware comparison states to logical window states */ - if (statusa_tmp & (AC_STATUSA_WSTATE0_BELOW << win_channel)) { - return win_status | AC_WIN_STATUS_BELOW; - } else if (statusa_tmp & (AC_STATUSA_WSTATE0_INSIDE << win_channel)) { - return win_status | AC_WIN_STATUS_INSIDE; - } else { - return win_status | AC_WIN_STATUS_ABOVE; - } - -}