]> git.sur5r.net Git - freertos/blob
13bcf70578678338fb4eab52f3e77b4ed963dbd0
[freertos] /
1 /***************************************************************************//**\r
2  * @file em_timer.h\r
3  * @brief Timer/counter (TIMER) peripheral API\r
4  * @version 4.0.0\r
5  *******************************************************************************\r
6  * @section License\r
7  * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>\r
8  *******************************************************************************\r
9  *\r
10  * Permission is granted to anyone to use this software for any purpose,\r
11  * including commercial applications, and to alter it and redistribute it\r
12  * freely, subject to the following restrictions:\r
13  *\r
14  * 1. The origin of this software must not be misrepresented; you must not\r
15  *    claim that you wrote the original software.\r
16  * 2. Altered source versions must be plainly marked as such, and must not be\r
17  *    misrepresented as being the original software.\r
18  * 3. This notice may not be removed or altered from any source distribution.\r
19  *\r
20  * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no\r
21  * obligation to support this Software. Silicon Labs is providing the\r
22  * Software "AS IS", with no express or implied warranties of any kind,\r
23  * including, but not limited to, any implied warranties of merchantability\r
24  * or fitness for any particular purpose or warranties against infringement\r
25  * of any proprietary rights of a third party.\r
26  *\r
27  * Silicon Labs will not be liable for any consequential, incidental, or\r
28  * special damages, or any other relief, or for any claim by any third party,\r
29  * arising from your use of this Software.\r
30  *\r
31  ******************************************************************************/\r
32 \r
33 \r
34 #ifndef __SILICON_LABS_EM_TIMER_H_\r
35 #define __SILICON_LABS_EM_TIMER_H_\r
36 \r
37 #include "em_device.h"\r
38 #if defined(TIMER_COUNT) && (TIMER_COUNT > 0)\r
39 \r
40 #include <stdbool.h>\r
41 #include "em_assert.h"\r
42 \r
43 #ifdef __cplusplus\r
44 extern "C" {\r
45 #endif\r
46 \r
47 /***************************************************************************//**\r
48  * @addtogroup EM_Library\r
49  * @{\r
50  ******************************************************************************/\r
51 \r
52 /***************************************************************************//**\r
53  * @addtogroup TIMER\r
54  * @{\r
55  ******************************************************************************/\r
56 \r
57 /*******************************************************************************\r
58  *******************************   DEFINES   ***********************************\r
59  ******************************************************************************/\r
60 \r
61 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
62 \r
63 \r
64 /** Validation of TIMER register block pointer reference for assert statements. */\r
65 #if (TIMER_COUNT == 1)\r
66 #define TIMER_REF_VALID(ref)    ((ref) == TIMER0)\r
67 #elif (TIMER_COUNT == 2)\r
68 #define TIMER_REF_VALID(ref)    (((ref) == TIMER0) || ((ref) == TIMER1))\r
69 #elif (TIMER_COUNT == 3)\r
70 #define TIMER_REF_VALID(ref)    (((ref) == TIMER0) || \\r
71                                  ((ref) == TIMER1) || \\r
72                                  ((ref) == TIMER2))\r
73 #elif (TIMER_COUNT == 4)\r
74 #define TIMER_REF_VALID(ref)    (((ref) == TIMER0) || \\r
75                                  ((ref) == TIMER1) || \\r
76                                  ((ref) == TIMER2) || \\r
77                                  ((ref) == TIMER3))\r
78 #else\r
79 #error Undefined number of timers.\r
80 #endif\r
81 \r
82 /** Validation of TIMER compare/capture channel number */\r
83 #define TIMER_CH_VALID(ch)    ((ch) < 3)\r
84 \r
85 /** @endcond */\r
86 \r
87 /*******************************************************************************\r
88  ********************************   ENUMS   ************************************\r
89  ******************************************************************************/\r
90 \r
91 /** Timer compare/capture mode. */\r
92 typedef enum\r
93 {\r
94   timerCCModeOff     = _TIMER_CC_CTRL_MODE_OFF,           /**< Channel turned off. */\r
95   timerCCModeCapture = _TIMER_CC_CTRL_MODE_INPUTCAPTURE,  /**< Input capture. */\r
96   timerCCModeCompare = _TIMER_CC_CTRL_MODE_OUTPUTCOMPARE, /**< Output compare. */\r
97   timerCCModePWM     = _TIMER_CC_CTRL_MODE_PWM            /**< Pulse-Width modulation. */\r
98 } TIMER_CCMode_TypeDef;\r
99 \r
100 \r
101 /** Clock select. */\r
102 typedef enum\r
103 {\r
104   /** Prescaled HFPER clock. */\r
105   timerClkSelHFPerClk = _TIMER_CTRL_CLKSEL_PRESCHFPERCLK,\r
106 \r
107   /** Prescaled HFPER clock. */\r
108   timerClkSelCC1      = _TIMER_CTRL_CLKSEL_CC1,\r
109 \r
110   /**\r
111    * Cascaded, clocked by underflow (down-counting) or overflow (up-counting)\r
112    * by lower numbered timer.\r
113    */\r
114   timerClkSelCascade  = _TIMER_CTRL_CLKSEL_TIMEROUF\r
115 } TIMER_ClkSel_TypeDef;\r
116 \r
117 \r
118 /** Input capture edge select. */\r
119 typedef enum\r
120 {\r
121   /** Rising edges detected. */\r
122   timerEdgeRising  = _TIMER_CC_CTRL_ICEDGE_RISING,\r
123 \r
124   /** Falling edges detected. */\r
125   timerEdgeFalling = _TIMER_CC_CTRL_ICEDGE_FALLING,\r
126 \r
127   /** Both edges detected. */\r
128   timerEdgeBoth    = _TIMER_CC_CTRL_ICEDGE_BOTH,\r
129 \r
130   /** No edge detection, leave signal as is. */\r
131   timerEdgeNone    = _TIMER_CC_CTRL_ICEDGE_NONE\r
132 } TIMER_Edge_TypeDef;\r
133 \r
134 \r
135 /** Input capture event control. */\r
136 typedef enum\r
137 {\r
138   /** PRS output pulse, interrupt flag and DMA request set on every capture. */\r
139   timerEventEveryEdge    = _TIMER_CC_CTRL_ICEVCTRL_EVERYEDGE,\r
140   /** PRS output pulse, interrupt flag and DMA request set on every second capture. */\r
141   timerEventEvery2ndEdge = _TIMER_CC_CTRL_ICEVCTRL_EVERYSECONDEDGE,\r
142   /**\r
143    * PRS output pulse, interrupt flag and DMA request set on rising edge (if\r
144    * input capture edge = BOTH).\r
145    */\r
146   timerEventRising       = _TIMER_CC_CTRL_ICEVCTRL_RISING,\r
147   /**\r
148    * PRS output pulse, interrupt flag and DMA request set on falling edge (if\r
149    * input capture edge = BOTH).\r
150    */\r
151   timerEventFalling      = _TIMER_CC_CTRL_ICEVCTRL_FALLING\r
152 } TIMER_Event_TypeDef;\r
153 \r
154 \r
155 /** Input edge action. */\r
156 typedef enum\r
157 {\r
158   /** No action taken. */\r
159   timerInputActionNone        = _TIMER_CTRL_FALLA_NONE,\r
160 \r
161   /** Start counter without reload. */\r
162   timerInputActionStart       = _TIMER_CTRL_FALLA_START,\r
163 \r
164   /** Stop counter without reload. */\r
165   timerInputActionStop        = _TIMER_CTRL_FALLA_STOP,\r
166 \r
167   /** Reload and start counter. */\r
168   timerInputActionReloadStart = _TIMER_CTRL_FALLA_RELOADSTART\r
169 } TIMER_InputAction_TypeDef;\r
170 \r
171 \r
172 /** Timer mode. */\r
173 typedef enum\r
174 {\r
175   timerModeUp     = _TIMER_CTRL_MODE_UP,     /**< Up-counting. */\r
176   timerModeDown   = _TIMER_CTRL_MODE_DOWN,   /**< Down-counting. */\r
177   timerModeUpDown = _TIMER_CTRL_MODE_UPDOWN, /**< Up/down-counting. */\r
178   timerModeQDec   = _TIMER_CTRL_MODE_QDEC    /**< Quadrature decoder. */\r
179 } TIMER_Mode_TypeDef;\r
180 \r
181 \r
182 /** Compare/capture output action. */\r
183 typedef enum\r
184 {\r
185   /** No action. */\r
186   timerOutputActionNone   = _TIMER_CC_CTRL_CUFOA_NONE,\r
187 \r
188   /** Toggle on event. */\r
189   timerOutputActionToggle = _TIMER_CC_CTRL_CUFOA_TOGGLE,\r
190 \r
191   /** Clear on event. */\r
192   timerOutputActionClear  = _TIMER_CC_CTRL_CUFOA_CLEAR,\r
193 \r
194   /** Set on event. */\r
195   timerOutputActionSet    = _TIMER_CC_CTRL_CUFOA_SET\r
196 } TIMER_OutputAction_TypeDef;\r
197 \r
198 \r
199 /** Prescaler. */\r
200 typedef enum\r
201 {\r
202   timerPrescale1    = _TIMER_CTRL_PRESC_DIV1,     /**< Divide by 1. */\r
203   timerPrescale2    = _TIMER_CTRL_PRESC_DIV2,     /**< Divide by 2. */\r
204   timerPrescale4    = _TIMER_CTRL_PRESC_DIV4,     /**< Divide by 4. */\r
205   timerPrescale8    = _TIMER_CTRL_PRESC_DIV8,     /**< Divide by 8. */\r
206   timerPrescale16   = _TIMER_CTRL_PRESC_DIV16,    /**< Divide by 16. */\r
207   timerPrescale32   = _TIMER_CTRL_PRESC_DIV32,    /**< Divide by 32. */\r
208   timerPrescale64   = _TIMER_CTRL_PRESC_DIV64,    /**< Divide by 64. */\r
209   timerPrescale128  = _TIMER_CTRL_PRESC_DIV128,   /**< Divide by 128. */\r
210   timerPrescale256  = _TIMER_CTRL_PRESC_DIV256,   /**< Divide by 256. */\r
211   timerPrescale512  = _TIMER_CTRL_PRESC_DIV512,   /**< Divide by 512. */\r
212   timerPrescale1024 = _TIMER_CTRL_PRESC_DIV1024   /**< Divide by 1024. */\r
213 } TIMER_Prescale_TypeDef;\r
214 \r
215 \r
216 /** Peripheral Reflex System signal. */\r
217 typedef enum\r
218 {\r
219   timerPRSSELCh0 = _TIMER_CC_CTRL_PRSSEL_PRSCH0,        /**< PRS channel 0. */\r
220   timerPRSSELCh1 = _TIMER_CC_CTRL_PRSSEL_PRSCH1,        /**< PRS channel 1. */\r
221   timerPRSSELCh2 = _TIMER_CC_CTRL_PRSSEL_PRSCH2,        /**< PRS channel 2. */\r
222   timerPRSSELCh3 = _TIMER_CC_CTRL_PRSSEL_PRSCH3,        /**< PRS channel 3. */\r
223 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH4 )\r
224   timerPRSSELCh4 = _TIMER_CC_CTRL_PRSSEL_PRSCH4,        /**< PRS channel 4. */\r
225 #endif\r
226 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH5 )\r
227   timerPRSSELCh5 = _TIMER_CC_CTRL_PRSSEL_PRSCH5,        /**< PRS channel 5. */\r
228 #endif\r
229 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH6 )\r
230   timerPRSSELCh6 = _TIMER_CC_CTRL_PRSSEL_PRSCH6,        /**< PRS channel 6. */\r
231 #endif\r
232 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH7 )\r
233   timerPRSSELCh7 = _TIMER_CC_CTRL_PRSSEL_PRSCH7,        /**< PRS channel 7. */\r
234 #endif\r
235 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH8 )\r
236   timerPRSSELCh8  = _TIMER_CC_CTRL_PRSSEL_PRSCH8,       /**< PRS channel 8. */\r
237 #endif\r
238 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH9 )\r
239   timerPRSSELCh9  = _TIMER_CC_CTRL_PRSSEL_PRSCH9,       /**< PRS channel 9. */\r
240 #endif\r
241 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH10 )\r
242   timerPRSSELCh10 = _TIMER_CC_CTRL_PRSSEL_PRSCH10,      /**< PRS channel 10. */\r
243 #endif\r
244 #if defined( _TIMER_CC_CTRL_PRSSEL_PRSCH11 )\r
245   timerPRSSELCh11 = _TIMER_CC_CTRL_PRSSEL_PRSCH11,      /**< PRS channel 11. */\r
246 #endif\r
247 } TIMER_PRSSEL_TypeDef;\r
248 \r
249 #ifdef _TIMER_DTFC_DTFA_NONE\r
250 /** DT (Dead Time) Fault Actions. */\r
251 typedef enum\r
252 {\r
253   timerDtiFaultActionNone     = _TIMER_DTFC_DTFA_NONE,     /**< No action on fault. */\r
254   timerDtiFaultActionInactive = _TIMER_DTFC_DTFA_INACTIVE, /**< Set outputs inactive. */\r
255   timerDtiFaultActionClear    = _TIMER_DTFC_DTFA_CLEAR,    /**< Clear outputs. */\r
256   timerDtiFaultActionTristate = _TIMER_DTFC_DTFA_TRISTATE  /**< Tristate outputs. */\r
257 } TIMER_DtiFaultAction_TypeDef;\r
258 #endif\r
259 \r
260 /*******************************************************************************\r
261  *******************************   STRUCTS   ***********************************\r
262  ******************************************************************************/\r
263 \r
264 /** TIMER initialization structure. */\r
265 typedef struct\r
266 {\r
267   /** Start counting when init completed. */\r
268   bool                      enable;\r
269 \r
270   /** Counter shall keep running during debug halt. */\r
271   bool                      debugRun;\r
272 \r
273   /** Prescaling factor, if HFPER clock used. */\r
274   TIMER_Prescale_TypeDef    prescale;\r
275 \r
276   /** Clock selection. */\r
277   TIMER_ClkSel_TypeDef      clkSel;\r
278 \r
279 #if defined( TIMER_CTRL_X2CNT ) && defined( TIMER_CTRL_ATI )\r
280   /** 2x Count mode, counter increments/decrements by 2, meant for PWN mode. */\r
281   bool                      count2x;\r
282 \r
283   /** ATI (Always Track Inputs) makes CCPOL always track\r
284    * the polarity of the inputs. */\r
285   bool                      ati;\r
286 #endif\r
287 \r
288   /** Action on falling input edge. */\r
289   TIMER_InputAction_TypeDef fallAction;\r
290 \r
291   /** Action on rising input edge. */\r
292   TIMER_InputAction_TypeDef riseAction;\r
293 \r
294   /** Counting mode. */\r
295   TIMER_Mode_TypeDef        mode;\r
296 \r
297   /** DMA request clear on active. */\r
298   bool                      dmaClrAct;\r
299 \r
300   /** Select X2 or X4 quadrature decode mode (if used). */\r
301   bool                      quadModeX4;\r
302 \r
303   /** Determines if only counting up or down once. */\r
304   bool                      oneShot;\r
305 \r
306   /** Timer start/stop/reload by other timers. */\r
307   bool                      sync;\r
308 } TIMER_Init_TypeDef;\r
309 \r
310 /** Default config for TIMER init structure. */\r
311 #if defined( TIMER_CTRL_X2CNT ) && defined( TIMER_CTRL_ATI )\r
312 #define TIMER_INIT_DEFAULT                                                              \\r
313   { true,                   /* Enable timer when init complete. */                      \\r
314     false,                  /* Stop counter during debug halt. */                       \\r
315     timerPrescale1,         /* No prescaling. */                                        \\r
316     timerClkSelHFPerClk,    /* Select HFPER clock. */                                   \\r
317     false,                  /* Not 2x count mode. */                                    \\r
318     false,                  /* No ATI. */                                               \\r
319     timerInputActionNone,   /* No action on falling input edge. */                      \\r
320     timerInputActionNone,   /* No action on rising input edge. */                       \\r
321     timerModeUp,            /* Up-counting. */                                          \\r
322     false,                  /* Do not clear DMA requests when DMA channel is active. */ \\r
323     false,                  /* Select X2 quadrature decode mode (if used). */           \\r
324     false,                  /* Disable one shot. */                                     \\r
325     false                   /* Not started/stopped/reloaded by other timers. */         \\r
326   }\r
327 #else\r
328 #define TIMER_INIT_DEFAULT                                                              \\r
329   { true,                   /* Enable timer when init complete. */                      \\r
330     false,                  /* Stop counter during debug halt. */                       \\r
331     timerPrescale1,         /* No prescaling. */                                        \\r
332     timerClkSelHFPerClk,    /* Select HFPER clock. */                                   \\r
333     timerInputActionNone,   /* No action on falling input edge. */                      \\r
334     timerInputActionNone,   /* No action on rising input edge. */                       \\r
335     timerModeUp,            /* Up-counting. */                                          \\r
336     false,                  /* Do not clear DMA requests when DMA channel is active. */ \\r
337     false,                  /* Select X2 quadrature decode mode (if used). */           \\r
338     false,                  /* Disable one shot. */                                     \\r
339     false                   /* Not started/stopped/reloaded by other timers. */         \\r
340   }\r
341 #endif\r
342 \r
343 /** TIMER compare/capture initialization structure. */\r
344 typedef struct\r
345 {\r
346   /** Input capture event control. */\r
347   TIMER_Event_TypeDef        eventCtrl;\r
348 \r
349   /** Input capture edge select. */\r
350   TIMER_Edge_TypeDef         edge;\r
351 \r
352   /**\r
353    * Peripheral reflex system trigger selection. Only applicable if @p prsInput\r
354    * is enabled.\r
355    */\r
356   TIMER_PRSSEL_TypeDef       prsSel;\r
357 \r
358   /** Counter underflow output action. */\r
359   TIMER_OutputAction_TypeDef cufoa;\r
360 \r
361   /** Counter overflow output action. */\r
362   TIMER_OutputAction_TypeDef cofoa;\r
363 \r
364   /** Counter match output action. */\r
365   TIMER_OutputAction_TypeDef cmoa;\r
366 \r
367   /** Compare/capture channel mode. */\r
368   TIMER_CCMode_TypeDef       mode;\r
369 \r
370   /** Enable digital filter. */\r
371   bool                       filter;\r
372 \r
373   /** Select TIMERnCCx (false) or PRS input (true). */\r
374   bool                       prsInput;\r
375 \r
376   /**\r
377    * Compare output initial state. Only used in Output Compare and PWM mode.\r
378    * When true, the compare/PWM output is set high when the counter is\r
379    * disabled. When counting resumes, this value will represent the initial\r
380    * value for the compare/PWM output. If the bit is cleared, the output\r
381    * will be cleared when the counter is disabled.\r
382    */\r
383   bool                       coist;\r
384 \r
385   /** Invert output from compare/capture channel. */\r
386   bool                       outInvert;\r
387 } TIMER_InitCC_TypeDef;\r
388 \r
389 /** Default config for TIMER compare/capture init structure. */\r
390 #define TIMER_INITCC_DEFAULT                                                   \\r
391   { timerEventEveryEdge,      /* Event on every capture. */                    \\r
392     timerEdgeRising,          /* Input capture edge on rising edge. */         \\r
393     timerPRSSELCh0,           /* Not used by default, select PRS channel 0. */ \\r
394     timerOutputActionNone,    /* No action on underflow. */                    \\r
395     timerOutputActionNone,    /* No action on overflow. */                     \\r
396     timerOutputActionNone,    /* No action on match. */                        \\r
397     timerCCModeOff,           /* Disable compare/capture channel. */           \\r
398     false,                    /* Disable filter. */                            \\r
399     false,                    /* Select TIMERnCCx input. */                    \\r
400     false,                    /* Clear output when counter disabled. */        \\r
401     false                     /* Do not invert output. */                      \\r
402   }\r
403 \r
404 #ifdef _TIMER_DTCTRL_MASK\r
405 /** TIMER Dead Time Insertion (DTI) initialization structure. */\r
406 typedef struct\r
407 {\r
408   /** Enable DTI or leave it disabled until @ref TIMER_EnableDTI() is called */\r
409   bool                          enable;\r
410 \r
411   /** DTI Output Polarity */\r
412   bool                          activeLowOut;\r
413 \r
414   /** DTI Complementary Output Invert */\r
415   bool                          invertComplementaryOut;\r
416 \r
417   /** Enable Automatic Start-up functionality (when debugger exits) */\r
418   bool                          autoRestart;\r
419 \r
420   /** Enable/disable PRS as DTI input. */\r
421   bool                          enablePrsSource;\r
422 \r
423   /** Select which PRS channel as DTI input. Only valid if @p enablePrsSource\r
424      is enabled. */\r
425   TIMER_PRSSEL_TypeDef          prsSel;\r
426 \r
427   /** DTI prescaling factor, if HFPER clock used. */\r
428   TIMER_Prescale_TypeDef        prescale;\r
429 \r
430   /** DTI Rise Time */\r
431   unsigned int                  riseTime;\r
432 \r
433   /** DTI Fall Time */\r
434   unsigned int                  fallTime;\r
435 \r
436   /** DTI outputs enable bit mask, consisting of one bit per DTI\r
437       output signal, i.e. CC0, CC1, CC2, CDTI0, CDTI1 and CDTI2.\r
438       This value should consist of one or more TIMER_DTOGEN_DTOGnnnEN flags\r
439       (defined in \<part_name\>_timer.h) OR'ed together. */\r
440   uint32_t                      outputsEnableMask;\r
441 \r
442   /** Enable core lockup as a fault source. */\r
443   bool                          enableFaultSourceCoreLockup;\r
444 \r
445   /** Enable debugger as a fault source. */\r
446   bool                          enableFaultSourceDebugger;\r
447 \r
448   /** Enable PRS fault source 0 (@p faultSourcePrsSel0) */\r
449   bool                          enableFaultSourcePrsSel0;\r
450 \r
451   /** Select which PRS signal to be PRS fault source 0. */\r
452   TIMER_PRSSEL_TypeDef          faultSourcePrsSel0;\r
453 \r
454   /** Enable PRS fault source 1 (@p faultSourcePrsSel1) */\r
455   bool                          enableFaultSourcePrsSel1;\r
456 \r
457   /** Select which PRS signal to be PRS fault source 1. */\r
458   TIMER_PRSSEL_TypeDef          faultSourcePrsSel1;\r
459 \r
460   /** Fault Action */\r
461   TIMER_DtiFaultAction_TypeDef  faultAction;\r
462 \r
463 } TIMER_InitDTI_TypeDef;\r
464 \r
465 \r
466   /** Default config for TIMER DTI init structure. */\r
467 #define TIMER_INITDTI_DEFAULT                                                  \\r
468   { true,                     /* Enable the DTI. */                            \\r
469     false,                    /* CC[0|1|2] outputs are active high. */         \\r
470     false,                    /* CDTI[0|1|2] outputs are not inverted. */      \\r
471     false,                    /* No auto restart when debugger exits. */       \\r
472     false,                    /* No PRS source selected. */                    \\r
473     timerPRSSELCh0,           /* Not used by default, select PRS channel 0. */ \\r
474     timerPrescale1,           /* No prescaling.  */                            \\r
475     0,                        /* No rise time. */                              \\r
476     0,                        /* No fall time. */                              \\r
477     TIMER_DTOGEN_DTOGCC0EN|TIMER_DTOGEN_DTOGCDTI0EN, /* Enable CC0 and CDTI0 */\\r
478     true,                     /* Enable core lockup as fault source */         \\r
479     true,                     /* Enable debugger as fault source */            \\r
480     false,                    /* Disable PRS fault source 0 */                 \\r
481     timerPRSSELCh0,           /* Not used by default, select PRS channel 0. */ \\r
482     false,                    /* Disable PRS fault source 1 */                 \\r
483     timerPRSSELCh0,           /* Not used by default, select PRS channel 0. */ \\r
484     timerDtiFaultActionInactive, /* No fault action. */                        \\r
485   }\r
486 #endif /* _TIMER_DTCTRL_MASK */\r
487 \r
488 \r
489 /*******************************************************************************\r
490  *****************************   PROTOTYPES   **********************************\r
491  ******************************************************************************/\r
492 \r
493 /***************************************************************************//**\r
494  * @brief\r
495  *   Get capture value for compare/capture channel when operating in capture\r
496  *   mode.\r
497  *\r
498  * @param[in] timer\r
499  *   Pointer to TIMER peripheral register block.\r
500  *\r
501  * @param[in] ch\r
502  *   Compare/capture channel to access.\r
503  *\r
504  * @return\r
505  *   Current capture value.\r
506  ******************************************************************************/\r
507 __STATIC_INLINE uint32_t TIMER_CaptureGet(TIMER_TypeDef *timer, unsigned int ch)\r
508 {\r
509   return(timer->CC[ch].CCV);\r
510 }\r
511 \r
512 \r
513 /***************************************************************************//**\r
514  * @brief\r
515  *   Set compare value buffer for compare/capture channel when operating in\r
516  *   compare or PWM mode.\r
517  *\r
518  * @details\r
519  *   The compare value buffer holds the value which will be written to\r
520  *   TIMERn_CCx_CCV on an update event if the buffer has been updated since\r
521  *   the last event.\r
522  *\r
523  * @param[in] timer\r
524  *   Pointer to TIMER peripheral register block.\r
525  *\r
526  * @param[in] ch\r
527  *   Compare/capture channel to access.\r
528  *\r
529  * @param[in] val\r
530  *   Value to set in compare value buffer register.\r
531  ******************************************************************************/\r
532 __STATIC_INLINE void TIMER_CompareBufSet(TIMER_TypeDef *timer,\r
533                                          unsigned int ch,\r
534                                          uint32_t val)\r
535 {\r
536   timer->CC[ch].CCVB = val;\r
537 }\r
538 \r
539 \r
540 /***************************************************************************//**\r
541  * @brief\r
542  *   Set compare value for compare/capture channel when operating in compare\r
543  *   or PWM mode.\r
544  *\r
545  * @param[in] timer\r
546  *   Pointer to TIMER peripheral register block.\r
547  *\r
548  * @param[in] ch\r
549  *   Compare/capture channel to access.\r
550  *\r
551  * @param[in] val\r
552  *   Value to set in compare value register.\r
553  ******************************************************************************/\r
554 __STATIC_INLINE void TIMER_CompareSet(TIMER_TypeDef *timer,\r
555                                       unsigned int ch,\r
556                                       uint32_t val)\r
557 {\r
558   timer->CC[ch].CCV = val;\r
559 }\r
560 \r
561 \r
562 /***************************************************************************//**\r
563  * @brief\r
564  *   Get TIMER counter value.\r
565  *\r
566  * @param[in] timer\r
567  *   Pointer to TIMER peripheral register block.\r
568  *\r
569  * @return\r
570  *   Current TIMER counter value.\r
571  ******************************************************************************/\r
572 __STATIC_INLINE uint32_t TIMER_CounterGet(TIMER_TypeDef *timer)\r
573 {\r
574   return(timer->CNT);\r
575 }\r
576 \r
577 \r
578 /***************************************************************************//**\r
579  * @brief\r
580  *   Set TIMER counter value.\r
581  *\r
582  * @param[in] timer\r
583  *   Pointer to TIMER peripheral register block.\r
584  *\r
585  * @param[in] val\r
586  *   Value to set counter to.\r
587  ******************************************************************************/\r
588 __STATIC_INLINE void TIMER_CounterSet(TIMER_TypeDef *timer, uint32_t val)\r
589 {\r
590   timer->CNT = val;\r
591 }\r
592 \r
593 \r
594 /***************************************************************************//**\r
595  * @brief\r
596  *   Start/stop TIMER.\r
597  *\r
598  * @param[in] timer\r
599  *   Pointer to TIMER peripheral register block.\r
600  *\r
601  * @param[in] enable\r
602  *   true to enable counting, false to disable.\r
603  ******************************************************************************/\r
604 __STATIC_INLINE void TIMER_Enable(TIMER_TypeDef *timer, bool enable)\r
605 {\r
606   EFM_ASSERT(TIMER_REF_VALID(timer));\r
607 \r
608   if (enable)\r
609   {\r
610     timer->CMD = TIMER_CMD_START;\r
611   }\r
612   else\r
613   {\r
614     timer->CMD = TIMER_CMD_STOP;\r
615   }\r
616 }\r
617 \r
618 \r
619 void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init);\r
620 void TIMER_InitCC(TIMER_TypeDef *timer,\r
621                   unsigned int ch,\r
622                   const TIMER_InitCC_TypeDef *init);\r
623 \r
624 #ifdef _TIMER_DTCTRL_MASK\r
625 void TIMER_InitDTI(TIMER_TypeDef *timer, const TIMER_InitDTI_TypeDef *init);\r
626 \r
627 /***************************************************************************//**\r
628  * @brief\r
629  *   Enable or disable DTI unit.\r
630  *\r
631  * @param[in] timer\r
632  *   Pointer to TIMER peripheral register block.\r
633  *\r
634  * @param[in] enable\r
635  *   true to enable DTI unit, false to disable.\r
636  ******************************************************************************/\r
637 __STATIC_INLINE void TIMER_EnableDTI(TIMER_TypeDef *timer, bool enable)\r
638 {\r
639   EFM_ASSERT(TIMER0 == timer);\r
640 \r
641   if (enable)\r
642   {\r
643     timer->DTCTRL |= TIMER_DTCTRL_DTEN;\r
644   }\r
645   else\r
646   {\r
647     timer->DTCTRL &= ~TIMER_DTCTRL_DTEN;\r
648   }\r
649 }\r
650 \r
651 \r
652 /***************************************************************************//**\r
653  * @brief\r
654  *   Get DTI fault source flags status.\r
655  *\r
656  * @note\r
657  *   The event bits are not cleared by the use of this function.\r
658  *\r
659  * @param[in] timer\r
660  *   Pointer to TIMER peripheral register block.\r
661  *\r
662  * @return\r
663  *   Status of the DTI fault source flags. Returns one or more valid\r
664  *   DTI fault source flags (TIMER_DTFAULT_nnn) OR'ed together.\r
665  ******************************************************************************/\r
666 __STATIC_INLINE uint32_t TIMER_GetDTIFault(TIMER_TypeDef *timer)\r
667 {\r
668   EFM_ASSERT(TIMER0 == timer);\r
669   return(timer->DTFAULT);\r
670 }\r
671 \r
672 \r
673 /***************************************************************************//**\r
674  * @brief\r
675  *   Clear DTI fault source flags.\r
676  *\r
677  * @param[in] timer\r
678  *   Pointer to TIMER peripheral register block.\r
679  *\r
680  * @param[in] flags\r
681  *   DTI fault source(s) to clear. Use one or more valid DTI fault\r
682  *   source flags (TIMER_DTFAULT_nnn) OR'ed together.\r
683  ******************************************************************************/\r
684 __STATIC_INLINE void TIMER_ClearDTIFault(TIMER_TypeDef *timer, uint32_t flags)\r
685 \r
686 {\r
687   EFM_ASSERT(TIMER0 == timer);\r
688   timer->DTFAULTC = flags;\r
689 }\r
690 #endif /* _TIMER_DTCTRL_MASK */\r
691 \r
692 \r
693 /***************************************************************************//**\r
694  * @brief\r
695  *   Clear one or more pending TIMER interrupts.\r
696  *\r
697  * @param[in] timer\r
698  *   Pointer to TIMER peripheral register block.\r
699  *\r
700  * @param[in] flags\r
701  *   Pending TIMER interrupt source(s) to clear. Use one or more valid\r
702  *   interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.\r
703  ******************************************************************************/\r
704 __STATIC_INLINE void TIMER_IntClear(TIMER_TypeDef *timer, uint32_t flags)\r
705 {\r
706   timer->IFC = flags;\r
707 }\r
708 \r
709 \r
710 /***************************************************************************//**\r
711  * @brief\r
712  *   Disable one or more TIMER interrupts.\r
713  *\r
714  * @param[in] timer\r
715  *   Pointer to TIMER peripheral register block.\r
716  *\r
717  * @param[in] flags\r
718  *   TIMER interrupt source(s) to disable. Use one or more valid\r
719  *   interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.\r
720  ******************************************************************************/\r
721 __STATIC_INLINE void TIMER_IntDisable(TIMER_TypeDef *timer, uint32_t flags)\r
722 {\r
723   timer->IEN &= ~(flags);\r
724 }\r
725 \r
726 \r
727 /***************************************************************************//**\r
728  * @brief\r
729  *   Enable one or more TIMER interrupts.\r
730  *\r
731  * @note\r
732  *   Depending on the use, a pending interrupt may already be set prior to\r
733  *   enabling the interrupt. Consider using TIMER_IntClear() prior to enabling\r
734  *   if such a pending interrupt should be ignored.\r
735  *\r
736  * @param[in] timer\r
737  *   Pointer to TIMER peripheral register block.\r
738  *\r
739  * @param[in] flags\r
740  *   TIMER interrupt source(s) to enable. Use one or more valid\r
741  *   interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.\r
742  ******************************************************************************/\r
743 __STATIC_INLINE void TIMER_IntEnable(TIMER_TypeDef *timer, uint32_t flags)\r
744 {\r
745   timer->IEN |= flags;\r
746 }\r
747 \r
748 \r
749 /***************************************************************************//**\r
750  * @brief\r
751  *   Get pending TIMER interrupt flags.\r
752  *\r
753  * @note\r
754  *   The event bits are not cleared by the use of this function.\r
755  *\r
756  * @param[in] timer\r
757  *   Pointer to TIMER peripheral register block.\r
758  *\r
759  * @return\r
760  *   TIMER interrupt source(s) pending. Returns one or more valid\r
761  *   interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.\r
762  ******************************************************************************/\r
763 __STATIC_INLINE uint32_t TIMER_IntGet(TIMER_TypeDef *timer)\r
764 {\r
765   return(timer->IF);\r
766 }\r
767 \r
768 \r
769 /***************************************************************************//**\r
770  * @brief\r
771  *   Get enabled and pending TIMER interrupt flags.\r
772  *   Useful for handling more interrupt sources in the same interrupt handler.\r
773  *\r
774  * @param[in] timer\r
775  *   Pointer to TIMER peripheral register block.\r
776  *\r
777  * @note\r
778  *   Interrupt flags are not cleared by the use of this function.\r
779  *\r
780  * @return\r
781  *   Pending and enabled TIMER interrupt sources.\r
782  *   The return value is the bitwise AND combination of\r
783  *   - the OR combination of enabled interrupt sources in TIMERx_IEN_nnn\r
784  *     register (TIMERx_IEN_nnn) and\r
785  *   - the OR combination of valid interrupt flags of the TIMER module\r
786  *     (TIMERx_IF_nnn).\r
787  ******************************************************************************/\r
788 __STATIC_INLINE uint32_t TIMER_IntGetEnabled(TIMER_TypeDef *timer)\r
789 {\r
790   uint32_t tmp;\r
791 \r
792   /* Store TIMER->IEN in temporary variable in order to define explicit order\r
793    * of volatile accesses. */\r
794   tmp = timer->IEN;\r
795 \r
796   /* Bitwise AND of pending and enabled interrupts */\r
797   return timer->IF & tmp;\r
798 }\r
799 \r
800 \r
801 /***************************************************************************//**\r
802  * @brief\r
803  *   Set one or more pending TIMER interrupts from SW.\r
804  *\r
805  * @param[in] timer\r
806  *   Pointer to TIMER peripheral register block.\r
807  *\r
808  * @param[in] flags\r
809  *   TIMER interrupt source(s) to set to pending. Use one or more valid\r
810  *   interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.\r
811  ******************************************************************************/\r
812 __STATIC_INLINE void TIMER_IntSet(TIMER_TypeDef *timer, uint32_t flags)\r
813 {\r
814   timer->IFS = flags;\r
815 }\r
816 \r
817 #ifdef TIMER_DTLOCK_LOCKKEY_LOCK\r
818 /***************************************************************************//**\r
819  * @brief\r
820  *   Lock some of the TIMER registers in order to protect them from being\r
821  *   modified.\r
822  *\r
823  * @details\r
824  *   Please refer to the reference manual for TIMER registers that will be\r
825  *   locked.\r
826  *\r
827  * @note\r
828  *   If locking the TIMER registers, they must be unlocked prior to using any\r
829  *   TIMER API functions modifying TIMER registers protected by the lock.\r
830  *\r
831  * @param[in] timer\r
832  *   Pointer to TIMER peripheral register block.\r
833  ******************************************************************************/\r
834 __STATIC_INLINE void TIMER_Lock(TIMER_TypeDef *timer)\r
835 {\r
836   EFM_ASSERT(TIMER0 == timer);\r
837 \r
838   timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_LOCK;\r
839 }\r
840 #endif\r
841 \r
842 void TIMER_Reset(TIMER_TypeDef *timer);\r
843 \r
844 /***************************************************************************//**\r
845  * @brief\r
846  *   Set top value buffer for timer.\r
847  *\r
848  * @details\r
849  *   When the top value buffer register is updated, the value is loaded into\r
850  *   the top value register at the next wrap around. This feature is useful\r
851  *   in order to update the top value safely when the timer is running.\r
852  *\r
853  * @param[in] timer\r
854  *   Pointer to TIMER peripheral register block.\r
855  *\r
856  * @param[in] val\r
857  *   Value to set in top value buffer register.\r
858  ******************************************************************************/\r
859 __STATIC_INLINE void TIMER_TopBufSet(TIMER_TypeDef *timer, uint32_t val)\r
860 {\r
861   timer->TOPB = val;\r
862 }\r
863 \r
864 \r
865 /***************************************************************************//**\r
866  * @brief\r
867  *   Get top value setting for timer.\r
868  *\r
869  * @param[in] timer\r
870  *   Pointer to TIMER peripheral register block.\r
871  *\r
872  * @return\r
873  *   Current top value.\r
874  ******************************************************************************/\r
875 __STATIC_INLINE uint32_t TIMER_TopGet(TIMER_TypeDef *timer)\r
876 {\r
877   return(timer->TOP);\r
878 }\r
879 \r
880 \r
881 /***************************************************************************//**\r
882  * @brief\r
883  *   Set top value for timer.\r
884  *\r
885  * @param[in] timer\r
886  *   Pointer to TIMER peripheral register block.\r
887  *\r
888  * @param[in] val\r
889  *   Value to set in top value register.\r
890  ******************************************************************************/\r
891 __STATIC_INLINE void TIMER_TopSet(TIMER_TypeDef *timer, uint32_t val)\r
892 {\r
893   timer->TOP = val;\r
894 }\r
895 \r
896 \r
897 #ifdef TIMER_DTLOCK_LOCKKEY_UNLOCK\r
898 /***************************************************************************//**\r
899  * @brief\r
900  *   Unlock the TIMER so that writing to locked registers again is possible.\r
901  *\r
902  * @param[in] timer\r
903  *   Pointer to TIMER peripheral register block.\r
904  ******************************************************************************/\r
905 __STATIC_INLINE void TIMER_Unlock(TIMER_TypeDef *timer)\r
906 {\r
907   EFM_ASSERT(TIMER0 == timer);\r
908 \r
909   timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_UNLOCK;\r
910 }\r
911 #endif\r
912 \r
913 \r
914 /** @} (end addtogroup TIMER) */\r
915 /** @} (end addtogroup EM_Library) */\r
916 \r
917 #ifdef __cplusplus\r
918 }\r
919 #endif\r
920 \r
921 #endif /* defined(TIMER_COUNT) && (TIMER_COUNT > 0) */\r
922 #endif /* __SILICON_LABS_EM_TIMER_H_ */\r