/***************************************************************************//** | |
* @file em_timer.h | |
* @brief Timer/counter (TIMER) peripheral API | |
* @version 5.1.2 | |
******************************************************************************* | |
* @section 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(WTIMER0) | |
|| (ref == WTIMER0) | |
#endif | |
#if defined(WTIMER1) | |
|| (ref == WTIMER1) | |
#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 | |
) | |
{ | |
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 */ |