em_timer.h

Go to the documentation of this file.
00001 /***************************************************************************/
00034 #ifndef __SILICON_LABS_EM_TIMER_H_
00035 #define __SILICON_LABS_EM_TIMER_H_
00036 
00037 #include "em_device.h"
00038 #if defined(TIMER_COUNT) && (TIMER_COUNT > 0)
00039 
00040 #include <stdbool.h>
00041 #include "em_assert.h"
00042 
00043 #ifdef __cplusplus
00044 extern "C" {
00045 #endif
00046 
00047 /***************************************************************************/
00052 /***************************************************************************/
00057 /*******************************************************************************
00058  *******************************   DEFINES   ***********************************
00059  ******************************************************************************/
00060 
00065 #if (TIMER_COUNT == 1)
00066 #define TIMER_REF_VALID(ref)    ((ref) == TIMER0)
00067 #elif (TIMER_COUNT == 2)
00068 #define TIMER_REF_VALID(ref)    (((ref) == TIMER0) || ((ref) == TIMER1))
00069 #elif (TIMER_COUNT == 3)
00070 #define TIMER_REF_VALID(ref)    (((ref) == TIMER0) || \
00071                                  ((ref) == TIMER1) || \
00072                                  ((ref) == TIMER2))
00073 #elif (TIMER_COUNT == 4)
00074 #define TIMER_REF_VALID(ref)    (((ref) == TIMER0) || \
00075                                  ((ref) == TIMER1) || \
00076                                  ((ref) == TIMER2) || \
00077                                  ((ref) == TIMER3))
00078 #else
00079 #error Undefined number of timers.
00080 #endif
00081 
00083 #define TIMER_CH_VALID(ch)    ((ch) < 3)
00084 
00087 /*******************************************************************************
00088  ********************************   ENUMS   ************************************
00089  ******************************************************************************/
00090 
00092 typedef enum
00093 {
00094   timerCCModeOff     = _TIMER_CC_CTRL_MODE_OFF,           
00095   timerCCModeCapture = _TIMER_CC_CTRL_MODE_INPUTCAPTURE,  
00096   timerCCModeCompare = _TIMER_CC_CTRL_MODE_OUTPUTCOMPARE, 
00097   timerCCModePWM     = _TIMER_CC_CTRL_MODE_PWM            
00098 } TIMER_CCMode_TypeDef;
00099 
00100 
00102 typedef enum
00103 {
00105   timerClkSelHFPerClk = _TIMER_CTRL_CLKSEL_PRESCHFPERCLK,
00106 
00108   timerClkSelCC1      = _TIMER_CTRL_CLKSEL_CC1,
00109 
00114   timerClkSelCascade  = _TIMER_CTRL_CLKSEL_TIMEROUF
00115 } TIMER_ClkSel_TypeDef;
00116 
00117 
00119 typedef enum
00120 {
00122   timerEdgeRising  = _TIMER_CC_CTRL_ICEDGE_RISING,
00123 
00125   timerEdgeFalling = _TIMER_CC_CTRL_ICEDGE_FALLING,
00126 
00128   timerEdgeBoth    = _TIMER_CC_CTRL_ICEDGE_BOTH,
00129 
00131   timerEdgeNone    = _TIMER_CC_CTRL_ICEDGE_NONE
00132 } TIMER_Edge_TypeDef;
00133 
00134 
00136 typedef enum
00137 {
00139   timerEventEveryEdge    = _TIMER_CC_CTRL_ICEVCTRL_EVERYEDGE,
00141   timerEventEvery2ndEdge = _TIMER_CC_CTRL_ICEVCTRL_EVERYSECONDEDGE,
00146   timerEventRising       = _TIMER_CC_CTRL_ICEVCTRL_RISING,
00151   timerEventFalling      = _TIMER_CC_CTRL_ICEVCTRL_FALLING
00152 } TIMER_Event_TypeDef;
00153 
00154 
00156 typedef enum
00157 {
00159   timerInputActionNone        = _TIMER_CTRL_FALLA_NONE,
00160 
00162   timerInputActionStart       = _TIMER_CTRL_FALLA_START,
00163 
00165   timerInputActionStop        = _TIMER_CTRL_FALLA_STOP,
00166 
00168   timerInputActionReloadStart = _TIMER_CTRL_FALLA_RELOADSTART
00169 } TIMER_InputAction_TypeDef;
00170 
00171 
00173 typedef enum
00174 {
00175   timerModeUp     = _TIMER_CTRL_MODE_UP,     
00176   timerModeDown   = _TIMER_CTRL_MODE_DOWN,   
00177   timerModeUpDown = _TIMER_CTRL_MODE_UPDOWN, 
00178   timerModeQDec   = _TIMER_CTRL_MODE_QDEC    
00179 } TIMER_Mode_TypeDef;
00180 
00181 
00183 typedef enum
00184 {
00186   timerOutputActionNone   = _TIMER_CC_CTRL_CUFOA_NONE,
00187 
00189   timerOutputActionToggle = _TIMER_CC_CTRL_CUFOA_TOGGLE,
00190 
00192   timerOutputActionClear  = _TIMER_CC_CTRL_CUFOA_CLEAR,
00193 
00195   timerOutputActionSet    = _TIMER_CC_CTRL_CUFOA_SET
00196 } TIMER_OutputAction_TypeDef;
00197 
00198 
00200 typedef enum
00201 {
00202   timerPrescale1    = _TIMER_CTRL_PRESC_DIV1,     
00203   timerPrescale2    = _TIMER_CTRL_PRESC_DIV2,     
00204   timerPrescale4    = _TIMER_CTRL_PRESC_DIV4,     
00205   timerPrescale8    = _TIMER_CTRL_PRESC_DIV8,     
00206   timerPrescale16   = _TIMER_CTRL_PRESC_DIV16,    
00207   timerPrescale32   = _TIMER_CTRL_PRESC_DIV32,    
00208   timerPrescale64   = _TIMER_CTRL_PRESC_DIV64,    
00209   timerPrescale128  = _TIMER_CTRL_PRESC_DIV128,   
00210   timerPrescale256  = _TIMER_CTRL_PRESC_DIV256,   
00211   timerPrescale512  = _TIMER_CTRL_PRESC_DIV512,   
00212   timerPrescale1024 = _TIMER_CTRL_PRESC_DIV1024   
00213 } TIMER_Prescale_TypeDef;
00214 
00215 
00217 typedef enum
00218 {
00219   timerPRSSELCh0 = _TIMER_CC_CTRL_PRSSEL_PRSCH0,        
00220   timerPRSSELCh1 = _TIMER_CC_CTRL_PRSSEL_PRSCH1,        
00221   timerPRSSELCh2 = _TIMER_CC_CTRL_PRSSEL_PRSCH2,        
00222   timerPRSSELCh3 = _TIMER_CC_CTRL_PRSSEL_PRSCH3,        
00223 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH4 )
00224   timerPRSSELCh4 = _TIMER_CC_CTRL_PRSSEL_PRSCH4,        
00225 #endif
00226 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH5 )
00227   timerPRSSELCh5 = _TIMER_CC_CTRL_PRSSEL_PRSCH5,        
00228 #endif
00229 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH6 )
00230   timerPRSSELCh6 = _TIMER_CC_CTRL_PRSSEL_PRSCH6,        
00231 #endif
00232 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH7 )
00233   timerPRSSELCh7 = _TIMER_CC_CTRL_PRSSEL_PRSCH7,        
00234 #endif
00235 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH8 )
00236   timerPRSSELCh8  = _TIMER_CC_CTRL_PRSSEL_PRSCH8,       
00237 #endif
00238 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH9 )
00239   timerPRSSELCh9  = _TIMER_CC_CTRL_PRSSEL_PRSCH9,       
00240 #endif
00241 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH10 )
00242   timerPRSSELCh10 = _TIMER_CC_CTRL_PRSSEL_PRSCH10,      
00243 #endif
00244 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH11 )
00245   timerPRSSELCh11 = _TIMER_CC_CTRL_PRSSEL_PRSCH11,      
00246 #endif
00247 } TIMER_PRSSEL_TypeDef;
00248 
00249 #ifdef _TIMER_DTFC_DTFA_NONE
00250 
00251 typedef enum
00252 {
00253   timerDtiFaultActionNone     = _TIMER_DTFC_DTFA_NONE,     
00254   timerDtiFaultActionInactive = _TIMER_DTFC_DTFA_INACTIVE, 
00255   timerDtiFaultActionClear    = _TIMER_DTFC_DTFA_CLEAR,    
00256   timerDtiFaultActionTristate = _TIMER_DTFC_DTFA_TRISTATE  
00257 } TIMER_DtiFaultAction_TypeDef;
00258 #endif
00259 
00260 /*******************************************************************************
00261  *******************************   STRUCTS   ***********************************
00262  ******************************************************************************/
00263 
00265 typedef struct
00266 {
00268   bool                      enable;
00269 
00271   bool                      debugRun;
00272 
00274   TIMER_Prescale_TypeDef    prescale;
00275 
00277   TIMER_ClkSel_TypeDef      clkSel;
00278 
00279 #if defined( TIMER_CTRL_X2CNT ) && defined( TIMER_CTRL_ATI )
00280 
00281   bool                      count2x;
00282 
00285   bool                      ati;
00286 #endif
00287 
00289   TIMER_InputAction_TypeDef fallAction;
00290 
00292   TIMER_InputAction_TypeDef riseAction;
00293 
00295   TIMER_Mode_TypeDef        mode;
00296 
00298   bool                      dmaClrAct;
00299 
00301   bool                      quadModeX4;
00302 
00304   bool                      oneShot;
00305 
00307   bool                      sync;
00308 } TIMER_Init_TypeDef;
00309 
00311 #if defined( TIMER_CTRL_X2CNT ) && defined( TIMER_CTRL_ATI )
00312 #define TIMER_INIT_DEFAULT                                                              \
00313   { true,                   /* Enable timer when init complete. */                      \
00314     false,                  /* Stop counter during debug halt. */                       \
00315     timerPrescale1,         /* No prescaling. */                                        \
00316     timerClkSelHFPerClk,    /* Select HFPER clock. */                                   \
00317     false,                  /* Not 2x count mode. */                                    \
00318     false,                  /* No ATI. */                                               \
00319     timerInputActionNone,   /* No action on falling input edge. */                      \
00320     timerInputActionNone,   /* No action on rising input edge. */                       \
00321     timerModeUp,            /* Up-counting. */                                          \
00322     false,                  /* Do not clear DMA requests when DMA channel is active. */ \
00323     false,                  /* Select X2 quadrature decode mode (if used). */           \
00324     false,                  /* Disable one shot. */                                     \
00325     false                   /* Not started/stopped/reloaded by other timers. */         \
00326   }
00327 #else
00328 #define TIMER_INIT_DEFAULT                                                              \
00329   { true,                   /* Enable timer when init complete. */                      \
00330     false,                  /* Stop counter during debug halt. */                       \
00331     timerPrescale1,         /* No prescaling. */                                        \
00332     timerClkSelHFPerClk,    /* Select HFPER clock. */                                   \
00333     timerInputActionNone,   /* No action on falling input edge. */                      \
00334     timerInputActionNone,   /* No action on rising input edge. */                       \
00335     timerModeUp,            /* Up-counting. */                                          \
00336     false,                  /* Do not clear DMA requests when DMA channel is active. */ \
00337     false,                  /* Select X2 quadrature decode mode (if used). */           \
00338     false,                  /* Disable one shot. */                                     \
00339     false                   /* Not started/stopped/reloaded by other timers. */         \
00340   }
00341 #endif
00342 
00344 typedef struct
00345 {
00347   TIMER_Event_TypeDef        eventCtrl;
00348 
00350   TIMER_Edge_TypeDef         edge;
00351 
00356   TIMER_PRSSEL_TypeDef       prsSel;
00357 
00359   TIMER_OutputAction_TypeDef cufoa;
00360 
00362   TIMER_OutputAction_TypeDef cofoa;
00363 
00365   TIMER_OutputAction_TypeDef cmoa;
00366 
00368   TIMER_CCMode_TypeDef       mode;
00369 
00371   bool                       filter;
00372 
00374   bool                       prsInput;
00375 
00383   bool                       coist;
00384 
00386   bool                       outInvert;
00387 } TIMER_InitCC_TypeDef;
00388 
00390 #define TIMER_INITCC_DEFAULT                                                   \
00391   { timerEventEveryEdge,      /* Event on every capture. */                    \
00392     timerEdgeRising,          /* Input capture edge on rising edge. */         \
00393     timerPRSSELCh0,           /* Not used by default, select PRS channel 0. */ \
00394     timerOutputActionNone,    /* No action on underflow. */                    \
00395     timerOutputActionNone,    /* No action on overflow. */                     \
00396     timerOutputActionNone,    /* No action on match. */                        \
00397     timerCCModeOff,           /* Disable compare/capture channel. */           \
00398     false,                    /* Disable filter. */                            \
00399     false,                    /* Select TIMERnCCx input. */                    \
00400     false,                    /* Clear output when counter disabled. */        \
00401     false                     /* Do not invert output. */                      \
00402   }
00403 
00404 #ifdef _TIMER_DTCTRL_MASK
00405 
00406 typedef struct
00407 {
00409   bool                          enable;
00410 
00412   bool                          activeLowOut;
00413 
00415   bool                          invertComplementaryOut;
00416 
00418   bool                          autoRestart;
00419 
00421   bool                          enablePrsSource;
00422 
00425   TIMER_PRSSEL_TypeDef          prsSel;
00426 
00428   TIMER_Prescale_TypeDef        prescale;
00429 
00431   unsigned int                  riseTime;
00432 
00434   unsigned int                  fallTime;
00435 
00440   uint32_t                      outputsEnableMask;
00441 
00443   bool                          enableFaultSourceCoreLockup;
00444 
00446   bool                          enableFaultSourceDebugger;
00447 
00449   bool                          enableFaultSourcePrsSel0;
00450 
00452   TIMER_PRSSEL_TypeDef          faultSourcePrsSel0;
00453 
00455   bool                          enableFaultSourcePrsSel1;
00456 
00458   TIMER_PRSSEL_TypeDef          faultSourcePrsSel1;
00459 
00461   TIMER_DtiFaultAction_TypeDef  faultAction;
00462 
00463 } TIMER_InitDTI_TypeDef;
00464 
00465 
00467 #define TIMER_INITDTI_DEFAULT                                                  \
00468   { true,                     /* Enable the DTI. */                            \
00469     false,                    /* CC[0|1|2] outputs are active high. */         \
00470     false,                    /* CDTI[0|1|2] outputs are not inverted. */      \
00471     false,                    /* No auto restart when debugger exits. */       \
00472     false,                    /* No PRS source selected. */                    \
00473     timerPRSSELCh0,           /* Not used by default, select PRS channel 0. */ \
00474     timerPrescale1,           /* No prescaling.  */                            \
00475     0,                        /* No rise time. */                              \
00476     0,                        /* No fall time. */                              \
00477     TIMER_DTOGEN_DTOGCC0EN|TIMER_DTOGEN_DTOGCDTI0EN, /* Enable CC0 and CDTI0 */\
00478     true,                     /* Enable core lockup as fault source */         \
00479     true,                     /* Enable debugger as fault source */            \
00480     false,                    /* Disable PRS fault source 0 */                 \
00481     timerPRSSELCh0,           /* Not used by default, select PRS channel 0. */ \
00482     false,                    /* Disable PRS fault source 1 */                 \
00483     timerPRSSELCh0,           /* Not used by default, select PRS channel 0. */ \
00484     timerDtiFaultActionInactive, /* No fault action. */                        \
00485   }
00486 #endif /* _TIMER_DTCTRL_MASK */
00487 
00488 
00489 /*******************************************************************************
00490  *****************************   PROTOTYPES   **********************************
00491  ******************************************************************************/
00492 
00493 /***************************************************************************/
00507 __STATIC_INLINE uint32_t TIMER_CaptureGet(TIMER_TypeDef *timer, unsigned int ch)
00508 {
00509   return(timer->CC[ch].CCV);
00510 }
00511 
00512 
00513 /***************************************************************************/
00532 __STATIC_INLINE void TIMER_CompareBufSet(TIMER_TypeDef *timer,
00533                                          unsigned int ch,
00534                                          uint32_t val)
00535 {
00536   timer->CC[ch].CCVB = val;
00537 }
00538 
00539 
00540 /***************************************************************************/
00554 __STATIC_INLINE void TIMER_CompareSet(TIMER_TypeDef *timer,
00555                                       unsigned int ch,
00556                                       uint32_t val)
00557 {
00558   timer->CC[ch].CCV = val;
00559 }
00560 
00561 
00562 /***************************************************************************/
00572 __STATIC_INLINE uint32_t TIMER_CounterGet(TIMER_TypeDef *timer)
00573 {
00574   return(timer->CNT);
00575 }
00576 
00577 
00578 /***************************************************************************/
00588 __STATIC_INLINE void TIMER_CounterSet(TIMER_TypeDef *timer, uint32_t val)
00589 {
00590   timer->CNT = val;
00591 }
00592 
00593 
00594 /***************************************************************************/
00604 __STATIC_INLINE void TIMER_Enable(TIMER_TypeDef *timer, bool enable)
00605 {
00606   EFM_ASSERT(TIMER_REF_VALID(timer));
00607 
00608   if (enable)
00609   {
00610     timer->CMD = TIMER_CMD_START;
00611   }
00612   else
00613   {
00614     timer->CMD = TIMER_CMD_STOP;
00615   }
00616 }
00617 
00618 
00619 void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init);
00620 void TIMER_InitCC(TIMER_TypeDef *timer,
00621                   unsigned int ch,
00622                   const TIMER_InitCC_TypeDef *init);
00623 
00624 #ifdef _TIMER_DTCTRL_MASK
00625 void TIMER_InitDTI(TIMER_TypeDef *timer, const TIMER_InitDTI_TypeDef *init);
00626 
00627 /***************************************************************************/
00637 __STATIC_INLINE void TIMER_EnableDTI(TIMER_TypeDef *timer, bool enable)
00638 {
00639   EFM_ASSERT(TIMER0 == timer);
00640 
00641   if (enable)
00642   {
00643     timer->DTCTRL |= TIMER_DTCTRL_DTEN;
00644   }
00645   else
00646   {
00647     timer->DTCTRL &= ~TIMER_DTCTRL_DTEN;
00648   }
00649 }
00650 
00651 
00652 /***************************************************************************/
00666 __STATIC_INLINE uint32_t TIMER_GetDTIFault(TIMER_TypeDef *timer)
00667 {
00668   EFM_ASSERT(TIMER0 == timer);
00669   return(timer->DTFAULT);
00670 }
00671 
00672 
00673 /***************************************************************************/
00684 __STATIC_INLINE void TIMER_ClearDTIFault(TIMER_TypeDef *timer, uint32_t flags)
00685 
00686 {
00687   EFM_ASSERT(TIMER0 == timer);
00688   timer->DTFAULTC = flags;
00689 }
00690 #endif /* _TIMER_DTCTRL_MASK */
00691 
00692 
00693 /***************************************************************************/
00704 __STATIC_INLINE void TIMER_IntClear(TIMER_TypeDef *timer, uint32_t flags)
00705 {
00706   timer->IFC = flags;
00707 }
00708 
00709 
00710 /***************************************************************************/
00721 __STATIC_INLINE void TIMER_IntDisable(TIMER_TypeDef *timer, uint32_t flags)
00722 {
00723   timer->IEN &= ~(flags);
00724 }
00725 
00726 
00727 /***************************************************************************/
00743 __STATIC_INLINE void TIMER_IntEnable(TIMER_TypeDef *timer, uint32_t flags)
00744 {
00745   timer->IEN |= flags;
00746 }
00747 
00748 
00749 /***************************************************************************/
00763 __STATIC_INLINE uint32_t TIMER_IntGet(TIMER_TypeDef *timer)
00764 {
00765   return(timer->IF);
00766 }
00767 
00768 
00769 /***************************************************************************/
00788 __STATIC_INLINE uint32_t TIMER_IntGetEnabled(TIMER_TypeDef *timer)
00789 {
00790   uint32_t tmp;
00791 
00792   /* Store TIMER->IEN in temporary variable in order to define explicit order
00793    * of volatile accesses. */
00794   tmp = timer->IEN;
00795 
00796   /* Bitwise AND of pending and enabled interrupts */
00797   return timer->IF & tmp;
00798 }
00799 
00800 
00801 /***************************************************************************/
00812 __STATIC_INLINE void TIMER_IntSet(TIMER_TypeDef *timer, uint32_t flags)
00813 {
00814   timer->IFS = flags;
00815 }
00816 
00817 #ifdef TIMER_DTLOCK_LOCKKEY_LOCK
00818 /***************************************************************************/
00834 __STATIC_INLINE void TIMER_Lock(TIMER_TypeDef *timer)
00835 {
00836   EFM_ASSERT(TIMER0 == timer);
00837 
00838   timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_LOCK;
00839 }
00840 #endif
00841 
00842 void TIMER_Reset(TIMER_TypeDef *timer);
00843 
00844 /***************************************************************************/
00859 __STATIC_INLINE void TIMER_TopBufSet(TIMER_TypeDef *timer, uint32_t val)
00860 {
00861   timer->TOPB = val;
00862 }
00863 
00864 
00865 /***************************************************************************/
00875 __STATIC_INLINE uint32_t TIMER_TopGet(TIMER_TypeDef *timer)
00876 {
00877   return(timer->TOP);
00878 }
00879 
00880 
00881 /***************************************************************************/
00891 __STATIC_INLINE void TIMER_TopSet(TIMER_TypeDef *timer, uint32_t val)
00892 {
00893   timer->TOP = val;
00894 }
00895 
00896 
00897 #ifdef TIMER_DTLOCK_LOCKKEY_UNLOCK
00898 /***************************************************************************/
00905 __STATIC_INLINE void TIMER_Unlock(TIMER_TypeDef *timer)
00906 {
00907   EFM_ASSERT(TIMER0 == timer);
00908 
00909   timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_UNLOCK;
00910 }
00911 #endif
00912 
00913 
00917 #ifdef __cplusplus
00918 }
00919 #endif
00920 
00921 #endif /* defined(TIMER_COUNT) && (TIMER_COUNT > 0) */
00922 #endif /* __SILICON_LABS_EM_TIMER_H_ */