]> git.sur5r.net Git - freertos/blob
a81b123d511a5e6bca5e15fb074612de93fddf70
[freertos] /
1 /***************************************************************************//**\r
2  * @file em_cryotimer.h\r
3  * @brief Ultra Low Energy Timer/Counter (CRYOTIMER) 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.@n\r
16  * 2. Altered source versions must be plainly marked as such, and must not be\r
17  *    misrepresented as being the original software.@n\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 EM_CRYOTIMER_H__\r
34 #define EM_CRYOTIMER_H__\r
35 \r
36 #include <stdbool.h>\r
37 #include "em_device.h"\r
38 #include "em_bus.h"\r
39 \r
40 #if defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT == 1)\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 CRYOTIMER\r
53  * @brief Ultra Low Energy Timer/Counter (CRYOTIMER) Peripheral API\r
54  *\r
55  * @details\r
56  *   The user is responsible for choosing which oscillator to use for the\r
57  *   CRYOTIMER. The oscillator that is choosen must be enabled and ready before\r
58  *   calling this @ref CRYOTIMER_Init function. See @ref CMU_OscillatorEnable\r
59  *   for details of how to enable and wait for an oscillator to become ready.\r
60  *   Note that ULFRCO is always ready while LFRCO and LFXO must be enable by\r
61  *   the user.\r
62  *\r
63  * @details\r
64  *   Note that the only oscillator which is running in EM3 is ULFRCO. Keep this\r
65  *   in mind when choosing which oscillator to use for the CRYOTIMER.\r
66  *\r
67  * @details\r
68  *   Special care must be taken if the user wants the CRYOTIMER to run during\r
69  *   EM4. All the low frequency oscillators can be used in EM4, however the\r
70  *   oscillator that is used must be be configured to be retained when going\r
71  *   into EM4. This can be configured by using functions in the @ref EMU module.\r
72  *   See @ref EMU_EM4Init and @ref EMU_EM4Init_TypeDef. If an oscillator is\r
73  *   retained in EM4 the user is also responsible for unlatching the retained\r
74  *   configuration on a wakeup from EM4.\r
75  *\r
76  * @{\r
77  ******************************************************************************/\r
78 \r
79 /*******************************************************************************\r
80  *********************************   ENUM   ************************************\r
81  ******************************************************************************/\r
82 \r
83 /** Prescaler selection. */\r
84 typedef enum\r
85 {\r
86   cryotimerPresc_1     = _CRYOTIMER_CTRL_PRESC_DIV1,      /**< Divide clock by 1. */\r
87   cryotimerPresc_2     = _CRYOTIMER_CTRL_PRESC_DIV2,      /**< Divide clock by 2. */\r
88   cryotimerPresc_4     = _CRYOTIMER_CTRL_PRESC_DIV4,      /**< Divide clock by 4. */\r
89   cryotimerPresc_8     = _CRYOTIMER_CTRL_PRESC_DIV8,      /**< Divide clock by 8. */\r
90   cryotimerPresc_16    = _CRYOTIMER_CTRL_PRESC_DIV16,     /**< Divide clock by 16. */\r
91   cryotimerPresc_32    = _CRYOTIMER_CTRL_PRESC_DIV32,     /**< Divide clock by 32. */\r
92   cryotimerPresc_64    = _CRYOTIMER_CTRL_PRESC_DIV64,     /**< Divide clock by 64. */\r
93   cryotimerPresc_128   = _CRYOTIMER_CTRL_PRESC_DIV128,    /**< Divide clock by 128. */\r
94 } CRYOTIMER_Presc_TypeDef;\r
95 \r
96 /** Low frequency oscillator selection. */\r
97 typedef enum \r
98 {\r
99   cryotimerOscLFRCO   = _CRYOTIMER_CTRL_OSCSEL_LFRCO,  /**< Select Low Frequency RC Oscillator. */\r
100   cryotimerOscLFXO    = _CRYOTIMER_CTRL_OSCSEL_LFXO,   /**< Select Low Frequency Crystal Oscillator. */\r
101   cryotimerOscULFRCO  = _CRYOTIMER_CTRL_OSCSEL_ULFRCO, /**< Select Ultra Low Frequency RC Oscillator. */\r
102 } CRYOTIMER_Osc_TypeDef;\r
103 \r
104 /** Period selection value */\r
105 typedef enum\r
106 {\r
107   cryotimerPeriod_1     = 0,    /**< Wakeup event after every Pre-scaled clock cycle. */\r
108   cryotimerPeriod_2     = 1,    /**< Wakeup event after 2 Pre-scaled clock cycles. */\r
109   cryotimerPeriod_4     = 2,    /**< Wakeup event after 4 Pre-scaled clock cycles. */\r
110   cryotimerPeriod_8     = 3,    /**< Wakeup event after 8 Pre-scaled clock cycles. */\r
111   cryotimerPeriod_16    = 4,    /**< Wakeup event after 16 Pre-scaled clock cycles. */\r
112   cryotimerPeriod_32    = 5,    /**< Wakeup event after 32 Pre-scaled clock cycles. */\r
113   cryotimerPeriod_64    = 6,    /**< Wakeup event after 64 Pre-scaled clock cycles. */\r
114   cryotimerPeriod_128   = 7,    /**< Wakeup event after 128 Pre-scaled clock cycles. */\r
115   cryotimerPeriod_256   = 8,    /**< Wakeup event after 256 Pre-scaled clock cycles. */\r
116   cryotimerPeriod_512   = 9,    /**< Wakeup event after 512 Pre-scaled clock cycles. */\r
117   cryotimerPeriod_1k    = 10,   /**< Wakeup event after 1k Pre-scaled clock cycles. */\r
118   cryotimerPeriod_2k    = 11,   /**< Wakeup event after 2k Pre-scaled clock cycles. */\r
119   cryotimerPeriod_4k    = 12,   /**< Wakeup event after 4k Pre-scaled clock cycles. */\r
120   cryotimerPeriod_8k    = 13,   /**< Wakeup event after 8k Pre-scaled clock cycles. */\r
121   cryotimerPeriod_16k   = 14,   /**< Wakeup event after 16k Pre-scaled clock cycles. */\r
122   cryotimerPeriod_32k   = 15,   /**< Wakeup event after 32k Pre-scaled clock cycles. */\r
123   cryotimerPeriod_64k   = 16,   /**< Wakeup event after 64k Pre-scaled clock cycles. */\r
124   cryotimerPeriod_128k  = 17,   /**< Wakeup event after 128k Pre-scaled clock cycles. */\r
125   cryotimerPeriod_256k  = 18,   /**< Wakeup event after 256k Pre-scaled clock cycles. */\r
126   cryotimerPeriod_512k  = 19,   /**< Wakeup event after 512k Pre-scaled clock cycles. */\r
127   cryotimerPeriod_1m    = 20,   /**< Wakeup event after 1m Pre-scaled clock cycles. */\r
128   cryotimerPeriod_2m    = 21,   /**< Wakeup event after 2m Pre-scaled clock cycles. */\r
129   cryotimerPeriod_4m    = 22,   /**< Wakeup event after 4m Pre-scaled clock cycles. */\r
130   cryotimerPeriod_8m    = 23,   /**< Wakeup event after 8m Pre-scaled clock cycles. */\r
131   cryotimerPeriod_16m   = 24,   /**< Wakeup event after 16m Pre-scaled clock cycles. */\r
132   cryotimerPeriod_32m   = 25,   /**< Wakeup event after 32m Pre-scaled clock cycles. */\r
133   cryotimerPeriod_64m   = 26,   /**< Wakeup event after 64m Pre-scaled clock cycles. */\r
134   cryotimerPeriod_128m  = 27,   /**< Wakeup event after 128m Pre-scaled clock cycles. */\r
135   cryotimerPeriod_256m  = 28,   /**< Wakeup event after 256m Pre-scaled clock cycles. */\r
136   cryotimerPeriod_512m  = 29,   /**< Wakeup event after 512m Pre-scaled clock cycles. */\r
137   cryotimerPeriod_1024m = 30,   /**< Wakeup event after 1024m Pre-scaled clock cycles. */\r
138   cryotimerPeriod_2048m = 31,   /**< Wakeup event after 2048m Pre-scaled clock cycles. */\r
139   cryotimerPeriod_4096m = 32,   /**< Wakeup event after 4096m Pre-scaled clock cycles. */\r
140 } CRYOTIMER_Period_TypeDef;\r
141 \r
142 /*******************************************************************************\r
143  *******************************   STRUCTS   ***********************************\r
144  ******************************************************************************/\r
145 \r
146 /** CRYOTIMER initialization structure. */\r
147 typedef struct\r
148 {\r
149   /** Enable/disable counting when initialization is completed. */\r
150   bool                      enable;\r
151 \r
152   /** Enable/disable timer counting during debug halt. */\r
153   bool                      debugRun;\r
154 \r
155   /** Enable/disable EM4 Wakeup. */\r
156   bool                      em4Wakeup;\r
157 \r
158   /** Select the oscillator for the CRYOTIMER. */\r
159   CRYOTIMER_Osc_TypeDef     osc;\r
160 \r
161   /** Prescaler. */\r
162   CRYOTIMER_Presc_TypeDef   presc;\r
163 \r
164   /** Period between wakeup event/interrupt. */\r
165   CRYOTIMER_Period_TypeDef  period;\r
166 } CRYOTIMER_Init_TypeDef;\r
167 \r
168 /*******************************************************************************\r
169  *******************************   DEFINES   ***********************************\r
170  ******************************************************************************/\r
171 \r
172 /** Default CRYOTIMER init structure. */\r
173 #define CRYOTIMER_INIT_DEFAULT                                                   \\r
174 {                                                                                \\r
175   true,                  /* Start counting when init done.                    */ \\r
176   false,                 /* Disable CRYOTIMER during debug halt.              */ \\r
177   false,                 /* Disable EM4 wakeup.                               */ \\r
178   cryotimerOscLFRCO,     /* Select Low Frequency RC Oscillator.               */ \\r
179   cryotimerPresc_1,      /* LF Oscillator frequency undivided.                */ \\r
180   cryotimerPeriod_4096m, /* Wakeup event after 4096M pre-scaled clock cycles. */ \\r
181 }\r
182 \r
183 /*******************************************************************************\r
184  *****************************   PROTOTYPES   **********************************\r
185  ******************************************************************************/\r
186 \r
187 /***************************************************************************//**\r
188  * @brief\r
189  *   Clear the CRYOTIMER period interrupt.\r
190  *\r
191  * @param[in] flags\r
192  *   CRYOTIMER interrupt sources to clear. Use CRYOTIMER_IFC_PERIOD\r
193  ******************************************************************************/\r
194 __STATIC_INLINE void CRYOTIMER_IntClear(uint32_t flags)\r
195 {\r
196   CRYOTIMER->IFC = flags & _CRYOTIMER_IFC_MASK;\r
197 }\r
198 \r
199 /***************************************************************************//**\r
200  * @brief\r
201  *   Get the CRYOTIMER interrupt flag.\r
202  * \r
203  * @note\r
204  *   The event bits are not cleared by the use of this function.\r
205  *\r
206  * @return\r
207  *   Pending CRYOTIMER interrupt sources.\r
208  ******************************************************************************/\r
209 __STATIC_INLINE uint32_t CRYOTIMER_IntGet(void)\r
210 {\r
211   return CRYOTIMER->IF;\r
212 }\r
213 \r
214 /***************************************************************************//**\r
215  * @brief\r
216  *   Get enabled and pending CRYOTIMER interrupt flags.\r
217  *   Useful for handling more interrupt sources in the same interrupt handler.\r
218  *\r
219  * @note\r
220  *   Interrupt flags are not cleared by the use of this function.\r
221  *\r
222  * @return\r
223  *   Pending and enabled CRYOTIMER interrupt sources\r
224  *   The return value is the bitwise AND of\r
225  *   - the enabled interrupt sources in CRYOTIMER_IEN and\r
226  *   - the pending interrupt flags CRYOTIMER_IF\r
227  ******************************************************************************/\r
228 __STATIC_INLINE uint32_t CRYOTIMER_IntGetEnabled(void)\r
229 {\r
230   uint32_t ien;\r
231 \r
232   ien = CRYOTIMER->IEN & _CRYOTIMER_IEN_MASK;\r
233   return CRYOTIMER->IF & ien;\r
234 }\r
235 \r
236 /***************************************************************************//**\r
237  * @brief\r
238  *   Enable one or more CRYOTIMER interrupts.\r
239  *\r
240  * @param[in] flags\r
241  *   CRYOTIMER interrupt sources to enable. Use CRYOTIMER_IEN_PERIOD.\r
242  ******************************************************************************/\r
243 __STATIC_INLINE void CRYOTIMER_IntEnable(uint32_t flags)\r
244 {\r
245   CRYOTIMER->IEN |= (flags & _CRYOTIMER_IEN_MASK);\r
246 }\r
247 \r
248 /***************************************************************************//**\r
249  * @brief\r
250  *   Disable one or more CRYOTIMER interrupts.\r
251  *\r
252  * @param[in] flags\r
253  *   CRYOTIMER interrupt sources to disable. Use CRYOTIMER_IEN_PERIOD.\r
254  ******************************************************************************/\r
255 __STATIC_INLINE void CRYOTIMER_IntDisable(uint32_t flags)\r
256 {\r
257   CRYOTIMER->IEN &= ~(flags & _CRYOTIMER_IEN_MASK);\r
258 }\r
259 \r
260 /***************************************************************************//**\r
261  * @brief\r
262  *   Set the CRYOTIMER period interrupt flag.\r
263  *\r
264  * @note\r
265  *   Writes 1 to the interrupt flag set register.\r
266  *\r
267  * @param[in] flags\r
268  *   CRYOTIMER interrupt sources to set to pending. Use CRYOTIMER_IFS_PERIOD.\r
269  ******************************************************************************/\r
270 __STATIC_INLINE void CRYOTIMER_IntSet(uint32_t flags)\r
271 {\r
272   CRYOTIMER->IFS = flags & _CRYOTIMER_IFS_MASK;\r
273 }\r
274 \r
275 /***************************************************************************//**\r
276  * @brief\r
277  *   Set the CRYOTIMER period select\r
278  *\r
279  * @note\r
280  *   Sets the duration between the Interrupts/Wakeup events based on \r
281  *   the pre-scaled clock.\r
282  *\r
283  * @param[in] period\r
284  *   2^period is the number of clock cycles before a wakeup event or \r
285  *   interrupt is triggered. The CRYOTIMER_Periodsel_TypeDef enum can \r
286  *   be used a convenience type when calling this function.\r
287  ******************************************************************************/\r
288 __STATIC_INLINE void CRYOTIMER_PeriodSet(uint32_t period)\r
289 {\r
290   CRYOTIMER->PERIODSEL = period & _CRYOTIMER_PERIODSEL_MASK;\r
291 }\r
292 \r
293 /***************************************************************************//**\r
294  * @brief\r
295  *   Get the CRYOTIMER period select value\r
296  *\r
297  * @note\r
298  *   Gets the duration between the Interrupts/Wakeup events in the \r
299  *   CRYOTIMER.\r
300  *\r
301  * @return\r
302  *   Duration between the interrupts/wakeup events. Returns the value\r
303  *   of the PERIODSEL register. The number of clock cycles can be calculated\r
304  *   as the 2^n where n is the return value of this function.\r
305  ******************************************************************************/\r
306 __STATIC_INLINE uint32_t CRYOTIMER_PeriodGet(void)\r
307 {\r
308   return CRYOTIMER->PERIODSEL;\r
309 }\r
310 \r
311 /***************************************************************************//**\r
312  * @brief\r
313  *   Get the CRYOTIMER counter value\r
314  *\r
315  * @return\r
316  *   Returns the current CRYOTIMER counter value.\r
317  ******************************************************************************/\r
318 __STATIC_INLINE uint32_t CRYOTIMER_CounterGet(void)\r
319 {\r
320   return CRYOTIMER->CNT;\r
321 }\r
322 \r
323 /***************************************************************************//**\r
324  * @brief\r
325  *   Enable/disable EM4 wakeup capability.\r
326  *\r
327  * @param[in] enable\r
328  *   True to enable EM4 wakeup, false to disable.\r
329  ******************************************************************************/\r
330 __STATIC_INLINE void CRYOTIMER_EM4WakeupEnable(bool enable)\r
331 {\r
332   BUS_RegBitWrite((&CRYOTIMER->EM4WUEN), _CRYOTIMER_EM4WUEN_EM4WU_SHIFT, enable);\r
333 }\r
334 \r
335 /***************************************************************************//**\r
336  * @brief\r
337  *   Enable/disable the CRYOTIMER.\r
338  *\r
339  * @param[in] enable\r
340  *   True to enable the CRYOTIMER, false to disable.\r
341  ******************************************************************************/\r
342 __STATIC_INLINE void CRYOTIMER_Enable(bool enable)\r
343 {\r
344   BUS_RegBitWrite((&CRYOTIMER->CTRL), _CRYOTIMER_CTRL_EN_SHIFT, enable);\r
345 }\r
346 \r
347 void CRYOTIMER_Init(const CRYOTIMER_Init_TypeDef *init);\r
348 \r
349 #ifdef __cplusplus\r
350 }\r
351 #endif\r
352 \r
353 /** @} (end addtogroup CRYOTIMER) */\r
354 /** @} (end addtogroup EM_Library) */\r
355 \r
356 #endif /* defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT == 1) */\r
357 #endif /* EM_CRYOTIMER_H__ */\r