1 /***************************************************************************//**
2  * @file
3  * @brief Timer/counter (TIMER) peripheral API
4  * @author Energy Micro AS
5  * @version 3.0.0
6  *******************************************************************************
7  * @section License
8  * <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.com</b>
9  *******************************************************************************
10  *
11  * Permission is granted to anyone to use this software for any purpose,
12  * including commercial applications, and to alter it and redistribute it
13  * freely, subject to the following restrictions:
14  *
15  * 1. The origin of this software must not be misrepresented; you must not
16  *    claim that you wrote the original software.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  *    misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  *
21  * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
22  * obligation to support this Software. Energy Micro AS is providing the
23  * Software "AS IS", with no express or implied warranties of any kind,
24  * including, but not limited to, any implied warranties of merchantability
25  * or fitness for any particular purpose or warranties against infringement
26  * of any proprietary rights of a third party.
27  *
28  * Energy Micro AS will not be liable for any consequential, incidental, or
29  * special damages, or any other relief, or for any claim by any third party,
30  * arising from your use of this Software.
31  *
32  ******************************************************************************/
33 #ifndef __EM_TIMER_H
34 #define __EM_TIMER_H
35 
36 #include <stdbool.h>
37 #include "em_part.h"
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /***************************************************************************//**
44  * @addtogroup EM_Library
45  * @{
46  ******************************************************************************/
47 
48 /***************************************************************************//**
49  * @addtogroup TIMER
50  * @{
51  ******************************************************************************/
52 
53 /*******************************************************************************
54  ********************************   ENUMS   ************************************
55  ******************************************************************************/
56 
57 /** Timer compare/capture mode. */
58 typedef enum
59 {
60   timerCCModeOff     = _TIMER_CC_CTRL_MODE_OFF,           /**< Channel turned off. */
61   timerCCModeCapture = _TIMER_CC_CTRL_MODE_INPUTCAPTURE,  /**< Input capture. */
62   timerCCModeCompare = _TIMER_CC_CTRL_MODE_OUTPUTCOMPARE, /**< Output compare. */
63   timerCCModePWM     = _TIMER_CC_CTRL_MODE_PWM            /**< Pulse-Width modulation. */
64 } TIMER_CCMode_TypeDef;
65 
66 
67 /** Clock select. */
68 typedef enum
69 {
70   /** Prescaled HFPER clock. */
71   timerClkSelHFPerClk = _TIMER_CTRL_CLKSEL_PRESCHFPERCLK,
72 
73   /** Prescaled HFPER clock. */
74   timerClkSelCC1      = _TIMER_CTRL_CLKSEL_CC1,
75 
76   /**
77    * Cascaded, clocked by underflow (down-counting) or overflow (up-counting)
78    * by lower numbered timer.
79    */
80   timerClkSelCascade  = _TIMER_CTRL_CLKSEL_TIMEROUF
81 } TIMER_ClkSel_TypeDef;
82 
83 
84 /** Input capture edge select. */
85 typedef enum
86 {
87   /** Rising edges detected. */
88   timerEdgeRising  = _TIMER_CC_CTRL_ICEDGE_RISING,
89 
90   /** Falling edges detected. */
91   timerEdgeFalling = _TIMER_CC_CTRL_ICEDGE_FALLING,
92 
93   /** Both edges detected. */
94   timerEdgeBoth    = _TIMER_CC_CTRL_ICEDGE_BOTH,
95 
96   /** No edge detection, leave signal as is. */
97   timerEdgeNone    = _TIMER_CC_CTRL_ICEDGE_NONE
98 } TIMER_Edge_TypeDef;
99 
100 
101 /** Input capture event control. */
102 typedef enum
103 {
104   /** PRS output pulse, interrupt flag and DMA request set on every capture. */
105   timerEventEveryEdge    = _TIMER_CC_CTRL_ICEVCTRL_EVERYEDGE,
106   /** PRS output pulse, interrupt flag and DMA request set on every second capture. */
107   timerEventEvery2ndEdge = _TIMER_CC_CTRL_ICEVCTRL_EVERYSECONDEDGE,
108   /**
109    * PRS output pulse, interrupt flag and DMA request set on rising edge (if
110    * input capture edge = BOTH).
111    */
112   timerEventRising       = _TIMER_CC_CTRL_ICEVCTRL_RISING,
113   /**
114    * PRS output pulse, interrupt flag and DMA request set on falling edge (if
115    * input capture edge = BOTH).
116    */
117   timerEventFalling      = _TIMER_CC_CTRL_ICEVCTRL_FALLING
118 } TIMER_Event_TypeDef;
119 
120 
121 /** Input edge action. */
122 typedef enum
123 {
124   /** No action taken. */
125   timerInputActionNone        = _TIMER_CTRL_FALLA_NONE,
126 
127   /** Start counter without reload. */
128   timerInputActionStart       = _TIMER_CTRL_FALLA_START,
129 
130   /** Stop counter without reload. */
131   timerInputActionStop        = _TIMER_CTRL_FALLA_STOP,
132 
133   /** Reload and start counter. */
134   timerInputActionReloadStart = _TIMER_CTRL_FALLA_RELOADSTART
135 } TIMER_InputAction_TypeDef;
136 
137 
138 /** Timer mode. */
139 typedef enum
140 {
141   timerModeUp     = _TIMER_CTRL_MODE_UP,     /**< Up-counting. */
142   timerModeDown   = _TIMER_CTRL_MODE_DOWN,   /**< Down-counting. */
143   timerModeUpDown = _TIMER_CTRL_MODE_UPDOWN, /**< Up/down-counting. */
144   timerModeQDec   = _TIMER_CTRL_MODE_QDEC    /**< Quadrature decoder. */
145 } TIMER_Mode_TypeDef;
146 
147 
148 /** Compare/capture output action. */
149 typedef enum
150 {
151   /** No action. */
152   timerOutputActionNone   = _TIMER_CC_CTRL_CUFOA_NONE,
153 
154   /** Toggle on event. */
155   timerOutputActionToggle = _TIMER_CC_CTRL_CUFOA_TOGGLE,
156 
157   /** Clear on event. */
158   timerOutputActionClear  = _TIMER_CC_CTRL_CUFOA_CLEAR,
159 
160   /** Set on event. */
161   timerOutputActionSet    = _TIMER_CC_CTRL_CUFOA_SET
162 } TIMER_OutputAction_TypeDef;
163 
164 
165 /** Prescaler. */
166 typedef enum
167 {
168   timerPrescale1    = _TIMER_CTRL_PRESC_DIV1,     /**< Divide by 1. */
169   timerPrescale2    = _TIMER_CTRL_PRESC_DIV2,     /**< Divide by 2. */
170   timerPrescale4    = _TIMER_CTRL_PRESC_DIV4,     /**< Divide by 4. */
171   timerPrescale8    = _TIMER_CTRL_PRESC_DIV8,     /**< Divide by 8. */
172   timerPrescale16   = _TIMER_CTRL_PRESC_DIV16,    /**< Divide by 16. */
173   timerPrescale32   = _TIMER_CTRL_PRESC_DIV32,    /**< Divide by 32. */
174   timerPrescale64   = _TIMER_CTRL_PRESC_DIV64,    /**< Divide by 64. */
175   timerPrescale128  = _TIMER_CTRL_PRESC_DIV128,   /**< Divide by 128. */
176   timerPrescale256  = _TIMER_CTRL_PRESC_DIV256,   /**< Divide by 256. */
177   timerPrescale512  = _TIMER_CTRL_PRESC_DIV512,   /**< Divide by 512. */
178   timerPrescale1024 = _TIMER_CTRL_PRESC_DIV1024   /**< Divide by 1024. */
179 } TIMER_Prescale_TypeDef;
180 
181 
182 /** Peripheral Reflex System signal. */
183 typedef enum
184 {
185   timerPRSSELCh0 = _ADC_SINGLECTRL_PRSSEL_PRSCH0, /**< PRS channel 0. */
186   timerPRSSELCh1 = _ADC_SINGLECTRL_PRSSEL_PRSCH1, /**< PRS channel 1. */
187   timerPRSSELCh2 = _ADC_SINGLECTRL_PRSSEL_PRSCH2, /**< PRS channel 2. */
188   timerPRSSELCh3 = _ADC_SINGLECTRL_PRSSEL_PRSCH3, /**< PRS channel 3. */
189   timerPRSSELCh4 = _ADC_SINGLECTRL_PRSSEL_PRSCH4, /**< PRS channel 4. */
190   timerPRSSELCh5 = _ADC_SINGLECTRL_PRSSEL_PRSCH5, /**< PRS channel 5. */
191   timerPRSSELCh6 = _ADC_SINGLECTRL_PRSSEL_PRSCH6, /**< PRS channel 6. */
192   timerPRSSELCh7 = _ADC_SINGLECTRL_PRSSEL_PRSCH7  /**< PRS channel 7. */
193 } TIMER_PRSSEL_TypeDef;
194 
195 
196 /*******************************************************************************
197  *******************************   STRUCTS   ***********************************
198  ******************************************************************************/
199 
200 /** TIMER initialization structure. */
201 typedef struct
202 {
203   /** Start counting when init completed. */
204   bool                      enable;
205 
206   /** Counter shall keep running during debug halt. */
207   bool                      debugRun;
208 
209   /** Prescaling factor, if HFPER clock used. */
210   TIMER_Prescale_TypeDef    prescale;
211 
212   /** Clock selection. */
213   TIMER_ClkSel_TypeDef      clkSel;
214 
215 #if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
216   /** 2x Count mode, counter increments/decrements by 2, meant for PWN mode. */
217   bool                      count2x;
218 
219   /** ATI (Always Track Inputs) makes CCPOL always track
220    * the polarity of the inputs. */
221   bool                      ati;
222 #endif
223 
224   /** Action on falling input edge. */
225   TIMER_InputAction_TypeDef fallAction;
226 
227   /** Action on rising input edge. */
228   TIMER_InputAction_TypeDef riseAction;
229 
230   /** Counting mode. */
231   TIMER_Mode_TypeDef        mode;
232 
233   /** DMA request clear on active. */
234   bool                      dmaClrAct;
235 
236   /** Select X2 or X4 quadrature decode mode (if used). */
237   bool                      quadModeX4;
238 
239   /** Determines if only counting up or down once. */
240   bool                      oneShot;
241 
242   /** Timer start/stop/reload by other timers. */
243   bool                      sync;
244 } TIMER_Init_TypeDef;
245 
246 /** Default config for TIMER init structure. */
247 #if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
248 #define TIMER_INIT_DEFAULT                                                              \
249   { true,                   /* Enable timer when init complete. */                      \
250     false,                  /* Stop counter during debug halt. */                       \
251     timerPrescale1,         /* No prescaling. */                                        \
252     timerClkSelHFPerClk,    /* Select HFPER clock. */                                   \
253     false,                  /* Not 2x count mode. */                                    \
254     false,                  /* No ATI. */                                               \
255     timerInputActionNone,   /* No action on falling input edge. */                      \
256     timerInputActionNone,   /* No action on rising input edge. */                       \
257     timerModeUp,            /* Up-counting. */                                          \
258     false,                  /* Do not clear DMA requests when DMA channel is active. */ \
259     false,                  /* Select X2 quadrature decode mode (if used). */           \
260     false,                  /* Disable one shot. */                                     \
261     false                   /* Not started/stopped/reloaded by other timers. */         \
262   }
263 #else
264 #define TIMER_INIT_DEFAULT                                                              \
265   { true,                   /* Enable timer when init complete. */                      \
266     false,                  /* Stop counter during debug halt. */                       \
267     timerPrescale1,         /* No prescaling. */                                        \
268     timerClkSelHFPerClk,    /* Select HFPER clock. */                                   \
269     timerInputActionNone,   /* No action on falling input edge. */                      \
270     timerInputActionNone,   /* No action on rising input edge. */                       \
271     timerModeUp,            /* Up-counting. */                                          \
272     false,                  /* Do not clear DMA requests when DMA channel is active. */ \
273     false,                  /* Select X2 quadrature decode mode (if used). */           \
274     false,                  /* Disable one shot. */                                     \
275     false                   /* Not started/stopped/reloaded by other timers. */         \
276   }
277 #endif
278 
279 /** TIMER compare/capture initialization structure. */
280 typedef struct
281 {
282   /** Input capture event control. */
283   TIMER_Event_TypeDef        eventCtrl;
284 
285   /** Input capture edge select. */
286   TIMER_Edge_TypeDef         edge;
287 
288   /**
289    * Peripheral reflex system trigger selection. Only applicable if @p prsInput
290    * is enabled.
291    */
292   TIMER_PRSSEL_TypeDef       prsSel;
293 
294   /** Counter underflow output action. */
295   TIMER_OutputAction_TypeDef cufoa;
296 
297   /** Counter overflow output action. */
298   TIMER_OutputAction_TypeDef cofoa;
299 
300   /** Counter match output action. */
301   TIMER_OutputAction_TypeDef cmoa;
302 
303   /** Compare/capture channel mode. */
304   TIMER_CCMode_TypeDef       mode;
305 
306   /** Enable digital filter. */
307   bool                       filter;
308 
309   /** Select TIMERnCCx (false) or PRS input (true). */
310   bool                       prsInput;
311 
312   /**
313    * Compare output initial state. Only used in Output Compare and PWM mode.
314    * When true, the compare/PWM output is set high when the counter is
315    * disabled. When counting resumes, this value will represent the initial
316    * value for the compare/PWM output. If the bit is cleared, the output
317    * will be cleared when the counter is disabled.
318    */
319   bool                       coist;
320 
321   /** Invert output from compare/capture channel. */
322   bool                       outInvert;
323 } TIMER_InitCC_TypeDef;
324 
325 /** Default config for TIMER compare/capture init structure. */
326 #define TIMER_INITCC_DEFAULT                                                   \
327   { timerEventEveryEdge,      /* Event on every capture. */                    \
328     timerEdgeRising,          /* Input capture edge on rising edge. */         \
329     timerPRSSELCh0,           /* Not used by default, select PRS channel 0. */ \
330     timerOutputActionNone,    /* No action on underflow. */                    \
331     timerOutputActionNone,    /* No action on overflow. */                     \
332     timerOutputActionNone,    /* No action on match. */                        \
333     timerCCModeOff,           /* Disable compare/capture channel. */           \
334     false,                    /* Disable filter. */                            \
335     false,                    /* Select TIMERnCCx input. */                    \
336     false,                    /* Clear output when countre disabled. */        \
337     false                     /* Do not invert output. */                      \
338   }
339 
340 
341 /*******************************************************************************
342  *****************************   PROTOTYPES   **********************************
343  ******************************************************************************/
344 
345 /***************************************************************************//**
346  * @brief
347  *   Get capture value for compare/capture channel when operating in capture
348  *   mode.
349  *
350  * @param[in] timer
351  *   Pointer to TIMER peripheral register block.
352  *
353  * @param[in] ch
354  *   Compare/capture channel to access.
355  *
356  * @return
357  *   Current capture value.
358  ******************************************************************************/
TIMER_CaptureGet(TIMER_TypeDef * timer,unsigned int ch)359 __STATIC_INLINE uint32_t TIMER_CaptureGet(TIMER_TypeDef *timer, unsigned int ch)
360 {
361   return(timer->CC[ch].CCV);
362 }
363 
364 
365 /***************************************************************************//**
366  * @brief
367  *   Set compare value buffer for compare/capture channel when operating in
368  *   compare or PWM mode.
369  *
370  * @details
371  *   The compare value buffer holds the value which will be written to
372  *   TIMERn_CCx_CCV on an update event if the buffer has been updated since
373  *   the last event.
374  *
375  * @param[in] timer
376  *   Pointer to TIMER peripheral register block.
377  *
378  * @param[in] ch
379  *   Compare/capture channel to access.
380  *
381  * @param[in] val
382  *   Value to set in compare value buffer register.
383  ******************************************************************************/
TIMER_CompareBufSet(TIMER_TypeDef * timer,unsigned int ch,uint32_t val)384 __STATIC_INLINE void TIMER_CompareBufSet(TIMER_TypeDef *timer,
385                                          unsigned int ch,
386                                          uint32_t val)
387 {
388   timer->CC[ch].CCVB = val;
389 }
390 
391 
392 /***************************************************************************//**
393  * @brief
394  *   Set compare value for compare/capture channel when operating in compare
395  *   or PWM mode.
396  *
397  * @param[in] timer
398  *   Pointer to TIMER peripheral register block.
399  *
400  * @param[in] ch
401  *   Compare/capture channel to access.
402  *
403  * @param[in] val
404  *   Value to set in compare value register.
405  ******************************************************************************/
TIMER_CompareSet(TIMER_TypeDef * timer,unsigned int ch,uint32_t val)406 __STATIC_INLINE void TIMER_CompareSet(TIMER_TypeDef *timer,
407                                       unsigned int ch,
408                                       uint32_t val)
409 {
410   timer->CC[ch].CCV = val;
411 }
412 
413 
414 /***************************************************************************//**
415  * @brief
416  *   Get TIMER counter value.
417  *
418  * @param[in] timer
419  *   Pointer to TIMER peripheral register block.
420  *
421  * @return
422  *   Current TIMER counter value.
423  ******************************************************************************/
TIMER_CounterGet(TIMER_TypeDef * timer)424 __STATIC_INLINE uint32_t TIMER_CounterGet(TIMER_TypeDef *timer)
425 {
426   return(timer->CNT);
427 }
428 
429 
430 /***************************************************************************//**
431  * @brief
432  *   Set TIMER counter value.
433  *
434  * @param[in] timer
435  *   Pointer to TIMER peripheral register block.
436  *
437  * @param[in] val
438  *   Value to set counter to.
439  ******************************************************************************/
TIMER_CounterSet(TIMER_TypeDef * timer,uint32_t val)440 __STATIC_INLINE void TIMER_CounterSet(TIMER_TypeDef *timer, uint32_t val)
441 {
442   timer->CNT = val;
443 }
444 
445 
446 void TIMER_Enable(TIMER_TypeDef *timer, bool enable);
447 void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init);
448 void TIMER_InitCC(TIMER_TypeDef *timer,
449                   unsigned int ch,
450                   const TIMER_InitCC_TypeDef *init);
451 
452 
453 /***************************************************************************//**
454  * @brief
455  *   Clear one or more pending TIMER interrupts.
456  *
457  * @param[in] timer
458  *   Pointer to TIMER peripheral register block.
459  *
460  * @param[in] flags
461  *   Pending TIMER interrupt source(s) to clear. Use one or more valid
462  *   interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
463  ******************************************************************************/
TIMER_IntClear(TIMER_TypeDef * timer,uint32_t flags)464 __STATIC_INLINE void TIMER_IntClear(TIMER_TypeDef *timer, uint32_t flags)
465 {
466   timer->IFC = flags;
467 }
468 
469 
470 /***************************************************************************//**
471  * @brief
472  *   Disable one or more TIMER interrupts.
473  *
474  * @param[in] timer
475  *   Pointer to TIMER peripheral register block.
476  *
477  * @param[in] flags
478  *   TIMER interrupt source(s) to disable. Use one or more valid
479  *   interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
480  ******************************************************************************/
TIMER_IntDisable(TIMER_TypeDef * timer,uint32_t flags)481 __STATIC_INLINE void TIMER_IntDisable(TIMER_TypeDef *timer, uint32_t flags)
482 {
483   timer->IEN &= ~(flags);
484 }
485 
486 
487 /***************************************************************************//**
488  * @brief
489  *   Enable one or more TIMER interrupts.
490  *
491  * @note
492  *   Depending on the use, a pending interrupt may already be set prior to
493  *   enabling the interrupt. Consider using TIMER_IntClear() prior to enabling
494  *   if such a pending interrupt should be ignored.
495  *
496  * @param[in] timer
497  *   Pointer to TIMER peripheral register block.
498  *
499  * @param[in] flags
500  *   TIMER interrupt source(s) to enable. Use one or more valid
501  *   interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
502  ******************************************************************************/
TIMER_IntEnable(TIMER_TypeDef * timer,uint32_t flags)503 __STATIC_INLINE void TIMER_IntEnable(TIMER_TypeDef *timer, uint32_t flags)
504 {
505   timer->IEN |= flags;
506 }
507 
508 
509 /***************************************************************************//**
510  * @brief
511  *   Get pending TIMER interrupt flags.
512  *
513  * @note
514  *   The event bits are not cleared by the use of this function.
515  *
516  * @param[in] timer
517  *   Pointer to TIMER peripheral register block.
518  *
519  * @return
520  *   TIMER interrupt source(s) pending. Returns one or more valid
521  *   interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
522  ******************************************************************************/
TIMER_IntGet(TIMER_TypeDef * timer)523 __STATIC_INLINE uint32_t TIMER_IntGet(TIMER_TypeDef *timer)
524 {
525   return(timer->IF);
526 }
527 
528 
529 /***************************************************************************//**
530  * @brief
531  *   Get enabled and pending TIMER interrupt flags.
532  *   Useful for handling more interrupt sources in the same interrupt handler.
533  *
534  * @param[in] timer
535  *   Pointer to TIMER peripheral register block.
536  *
537  * @note
538  *   Interrupt flags are not cleared by the use of this function.
539  *
540  * @return
541  *   Pending and enabled TIMER interrupt sources.
542  *   The return value is the bitwise AND combination of
543  *   - the OR combination of enabled interrupt sources in TIMERx_IEN_nnn
544  *     register (TIMERx_IEN_nnn) and
545  *   - the OR combination of valid interrupt flags of the TIMER module
546  *     (TIMERx_IF_nnn).
547  ******************************************************************************/
TIMER_IntGetEnabled(TIMER_TypeDef * timer)548 __STATIC_INLINE uint32_t TIMER_IntGetEnabled(TIMER_TypeDef *timer)
549 {
550   uint32_t tmp;
551 
552   /* Store TIMER->IEN in temporary variable in order to define explicit order
553    * of volatile accesses. */
554   tmp = timer->IEN;
555 
556   /* Bitwise AND of pending and enabled interrupts */
557   return timer->IF & tmp;
558 }
559 
560 
561 /***************************************************************************//**
562  * @brief
563  *   Set one or more pending TIMER interrupts from SW.
564  *
565  * @param[in] timer
566  *   Pointer to TIMER peripheral register block.
567  *
568  * @param[in] flags
569  *   TIMER interrupt source(s) to set to pending. Use one or more valid
570  *   interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
571  ******************************************************************************/
TIMER_IntSet(TIMER_TypeDef * timer,uint32_t flags)572 __STATIC_INLINE void TIMER_IntSet(TIMER_TypeDef *timer, uint32_t flags)
573 {
574   timer->IFS = flags;
575 }
576 
577 #ifdef TIMER_DTLOCK_LOCKKEY_LOCK
578 void TIMER_Lock(TIMER_TypeDef *timer);
579 #endif
580 
581 void TIMER_Reset(TIMER_TypeDef *timer);
582 
583 /***************************************************************************//**
584  * @brief
585  *   Set top value buffer for timer.
586  *
587  * @details
588  *   When the top value buffer register is updated, the value is loaded into
589  *   the top value register at the next wrap around. This feature is useful
590  *   in order to update the top value safely when the timer is running.
591  *
592  * @param[in] timer
593  *   Pointer to TIMER peripheral register block.
594  *
595  * @param[in] val
596  *   Value to set in top value buffer register.
597  ******************************************************************************/
TIMER_TopBufSet(TIMER_TypeDef * timer,uint32_t val)598 __STATIC_INLINE void TIMER_TopBufSet(TIMER_TypeDef *timer, uint32_t val)
599 {
600   timer->TOPB = val;
601 }
602 
603 
604 /***************************************************************************//**
605  * @brief
606  *   Get top value setting for timer.
607  *
608  * @param[in] timer
609  *   Pointer to TIMER peripheral register block.
610  *
611  * @return
612  *   Current top value.
613  ******************************************************************************/
TIMER_TopGet(TIMER_TypeDef * timer)614 __STATIC_INLINE uint32_t TIMER_TopGet(TIMER_TypeDef *timer)
615 {
616   return(timer->TOP);
617 }
618 
619 
620 /***************************************************************************//**
621  * @brief
622  *   Set top value for timer.
623  *
624  * @param[in] timer
625  *   Pointer to TIMER peripheral register block.
626  *
627  * @param[in] val
628  *   Value to set in top value register.
629  ******************************************************************************/
TIMER_TopSet(TIMER_TypeDef * timer,uint32_t val)630 __STATIC_INLINE void TIMER_TopSet(TIMER_TypeDef *timer, uint32_t val)
631 {
632   timer->TOP = val;
633 }
634 
635 #ifdef TIMER_DTLOCK_LOCKKEY_UNLOCK
636 void TIMER_Unlock(TIMER_TypeDef *timer);
637 #endif
638 
639 
640 /** @} (end addtogroup TIMER) */
641 /** @} (end addtogroup EM_Library) */
642 
643 #ifdef __cplusplus
644 }
645 #endif
646 
647 #endif /* __EM_TIMER_H */
648