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