mbed library sources
Fork of mbed-src by
Diff: targets/hal/TARGET_Atmel/TARGET_SAM21/drivers/tc/tc.h
- Revision:
- 613:bc40b8d2aec4
- Parent:
- 612:fba1c7dc54c0
- Child:
- 614:9d86c2ae5de0
--- a/targets/hal/TARGET_Atmel/TARGET_SAM21/drivers/tc/tc.h Tue Aug 18 15:00:09 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1669 +0,0 @@ -#ifndef TC_H_INCLUDED -#define TC_H_INCLUDED - -/** - * \defgroup asfdoc_sam0_tc_group SAM Timer/Counter Driver (TC) - * - * This driver for Atmel庐 | SMART SAM devices provides an interface for the configuration - * and management of the timer modules within the device, for waveform - * generation and timing operations. The following driver API modes are covered - * by this manual: - * - * - Polled APIs - * \if TC_CALLBACK_MODE - * - Callback APIs - * \endif - * - * - * The following peripherals are used by this module: - * - TC (Timer/Counter) - * - * 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 - * - * The outline of this documentation is as follows: - * - \ref asfdoc_sam0_tc_prerequisites - * - \ref asfdoc_sam0_tc_module_overview - * - \ref asfdoc_sam0_tc_special_considerations - * - \ref asfdoc_sam0_tc_extra_info - * - \ref asfdoc_sam0_tc_examples - * - \ref asfdoc_sam0_tc_api_overview - * - * - * \section asfdoc_sam0_tc_prerequisites Prerequisites - * - * There are no prerequisites for this module. - * - * - * \section asfdoc_sam0_tc_module_overview Module Overview - * - * The Timer/Counter (TC) module provides a set of timing and counting related - * functionality, such as the generation of periodic waveforms, the capturing - * of a periodic waveform's frequency/duty cycle, and software timekeeping for - * periodic operations. TC modules can be configured to use an 8-, 16-, or - * 32-bit counter size. - * - * This TC module for the SAM is capable of the following functions: - * - * - Generation of PWM signals - * - Generation of timestamps for events - * - General time counting - * - Waveform period capture - * - Waveform frequency capture - * - * \ref asfdoc_sam0_tc_block_diagram "The diagram below" shows the overview - * of the TC module design. - * - * \anchor asfdoc_sam0_tc_block_diagram - * \image html overview.svg "Basic Overview of the TC Module" - * - * - * \subsection asfdoc_sam0_tc_features Driver Feature Macro Definition - * <table> - * <tr> - * <th>Driver Feature Macro</th> - * <th>Supported devices</th> - * </tr> - * <tr> - * <td>FEATURE_TC_DOUBLE_BUFFERED</td> - * <td>SAML21</td> - * </tr> - * <tr> - * <td>FEATURE_TC_SYNCBUSY_SCHEME_VERSION_2</td> - * <td>SAML21</td> - * </tr> - * <tr> - * <td>FEATURE_TC_STAMP_PW_CAPTURE</td> - * <td>SAML21</td> - * </tr> - * <tr> - * <td>FEATURE_TC_READ_SYNC</td> - * <td>SAML21</td> - * </tr> - * <tr> - * <td>FEATURE_TC_IO_CAPTURE</td> - * <td>SAML21</td> - * </tr> - * </table> - * \note The specific features are only available in the driver when the - * selected device supports those features. - * - * \subsection asfdoc_sam0_tc_module_overview_func_desc Functional Description - * Independent of the configured counter size, each TC module can be set up - * in one of two different modes; capture and compare. - * - * In capture mode, the counter value is stored when a configurable event - * occurs. This mode can be used to generate timestamps used in event capture, - * or it can be used for the measurement of a periodic input signal's - * frequency/duty cycle. - * - * In compare mode, the counter value is compared against one or more of the - * configured channel compare values. When the counter value coincides with a - * compare value an action can be taken automatically by the module, such as - * generating an output event or toggling a pin when used for frequency or PWM - * signal generation. - * - * \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. - * - * \subsection asfdoc_sam0_tc_module_overview_tc_size Timer/Counter Size - * Each timer module can be configured in one of three different counter - * sizes; 8-, 16-, and 32-bit. The size of the counter determines the maximum - * value it can count to before an overflow occurs and the count is reset back - * to zero. \ref asfdoc_sam0_tc_count_size_vs_top "The table below" shows the - * maximum values for each of the possible counter sizes. - * - * \anchor asfdoc_sam0_tc_count_size_vs_top - * <table> - * <caption>Timer Counter Sizes and Their Maximum Count Values</caption> - * <tr> - * <th>Counter size</th> - * <th>Max. (hexadecimal)</th> - * <th>Max. (decimal)</th> - * </tr> - * <tr> - * <td>8-bit</td> - * <td>0xFF</td> - * <td>255</td> - * </tr> - * <tr> - * <td>16-bit</td> - * <td>0xFFFF</td> - * <td>65,535</td> - * </tr> - * <tr> - * <td>32-bit</td> - * <td>0xFFFFFFFF</td> - * <td>4,294,967,295</td> - * </tr> - * </table> - * - * When using the counter in 16- or 32-bit count mode, Compare Capture - * register 0 (CC0) is used to store the period value when running in PWM - * generation match mode. - * - * When using 32-bit counter size, two 16-bit counters are chained together - * in a cascade formation. Except in SAM D10/D11, Even numbered TC modules - * (e.g. TC0, TC2) can be configured as 32-bit counters. The odd numbered - * counters will act as slaves to the even numbered masters, and will not - * be reconfigurable until the master timer is disabled. The pairing of timer - * modules for 32-bit mode is shown in \ref asfdoc_sam0_tc_module_ms_pairs - * "the table below". - * - * \anchor asfdoc_sam0_tc_module_ms_pairs - * <table> - * <caption>TC Master and Slave Module Pairings</caption> - * <tr> - * <th>Master TC Module</th> - * <th>Slave TC Module</th> - * </tr> - * <tr> - * <td>TC0</td> - * <td>TC1</td> - * </tr> - * <tr> - * <td>TC2</td> - * <td>TC3</td> - * </tr> - * <tr> - * <td>...</td> - * <td>...</td> - * </tr> - * <tr> - * <td>TCn-1</td> - * <td>TCn</td> - * </tr> - * </table> - * - * In SAMD10/D11, odd numbered TC modules (e.g. TC1) can be configured as 32-bit - * counters. The even numbered(e.g. TC2) counters will act as slaves to the odd - * numbered masters. - * - * \subsection asfdoc_sam0_tc_module_overview_clock Clock Settings - * - * \subsubsection asfdoc_sam0_tc_module_overview_clock_selection Clock Selection - * Each TC peripheral is clocked asynchronously to the system clock by a GCLK - * (Generic Clock) channel. The GCLK channel connects to any of the GCLK - * generators. The GCLK generators are configured to use one of the available - * clock sources on the system such as internal oscillator, external crystals, - * etc. see the \ref asfdoc_sam0_system_clock_group "Generic Clock driver" - *for - * more information. - * - * \subsubsection asfdoc_sam0_tc_module_overview_clock_prescaler Prescaler - * Each TC module in the SAM has its own individual clock prescaler, which - * can be used to divide the input clock frequency used in the counter. This - * prescaler only scales the clock used to provide clock pulses for the counter - * to count, and does not affect the digital register interface portion of - * the module, thus the timer registers will synchronize to the raw GCLK - * frequency input to the module. - * - * As a result of this, when selecting a GCLK frequency and timer prescaler - * value the user application should consider both the timer resolution - * required and the synchronization frequency, to avoid lengthy - * synchronization times of the module if a very slow GCLK frequency is fed - * into the TC module. It is preferable to use a higher module GCLK frequency - * as the input to the timer, and prescale this down as much as possible to - * obtain a suitable counter frequency in latency-sensitive applications. - * - * \subsubsection asfdoc_sam0_tc_module_overview_clock_reloading Reloading - * Timer modules also contain a configurable reload action, used when a - * re-trigger event occurs. Examples of a re-trigger event are the counter - * reaching the maximum value when counting up, or when an event from the event - * system tells the counter to re-trigger. The reload action determines if the - * prescaler should be reset, and when this should happen. The counter will - * always be reloaded with the value it is set to start counting from. The user - * can choose between three different reload actions, described in - * \ref asfdoc_sam0_tc_module_reload_act "the table below". - * - * \anchor asfdoc_sam0_tc_module_reload_act - * <table> - * <caption>TC Module Reload Actions</caption> - * <tr> - * <th>Reload action</th> - * <th>Description</th> - * </tr> - * <tr> - * <td>\ref TC_RELOAD_ACTION_GCLK </td> - * <td>Reload TC counter value on next GCLK cycle. Leave prescaler - * as-is.</td> - * </tr> - * <tr> - * <td>\ref TC_RELOAD_ACTION_PRESC </td> - * <td>Reloads TC counter value on next prescaler clock. Leave prescaler - * as-is.</td> - * </tr> - * <tr> - * <td> \ref TC_RELOAD_ACTION_RESYNC </td> - * <td>Reload TC counter value on next GCLK cycle. Clear prescaler to - * zero.</td> - * </tr> - * </table> - * - * The reload action to use will depend on the specific application being - * implemented. One example is when an external trigger for a reload occurs; if - * the TC uses the prescaler, the counter in the prescaler should not have a - * value between zero and the division factor. The TC counter and the counter - * in the prescaler should both start at zero. When the counter is set to - * re-trigger when it reaches the maximum value on the other hand, this is not the - * right option to use. In such a case it would be better if the prescaler is - * left unaltered when the re-trigger happens, letting the counter reset on the - * next GCLK cycle. - * - * \subsection asfdoc_sam0_tc_module_overview_compare_match Compare Match Operations - * In compare match operation, Compare/Capture registers are used in comparison - * with the counter value. When the timer's count value matches the value of a - * compare channel, a user defined action can be taken. - * - * \subsubsection asfdoc_sam0_tc_module_overview_compare_match_timer Basic Timer - * - * A Basic Timer is a simple application where compare match operations is used - * to determine when a specific period has elapsed. In Basic Timer operations, - * one or more values in the module's Compare/Capture registers are used to - * specify the time (as a number of prescaled GCLK cycles) when an action should - * be taken by the microcontroller. This can be an Interrupt Service Routine - * (ISR), event generator via the event system, or a software flag that is - * polled via the user application. - * - * \subsubsection asfdoc_sam0_tc_module_overview_compare_match_wg Waveform Generation - * - * Waveform generation enables the TC module to generate square waves, or if - * combined with an external passive low-pass filter; analog waveforms. - * - * \subsubsection asfdoc_sam0_tc_module_overview_compare_match_wg_pwm Waveform Generation - PWM - * - * Pulse width modulation is a form of waveform generation and a signalling - * technique that can be useful in many situations. When PWM mode is used, - * a digital pulse train with a configurable frequency and duty cycle can be - * generated by the TC module and output to a GPIO pin of the device. - * - * Often PWM is used to communicate a control or information parameter to an - * external circuit or component. Differing impedances of the source generator - * and sink receiver circuits is less of an issue when using PWM compared to - * using an analog voltage value, as noise will not generally affect the - * signal's integrity to a meaningful extent. - * - * \ref asfdoc_sam0_tc_module_pwm_normal_diag "The figure below" illustrates - * operations and different states of the counter and its output when running - * the counter in PWM normal mode. As can be seen, the TOP value is unchanged - * and is set to MAX. The compare match value is changed at several points to - * illustrate the resulting waveform output changes. The PWM output is set to - * normal (i.e. non-inverted) output mode. - * - * \anchor asfdoc_sam0_tc_module_pwm_normal_diag - * \image html pwm_normal_ex.svg "Example of PWM in Normal Mode, and Different Counter Operations" - * - * - * In \ref asfdoc_sam0_tc_module_pwm_match_diag "the figure below", the - * counter is set to generate PWM in Match mode. The PWM output is inverted via - * the appropriate configuration option in the TC driver configuration - * structure. In this example, the counter value is changed once, but the - * compare match value is kept unchanged. As can be seen, it is possible to - * change the TOP value when running in PWM match mode. - * - * \anchor asfdoc_sam0_tc_module_pwm_match_diag - * \image html pwm_match_ex.svg "Example of PWM in Match Mode, and Different Counter Operations" - * - * \subsubsection asfdoc_sam0_tc_module_overview_compare_match_wg_freq Waveform Generation - Frequency - * - * Frequency Generation mode is in many ways identical to PWM - * generation. However, in Frequency Generation a toggle only occurs - * on the output when a match on a capture channels occurs. When the - * match is made, the timer value is reset, resulting in a variable - * frequency square wave with a fixed 50% duty cycle. - * - * \subsubsection asfdoc_sam0_tc_module_overview_compare_match_capt Capture Operations - * - * In capture operations, any event from the event system or a pin change can - * trigger a capture of the counter value. This captured counter value can be - * used as a timestamp for the event, or it can be used in frequency and pulse - * width capture. - * - * \subsubsection asfdoc_sam0_tc_module_overview_compare_match_capt_event_capture Capture Operations - Event - * - * Event capture is a simple use of the capture functionality, - * designed to create timestamps for specific events. When the TC - * module's input capture pin is externally toggled, the current timer - * count value is copied into a buffered register which can then be - * read out by the user application. - * - * Note that when performing any capture operation, there is a risk that the - * counter reaches its top value (MAX) when counting up, or the bottom value - * (zero) when counting down, before the capture event occurs. This can distort - * the result, making event timestamps to appear shorter than reality; the - * user application should check for timer overflow when reading a capture - * result in order to detect this situation and perform an appropriate - * adjustment. - * - * Before checking for a new capture, \ref TC_STATUS_COUNT_OVERFLOW - * should be checked. The response to an overflow error is left to the user - * application, however it may be necessary to clear both the capture overflow - * flag and the capture flag upon each capture reading. - * - * \subsubsection asfdoc_sam0_tc_module_overview_compare_match_capt_pwc Capture Operations - Pulse Width - * - * Pulse Width Capture mode makes it possible to measure the pulse width and - * period of PWM signals. This mode uses two capture channels of the counter. - * This means that the counter module used for Pulse Width Capture can not be - * used for any other purpose. There are two modes for pulse width capture; - * Pulse Width Period (PWP) and Period Pulse Width (PPW). In PWP mode, capture - * channel 0 is used for storing the pulse width and capture channel 1 stores - * the observed period. While in PPW mode, the roles of the two capture channels - * is reversed. - * - * As in the above example it is necessary to poll on interrupt flags to see - * if a new capture has happened and check that a capture overflow error has - * not occurred. - * - * \subsection asfdoc_sam0_tc_module_overview_oneshot One-shot Mode - * - * TC modules can be configured into a one-shot mode. When configured in this - * manner, starting the timer will cause it to count until the next overflow - * or underflow condition before automatically halting, waiting to be manually - * triggered by the user application software or an event signal from the event - * system. - * - * \subsubsection asfdoc_sam0_tc_module_overview_inversion Wave Generation Output Inversion - * - * The output of the wave generation can be inverted by hardware if desired, - * resulting in the logically inverted value being output to the configured - * device GPIO pin. - * - * - * \section asfdoc_sam0_tc_special_considerations Special Considerations - * - * The number of capture compare registers in each TC module is dependent on - * the specific SAM device being used, and in some cases the counter size. - * - * The maximum amount of capture compare registers available in any SAM - * device is two when running in 32-bit mode and four in 8- and 16-bit modes. - * - * - * \section asfdoc_sam0_tc_extra_info Extra Information - * - * For extra information, see \ref asfdoc_sam0_tc_extra. This includes: - * - \ref asfdoc_sam0_tc_extra_acronyms - * - \ref asfdoc_sam0_tc_extra_dependencies - * - \ref asfdoc_sam0_tc_extra_errata - * - \ref asfdoc_sam0_tc_extra_history - * - * - * \section asfdoc_sam0_tc_examples Examples - * - * For a list of examples related to this driver, see - * \ref asfdoc_sam0_tc_exqsg. - * - * \section asfdoc_sam0_tc_api_overview API Overview - * @{ - */ - -#include <compiler.h> -#include <clock.h> -#include <gclk.h> -#include <pinmux.h> - -/** - * Define port features set according to different device family - * @{ -*/ -#if (SAML21) || defined(__DOXYGEN__) -/** TC double buffered */ -# define FEATURE_TC_DOUBLE_BUFFERED -/** SYNCBUSY scheme version 2 */ -# define FEATURE_TC_SYNCBUSY_SCHEME_VERSION_2 -/** TC time stamp capture and pulse width capture */ -# define FEATURE_TC_STAMP_PW_CAPTURE -/** Read synchronization of COUNT*/ -# define FEATURE_TC_READ_SYNC -/** IO pin edge capture*/ -# define FEATURE_TC_IO_CAPTURE -#endif -/*@}*/ - -#if !defined(__DOXYGEN__) -#if SAMD20 || SAML21 -# define TC_INSTANCE_OFFSET 0 -#endif -#if defined(SAMD21) || defined(SAMR21) -//#if SAMD21 || SAMR21 -# define TC_INSTANCE_OFFSET 3 -#endif -#if SAMD10 || SAMD11 -# define TC_INSTANCE_OFFSET 1 -#endif - -#if SAMD20 -# define NUMBER_OF_COMPARE_CAPTURE_CHANNELS TC0_CC8_NUM -#elif SAML21 -# define NUMBER_OF_COMPARE_CAPTURE_CHANNELS TC0_CC_NUM -#elif SAMD10 || SAMD11 -# define NUMBER_OF_COMPARE_CAPTURE_CHANNELS TC1_CC8_NUM -#else -# define NUMBER_OF_COMPARE_CAPTURE_CHANNELS TC3_CC8_NUM -/* Same number for 8-, 16- and 32-bit TC and all TC instances */ -#endif - -/** TC Instance MAX ID Number. */ -#if SAMD20E || SAMD21G || SAMD21E || SAMR21 -#define TC_INST_MAX_ID 5 -#elif SAML21 -#define TC_INST_MAX_ID 4 -#elif SAMD10 || SAMD11 -#define TC_INST_MAX_ID 2 -#else -#define TC_INST_MAX_ID 7 -#endif - -#endif - -//#if TC_ASYNC == true // TEMP: Commented by V -# include <system_interrupt.h> -//#endif - -#ifdef __cplusplus -extern "C" { -#endif - -//#if TC_ASYNC == true // TEMP: Commented by V -/** Enum for the possible callback types for the TC module. */ -enum tc_callback { - /** Callback for TC overflow. */ - TC_CALLBACK_OVERFLOW, - /** Callback for capture overflow error. */ - TC_CALLBACK_ERROR, - /** Callback for capture compare channel 0. */ - TC_CALLBACK_CC_CHANNEL0, - /** Callback for capture compare channel 1. */ - TC_CALLBACK_CC_CHANNEL1, -# if !defined(__DOXYGEN__) - /** Number of available callbacks. */ - TC_CALLBACK_N, -# endif -}; -//#endif - -/** - * \name Module Status Flags - * - * TC status flags, returned by \ref tc_get_status() and cleared by - * \ref tc_clear_status(). - * - * @{ - */ - -/** Timer channel 0 has matched against its compare value, or has captured a - * new value. - */ -#define TC_STATUS_CHANNEL_0_MATCH (1UL << 0) - -/** Timer channel 1 has matched against its compare value, or has captured a - * new value. - */ -#define TC_STATUS_CHANNEL_1_MATCH (1UL << 1) - -/** Timer register synchronization has completed, and the synchronized count - * value may be read. - */ -#define TC_STATUS_SYNC_READY (1UL << 2) - -/** A new value was captured before the previous value was read, resulting in - * lost data. - */ -#define TC_STATUS_CAPTURE_OVERFLOW (1UL << 3) - -/** The timer count value has overflowed from its maximum value to its minimum - * when counting upward, or from its minimum value to its maximum when - * counting downward. - */ -#define TC_STATUS_COUNT_OVERFLOW (1UL << 4) - -#ifdef FEATURE_TC_DOUBLE_BUFFERED -/** Channel 0 compare or capture buffer valid. */ -#define TC_STATUS_CHN0_BUFFER_VALID (1UL << 5) -/** Channel 1 compare or capture buffer valid. */ -#define TC_STATUS_CHN1_BUFFER_VALID (1UL << 6) -/** Period buffer valid. */ -#define TC_STATUS_PERIOD_BUFFER_VALID (1UL << 7) -#endif -/** @} */ - -/** - * \brief Index of the compare capture channels. - * - * This enum is used to specify which capture/compare channel to do - * operations on. - */ -enum tc_compare_capture_channel { - /** Index of compare capture channel 0. */ - TC_COMPARE_CAPTURE_CHANNEL_0, - /** Index of compare capture channel 1. */ - TC_COMPARE_CAPTURE_CHANNEL_1, -}; - -/** TC wave generation mode. */ -#if SAML21 -#define TC_WAVE_GENERATION_NORMAL_FREQ_MODE TC_WAVE_WAVEGEN_NFRQ -#define TC_WAVE_GENERATION_MATCH_FREQ_MODE TC_WAVE_WAVEGEN_MFRQ -#define TC_WAVE_GENERATION_NORMAL_PWM_MODE TC_WAVE_WAVEGEN_NPWM -#define TC_WAVE_GENERATION_MATCH_PWM_MODE TC_WAVE_WAVEGEN_MPWM -#else -#define TC_WAVE_GENERATION_NORMAL_FREQ_MODE TC_CTRLA_WAVEGEN_NFRQ -#define TC_WAVE_GENERATION_MATCH_FREQ_MODE TC_CTRLA_WAVEGEN_MFRQ -#define TC_WAVE_GENERATION_NORMAL_PWM_MODE TC_CTRLA_WAVEGEN_NPWM -#define TC_WAVE_GENERATION_MATCH_PWM_MODE TC_CTRLA_WAVEGEN_MPWM -#endif - -/** - * \brief TC wave generation mode enum. - * - * This enum is used to select which mode to run the wave - * generation in. - * - */ -enum tc_wave_generation { - /** Top is maximum, except in 8-bit counter size where it is the PER - * register. - */ - TC_WAVE_GENERATION_NORMAL_FREQ = TC_WAVE_GENERATION_NORMAL_FREQ_MODE, - - /** Top is CC0, except in 8-bit counter size where it is the PER - * register. - */ - TC_WAVE_GENERATION_MATCH_FREQ = TC_WAVE_GENERATION_MATCH_FREQ_MODE, - - /** Top is maximum, except in 8-bit counter size where it is the PER - * register. - */ - TC_WAVE_GENERATION_NORMAL_PWM = TC_WAVE_GENERATION_NORMAL_PWM_MODE, - - /** Top is CC0, except in 8-bit counter size where it is the PER - * register. - */ - TC_WAVE_GENERATION_MATCH_PWM = TC_WAVE_GENERATION_MATCH_PWM_MODE, -}; - -/** - * \brief Specifies if the counter is 8-, 16-, or 32-bit. - * - * This enum specifies the maximum value it is possible to count to. - */ -enum tc_counter_size { - /** The counter's maximum value is 0xFF, the period register is - * available to be used as top value. - */ - TC_COUNTER_SIZE_8BIT = TC_CTRLA_MODE_COUNT8, - - /** The counter's maximum value is 0xFFFF. There is no separate - * period register, to modify top one of the capture compare - * registers has to be used. This limits the amount of - * available channels. - */ - TC_COUNTER_SIZE_16BIT = TC_CTRLA_MODE_COUNT16, - - /** The counter's maximum value is 0xFFFFFFFF. There is no separate - * period register, to modify top one of the capture compare - * registers has to be used. This limits the amount of - * available channels. - */ - TC_COUNTER_SIZE_32BIT = TC_CTRLA_MODE_COUNT32, -}; - -/** - * \brief TC Counter reload action enum. - * - * This enum specify how the counter and prescaler should reload. - */ -enum tc_reload_action { - /** The counter is reloaded/reset on the next GCLK and starts - * counting on the prescaler clock. - */ - TC_RELOAD_ACTION_GCLK = TC_CTRLA_PRESCSYNC_GCLK, - - /** The counter is reloaded/reset on the next prescaler clock. - */ - TC_RELOAD_ACTION_PRESC = TC_CTRLA_PRESCSYNC_PRESC, - - /** The counter is reloaded/reset on the next GCLK, and the - * prescaler is restarted as well. - */ - TC_RELOAD_ACTION_RESYNC = TC_CTRLA_PRESCSYNC_RESYNC, -}; - -/** - * \brief TC clock prescaler values. - * - * This enum is used to choose the clock prescaler - * configuration. The prescaler divides the clock frequency of the TC - * module to make the counter count slower. - */ -enum tc_clock_prescaler { - /** Divide clock by 1. */ - TC_CLOCK_PRESCALER_DIV1 = TC_CTRLA_PRESCALER(0), - /** Divide clock by 2. */ - TC_CLOCK_PRESCALER_DIV2 = TC_CTRLA_PRESCALER(1), - /** Divide clock by 4. */ - TC_CLOCK_PRESCALER_DIV4 = TC_CTRLA_PRESCALER(2), - /** Divide clock by 8. */ - TC_CLOCK_PRESCALER_DIV8 = TC_CTRLA_PRESCALER(3), - /** Divide clock by 16. */ - TC_CLOCK_PRESCALER_DIV16 = TC_CTRLA_PRESCALER(4), - /** Divide clock by 64. */ - TC_CLOCK_PRESCALER_DIV64 = TC_CTRLA_PRESCALER(5), - /** Divide clock by 256. */ - TC_CLOCK_PRESCALER_DIV256 = TC_CTRLA_PRESCALER(6), - /** Divide clock by 1024. */ - TC_CLOCK_PRESCALER_DIV1024 = TC_CTRLA_PRESCALER(7), -}; - -/** - * \brief TC module count direction. - * - * Timer/Counter count direction. - */ -enum tc_count_direction { - /** Timer should count upward from zero to MAX. */ - TC_COUNT_DIRECTION_UP, - - /** Timer should count downward to zero from MAX. */ - TC_COUNT_DIRECTION_DOWN, -}; - -/** Waveform inversion mode. */ -#if SAML21 -#define TC_WAVEFORM_INVERT_CC0_MODE TC_DRVCTRL_INVEN(1) -#define TC_WAVEFORM_INVERT_CC1_MODE TC_DRVCTRL_INVEN(2) -#else -#define TC_WAVEFORM_INVERT_CC0_MODE TC_CTRLC_INVEN(1) -#define TC_WAVEFORM_INVERT_CC1_MODE TC_CTRLC_INVEN(2) -#endif - -/** - * \brief Waveform inversion mode. - * - * Output waveform inversion mode. - */ -enum tc_waveform_invert_output { - /** No inversion of the waveform output. */ - TC_WAVEFORM_INVERT_OUTPUT_NONE = 0, - /** Invert output from compare channel 0. */ - TC_WAVEFORM_INVERT_OUTPUT_CHANNEL_0 = TC_WAVEFORM_INVERT_CC0_MODE, - /** Invert output from compare channel 1. */ - TC_WAVEFORM_INVERT_OUTPUT_CHANNEL_1 = TC_WAVEFORM_INVERT_CC1_MODE, -}; - -/** - * \brief Action to perform when the TC module is triggered by an event. - * - * Event action to perform when the module is triggered by an event. - */ -enum tc_event_action { - /** No event action. */ - TC_EVENT_ACTION_OFF = TC_EVCTRL_EVACT_OFF, - /** Re-trigger on event. */ - TC_EVENT_ACTION_RETRIGGER = TC_EVCTRL_EVACT_RETRIGGER, - /** Increment counter on event. */ - TC_EVENT_ACTION_INCREMENT_COUNTER = TC_EVCTRL_EVACT_COUNT, - /** Start counter on event. */ - TC_EVENT_ACTION_START = TC_EVCTRL_EVACT_START, - - /** Store period in capture register 0, pulse width in capture - * register 1. - */ - TC_EVENT_ACTION_PPW = TC_EVCTRL_EVACT_PPW, - - /** Store pulse width in capture register 0, period in capture - * register 1. - */ - TC_EVENT_ACTION_PWP = TC_EVCTRL_EVACT_PWP, -#ifdef FEATURE_TC_STAMP_PW_CAPTURE - /** Time stamp capture. */ - TC_EVENT_ACTION_STAMP = TC_EVCTRL_EVACT_STAMP, - /** Pulse width capture. */ - TC_EVENT_ACTION_PW = TC_EVCTRL_EVACT_PW, -#endif -}; - -/** - * \brief TC event enable/disable structure. - * - * Event flags for the \ref tc_enable_events() and \ref tc_disable_events(). - */ -struct tc_events { - /** Generate an output event on a compare channel match. */ - bool generate_event_on_compare_channel - [NUMBER_OF_COMPARE_CAPTURE_CHANNELS]; - /** Generate an output event on counter overflow. */ - bool generate_event_on_overflow; - /** Perform the configured event action when an incoming event is signalled. */ - bool on_event_perform_action; - /** Specifies if the input event source is inverted, when used in PWP or - * PPW event action modes. - */ - bool invert_event_input; - /** Specifies which event to trigger if an event is triggered. */ - enum tc_event_action event_action; -}; - -/** - * \brief Configuration struct for TC module in 8-bit size counter mode. - */ -struct tc_8bit_config { - /** Initial timer count value. */ - uint8_t value; - /** Where to count to or from depending on the direction on the counter. */ - uint8_t period; - /** Value to be used for compare match on each channel. */ - uint8_t compare_capture_channel[NUMBER_OF_COMPARE_CAPTURE_CHANNELS]; -}; - -/** - * \brief Configuration struct for TC module in 16-bit size counter mode. - */ -struct tc_16bit_config { - /** Initial timer count value. */ - uint16_t value; - /** Value to be used for compare match on each channel. */ - uint16_t compare_capture_channel[NUMBER_OF_COMPARE_CAPTURE_CHANNELS]; -}; - -/** - * \brief Configuration struct for TC module in 32-bit size counter mode. - */ -struct tc_32bit_config { - /** Initial timer count value. */ - uint32_t value; - /** Value to be used for compare match on each channel. */ - uint32_t compare_capture_channel[NUMBER_OF_COMPARE_CAPTURE_CHANNELS]; -}; - -/** - * \brief Configuration struct for TC module in 32-bit size counter mode. - */ -struct tc_pwm_channel { - /** When \c true, PWM output for the given channel is enabled. */ - bool enabled; - /** Specifies pin output for each channel. */ - uint32_t pin_out; - /** Specifies MUX setting for each output channel pin. */ - uint32_t pin_mux; -}; - -/** - * \brief TC configuration structure. - * - * Configuration struct for a TC instance. This structure should be - * initialized by the \ref tc_get_config_defaults function before being - * modified by the user application. - */ -struct tc_config { - /** GCLK generator used to clock the peripheral. */ - enum gclk_generator clock_source; - - /** When \c true the module is enabled during standby. */ - bool run_in_standby; -#if (SAML21) - /** Run on demand. */ - bool on_demand; -#endif - /** Specifies either 8-, 16-, or 32-bit counter size. */ - enum tc_counter_size counter_size; - /** Specifies the prescaler value for GCLK_TC. */ - enum tc_clock_prescaler clock_prescaler; - /** Specifies which waveform generation mode to use. */ - enum tc_wave_generation wave_generation; - - /** Specifies the reload or reset time of the counter and prescaler - * resynchronization on a re-trigger event for the TC. - */ - enum tc_reload_action reload_action; - - /** Specifies which channel(s) to invert the waveform on. - For SAML21, it's also used to invert IO input pin. */ - uint8_t waveform_invert_output; - - /** Specifies which channel(s) to enable channel capture - * operation on. - */ - bool enable_capture_on_channel[NUMBER_OF_COMPARE_CAPTURE_CHANNELS]; -#ifdef FEATURE_TC_IO_CAPTURE - /** Specifies which channel(s) to enable I/O capture - * operation on. - */ - bool enable_capture_on_IO[NUMBER_OF_COMPARE_CAPTURE_CHANNELS]; -#endif - - /** When \c true, one-shot will stop the TC on next hardware or software - * re-trigger event or overflow/underflow. - */ - bool oneshot; - - /** Specifies the direction for the TC to count. */ - enum tc_count_direction count_direction; - - /** Specifies the PWM channel for TC. */ - struct tc_pwm_channel pwm_channel[NUMBER_OF_COMPARE_CAPTURE_CHANNELS]; - - /** Access the different counter size settings though this configuration member. */ - union { - /** Struct for 8-bit specific timer configuration. */ - struct tc_8bit_config counter_8_bit; - /** Struct for 16-bit specific timer configuration. */ - struct tc_16bit_config counter_16_bit; - /** Struct for 32-bit specific timer configuration. */ - struct tc_32bit_config counter_32_bit; - }; - -#ifdef FEATURE_TC_DOUBLE_BUFFERED - /** Set to \c true to enable double buffering write. When enabled any write - * through \ref tc_set_top_value(), \ref tc_set_compare_value() and - * will direct to the buffer register as buffered - * value, and the buffered value will be committed to effective register - * on UPDATE condition, if update is not locked. - */ - bool double_buffering_enabled; -#endif -}; - - -//#if TC_ASYNC == true // TEMP: Commented by V -/* Forward Declaration for the device instance. */ -struct tc_module; - -/* Type of the callback functions. */ -typedef void (*tc_callback_t)(struct tc_module *const module); -//#endif - -/** - * \brief TC software device instance structure. - * - * TC 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 tc_module { -#if !defined(__DOXYGEN__) - /** Hardware module pointer of the associated Timer/Counter peripheral. */ - Tc *hw; - - /** Size of the initialized Timer/Counter module configuration. */ - enum tc_counter_size counter_size; -//# if TC_ASYNC == true // TEMP: Commented by V - /** Array of callbacks. */ - tc_callback_t callback[TC_CALLBACK_N]; - /** Bit mask for callbacks registered. */ - uint8_t register_callback_mask; - /** Bit mask for callbacks enabled. */ - uint8_t enable_callback_mask; -//# endif -#ifdef FEATURE_TC_DOUBLE_BUFFERED - /** Set to \c true to enable double buffering write. */ - bool double_buffering_enabled; -#endif -#endif -}; - -#if !defined(__DOXYGEN__) -uint8_t _tc_get_inst_index( - Tc *const hw); -#endif - -/** - * \name Driver Initialization and Configuration - * @{ - */ - -/** - * \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 software module instance struct - * - * \return Synchronization status of the underlying hardware module(s). - * - * \retval false If the module has completed synchronization - * \retval true If the module synchronization is ongoing - */ -static inline bool tc_is_syncing( - const struct tc_module *const module_inst) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - /* Get a pointer to the module's hardware instance */ - TcCount8 *const tc_module = &(module_inst->hw->COUNT8); - -#if (SAML21) - return (tc_module->SYNCBUSY.reg); -#else - return (tc_module->STATUS.reg & TC_STATUS_SYNCBUSY); -#endif -} - -/** - * \brief Initializes config with predefined default values. - * - * This function will initialize a given TC configuration structure to - * a set of known default values. This function should be called on - * any new instance of the configuration structures before being - * modified by the user application. - * - * The default configuration is as follows: - * \li GCLK generator 0 (GCLK main) clock source - * \li 16-bit counter size on the counter - * \li No prescaler - * \li Normal frequency wave generation - * \li GCLK reload action - * \li Don't run in standby - * \li Don't run on demand for SAML21 - * \li No inversion of waveform output - * \li No capture enabled - * \li No I/O capture enabled for SAML21 - * \li No event input enabled - * \li Count upward - * \li Don't perform one-shot operations - * \li No event action - * \li No channel 0 PWM output - * \li No channel 1 PWM output - * \li Counter starts on 0 - * \li Capture compare channel 0 set to 0 - * \li Capture compare channel 1 set to 0 - * \li No PWM pin output enabled - * \li Pin and MUX configuration not set - * \li Double buffer disabled (if have this feature) - * - * \param[out] config Pointer to a TC module configuration structure to set - */ -static inline void tc_get_config_defaults( - struct tc_config *const config) -{ - /* Sanity check arguments */ - Assert(config); - - /* Write default config to config struct */ - config->clock_source = GCLK_GENERATOR_0; - config->counter_size = TC_COUNTER_SIZE_16BIT; - config->clock_prescaler = TC_CLOCK_PRESCALER_DIV1; - config->wave_generation = TC_WAVE_GENERATION_NORMAL_FREQ; - config->reload_action = TC_RELOAD_ACTION_GCLK; - config->run_in_standby = false; -#if (SAML21) - config->on_demand = false; -#endif - config->waveform_invert_output = TC_WAVEFORM_INVERT_OUTPUT_NONE; - config->enable_capture_on_channel[TC_COMPARE_CAPTURE_CHANNEL_0] = false; - config->enable_capture_on_channel[TC_COMPARE_CAPTURE_CHANNEL_1] = false; -#ifdef FEATURE_TC_IO_CAPTURE - config->enable_capture_on_IO[TC_COMPARE_CAPTURE_CHANNEL_0] = false; - config->enable_capture_on_IO[TC_COMPARE_CAPTURE_CHANNEL_1] = false; -#endif - - config->count_direction = TC_COUNT_DIRECTION_UP; - config->oneshot = false; - - config->pwm_channel[TC_COMPARE_CAPTURE_CHANNEL_0].enabled = false; - config->pwm_channel[TC_COMPARE_CAPTURE_CHANNEL_0].pin_out = 0; - config->pwm_channel[TC_COMPARE_CAPTURE_CHANNEL_0].pin_mux = 0; - - config->pwm_channel[TC_COMPARE_CAPTURE_CHANNEL_1].enabled = false; - config->pwm_channel[TC_COMPARE_CAPTURE_CHANNEL_1].pin_out = 0; - config->pwm_channel[TC_COMPARE_CAPTURE_CHANNEL_1].pin_mux = 0; - - config->counter_16_bit.value = 0x0000; - config->counter_16_bit.compare_capture_channel\ - [TC_COMPARE_CAPTURE_CHANNEL_0] = 0x0000; - config->counter_16_bit.compare_capture_channel\ - [TC_COMPARE_CAPTURE_CHANNEL_1] = 0x0000; -#ifdef FEATURE_TC_DOUBLE_BUFFERED - config->double_buffering_enabled = false; -#endif - -} - -enum status_code tc_init( - struct tc_module *const module_inst, - Tc *const hw, - const struct tc_config *const config); - -/** @} */ - -/** - * \name Event Management - * @{ - */ - -/** - * \brief Enables a TC module event input or output. - * - * Enables one or more input or output events to or from the TC module. - * See \ref tc_events for a list of events this module supports. - * - * \note Events cannot be altered while the module is enabled. - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] events Struct containing flags of events to enable - */ -static inline void tc_enable_events( - struct tc_module *const module_inst, - struct tc_events *const events) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - Assert(events); - - Tc *const tc_module = module_inst->hw; - - uint32_t event_mask = 0; - - if (events->invert_event_input == true) { - event_mask |= TC_EVCTRL_TCINV; - } - - if (events->on_event_perform_action == true) { - event_mask |= TC_EVCTRL_TCEI; - } - - if (events->generate_event_on_overflow == true) { - event_mask |= TC_EVCTRL_OVFEO; - } - - for (uint8_t i = 0; i < NUMBER_OF_COMPARE_CAPTURE_CHANNELS; i++) { - if (events->generate_event_on_compare_channel[i] == true) { - event_mask |= (TC_EVCTRL_MCEO(1) << i); - } - } - - tc_module->COUNT8.EVCTRL.reg |= event_mask | events->event_action; -} - -/** - * \brief Disables a TC module event input or output. - * - * Disables one or more input or output events to or from the TC module. - * See \ref tc_events for a list of events this module supports. - * - * \note Events cannot be altered while the module is enabled. - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] events Struct containing flags of events to disable - */ -static inline void tc_disable_events( - struct tc_module *const module_inst, - struct tc_events *const events) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - Assert(events); - - Tc *const tc_module = module_inst->hw; - - uint32_t event_mask = 0; - - if (events->invert_event_input == true) { - event_mask |= TC_EVCTRL_TCINV; - } - - if (events->on_event_perform_action == true) { - event_mask |= TC_EVCTRL_TCEI; - } - - if (events->generate_event_on_overflow == true) { - event_mask |= TC_EVCTRL_OVFEO; - } - - for (uint8_t i = 0; i < NUMBER_OF_COMPARE_CAPTURE_CHANNELS; i++) { - if (events->generate_event_on_compare_channel[i] == true) { - event_mask |= (TC_EVCTRL_MCEO(1) << i); - } - } - - tc_module->COUNT8.EVCTRL.reg &= ~event_mask; -} - -/** @} */ - -/** - * \name Enable/Disable/Reset - * @{ - */ - -enum status_code tc_reset( - const struct tc_module *const module_inst); - -/** - * \brief Enable the TC module. - * - * Enables a TC module that has been previously initialized. The counter will - * start when the counter is enabled. - * - * \note When the counter is configured to re-trigger on an event, the counter - * will not start until the start function is used. - * - * \param[in] module_inst Pointer to the software module instance struct - */ -static inline void tc_enable( - const struct tc_module *const module_inst) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - /* Get a pointer to the module's hardware instance */ - TcCount8 *const tc_module = &(module_inst->hw->COUNT8); - - while (tc_is_syncing(module_inst)) { - /* Wait for sync */ - } - - /* Enable TC module */ - tc_module->CTRLA.reg |= TC_CTRLA_ENABLE; -} - -/** - * \brief Disables the TC module. - * - * Disables a TC module and stops the counter. - * - * \param[in] module_inst Pointer to the software module instance struct - */ -static inline void tc_disable( - const struct tc_module *const module_inst) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - /* Get a pointer to the module's hardware instance */ - TcCount8 *const tc_module = &(module_inst->hw->COUNT8); - - while (tc_is_syncing(module_inst)) { - /* Wait for sync */ - } - - /* Disable TC module */ - tc_module->CTRLA.reg &= ~TC_CTRLA_ENABLE; -} - -/** @} */ - -/** - * \name Get/Set Count Value - * @{ - */ - -uint32_t tc_get_count_value( - const struct tc_module *const module_inst); - -enum status_code tc_set_count_value( - const struct tc_module *const module_inst, - const uint32_t count); - -/** @} */ - -/** - * \name Start/Stop Counter - * @{ - */ - -/** - * \brief Stops the counter. - * - * This function will stop the counter. When the counter is stopped - * the value in the count value is set to 0 if the counter was - * counting up, or maximum if the counter was counting - * down when stopped. - * - * \param[in] module_inst Pointer to the software module instance struct - */ -static inline void tc_stop_counter( - const struct tc_module *const module_inst) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - /* Get a pointer to the module's hardware instance */ - TcCount8 *const tc_module = &(module_inst->hw->COUNT8); - - while (tc_is_syncing(module_inst)) { - /* Wait for sync */ - } - - /* Write command to execute */ - tc_module->CTRLBSET.reg = TC_CTRLBSET_CMD(2); -} - -/** - * \brief Starts the counter. - * - * Starts or restarts an initialized TC module's counter. - * - * \param[in] module_inst Pointer to the software module instance struct - */ -static inline void tc_start_counter( - const struct tc_module *const module_inst) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - /* Get a pointer to the module's hardware instance */ - TcCount8 *const tc_module = &(module_inst->hw->COUNT8); - - while (tc_is_syncing(module_inst)) { - /* Wait for sync */ - } - - /* Make certain that there are no conflicting commands in the register */ - tc_module->CTRLBCLR.reg = TC_CTRLBCLR_CMD_NONE; - - while (tc_is_syncing(module_inst)) { - /* Wait for sync */ - } - - /* Write command to execute */ - tc_module->CTRLBSET.reg = TC_CTRLBSET_CMD(1); -} - -/** @} */ - -#ifdef FEATURE_TC_DOUBLE_BUFFERED -/** - * \name Double Buffering - * @{ - */ - -/** - * \brief Update double buffer. - * - * Update double buffer. - * - * \param[in] module_inst Pointer to the software module instance struct - */ -static inline void tc_update_double_buffer( - const struct tc_module *const module_inst) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - /* Get a pointer to the module's hardware instance */ - TcCount8 *const tc_module = &(module_inst->hw->COUNT8); - - while (tc_is_syncing(module_inst)) { - /* Wait for sync */ - } - - /* Make certain that there are no conflicting commands in the register */ - tc_module->CTRLBCLR.reg = TC_CTRLBCLR_CMD_NONE; - - while (tc_is_syncing(module_inst)) { - /* Wait for sync */ - } - - /* Write command to execute */ - tc_module->CTRLBSET.reg = TC_CTRLBSET_CMD(3); -} -/** @} */ -#endif - -#ifdef FEATURE_TC_READ_SYNC -/** - * \name Count Read Synchronization - * @{ - */ - -/** - * \brief Read synchronization of COUNT. - * - * Read synchronization of COUNT. - * - * \param[in] module_inst Pointer to the software module instance struct - */ -static inline void tc_sync_read_count( - const struct tc_module *const module_inst) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - /* Get a pointer to the module's hardware instance */ - TcCount8 *const tc_module = &(module_inst->hw->COUNT8); - - while (tc_is_syncing(module_inst)) { - /* Wait for sync */ - } - - /* Make certain that there are no conflicting commands in the register */ - tc_module->CTRLBCLR.reg = TC_CTRLBCLR_CMD_NONE; - - while (tc_is_syncing(module_inst)) { - /* Wait for sync */ - } - - /* Write command to execute */ - tc_module->CTRLBSET.reg = TC_CTRLBSET_CMD(4); -} -/** @} */ -#endif - -/** - * \name Get Capture Set Compare - * @{ - */ - -uint32_t tc_get_capture_value( - const struct tc_module *const module_inst, - const enum tc_compare_capture_channel channel_index); - -enum status_code tc_set_compare_value( - const struct tc_module *const module_inst, - const enum tc_compare_capture_channel channel_index, - const uint32_t compare_value); - -/** @} */ - -/** - * \name Set Top Value - * @{ - */ - -enum status_code tc_set_top_value( - const struct tc_module *const module_inst, - const uint32_t top_value); - -/** @} */ - -/** - * \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 TC software instance struct - * - * \return Bitmask of \c TC_STATUS_* flags. - * - * \retval TC_STATUS_CHANNEL_0_MATCH Timer channel 0 compare/capture match - * \retval TC_STATUS_CHANNEL_1_MATCH Timer channel 1 compare/capture match - * \retval TC_STATUS_SYNC_READY Timer read synchronization has completed - * \retval TC_STATUS_CAPTURE_OVERFLOW Timer capture data has overflowed - * \retval TC_STATUS_COUNT_OVERFLOW Timer count value has overflowed - * \retval TC_STATUS_CHN0_BUFFER_VALID Timer count channel 0 compare/capture buffer valid - * \retval TC_STATUS_CHN1_BUFFER_VALID Timer count channel 1 compare/capture buffer valid - * \retval TC_STATUS_PERIOD_BUFFER_VALID Timer count period buffer valid - */ -static inline uint32_t tc_get_status( - struct tc_module *const module_inst) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - /* Get a pointer to the module's hardware instance */ - TcCount8 *const tc_module = &(module_inst->hw->COUNT8); - - uint32_t int_flags = tc_module->INTFLAG.reg; - - uint32_t status_flags = 0; - - /* Check for TC channel 0 match */ - if (int_flags & TC_INTFLAG_MC(1)) { - status_flags |= TC_STATUS_CHANNEL_0_MATCH; - } - - /* Check for TC channel 1 match */ - if (int_flags & TC_INTFLAG_MC(2)) { - status_flags |= TC_STATUS_CHANNEL_1_MATCH; - } - -#if !defined(FEATURE_TC_SYNCBUSY_SCHEME_VERSION_2) - /* Check for TC read synchronization ready */ - if (int_flags & TC_INTFLAG_SYNCRDY) { - status_flags |= TC_STATUS_SYNC_READY; - } -#endif - - /* Check for TC capture overflow */ - if (int_flags & TC_INTFLAG_ERR) { - status_flags |= TC_STATUS_CAPTURE_OVERFLOW; - } - - /* Check for TC count overflow */ - if (int_flags & TC_INTFLAG_OVF) { - status_flags |= TC_STATUS_COUNT_OVERFLOW; - } -#ifdef FEATURE_TC_DOUBLE_BUFFERED - uint8_t double_buffer_valid_status = tc_module->STATUS.reg; - - /* Check channel 0 compare or capture buffer valid */ - if (double_buffer_valid_status & TC_STATUS_CCBUFV0) { - status_flags |= TC_STATUS_CHN0_BUFFER_VALID; - } - /* Check channel 0 compare or capture buffer valid */ - if (double_buffer_valid_status & TC_STATUS_CCBUFV1) { - status_flags |= TC_STATUS_CHN1_BUFFER_VALID; - } - /* Check period buffer valid */ - if (double_buffer_valid_status & TC_STATUS_PERBUFV) { - status_flags |= TC_STATUS_PERIOD_BUFFER_VALID; - } -#endif - - return status_flags; -} - -/** - * \brief Clears a module status flag. - * - * Clears the given status flag of the module. - * - * \param[in] module_inst Pointer to the TC software instance struct - * \param[in] status_flags Bitmask of \c TC_STATUS_* flags to clear - */ -static inline void tc_clear_status( - struct tc_module *const module_inst, - const uint32_t status_flags) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - /* Get a pointer to the module's hardware instance */ - TcCount8 *const tc_module = &(module_inst->hw->COUNT8); - - uint32_t int_flags = 0; - - /* Check for TC channel 0 match */ - if (status_flags & TC_STATUS_CHANNEL_0_MATCH) { - int_flags |= TC_INTFLAG_MC(1); - } - - /* Check for TC channel 1 match */ - if (status_flags & TC_STATUS_CHANNEL_1_MATCH) { - int_flags |= TC_INTFLAG_MC(2); - } - -#if !defined(FEATURE_TC_SYNCBUSY_SCHEME_VERSION_2) - /* Check for TC read synchronization ready */ - if (status_flags & TC_STATUS_SYNC_READY) { - int_flags |= TC_INTFLAG_SYNCRDY; - } -#endif - - /* Check for TC capture overflow */ - if (status_flags & TC_STATUS_CAPTURE_OVERFLOW) { - int_flags |= TC_INTFLAG_ERR; - } - - /* Check for TC count overflow */ - if (status_flags & TC_STATUS_COUNT_OVERFLOW) { - int_flags |= TC_INTFLAG_OVF; - } - - /* Clear interrupt flag */ - tc_module->INTFLAG.reg = int_flags; -} - -/** @} */ - -/** @} */ - -#ifdef __cplusplus -} -#endif - -/** - * \page asfdoc_sam0_tc_extra Extra Information for TC Driver - * - * \section asfdoc_sam0_tc_extra_acronyms Acronyms - * The table below presents the acronyms used in this module: - * - * <table> - * <tr> - * <th>Acronym</th> - * <th>Description</th> - * </tr> - * <tr> - * <td>DMA</td> - * <td>Direct Memory Access</td> - * </tr> - * <tr> - * <td>TC</td> - * <td>Timer Counter</td> - * </tr> - * <tr> - * <td>PWM</td> - * <td>Pulse Width Modulation</td> - * </tr> - * <tr> - * <td>PWP</td> - * <td>Pulse Width Period</td> - * </tr> - * <tr> - * <td>PPW</td> - * <td>Period Pulse Width</td> - * </tr> - * </table> - * - * - * \section asfdoc_sam0_tc_extra_dependencies Dependencies - * This driver has the following dependencies: - * - * - \ref asfdoc_sam0_system_pinmux_group "System Pin Multiplexer Driver" - * - * - * \section asfdoc_sam0_tc_extra_errata Errata - * There are no errata related to this driver. - * - * - * \section asfdoc_sam0_tc_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>Added support for SAML21</td> - * </tr> - * <tr> - * <td>Added support for SAMD10/D11</td> - * </tr> - * <tr> - * <td>Added support for SAMR21</td> - * </tr> - * <tr> - * <td>Added support for SAMD21 and do some modifications as below: - * \li Clean up in the configuration structure, the counter size - * setting specific registers is accessed through the counter_8_bit, - * counter_16_bit and counter_32_bit structures - * \li All event related settings moved into the tc_event structure </td> - * </tr> - * <tr> - * <td>Added automatic digital clock interface enable for the slave TC - * module when a timer is initialized in 32-bit mode</td> - * </tr> - * <tr> - * <td>Initial Release</td> - * </tr> - * </table> - */ - -/** - * \page asfdoc_sam0_tc_exqsg Examples for TC Driver - * - * This is a list of the available Quick Start guides (QSGs) and example - * applications for \ref asfdoc_sam0_tc_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_tc_basic_use_case - * \if TC_CALLBACK_MODE - * - \subpage asfdoc_sam0_tc_timer_use_case - * - \subpage asfdoc_sam0_tc_callback_use_case - * \endif - * - \subpage asfdoc_sam0_tc_dma_use_case - * - * \page asfdoc_sam0_tc_document_revision_history Document Revision History - * - * <table> - * <tr> - * <th>Doc. Rev.</td> - * <th>Date</td> - * <th>Comments</td> - * </tr> - * <tr> - * <td>E</td> - * <td>11/2014</td> - * <td>Added support for SAML21.</td> - * </tr> - * <tr> - * <td>D</td> - * <td>12/2014</td> - * <td>Added timer use case. - * 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>Corrected documentation typos.</td> - * </tr> - * <tr> - * <td>A</td> - * <td>06/2013</td> - * <td>Initial release</td> - * </tr> - * </table> - */ - -#endif /* TC_H_INCLUDED */