1 /***************************************************************************//**
\r
2 * @file em_cryotimer.h
\r
3 * @brief Ultra Low Energy Timer/Counter (CRYOTIMER) peripheral API
\r
5 *******************************************************************************
\r
7 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
\r
8 *******************************************************************************
\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
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
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
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
31 ******************************************************************************/
\r
33 #ifndef EM_CRYOTIMER_H__
\r
34 #define EM_CRYOTIMER_H__
\r
36 #include <stdbool.h>
\r
37 #include "em_device.h"
\r
40 #if defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT == 1)
\r
46 /***************************************************************************//**
\r
47 * @addtogroup EM_Library
\r
49 ******************************************************************************/
\r
51 /***************************************************************************//**
\r
52 * @addtogroup CRYOTIMER
\r
53 * @brief Ultra Low Energy Timer/Counter (CRYOTIMER) Peripheral API
\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
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
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
77 ******************************************************************************/
\r
79 /*******************************************************************************
\r
80 ********************************* ENUM ************************************
\r
81 ******************************************************************************/
\r
83 /** Prescaler selection. */
\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
96 /** Low frequency oscillator selection. */
\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
104 /** Period selection value */
\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
142 /*******************************************************************************
\r
143 ******************************* STRUCTS ***********************************
\r
144 ******************************************************************************/
\r
146 /** CRYOTIMER initialization structure. */
\r
149 /** Enable/disable counting when initialization is completed. */
\r
152 /** Enable/disable timer counting during debug halt. */
\r
155 /** Enable/disable EM4 Wakeup. */
\r
158 /** Select the oscillator for the CRYOTIMER. */
\r
159 CRYOTIMER_Osc_TypeDef osc;
\r
162 CRYOTIMER_Presc_TypeDef presc;
\r
164 /** Period between wakeup event/interrupt. */
\r
165 CRYOTIMER_Period_TypeDef period;
\r
166 } CRYOTIMER_Init_TypeDef;
\r
168 /*******************************************************************************
\r
169 ******************************* DEFINES ***********************************
\r
170 ******************************************************************************/
\r
172 /** Default CRYOTIMER init structure. */
\r
173 #define CRYOTIMER_INIT_DEFAULT \
\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
183 /*******************************************************************************
\r
184 ***************************** PROTOTYPES **********************************
\r
185 ******************************************************************************/
\r
187 /***************************************************************************//**
\r
189 * Clear the CRYOTIMER period interrupt.
\r
192 * CRYOTIMER interrupt sources to clear. Use CRYOTIMER_IFC_PERIOD
\r
193 ******************************************************************************/
\r
194 __STATIC_INLINE void CRYOTIMER_IntClear(uint32_t flags)
\r
196 CRYOTIMER->IFC = flags & _CRYOTIMER_IFC_MASK;
\r
199 /***************************************************************************//**
\r
201 * Get the CRYOTIMER interrupt flag.
\r
204 * The event bits are not cleared by the use of this function.
\r
207 * Pending CRYOTIMER interrupt sources.
\r
208 ******************************************************************************/
\r
209 __STATIC_INLINE uint32_t CRYOTIMER_IntGet(void)
\r
211 return CRYOTIMER->IF;
\r
214 /***************************************************************************//**
\r
216 * Get enabled and pending CRYOTIMER interrupt flags.
\r
217 * Useful for handling more interrupt sources in the same interrupt handler.
\r
220 * Interrupt flags are not cleared by the use of this function.
\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
232 ien = CRYOTIMER->IEN & _CRYOTIMER_IEN_MASK;
\r
233 return CRYOTIMER->IF & ien;
\r
236 /***************************************************************************//**
\r
238 * Enable one or more CRYOTIMER interrupts.
\r
241 * CRYOTIMER interrupt sources to enable. Use CRYOTIMER_IEN_PERIOD.
\r
242 ******************************************************************************/
\r
243 __STATIC_INLINE void CRYOTIMER_IntEnable(uint32_t flags)
\r
245 CRYOTIMER->IEN |= (flags & _CRYOTIMER_IEN_MASK);
\r
248 /***************************************************************************//**
\r
250 * Disable one or more CRYOTIMER interrupts.
\r
253 * CRYOTIMER interrupt sources to disable. Use CRYOTIMER_IEN_PERIOD.
\r
254 ******************************************************************************/
\r
255 __STATIC_INLINE void CRYOTIMER_IntDisable(uint32_t flags)
\r
257 CRYOTIMER->IEN &= ~(flags & _CRYOTIMER_IEN_MASK);
\r
260 /***************************************************************************//**
\r
262 * Set the CRYOTIMER period interrupt flag.
\r
265 * Writes 1 to the interrupt flag set register.
\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
272 CRYOTIMER->IFS = flags & _CRYOTIMER_IFS_MASK;
\r
275 /***************************************************************************//**
\r
277 * Set the CRYOTIMER period select
\r
280 * Sets the duration between the Interrupts/Wakeup events based on
\r
281 * the pre-scaled clock.
\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
290 CRYOTIMER->PERIODSEL = period & _CRYOTIMER_PERIODSEL_MASK;
\r
293 /***************************************************************************//**
\r
295 * Get the CRYOTIMER period select value
\r
298 * Gets the duration between the Interrupts/Wakeup events in the
\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
308 return CRYOTIMER->PERIODSEL;
\r
311 /***************************************************************************//**
\r
313 * Get the CRYOTIMER counter value
\r
316 * Returns the current CRYOTIMER counter value.
\r
317 ******************************************************************************/
\r
318 __STATIC_INLINE uint32_t CRYOTIMER_CounterGet(void)
\r
320 return CRYOTIMER->CNT;
\r
323 /***************************************************************************//**
\r
325 * Enable/disable EM4 wakeup capability.
\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
332 BUS_RegBitWrite((&CRYOTIMER->EM4WUEN), _CRYOTIMER_EM4WUEN_EM4WU_SHIFT, enable);
\r
335 /***************************************************************************//**
\r
337 * Enable/disable the CRYOTIMER.
\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
344 BUS_RegBitWrite((&CRYOTIMER->CTRL), _CRYOTIMER_CTRL_EN_SHIFT, enable);
\r
347 void CRYOTIMER_Init(const CRYOTIMER_Init_TypeDef *init);
\r
353 /** @} (end addtogroup CRYOTIMER) */
\r
354 /** @} (end addtogroup EM_Library) */
\r
356 #endif /* defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT == 1) */
\r
357 #endif /* EM_CRYOTIMER_H__ */
\r