The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.
Dependents: hello SerialTestv11 SerialTestv12 Sierpinski ... more
mbed 2
This is the mbed 2 library. If you'd like to learn about Mbed OS please see the mbed-os docs.
Diff: TARGET_EFM32HG_STK3400/TOOLCHAIN_ARM_MICRO/em_timer.h
- Revision:
- 171:3a7713b1edbc
- Parent:
- 160:5571c4ff569f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TARGET_EFM32HG_STK3400/TOOLCHAIN_ARM_MICRO/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 */