em_timer.h

Go to the documentation of this file.
00001 /***************************************************************************/
00034 #ifndef __EM_TIMER_H
00035 #define __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_PRSCH7 )
00224   timerPRSSELCh4 = _TIMER_CC_CTRL_PRSSEL_PRSCH4, 
00225   timerPRSSELCh5 = _TIMER_CC_CTRL_PRSSEL_PRSCH5, 
00226   timerPRSSELCh6 = _TIMER_CC_CTRL_PRSSEL_PRSCH6, 
00227   timerPRSSELCh7 = _TIMER_CC_CTRL_PRSSEL_PRSCH7, 
00228 #endif
00229 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH11 )
00230   timerPRSSELCh8  = _TIMER_CC_CTRL_PRSSEL_PRSCH8,  
00231   timerPRSSELCh9  = _TIMER_CC_CTRL_PRSSEL_PRSCH9,  
00232   timerPRSSELCh10 = _TIMER_CC_CTRL_PRSSEL_PRSCH10, 
00233   timerPRSSELCh11 = _TIMER_CC_CTRL_PRSSEL_PRSCH11  
00234 #endif
00235 } TIMER_PRSSEL_TypeDef;
00236 
00237 #ifdef _TIMER_DTFC_DTFA_NONE
00238 
00239 typedef enum
00240 {
00241   timerDtiFaultActionNone     = _TIMER_DTFC_DTFA_NONE,     
00242   timerDtiFaultActionInactive = _TIMER_DTFC_DTFA_INACTIVE, 
00243   timerDtiFaultActionClear    = _TIMER_DTFC_DTFA_CLEAR,    
00244   timerDtiFaultActionTristate = _TIMER_DTFC_DTFA_TRISTATE  
00245 } TIMER_DtiFaultAction_TypeDef;
00246 #endif
00247 
00248 /*******************************************************************************
00249  *******************************   STRUCTS   ***********************************
00250  ******************************************************************************/
00251 
00253 typedef struct
00254 {
00256   bool                      enable;
00257 
00259   bool                      debugRun;
00260 
00262   TIMER_Prescale_TypeDef    prescale;
00263 
00265   TIMER_ClkSel_TypeDef      clkSel;
00266 
00267 #if defined( TIMER_CTRL_X2CNT ) && defined( TIMER_CTRL_ATI )
00268 
00269   bool                      count2x;
00270 
00273   bool                      ati;
00274 #endif
00275 
00277   TIMER_InputAction_TypeDef fallAction;
00278 
00280   TIMER_InputAction_TypeDef riseAction;
00281 
00283   TIMER_Mode_TypeDef        mode;
00284 
00286   bool                      dmaClrAct;
00287 
00289   bool                      quadModeX4;
00290 
00292   bool                      oneShot;
00293 
00295   bool                      sync;
00296 } TIMER_Init_TypeDef;
00297 
00299 #if defined( TIMER_CTRL_X2CNT ) && defined( TIMER_CTRL_ATI )
00300 #define TIMER_INIT_DEFAULT                                                              \
00301   { true,                   /* Enable timer when init complete. */                      \
00302     false,                  /* Stop counter during debug halt. */                       \
00303     timerPrescale1,         /* No prescaling. */                                        \
00304     timerClkSelHFPerClk,    /* Select HFPER clock. */                                   \
00305     false,                  /* Not 2x count mode. */                                    \
00306     false,                  /* No ATI. */                                               \
00307     timerInputActionNone,   /* No action on falling input edge. */                      \
00308     timerInputActionNone,   /* No action on rising input edge. */                       \
00309     timerModeUp,            /* Up-counting. */                                          \
00310     false,                  /* Do not clear DMA requests when DMA channel is active. */ \
00311     false,                  /* Select X2 quadrature decode mode (if used). */           \
00312     false,                  /* Disable one shot. */                                     \
00313     false                   /* Not started/stopped/reloaded by other timers. */         \
00314   }
00315 #else
00316 #define TIMER_INIT_DEFAULT                                                              \
00317   { true,                   /* Enable timer when init complete. */                      \
00318     false,                  /* Stop counter during debug halt. */                       \
00319     timerPrescale1,         /* No prescaling. */                                        \
00320     timerClkSelHFPerClk,    /* Select HFPER clock. */                                   \
00321     timerInputActionNone,   /* No action on falling input edge. */                      \
00322     timerInputActionNone,   /* No action on rising input edge. */                       \
00323     timerModeUp,            /* Up-counting. */                                          \
00324     false,                  /* Do not clear DMA requests when DMA channel is active. */ \
00325     false,                  /* Select X2 quadrature decode mode (if used). */           \
00326     false,                  /* Disable one shot. */                                     \
00327     false                   /* Not started/stopped/reloaded by other timers. */         \
00328   }
00329 #endif
00330 
00332 typedef struct
00333 {
00335   TIMER_Event_TypeDef        eventCtrl;
00336 
00338   TIMER_Edge_TypeDef         edge;
00339 
00344   TIMER_PRSSEL_TypeDef       prsSel;
00345 
00347   TIMER_OutputAction_TypeDef cufoa;
00348 
00350   TIMER_OutputAction_TypeDef cofoa;
00351 
00353   TIMER_OutputAction_TypeDef cmoa;
00354 
00356   TIMER_CCMode_TypeDef       mode;
00357 
00359   bool                       filter;
00360 
00362   bool                       prsInput;
00363 
00371   bool                       coist;
00372 
00374   bool                       outInvert;
00375 } TIMER_InitCC_TypeDef;
00376 
00378 #define TIMER_INITCC_DEFAULT                                                   \
00379   { timerEventEveryEdge,      /* Event on every capture. */                    \
00380     timerEdgeRising,          /* Input capture edge on rising edge. */         \
00381     timerPRSSELCh0,           /* Not used by default, select PRS channel 0. */ \
00382     timerOutputActionNone,    /* No action on underflow. */                    \
00383     timerOutputActionNone,    /* No action on overflow. */                     \
00384     timerOutputActionNone,    /* No action on match. */                        \
00385     timerCCModeOff,           /* Disable compare/capture channel. */           \
00386     false,                    /* Disable filter. */                            \
00387     false,                    /* Select TIMERnCCx input. */                    \
00388     false,                    /* Clear output when countre disabled. */        \
00389     false                     /* Do not invert output. */                      \
00390   }
00391 
00392 #ifdef _TIMER_DTCTRL_MASK
00393 
00394 typedef struct
00395 {
00397   bool                          enable;
00398 
00400   bool                          activeLowOut;
00401 
00403   bool                          invertComplementaryOut;
00404 
00406   bool                          autoRestart;
00407 
00409   bool                          enablePrsSource;
00410 
00413   TIMER_PRSSEL_TypeDef          prsSel;
00414 
00416   TIMER_Prescale_TypeDef        prescale;
00417 
00419   unsigned int                  riseTime;
00420 
00422   unsigned int                  fallTime;
00423 
00428   uint32_t                      outputsEnableMask;
00429 
00431   bool                          enableFaultSourceCoreLockup;
00432 
00434   bool                          enableFaultSourceDebugger;
00435 
00437   bool                          enableFaultSourcePrsSel0;
00438 
00440   TIMER_PRSSEL_TypeDef          faultSourcePrsSel0;
00441 
00443   bool                          enableFaultSourcePrsSel1;
00444 
00446   TIMER_PRSSEL_TypeDef          faultSourcePrsSel1;
00447 
00449   TIMER_DtiFaultAction_TypeDef  faultAction;
00450 
00451 } TIMER_InitDTI_TypeDef;
00452 
00453 
00455 #define TIMER_INITDTI_DEFAULT                                                  \
00456   { true,                     /* Enable the DTI. */                            \
00457     false,                    /* CC[0|1|2] outputs are active high. */         \
00458     false,                    /* CDTI[0|1|2] outputs are not inverted. */      \
00459     false,                    /* No auto restart when debugger exits. */       \
00460     false,                    /* No PRS source selected. */                    \
00461     timerPRSSELCh0,           /* Not used by default, select PRS channel 0. */ \
00462     timerPrescale1,           /* No prescaling.  */                            \
00463     0,                        /* No rise time. */                              \
00464     0,                        /* No fall time. */                              \
00465     TIMER_DTOGEN_DTOGCC0EN|TIMER_DTOGEN_DTOGCDTI0EN, /* Enable CC0 and CDTI0 */\
00466     true,                     /* Enable core lockup as fault source */         \
00467     true,                     /* Enable debugger as fault source */            \
00468     false,                    /* Disable PRS fault source 0 */                 \
00469     timerPRSSELCh0,           /* Not used by default, select PRS channel 0. */ \
00470     false,                    /* Disable PRS fault source 1 */                 \
00471     timerPRSSELCh0,           /* Not used by default, select PRS channel 0. */ \
00472     timerDtiFaultActionInactive, /* No fault action. */                        \
00473   }
00474 #endif /* _TIMER_DTCTRL_MASK */
00475 
00476 
00477 /*******************************************************************************
00478  *****************************   PROTOTYPES   **********************************
00479  ******************************************************************************/
00480 
00481 /***************************************************************************/
00495 __STATIC_INLINE uint32_t TIMER_CaptureGet(TIMER_TypeDef *timer, unsigned int ch)
00496 {
00497   return(timer->CC[ch].CCV);
00498 }
00499 
00500 
00501 /***************************************************************************/
00520 __STATIC_INLINE void TIMER_CompareBufSet(TIMER_TypeDef *timer,
00521                                          unsigned int ch,
00522                                          uint32_t val)
00523 {
00524   timer->CC[ch].CCVB = val;
00525 }
00526 
00527 
00528 /***************************************************************************/
00542 __STATIC_INLINE void TIMER_CompareSet(TIMER_TypeDef *timer,
00543                                       unsigned int ch,
00544                                       uint32_t val)
00545 {
00546   timer->CC[ch].CCV = val;
00547 }
00548 
00549 
00550 /***************************************************************************/
00560 __STATIC_INLINE uint32_t TIMER_CounterGet(TIMER_TypeDef *timer)
00561 {
00562   return(timer->CNT);
00563 }
00564 
00565 
00566 /***************************************************************************/
00576 __STATIC_INLINE void TIMER_CounterSet(TIMER_TypeDef *timer, uint32_t val)
00577 {
00578   timer->CNT = val;
00579 }
00580 
00581 
00582 /***************************************************************************/
00592 __STATIC_INLINE void TIMER_Enable(TIMER_TypeDef *timer, bool enable)
00593 {
00594   EFM_ASSERT(TIMER_REF_VALID(timer));
00595 
00596   if (enable)
00597   {
00598     timer->CMD = TIMER_CMD_START;
00599   }
00600   else
00601   {
00602     timer->CMD = TIMER_CMD_STOP;
00603   }
00604 }
00605 
00606 
00607 void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init);
00608 void TIMER_InitCC(TIMER_TypeDef *timer,
00609                   unsigned int ch,
00610                   const TIMER_InitCC_TypeDef *init);
00611 
00612 #ifdef _TIMER_DTCTRL_MASK
00613 void TIMER_InitDTI(TIMER_TypeDef *timer, const TIMER_InitDTI_TypeDef *init);
00614 
00615 /***************************************************************************/
00625 __STATIC_INLINE void TIMER_EnableDTI(TIMER_TypeDef *timer, bool enable)
00626 {
00627   EFM_ASSERT(TIMER0 == timer);
00628 
00629   if (enable)
00630   {
00631     timer->DTCTRL |= TIMER_DTCTRL_DTEN;
00632   }
00633   else
00634   {
00635     timer->DTCTRL &= ~TIMER_DTCTRL_DTEN;
00636   }
00637 }
00638 
00639 
00640 /***************************************************************************/
00654 __STATIC_INLINE uint32_t TIMER_GetDTIFault(TIMER_TypeDef *timer)
00655 {
00656   EFM_ASSERT(TIMER0 == timer);
00657   return(timer->DTFAULT);
00658 }
00659 
00660 
00661 /***************************************************************************/
00672 __STATIC_INLINE void TIMER_ClearDTIFault(TIMER_TypeDef *timer, uint32_t flags)
00673                                          
00674 {
00675   EFM_ASSERT(TIMER0 == timer);
00676   timer->DTFAULTC = flags;
00677 }
00678 #endif /* _TIMER_DTCTRL_MASK */
00679 
00680 
00681 /***************************************************************************/
00692 __STATIC_INLINE void TIMER_IntClear(TIMER_TypeDef *timer, uint32_t flags)
00693 {
00694   timer->IFC = flags;
00695 }
00696 
00697 
00698 /***************************************************************************/
00709 __STATIC_INLINE void TIMER_IntDisable(TIMER_TypeDef *timer, uint32_t flags)
00710 {
00711   timer->IEN &= ~(flags);
00712 }
00713 
00714 
00715 /***************************************************************************/
00731 __STATIC_INLINE void TIMER_IntEnable(TIMER_TypeDef *timer, uint32_t flags)
00732 {
00733   timer->IEN |= flags;
00734 }
00735 
00736 
00737 /***************************************************************************/
00751 __STATIC_INLINE uint32_t TIMER_IntGet(TIMER_TypeDef *timer)
00752 {
00753   return(timer->IF);
00754 }
00755 
00756 
00757 /***************************************************************************/
00776 __STATIC_INLINE uint32_t TIMER_IntGetEnabled(TIMER_TypeDef *timer)
00777 {
00778   uint32_t tmp;
00779 
00780   /* Store TIMER->IEN in temporary variable in order to define explicit order
00781    * of volatile accesses. */
00782   tmp = timer->IEN;
00783 
00784   /* Bitwise AND of pending and enabled interrupts */
00785   return timer->IF & tmp;
00786 }
00787 
00788 
00789 /***************************************************************************/
00800 __STATIC_INLINE void TIMER_IntSet(TIMER_TypeDef *timer, uint32_t flags)
00801 {
00802   timer->IFS = flags;
00803 }
00804 
00805 #ifdef TIMER_DTLOCK_LOCKKEY_LOCK
00806 /***************************************************************************/
00822 __STATIC_INLINE void TIMER_Lock(TIMER_TypeDef *timer)
00823 {
00824   EFM_ASSERT(TIMER0 == timer);
00825 
00826   timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_LOCK;
00827 }
00828 #endif
00829 
00830 void TIMER_Reset(TIMER_TypeDef *timer);
00831 
00832 /***************************************************************************/
00847 __STATIC_INLINE void TIMER_TopBufSet(TIMER_TypeDef *timer, uint32_t val)
00848 {
00849   timer->TOPB = val;
00850 }
00851 
00852 
00853 /***************************************************************************/
00863 __STATIC_INLINE uint32_t TIMER_TopGet(TIMER_TypeDef *timer)
00864 {
00865   return(timer->TOP);
00866 }
00867 
00868 
00869 /***************************************************************************/
00879 __STATIC_INLINE void TIMER_TopSet(TIMER_TypeDef *timer, uint32_t val)
00880 {
00881   timer->TOP = val;
00882 }
00883 
00884 
00885 #ifdef TIMER_DTLOCK_LOCKKEY_UNLOCK
00886 /***************************************************************************/
00893 __STATIC_INLINE void TIMER_Unlock(TIMER_TypeDef *timer)
00894 {
00895   EFM_ASSERT(TIMER0 == timer);
00896 
00897   timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_UNLOCK;
00898 }
00899 #endif
00900 
00901 
00905 #ifdef __cplusplus
00906 }
00907 #endif
00908 
00909 #endif /* defined(TIMER_COUNT) && (TIMER_COUNT > 0) */
00910 #endif /* __EM_TIMER_H */