1 /***************************************************************************//**
2  * @file
3  * @brief Low Energy Timer (LETIMER) 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_LETIMER_H
34 #define __EM_LETIMER_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 LETIMER
50  * @{
51  ******************************************************************************/
52 
53 /*******************************************************************************
54  ********************************   ENUMS   ************************************
55  ******************************************************************************/
56 
57 /** Repeat mode. */
58 typedef enum
59 {
60   /** Count until stopped by SW. */
61   letimerRepeatFree     = _LETIMER_CTRL_REPMODE_FREE,
62   /** Count REP0 times. */
63   letimerRepeatOneshot  = _LETIMER_CTRL_REPMODE_ONESHOT,
64   /**
65    * Count REP0 times, if REP1 has been written to, it is loaded into
66    * REP0 when REP0 is about to be decremented to 0.
67    */
68   letimerRepeatBuffered = _LETIMER_CTRL_REPMODE_BUFFERED,
69   /**
70    * Run as long as both REP0 and REP1 are not 0. Both REP0 and REP1
71    * are decremented when counter underflows.
72    */
73   letimerRepeatDouble   = _LETIMER_CTRL_REPMODE_DOUBLE
74 } LETIMER_RepeatMode_TypeDef;
75 
76 
77 /** Underflow action on output. */
78 typedef enum
79 {
80   /** No output action. */
81   letimerUFOANone   = _LETIMER_CTRL_UFOA0_NONE,
82   /** Toggle output when counter underflows. */
83   letimerUFOAToggle = _LETIMER_CTRL_UFOA0_TOGGLE,
84   /** Hold output one LETIMER clock cycle when counter underflows. */
85   letimerUFOAPulse  = _LETIMER_CTRL_UFOA0_PULSE,
86   /** Set output idle when counter underflows, and active when matching COMP1. */
87   letimerUFOAPwm    = _LETIMER_CTRL_UFOA0_PWM
88 } LETIMER_UFOA_TypeDef;
89 
90 /*******************************************************************************
91  *******************************   STRUCTS   ***********************************
92  ******************************************************************************/
93 
94 /** LETIMER initialization structure. */
95 typedef struct
96 {
97   bool                       enable;         /**< Start counting when init completed. */
98   bool                       debugRun;       /**< Counter shall keep running during debug halt. */
99   bool                       rtcComp0Enable; /**< Start counting on RTC COMP0 match. */
100   bool                       rtcComp1Enable; /**< Start counting on RTC COMP1 match. */
101   bool                       comp0Top;       /**< Load COMP0 register into CNT when counter underflows. */
102   bool                       bufTop;         /**< Load COMP1 into COMP0 when REP0 reaches 0. */
103   uint8_t                    out0Pol;        /**< Idle value for output 0. */
104   uint8_t                    out1Pol;        /**< Idle value for output 1. */
105   LETIMER_UFOA_TypeDef       ufoa0;          /**< Underflow output 0 action. */
106   LETIMER_UFOA_TypeDef       ufoa1;          /**< Underflow output 1 action. */
107   LETIMER_RepeatMode_TypeDef repMode;        /**< Repeat mode. */
108 } LETIMER_Init_TypeDef;
109 
110 /** Default config for LETIMER init structure. */
111 #define LETIMER_INIT_DEFAULT                                                    \
112   { true,               /* Enable timer when init complete. */                  \
113     false,              /* Stop counter during debug halt. */                   \
114     false,              /* Do not start counting on RTC COMP0 match. */         \
115     false,              /* Do not start counting on RTC COMP1 match. */         \
116     false,              /* Do not load COMP0 into CNT on underflow. */          \
117     false,              /* Do not load COMP1 into COMP0 when REP0 reaches 0. */ \
118     0,                  /* Idle value 0 for output 0. */                        \
119     0,                  /* Idle value 0 for output 1. */                        \
120     letimerUFOANone,    /* No action on underflow on output 0. */               \
121     letimerUFOANone,    /* No action on underflow on output 1. */               \
122     letimerRepeatFree   /* Count until stopped by SW. */                        \
123   }
124 
125 
126 /*******************************************************************************
127  *****************************   PROTOTYPES   **********************************
128  ******************************************************************************/
129 
130 uint32_t LETIMER_CompareGet(LETIMER_TypeDef *letimer, unsigned int comp);
131 void LETIMER_CompareSet(LETIMER_TypeDef *letimer,
132                         unsigned int comp,
133                         uint32_t value);
134 
135 
136 /***************************************************************************//**
137  * @brief
138  *   Get LETIMER counter value.
139  *
140  * @param[in] letimer
141  *   Pointer to LETIMER peripheral register block.
142  *
143  * @return
144  *   Current LETIMER counter value.
145  ******************************************************************************/
LETIMER_CounterGet(LETIMER_TypeDef * letimer)146 __STATIC_INLINE uint32_t LETIMER_CounterGet(LETIMER_TypeDef *letimer)
147 {
148   return(letimer->CNT);
149 }
150 
151 
152 void LETIMER_Enable(LETIMER_TypeDef *letimer, bool enable);
153 void LETIMER_FreezeEnable(LETIMER_TypeDef *letimer, bool enable);
154 void LETIMER_Init(LETIMER_TypeDef *letimer, const LETIMER_Init_TypeDef *init);
155 
156 
157 /***************************************************************************//**
158  * @brief
159  *   Clear one or more pending LETIMER interrupts.
160  *
161  * @param[in] letimer
162  *   Pointer to LETIMER peripheral register block.
163  *
164  * @param[in] flags
165  *   Pending LETIMER interrupt source to clear. Use a bitwise logic OR
166  *    combination of valid interrupt flags for the LETIMER module
167  *    (LETIMER_IF_nnn).
168  ******************************************************************************/
LETIMER_IntClear(LETIMER_TypeDef * letimer,uint32_t flags)169 __STATIC_INLINE void LETIMER_IntClear(LETIMER_TypeDef *letimer, uint32_t flags)
170 {
171   letimer->IFC = flags;
172 }
173 
174 
175 /***************************************************************************//**
176  * @brief
177  *   Disable one or more LETIMER interrupts.
178  *
179  * @param[in] letimer
180  *   Pointer to LETIMER peripheral register block.
181  *
182  * @param[in] flags
183  *   LETIMER interrupt sources to disable. Use a bitwise logic OR combination of
184  *   valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
185  ******************************************************************************/
LETIMER_IntDisable(LETIMER_TypeDef * letimer,uint32_t flags)186 __STATIC_INLINE void LETIMER_IntDisable(LETIMER_TypeDef *letimer, uint32_t flags)
187 {
188   letimer->IEN &= ~(flags);
189 }
190 
191 
192 /***************************************************************************//**
193  * @brief
194  *   Enable one or more LETIMER interrupts.
195  *
196  * @note
197  *   Depending on the use, a pending interrupt may already be set prior to
198  *   enabling the interrupt. Consider using LETIMER_IntClear() prior to enabling
199  *   if such a pending interrupt should be ignored.
200  *
201  * @param[in] letimer
202  *   Pointer to LETIMER peripheral register block.
203  *
204  * @param[in] flags
205  *   LETIMER interrupt sources to enable. Use a bitwise logic OR combination of
206  *   valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
207  ******************************************************************************/
LETIMER_IntEnable(LETIMER_TypeDef * letimer,uint32_t flags)208 __STATIC_INLINE void LETIMER_IntEnable(LETIMER_TypeDef *letimer, uint32_t flags)
209 {
210   letimer->IEN |= flags;
211 }
212 
213 
214 /***************************************************************************//**
215  * @brief
216  *   Get pending LETIMER interrupt flags.
217  *
218  * @note
219  *   The event bits are not cleared by the use of this function.
220  *
221  * @param[in] letimer
222  *   Pointer to LETIMER peripheral register block.
223  *
224  * @return
225  *   LETIMER interrupt sources pending. A bitwise logic OR combination of
226  *    valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
227  ******************************************************************************/
LETIMER_IntGet(LETIMER_TypeDef * letimer)228 __STATIC_INLINE uint32_t LETIMER_IntGet(LETIMER_TypeDef *letimer)
229 {
230   return(letimer->IF);
231 }
232 
233 
234 /***************************************************************************//**
235  * @brief
236  *   Set one or more pending LETIMER interrupts from SW.
237  *
238  * @param[in] letimer
239  *   Pointer to LETIMER peripheral register block.
240  *
241  * @param[in] flags
242  *   LETIMER interrupt sources to set to pending. Use a bitwise logic OR
243  *   combination of valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
244  ******************************************************************************/
LETIMER_IntSet(LETIMER_TypeDef * letimer,uint32_t flags)245 __STATIC_INLINE void LETIMER_IntSet(LETIMER_TypeDef *letimer, uint32_t flags)
246 {
247   letimer->IFS = flags;
248 }
249 
250 uint32_t LETIMER_RepeatGet(LETIMER_TypeDef *letimer, unsigned int rep);
251 void LETIMER_RepeatSet(LETIMER_TypeDef *letimer,
252                        unsigned int rep,
253                        uint32_t value);
254 void LETIMER_Reset(LETIMER_TypeDef *letimer);
255 
256 
257 /** @} (end addtogroup LETIMER) */
258 /** @} (end addtogroup EM_Library) */
259 
260 #ifdef __cplusplus
261 }
262 #endif
263 
264 #endif /* __EM_LETIMER_H */
265