Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: hello SerialTestv11 SerialTestv12 Sierpinski ... more
Diff: TARGET_EFM32PG12_STK3402/TOOLCHAIN_GCC_ARM/em_timer.h
- Revision:
- 171:3a7713b1edbc
- Parent:
- 160:5571c4ff569f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TARGET_EFM32PG12_STK3402/TOOLCHAIN_GCC_ARM/em_timer.h Thu Nov 08 11:45:42 2018 +0000
@@ -0,0 +1,951 @@
+/***************************************************************************//**
+ * @file em_timer.h
+ * @brief Timer/counter (TIMER) peripheral API
+ * @version 5.3.3
+ *******************************************************************************
+ * # License
+ * <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
+ *******************************************************************************
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
+ * obligation to support this Software. Silicon Labs is providing the
+ * Software "AS IS", with no express or implied warranties of any kind,
+ * including, but not limited to, any implied warranties of merchantability
+ * or fitness for any particular purpose or warranties against infringement
+ * of any proprietary rights of a third party.
+ *
+ * Silicon Labs will not be liable for any consequential, incidental, or
+ * special damages, or any other relief, or for any claim by any third party,
+ * arising from your use of this Software.
+ *
+ ******************************************************************************/
+
+#ifndef EM_TIMER_H
+#define EM_TIMER_H
+
+#include "em_device.h"
+#if defined(TIMER_COUNT) && (TIMER_COUNT > 0)
+
+#include <stdbool.h>
+#include "em_assert.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * @addtogroup emlib
+ * @{
+ ******************************************************************************/
+
+/***************************************************************************//**
+ * @addtogroup TIMER
+ * @{
+ ******************************************************************************/
+
+/*******************************************************************************
+ ******************************* DEFINES ***********************************
+ ******************************************************************************/
+
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
+
+/** Validation of TIMER register block pointer reference for assert statements. */
+#define TIMER_REF_VALID(ref) TIMER_Valid(ref)
+
+/** Validation of TIMER compare/capture channel number */
+#if defined(_SILICON_LABS_32B_SERIES_0)
+#define TIMER_CH_VALID(ch) ((ch) < 3)
+#elif defined(_SILICON_LABS_32B_SERIES_1)
+#define TIMER_CH_VALID(ch) ((ch) < 4)
+#else
+#error "Unknown device. Undefined number of channels."
+#endif
+
+/** @endcond */
+
+/*******************************************************************************
+ ******************************** ENUMS ************************************
+ ******************************************************************************/
+
+/** Timer compare/capture mode. */
+typedef enum {
+ timerCCModeOff = _TIMER_CC_CTRL_MODE_OFF, /**< Channel turned off. */
+ timerCCModeCapture = _TIMER_CC_CTRL_MODE_INPUTCAPTURE, /**< Input capture. */
+ timerCCModeCompare = _TIMER_CC_CTRL_MODE_OUTPUTCOMPARE, /**< Output compare. */
+ timerCCModePWM = _TIMER_CC_CTRL_MODE_PWM /**< Pulse-Width modulation. */
+} TIMER_CCMode_TypeDef;
+
+/** Clock select. */
+typedef enum {
+ /** Prescaled HFPER clock. */
+ timerClkSelHFPerClk = _TIMER_CTRL_CLKSEL_PRESCHFPERCLK,
+
+ /** Compare/Capture Channel 1 Input. */
+ timerClkSelCC1 = _TIMER_CTRL_CLKSEL_CC1,
+
+ /**
+ * Cascaded, clocked by underflow (down-counting) or overflow (up-counting)
+ * by lower numbered timer.
+ */
+ timerClkSelCascade = _TIMER_CTRL_CLKSEL_TIMEROUF
+} TIMER_ClkSel_TypeDef;
+
+/** Input capture edge select. */
+typedef enum {
+ /** Rising edges detected. */
+ timerEdgeRising = _TIMER_CC_CTRL_ICEDGE_RISING,
+
+ /** Falling edges detected. */
+ timerEdgeFalling = _TIMER_CC_CTRL_ICEDGE_FALLING,
+
+ /** Both edges detected. */
+ timerEdgeBoth = _TIMER_CC_CTRL_ICEDGE_BOTH,
+
+ /** No edge detection, leave signal as is. */
+ timerEdgeNone = _TIMER_CC_CTRL_ICEDGE_NONE
+} TIMER_Edge_TypeDef;
+
+/** Input capture event control. */
+typedef enum {
+ /** PRS output pulse, interrupt flag and DMA request set on every capture. */
+ timerEventEveryEdge = _TIMER_CC_CTRL_ICEVCTRL_EVERYEDGE,
+ /** PRS output pulse, interrupt flag and DMA request set on every second capture. */
+ timerEventEvery2ndEdge = _TIMER_CC_CTRL_ICEVCTRL_EVERYSECONDEDGE,
+ /**
+ * PRS output pulse, interrupt flag and DMA request set on rising edge (if
+ * input capture edge = BOTH).
+ */
+ timerEventRising = _TIMER_CC_CTRL_ICEVCTRL_RISING,
+ /**
+ * PRS output pulse, interrupt flag and DMA request set on falling edge (if
+ * input capture edge = BOTH).
+ */
+ timerEventFalling = _TIMER_CC_CTRL_ICEVCTRL_FALLING
+} TIMER_Event_TypeDef;
+
+/** Input edge action. */
+typedef enum {
+ /** No action taken. */
+ timerInputActionNone = _TIMER_CTRL_FALLA_NONE,
+
+ /** Start counter without reload. */
+ timerInputActionStart = _TIMER_CTRL_FALLA_START,
+
+ /** Stop counter without reload. */
+ timerInputActionStop = _TIMER_CTRL_FALLA_STOP,
+
+ /** Reload and start counter. */
+ timerInputActionReloadStart = _TIMER_CTRL_FALLA_RELOADSTART
+} TIMER_InputAction_TypeDef;
+
+/** Timer mode. */
+typedef enum {
+ timerModeUp = _TIMER_CTRL_MODE_UP, /**< Up-counting. */
+ timerModeDown = _TIMER_CTRL_MODE_DOWN, /**< Down-counting. */
+ timerModeUpDown = _TIMER_CTRL_MODE_UPDOWN, /**< Up/down-counting. */
+ timerModeQDec = _TIMER_CTRL_MODE_QDEC /**< Quadrature decoder. */
+} TIMER_Mode_TypeDef;
+
+/** Compare/capture output action. */
+typedef enum {
+ /** No action. */
+ timerOutputActionNone = _TIMER_CC_CTRL_CUFOA_NONE,
+
+ /** Toggle on event. */
+ timerOutputActionToggle = _TIMER_CC_CTRL_CUFOA_TOGGLE,
+
+ /** Clear on event. */
+ timerOutputActionClear = _TIMER_CC_CTRL_CUFOA_CLEAR,
+
+ /** Set on event. */
+ timerOutputActionSet = _TIMER_CC_CTRL_CUFOA_SET
+} TIMER_OutputAction_TypeDef;
+
+/** Prescaler. */
+typedef enum {
+ timerPrescale1 = _TIMER_CTRL_PRESC_DIV1, /**< Divide by 1. */
+ timerPrescale2 = _TIMER_CTRL_PRESC_DIV2, /**< Divide by 2. */
+ timerPrescale4 = _TIMER_CTRL_PRESC_DIV4, /**< Divide by 4. */
+ timerPrescale8 = _TIMER_CTRL_PRESC_DIV8, /**< Divide by 8. */
+ timerPrescale16 = _TIMER_CTRL_PRESC_DIV16, /**< Divide by 16. */
+ timerPrescale32 = _TIMER_CTRL_PRESC_DIV32, /**< Divide by 32. */
+ timerPrescale64 = _TIMER_CTRL_PRESC_DIV64, /**< Divide by 64. */
+ timerPrescale128 = _TIMER_CTRL_PRESC_DIV128, /**< Divide by 128. */
+ timerPrescale256 = _TIMER_CTRL_PRESC_DIV256, /**< Divide by 256. */
+ timerPrescale512 = _TIMER_CTRL_PRESC_DIV512, /**< Divide by 512. */
+ timerPrescale1024 = _TIMER_CTRL_PRESC_DIV1024 /**< Divide by 1024. */
+} TIMER_Prescale_TypeDef;
+
+/** Peripheral Reflex System signal. */
+typedef enum {
+ timerPRSSELCh0 = _TIMER_CC_CTRL_PRSSEL_PRSCH0, /**< PRS channel 0. */
+ timerPRSSELCh1 = _TIMER_CC_CTRL_PRSSEL_PRSCH1, /**< PRS channel 1. */
+ timerPRSSELCh2 = _TIMER_CC_CTRL_PRSSEL_PRSCH2, /**< PRS channel 2. */
+ timerPRSSELCh3 = _TIMER_CC_CTRL_PRSSEL_PRSCH3, /**< PRS channel 3. */
+#if defined(_TIMER_CC_CTRL_PRSSEL_PRSCH4)
+ timerPRSSELCh4 = _TIMER_CC_CTRL_PRSSEL_PRSCH4, /**< PRS channel 4. */
+#endif
+#if defined(_TIMER_CC_CTRL_PRSSEL_PRSCH5)
+ timerPRSSELCh5 = _TIMER_CC_CTRL_PRSSEL_PRSCH5, /**< PRS channel 5. */
+#endif
+#if defined(_TIMER_CC_CTRL_PRSSEL_PRSCH6)
+ timerPRSSELCh6 = _TIMER_CC_CTRL_PRSSEL_PRSCH6, /**< PRS channel 6. */
+#endif
+#if defined(_TIMER_CC_CTRL_PRSSEL_PRSCH7)
+ timerPRSSELCh7 = _TIMER_CC_CTRL_PRSSEL_PRSCH7, /**< PRS channel 7. */
+#endif
+#if defined(_TIMER_CC_CTRL_PRSSEL_PRSCH8)
+ timerPRSSELCh8 = _TIMER_CC_CTRL_PRSSEL_PRSCH8, /**< PRS channel 8. */
+#endif
+#if defined(_TIMER_CC_CTRL_PRSSEL_PRSCH9)
+ timerPRSSELCh9 = _TIMER_CC_CTRL_PRSSEL_PRSCH9, /**< PRS channel 9. */
+#endif
+#if defined(_TIMER_CC_CTRL_PRSSEL_PRSCH10)
+ timerPRSSELCh10 = _TIMER_CC_CTRL_PRSSEL_PRSCH10, /**< PRS channel 10. */
+#endif
+#if defined(_TIMER_CC_CTRL_PRSSEL_PRSCH11)
+ timerPRSSELCh11 = _TIMER_CC_CTRL_PRSSEL_PRSCH11, /**< PRS channel 11. */
+#endif
+} TIMER_PRSSEL_TypeDef;
+
+#if defined(_TIMER_DTFC_DTFA_NONE)
+/** DT (Dead Time) Fault Actions. */
+typedef enum {
+ timerDtiFaultActionNone = _TIMER_DTFC_DTFA_NONE, /**< No action on fault. */
+ timerDtiFaultActionInactive = _TIMER_DTFC_DTFA_INACTIVE, /**< Set outputs inactive. */
+ timerDtiFaultActionClear = _TIMER_DTFC_DTFA_CLEAR, /**< Clear outputs. */
+ timerDtiFaultActionTristate = _TIMER_DTFC_DTFA_TRISTATE /**< Tristate outputs. */
+} TIMER_DtiFaultAction_TypeDef;
+#endif
+
+/*******************************************************************************
+ ******************************* STRUCTS ***********************************
+ ******************************************************************************/
+
+/** TIMER initialization structure. */
+typedef struct {
+ /** Start counting when init completed. */
+ bool enable;
+
+ /** Counter shall keep running during debug halt. */
+ bool debugRun;
+
+ /** Prescaling factor, if HFPER clock used. */
+ TIMER_Prescale_TypeDef prescale;
+
+ /** Clock selection. */
+ TIMER_ClkSel_TypeDef clkSel;
+
+#if defined(TIMER_CTRL_X2CNT) && defined(TIMER_CTRL_ATI)
+ /** 2x Count mode, counter increments/decrements by 2, meant for PWN mode. */
+ bool count2x;
+
+ /** ATI (Always Track Inputs) makes CCPOL always track
+ * the polarity of the inputs. */
+ bool ati;
+#endif
+
+ /** Action on falling input edge. */
+ TIMER_InputAction_TypeDef fallAction;
+
+ /** Action on rising input edge. */
+ TIMER_InputAction_TypeDef riseAction;
+
+ /** Counting mode. */
+ TIMER_Mode_TypeDef mode;
+
+ /** DMA request clear on active. */
+ bool dmaClrAct;
+
+ /** Select X2 or X4 quadrature decode mode (if used). */
+ bool quadModeX4;
+
+ /** Determines if only counting up or down once. */
+ bool oneShot;
+
+ /** Timer start/stop/reload by other timers. */
+ bool sync;
+} TIMER_Init_TypeDef;
+
+/** Default config for TIMER init structure. */
+#if defined(TIMER_CTRL_X2CNT) && defined(TIMER_CTRL_ATI)
+#define TIMER_INIT_DEFAULT \
+ { \
+ true, /* Enable timer when init complete. */ \
+ false, /* Stop counter during debug halt. */ \
+ timerPrescale1, /* No prescaling. */ \
+ timerClkSelHFPerClk, /* Select HFPER clock. */ \
+ false, /* Not 2x count mode. */ \
+ false, /* No ATI. */ \
+ timerInputActionNone, /* No action on falling input edge. */ \
+ timerInputActionNone, /* No action on rising input edge. */ \
+ timerModeUp, /* Up-counting. */ \
+ false, /* Do not clear DMA requests when DMA channel is active. */ \
+ false, /* Select X2 quadrature decode mode (if used). */ \
+ false, /* Disable one shot. */ \
+ false /* Not started/stopped/reloaded by other timers. */ \
+ }
+#else
+#define TIMER_INIT_DEFAULT \
+ { \
+ true, /* Enable timer when init complete. */ \
+ false, /* Stop counter during debug halt. */ \
+ timerPrescale1, /* No prescaling. */ \
+ timerClkSelHFPerClk, /* Select HFPER clock. */ \
+ timerInputActionNone, /* No action on falling input edge. */ \
+ timerInputActionNone, /* No action on rising input edge. */ \
+ timerModeUp, /* Up-counting. */ \
+ false, /* Do not clear DMA requests when DMA channel is active. */ \
+ false, /* Select X2 quadrature decode mode (if used). */ \
+ false, /* Disable one shot. */ \
+ false /* Not started/stopped/reloaded by other timers. */ \
+ }
+#endif
+
+/** TIMER compare/capture initialization structure. */
+typedef struct {
+ /** Input capture event control. */
+ TIMER_Event_TypeDef eventCtrl;
+
+ /** Input capture edge select. */
+ TIMER_Edge_TypeDef edge;
+
+ /**
+ * Peripheral reflex system trigger selection. Only applicable if @p prsInput
+ * is enabled.
+ */
+ TIMER_PRSSEL_TypeDef prsSel;
+
+ /** Counter underflow output action. */
+ TIMER_OutputAction_TypeDef cufoa;
+
+ /** Counter overflow output action. */
+ TIMER_OutputAction_TypeDef cofoa;
+
+ /** Counter match output action. */
+ TIMER_OutputAction_TypeDef cmoa;
+
+ /** Compare/capture channel mode. */
+ TIMER_CCMode_TypeDef mode;
+
+ /** Enable digital filter. */
+ bool filter;
+
+ /** Select TIMERnCCx (false) or PRS input (true). */
+ bool prsInput;
+
+ /**
+ * Compare output initial state. Only used in Output Compare and PWM mode.
+ * When true, the compare/PWM output is set high when the counter is
+ * disabled. When counting resumes, this value will represent the initial
+ * value for the compare/PWM output. If the bit is cleared, the output
+ * will be cleared when the counter is disabled.
+ */
+ bool coist;
+
+ /** Invert output from compare/capture channel. */
+ bool outInvert;
+} TIMER_InitCC_TypeDef;
+
+/** Default config for TIMER compare/capture init structure. */
+#define TIMER_INITCC_DEFAULT \
+ { \
+ timerEventEveryEdge, /* Event on every capture. */ \
+ timerEdgeRising, /* Input capture edge on rising edge. */ \
+ timerPRSSELCh0, /* Not used by default, select PRS channel 0. */ \
+ timerOutputActionNone, /* No action on underflow. */ \
+ timerOutputActionNone, /* No action on overflow. */ \
+ timerOutputActionNone, /* No action on match. */ \
+ timerCCModeOff, /* Disable compare/capture channel. */ \
+ false, /* Disable filter. */ \
+ false, /* Select TIMERnCCx input. */ \
+ false, /* Clear output when counter disabled. */ \
+ false /* Do not invert output. */ \
+ }
+
+#if defined(_TIMER_DTCTRL_MASK)
+/** TIMER Dead Time Insertion (DTI) initialization structure. */
+typedef struct {
+ /** Enable DTI or leave it disabled until @ref TIMER_EnableDTI() is called */
+ bool enable;
+
+ /** DTI Output Polarity */
+ bool activeLowOut;
+
+ /** DTI Complementary Output Invert */
+ bool invertComplementaryOut;
+
+ /** Enable Automatic Start-up functionality (when debugger exits) */
+ bool autoRestart;
+
+ /** Enable/disable PRS as DTI input. */
+ bool enablePrsSource;
+
+ /** Select which PRS channel as DTI input. Only valid if @p enablePrsSource
+ is enabled. */
+ TIMER_PRSSEL_TypeDef prsSel;
+
+ /** DTI prescaling factor, if HFPER clock used. */
+ TIMER_Prescale_TypeDef prescale;
+
+ /** DTI Rise Time */
+ unsigned int riseTime;
+
+ /** DTI Fall Time */
+ unsigned int fallTime;
+
+ /** DTI outputs enable bit mask, consisting of one bit per DTI
+ output signal, i.e. CC0, CC1, CC2, CDTI0, CDTI1 and CDTI2.
+ This value should consist of one or more TIMER_DTOGEN_DTOGnnnEN flags
+ (defined in \<part_name\>_timer.h) OR'ed together. */
+ uint32_t outputsEnableMask;
+
+ /** Enable core lockup as a fault source. */
+ bool enableFaultSourceCoreLockup;
+
+ /** Enable debugger as a fault source. */
+ bool enableFaultSourceDebugger;
+
+ /** Enable PRS fault source 0 (@p faultSourcePrsSel0) */
+ bool enableFaultSourcePrsSel0;
+
+ /** Select which PRS signal to be PRS fault source 0. */
+ TIMER_PRSSEL_TypeDef faultSourcePrsSel0;
+
+ /** Enable PRS fault source 1 (@p faultSourcePrsSel1) */
+ bool enableFaultSourcePrsSel1;
+
+ /** Select which PRS signal to be PRS fault source 1. */
+ TIMER_PRSSEL_TypeDef faultSourcePrsSel1;
+
+ /** Fault Action */
+ TIMER_DtiFaultAction_TypeDef faultAction;
+} TIMER_InitDTI_TypeDef;
+
+/** Default config for TIMER DTI init structure. */
+#define TIMER_INITDTI_DEFAULT \
+ { \
+ true, /* Enable the DTI. */ \
+ false, /* CC[0|1|2] outputs are active high. */ \
+ false, /* CDTI[0|1|2] outputs are not inverted. */ \
+ false, /* No auto restart when debugger exits. */ \
+ false, /* No PRS source selected. */ \
+ timerPRSSELCh0, /* Not used by default, select PRS channel 0. */ \
+ timerPrescale1, /* No prescaling. */ \
+ 0, /* No rise time. */ \
+ 0, /* No fall time. */ \
+ TIMER_DTOGEN_DTOGCC0EN | TIMER_DTOGEN_DTOGCDTI0EN, /* Enable CC0 and CDTI0 */ \
+ true, /* Enable core lockup as fault source */ \
+ true, /* Enable debugger as fault source */ \
+ false, /* Disable PRS fault source 0 */ \
+ timerPRSSELCh0, /* Not used by default, select PRS channel 0. */ \
+ false, /* Disable PRS fault source 1 */ \
+ timerPRSSELCh0, /* Not used by default, select PRS channel 0. */ \
+ timerDtiFaultActionInactive, /* No fault action. */ \
+ }
+#endif /* _TIMER_DTCTRL_MASK */
+
+/*******************************************************************************
+ ***************************** PROTOTYPES **********************************
+ ******************************************************************************/
+
+/***************************************************************************//**
+ * @brief
+ * Validate the TIMER register block pointer
+ *
+ * @param[in] ref
+ * Pointer to TIMER peripheral register block.
+ *
+ * @return
+ * true if ref points to a valid timer, false otherwise.
+ ******************************************************************************/
+__STATIC_INLINE bool TIMER_Valid(const TIMER_TypeDef *ref)
+{
+ return (ref == TIMER0)
+#if defined(TIMER1)
+ || (ref == TIMER1)
+#endif
+#if defined(TIMER2)
+ || (ref == TIMER2)
+#endif
+#if defined(TIMER3)
+ || (ref == TIMER3)
+#endif
+#if defined(TIMER4)
+ || (ref == TIMER4)
+#endif
+#if defined(TIMER5)
+ || (ref == TIMER5)
+#endif
+#if defined(TIMER6)
+ || (ref == TIMER6)
+#endif
+#if defined(WTIMER0)
+ || (ref == WTIMER0)
+#endif
+#if defined(WTIMER1)
+ || (ref == WTIMER1)
+#endif
+#if defined(WTIMER2)
+ || (ref == WTIMER2)
+#endif
+#if defined(WTIMER3)
+ || (ref == WTIMER3)
+#endif
+ ;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get the Max count of the timer
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @return
+ * The max count value of the timer. This is 0xFFFF for 16 bit timers
+ * and 0xFFFFFFFF for 32 bit timers.
+ ******************************************************************************/
+__STATIC_INLINE uint32_t TIMER_MaxCount(const TIMER_TypeDef *ref)
+{
+#if defined(WTIMER_PRESENT)
+ if ((ref == WTIMER0)
+#if defined(WTIMER1)
+ || (ref == WTIMER1)
+#endif
+#if defined(WTIMER2)
+ || (ref == WTIMER2)
+#endif
+#if defined(WTIMER3)
+ || (ref == WTIMER3)
+#endif
+ ) {
+ return 0xFFFFFFFFUL;
+ }
+#else
+ (void) ref;
+#endif
+ return 0xFFFFUL;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get capture value for compare/capture channel when operating in capture
+ * mode.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @param[in] ch
+ * Compare/capture channel to access.
+ *
+ * @return
+ * Current capture value.
+ ******************************************************************************/
+__STATIC_INLINE uint32_t TIMER_CaptureGet(TIMER_TypeDef *timer, unsigned int ch)
+{
+ return timer->CC[ch].CCV;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Set compare value buffer for compare/capture channel when operating in
+ * compare or PWM mode.
+ *
+ * @details
+ * The compare value buffer holds the value which will be written to
+ * TIMERn_CCx_CCV on an update event if the buffer has been updated since
+ * the last event.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @param[in] ch
+ * Compare/capture channel to access.
+ *
+ * @param[in] val
+ * Value to set in compare value buffer register.
+ ******************************************************************************/
+__STATIC_INLINE void TIMER_CompareBufSet(TIMER_TypeDef *timer,
+ unsigned int ch,
+ uint32_t val)
+{
+ EFM_ASSERT(val <= TIMER_MaxCount(timer));
+ timer->CC[ch].CCVB = val;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Set compare value for compare/capture channel when operating in compare
+ * or PWM mode.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @param[in] ch
+ * Compare/capture channel to access.
+ *
+ * @param[in] val
+ * Value to set in compare value register.
+ ******************************************************************************/
+__STATIC_INLINE void TIMER_CompareSet(TIMER_TypeDef *timer,
+ unsigned int ch,
+ uint32_t val)
+{
+ EFM_ASSERT(val <= TIMER_MaxCount(timer));
+ timer->CC[ch].CCV = val;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get TIMER counter value.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @return
+ * Current TIMER counter value.
+ ******************************************************************************/
+__STATIC_INLINE uint32_t TIMER_CounterGet(TIMER_TypeDef *timer)
+{
+ return timer->CNT;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Set TIMER counter value.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @param[in] val
+ * Value to set counter to.
+ ******************************************************************************/
+__STATIC_INLINE void TIMER_CounterSet(TIMER_TypeDef *timer, uint32_t val)
+{
+ EFM_ASSERT(val <= TIMER_MaxCount(timer));
+ timer->CNT = val;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Start/stop TIMER.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @param[in] enable
+ * true to enable counting, false to disable.
+ ******************************************************************************/
+__STATIC_INLINE void TIMER_Enable(TIMER_TypeDef *timer, bool enable)
+{
+ EFM_ASSERT(TIMER_REF_VALID(timer));
+
+ if (enable) {
+ timer->CMD = TIMER_CMD_START;
+ } else {
+ timer->CMD = TIMER_CMD_STOP;
+ }
+}
+
+void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init);
+void TIMER_InitCC(TIMER_TypeDef *timer,
+ unsigned int ch,
+ const TIMER_InitCC_TypeDef *init);
+
+#if defined(_TIMER_DTCTRL_MASK)
+void TIMER_InitDTI(TIMER_TypeDef *timer, const TIMER_InitDTI_TypeDef *init);
+
+/***************************************************************************//**
+ * @brief
+ * Enable or disable DTI unit.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @param[in] enable
+ * true to enable DTI unit, false to disable.
+ ******************************************************************************/
+__STATIC_INLINE void TIMER_EnableDTI(TIMER_TypeDef *timer, bool enable)
+{
+ EFM_ASSERT(TIMER0 == timer);
+
+ if (enable) {
+ timer->DTCTRL |= TIMER_DTCTRL_DTEN;
+ } else {
+ timer->DTCTRL &= ~TIMER_DTCTRL_DTEN;
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get DTI fault source flags status.
+ *
+ * @note
+ * The event bits are not cleared by the use of this function.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @return
+ * Status of the DTI fault source flags. Returns one or more valid
+ * DTI fault source flags (TIMER_DTFAULT_nnn) OR'ed together.
+ ******************************************************************************/
+__STATIC_INLINE uint32_t TIMER_GetDTIFault(TIMER_TypeDef *timer)
+{
+ EFM_ASSERT(TIMER0 == timer);
+ return timer->DTFAULT;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Clear DTI fault source flags.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @param[in] flags
+ * DTI fault source(s) to clear. Use one or more valid DTI fault
+ * source flags (TIMER_DTFAULT_nnn) OR'ed together.
+ ******************************************************************************/
+__STATIC_INLINE void TIMER_ClearDTIFault(TIMER_TypeDef *timer, uint32_t flags)
+
+{
+ EFM_ASSERT(TIMER0 == timer);
+ timer->DTFAULTC = flags;
+}
+#endif /* _TIMER_DTCTRL_MASK */
+
+/***************************************************************************//**
+ * @brief
+ * Clear one or more pending TIMER interrupts.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @param[in] flags
+ * Pending TIMER interrupt source(s) to clear. Use one or more valid
+ * interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
+ ******************************************************************************/
+__STATIC_INLINE void TIMER_IntClear(TIMER_TypeDef *timer, uint32_t flags)
+{
+ timer->IFC = flags;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Disable one or more TIMER interrupts.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @param[in] flags
+ * TIMER interrupt source(s) to disable. Use one or more valid
+ * interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
+ ******************************************************************************/
+__STATIC_INLINE void TIMER_IntDisable(TIMER_TypeDef *timer, uint32_t flags)
+{
+ timer->IEN &= ~flags;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Enable one or more TIMER interrupts.
+ *
+ * @note
+ * Depending on the use, a pending interrupt may already be set prior to
+ * enabling the interrupt. Consider using TIMER_IntClear() prior to enabling
+ * if such a pending interrupt should be ignored.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @param[in] flags
+ * TIMER interrupt source(s) to enable. Use one or more valid
+ * interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
+ ******************************************************************************/
+__STATIC_INLINE void TIMER_IntEnable(TIMER_TypeDef *timer, uint32_t flags)
+{
+ timer->IEN |= flags;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get pending TIMER interrupt flags.
+ *
+ * @note
+ * The event bits are not cleared by the use of this function.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @return
+ * TIMER interrupt source(s) pending. Returns one or more valid
+ * interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
+ ******************************************************************************/
+__STATIC_INLINE uint32_t TIMER_IntGet(TIMER_TypeDef *timer)
+{
+ return timer->IF;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get enabled and pending TIMER interrupt flags.
+ * Useful for handling more interrupt sources in the same interrupt handler.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @note
+ * Interrupt flags are not cleared by the use of this function.
+ *
+ * @return
+ * Pending and enabled TIMER interrupt sources.
+ * The return value is the bitwise AND combination of
+ * - the OR combination of enabled interrupt sources in TIMERx_IEN_nnn
+ * register (TIMERx_IEN_nnn) and
+ * - the OR combination of valid interrupt flags of the TIMER module
+ * (TIMERx_IF_nnn).
+ ******************************************************************************/
+__STATIC_INLINE uint32_t TIMER_IntGetEnabled(TIMER_TypeDef *timer)
+{
+ uint32_t ien;
+
+ /* Store TIMER->IEN in temporary variable in order to define explicit order
+ * of volatile accesses. */
+ ien = timer->IEN;
+
+ /* Bitwise AND of pending and enabled interrupts */
+ return timer->IF & ien;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Set one or more pending TIMER interrupts from SW.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @param[in] flags
+ * TIMER interrupt source(s) to set to pending. Use one or more valid
+ * interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
+ ******************************************************************************/
+__STATIC_INLINE void TIMER_IntSet(TIMER_TypeDef *timer, uint32_t flags)
+{
+ timer->IFS = flags;
+}
+
+#if defined(_TIMER_DTLOCK_LOCKKEY_LOCK)
+/***************************************************************************//**
+ * @brief
+ * Lock some of the TIMER registers in order to protect them from being
+ * modified.
+ *
+ * @details
+ * Please refer to the reference manual for TIMER registers that will be
+ * locked.
+ *
+ * @note
+ * If locking the TIMER registers, they must be unlocked prior to using any
+ * TIMER API functions modifying TIMER registers protected by the lock.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ ******************************************************************************/
+__STATIC_INLINE void TIMER_Lock(TIMER_TypeDef *timer)
+{
+ EFM_ASSERT(TIMER0 == timer);
+
+ timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_LOCK;
+}
+#endif
+
+void TIMER_Reset(TIMER_TypeDef *timer);
+
+/***************************************************************************//**
+ * @brief
+ * Set top value buffer for timer.
+ *
+ * @details
+ * When the top value buffer register is updated, the value is loaded into
+ * the top value register at the next wrap around. This feature is useful
+ * in order to update the top value safely when the timer is running.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @param[in] val
+ * Value to set in top value buffer register.
+ ******************************************************************************/
+__STATIC_INLINE void TIMER_TopBufSet(TIMER_TypeDef *timer, uint32_t val)
+{
+ EFM_ASSERT(val <= TIMER_MaxCount(timer));
+ timer->TOPB = val;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get top value setting for timer.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @return
+ * Current top value.
+ ******************************************************************************/
+__STATIC_INLINE uint32_t TIMER_TopGet(TIMER_TypeDef *timer)
+{
+ return timer->TOP;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Set top value for timer.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ *
+ * @param[in] val
+ * Value to set in top value register.
+ ******************************************************************************/
+__STATIC_INLINE void TIMER_TopSet(TIMER_TypeDef *timer, uint32_t val)
+{
+ EFM_ASSERT(val <= TIMER_MaxCount(timer));
+ timer->TOP = val;
+}
+
+#if defined(TIMER_DTLOCK_LOCKKEY_UNLOCK)
+/***************************************************************************//**
+ * @brief
+ * Unlock the TIMER so that writing to locked registers again is possible.
+ *
+ * @param[in] timer
+ * Pointer to TIMER peripheral register block.
+ ******************************************************************************/
+__STATIC_INLINE void TIMER_Unlock(TIMER_TypeDef *timer)
+{
+ EFM_ASSERT(TIMER0 == timer);
+
+ timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_UNLOCK;
+}
+#endif
+
+/** @} (end addtogroup TIMER) */
+/** @} (end addtogroup emlib) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* defined(TIMER_COUNT) && (TIMER_COUNT > 0) */
+#endif /* EM_TIMER_H */


