1 /***************************************************************************//**
2 * @file
3 * @brief Clock management unit (CMU) 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_CMU_H
34 #define __EM_CMU_H
35
36 #include <stdbool.h>
37 #include "em_part.h"
38 #include "em_bitband.h"
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 /***************************************************************************//**
45 * @addtogroup EM_Library
46 * @{
47 ******************************************************************************/
48
49 /***************************************************************************//**
50 * @addtogroup CMU
51 * @{
52 ******************************************************************************/
53
54 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
55
56 /* Select register ids, for internal use */
57 #define CMU_NOSEL_REG 0
58 #define CMU_HFCLKSEL_REG 1
59 #define CMU_LFACLKSEL_REG 2
60 #define CMU_LFBCLKSEL_REG 3
61 #define CMU_DBGCLKSEL_REG 4
62 #if defined (_EFM32_GIANT_FAMILY)
63 #define CMU_USBCCLKSEL_REG 5
64 #endif
65
66 #define CMU_SEL_REG_POS 0
67 #define CMU_SEL_REG_MASK 0xf
68
69 /* Divisor register ids, for internal use */
70 #define CMU_NODIV_REG 0
71 #define CMU_HFPERCLKDIV_REG 1
72 #define CMU_HFCORECLKDIV_REG 2
73 #define CMU_LFAPRESC0_REG 3
74 #define CMU_LFBPRESC0_REG 4
75 #if defined (_EFM32_GIANT_FAMILY)
76 #define CMU_HFCLKDIV_REG 5
77 #endif
78 #define CMU_DIV_REG_POS 4
79 #define CMU_DIV_REG_MASK 0xf
80
81 /* Enable register ids, for internal use */
82 #define CMU_NO_EN_REG 0
83 #define CMU_HFPERCLKDIV_EN_REG 1
84 #define CMU_HFPERCLKEN0_EN_REG 2
85 #define CMU_HFCORECLKEN0_EN_REG 3
86 #define CMU_LFACLKEN0_EN_REG 4
87 #define CMU_LFBCLKEN0_EN_REG 5
88 #define CMU_PCNT_EN_REG 6
89
90 #define CMU_EN_REG_POS 8
91 #define CMU_EN_REG_MASK 0xf
92
93 /* Enable register bit position, for internal use */
94 #define CMU_EN_BIT_POS 12
95 #define CMU_EN_BIT_MASK 0x1f
96
97 /* Clock branch bitfield position, for internal use */
98 #define CMU_HF_CLK_BRANCH 0
99 #define CMU_HFPER_CLK_BRANCH 1
100 #define CMU_HFCORE_CLK_BRANCH 2
101 #define CMU_LFA_CLK_BRANCH 3
102 #define CMU_RTC_CLK_BRANCH 4
103 #define CMU_LETIMER_CLK_BRANCH 5
104 #define CMU_LCDPRE_CLK_BRANCH 6
105 #define CMU_LCD_CLK_BRANCH 7
106 #define CMU_LESENSE_CLK_BRANCH 8
107 #define CMU_LFB_CLK_BRANCH 9
108 #define CMU_LEUART0_CLK_BRANCH 10
109 #define CMU_LEUART1_CLK_BRANCH 11
110 #define CMU_DBG_CLK_BRANCH 12
111 #define CMU_AUX_CLK_BRANCH 13
112 #define CMU_USBC_CLK_BRANCH 14
113
114 #define CMU_CLK_BRANCH_POS 17
115 #define CMU_CLK_BRANCH_MASK 0x1f
116
117 /** @endcond */
118
119 /*******************************************************************************
120 ******************************** ENUMS ************************************
121 ******************************************************************************/
122
123 /** Clock divisors. These values are valid for prescalers. */
124 #define cmuClkDiv_1 1 /**< Divide clock by 1. */
125 #define cmuClkDiv_2 2 /**< Divide clock by 2. */
126 #define cmuClkDiv_4 4 /**< Divide clock by 4. */
127 #define cmuClkDiv_8 8 /**< Divide clock by 8. */
128 #define cmuClkDiv_16 16 /**< Divide clock by 16. */
129 #define cmuClkDiv_32 32 /**< Divide clock by 32. */
130 #define cmuClkDiv_64 64 /**< Divide clock by 64. */
131 #define cmuClkDiv_128 128 /**< Divide clock by 128. */
132 #define cmuClkDiv_256 256 /**< Divide clock by 256. */
133 #define cmuClkDiv_512 512 /**< Divide clock by 512. */
134 #define cmuClkDiv_1024 1024 /**< Divide clock by 1024. */
135 #define cmuClkDiv_2048 2048 /**< Divide clock by 2048. */
136 #define cmuClkDiv_4096 4096 /**< Divide clock by 4096. */
137 #define cmuClkDiv_8192 8192 /**< Divide clock by 8192. */
138 #define cmuClkDiv_16384 16384 /**< Divide clock by 16384. */
139 #define cmuClkDiv_32768 32768 /**< Divide clock by 32768. */
140
141 /** Clock divider configuration */
142 typedef uint32_t CMU_ClkDiv_TypeDef;
143
144 /** High frequency RC bands. */
145 typedef enum
146 {
147 /** 1MHz RC band. */
148 cmuHFRCOBand_1MHz = _CMU_HFRCOCTRL_BAND_1MHZ,
149 /** 7MHz RC band. */
150 cmuHFRCOBand_7MHz = _CMU_HFRCOCTRL_BAND_7MHZ,
151 /** 11MHz RC band. */
152 cmuHFRCOBand_11MHz = _CMU_HFRCOCTRL_BAND_11MHZ,
153 /** 14MHz RC band. */
154 cmuHFRCOBand_14MHz = _CMU_HFRCOCTRL_BAND_14MHZ,
155 /** 21MHz RC band. */
156 cmuHFRCOBand_21MHz = _CMU_HFRCOCTRL_BAND_21MHZ,
157 /** 28MHz RC band. */
158 cmuHFRCOBand_28MHz = _CMU_HFRCOCTRL_BAND_28MHZ
159 } CMU_HFRCOBand_TypeDef;
160
161
162 #if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
163 /** AUX High frequency RC bands. */
164 typedef enum
165 {
166 /** 1MHz RC band. */
167 cmuAUXHFRCOBand_1MHz = _CMU_AUXHFRCOCTRL_BAND_1MHZ,
168 /** 7MHz RC band. */
169 cmuAUXHFRCOBand_7MHz = _CMU_AUXHFRCOCTRL_BAND_7MHZ,
170 /** 11MHz RC band. */
171 cmuAUXHFRCOBand_11MHz = _CMU_AUXHFRCOCTRL_BAND_11MHZ,
172 /** 14MHz RC band. */
173 cmuAUXHFRCOBand_14MHz = _CMU_AUXHFRCOCTRL_BAND_14MHZ,
174 /** 21MHz RC band. */
175 cmuAUXHFRCOBand_21MHz = _CMU_AUXHFRCOCTRL_BAND_21MHZ,
176 /** 28MHz RC band. */
177 cmuAUXHFRCOBand_28MHz = _CMU_AUXHFRCOCTRL_BAND_28MHZ
178 } CMU_AUXHFRCOBand_TypeDef;
179 #endif
180
181 /** Clock points in CMU. Please refer to CMU overview in reference manual. */
182 typedef enum
183 {
184 /*******************/
185 /* HF clock branch */
186 /*******************/
187
188 /** High frequency clock */
189 #if defined(_EFM32_GIANT_FAMILY)
190 cmuClock_HF = (CMU_HFCLKDIV_REG << CMU_DIV_REG_POS) |
191 (CMU_HFCLKSEL_REG << CMU_SEL_REG_POS) |
192 (CMU_NO_EN_REG << CMU_EN_REG_POS) |
193 (0 << CMU_EN_BIT_POS) |
194 (CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS),
195 #else
196 cmuClock_HF = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
197 (CMU_HFCLKSEL_REG << CMU_SEL_REG_POS) |
198 (CMU_NO_EN_REG << CMU_EN_REG_POS) |
199 (0 << CMU_EN_BIT_POS) |
200 (CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS),
201 #endif
202
203 /** Debug clock */
204 cmuClock_DBG = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
205 (CMU_DBGCLKSEL_REG << CMU_SEL_REG_POS) |
206 (CMU_NO_EN_REG << CMU_EN_REG_POS) |
207 (0 << CMU_EN_BIT_POS) |
208 (CMU_DBG_CLK_BRANCH << CMU_CLK_BRANCH_POS),
209
210 /** AUX clock */
211 cmuClock_AUX = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
212 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
213 (CMU_NO_EN_REG << CMU_EN_REG_POS) |
214 (0 << CMU_EN_BIT_POS) |
215 (CMU_AUX_CLK_BRANCH << CMU_CLK_BRANCH_POS),
216
217 /**********************************/
218 /* HF peripheral clock sub-branch */
219 /**********************************/
220
221 /** High frequency peripheral clock */
222 cmuClock_HFPER = (CMU_HFPERCLKDIV_REG << CMU_DIV_REG_POS) |
223 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
224 (CMU_HFPERCLKDIV_EN_REG << CMU_EN_REG_POS) |
225 (_CMU_HFPERCLKDIV_HFPERCLKEN_SHIFT << CMU_EN_BIT_POS) |
226 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
227
228 /** Universal sync/async receiver/transmitter 0 clock. */
229 #if defined(_CMU_HFPERCLKEN0_USART0_MASK)
230 cmuClock_USART0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
231 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
232 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
233 (_CMU_HFPERCLKEN0_USART0_SHIFT << CMU_EN_BIT_POS) |
234 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
235 #endif
236
237 /** Universal sync/async receiver/transmitter 1 clock. */
238 #if defined(_CMU_HFPERCLKEN0_USART1_MASK)
239 cmuClock_USART1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
240 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
241 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
242 (_CMU_HFPERCLKEN0_USART1_SHIFT << CMU_EN_BIT_POS) |
243 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
244 #endif
245
246 /** Universal sync/async receiver/transmitter 2 clock. */
247 #if defined(_CMU_HFPERCLKEN0_USART2_MASK)
248 cmuClock_USART2 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
249 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
250 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
251 (_CMU_HFPERCLKEN0_USART2_SHIFT << CMU_EN_BIT_POS) |
252 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
253 #endif
254
255 /** Universal async receiver/transmitter 0 clock. */
256 #if defined(_CMU_HFPERCLKEN0_UART0_MASK)
257 cmuClock_UART0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
258 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
259 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
260 (_CMU_HFPERCLKEN0_UART0_SHIFT << CMU_EN_BIT_POS) |
261 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
262 #endif
263
264 /** Universal async receiver/transmitter 1 clock. */
265 #if defined(_CMU_HFPERCLKEN0_UART1_MASK)
266 cmuClock_UART1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
267 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
268 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
269 (_CMU_HFPERCLKEN0_UART1_SHIFT << CMU_EN_BIT_POS) |
270 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
271 #endif
272
273 /** Timer 0 clock. */
274 #if defined(_CMU_HFPERCLKEN0_TIMER0_MASK)
275 cmuClock_TIMER0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
276 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
277 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
278 (_CMU_HFPERCLKEN0_TIMER0_SHIFT << CMU_EN_BIT_POS) |
279 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
280 #endif
281
282 /** Timer 1 clock. */
283 #if defined(_CMU_HFPERCLKEN0_TIMER1_MASK)
284 cmuClock_TIMER1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
285 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
286 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
287 (_CMU_HFPERCLKEN0_TIMER1_SHIFT << CMU_EN_BIT_POS) |
288 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
289 #endif
290
291 /** Timer 2 clock. */
292 #if defined(_CMU_HFPERCLKEN0_TIMER2_MASK)
293 cmuClock_TIMER2 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
294 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
295 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
296 (_CMU_HFPERCLKEN0_TIMER2_SHIFT << CMU_EN_BIT_POS) |
297 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
298 #endif
299
300 /** Timer 3 clock. */
301 #if defined(_CMU_HFPERCLKEN0_TIMER3_MASK)
302 cmuClock_TIMER3 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
303 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
304 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
305 (_CMU_HFPERCLKEN0_TIMER3_SHIFT << CMU_EN_BIT_POS) |
306 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
307 #endif
308
309 /** Analog comparator 0 clock. */
310 #if defined(_CMU_HFPERCLKEN0_ACMP0_MASK)
311 cmuClock_ACMP0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
312 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
313 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
314 (_CMU_HFPERCLKEN0_ACMP0_SHIFT << CMU_EN_BIT_POS) |
315 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
316 #endif
317
318 /** Analog comparator 1 clock. */
319 #if defined(_CMU_HFPERCLKEN0_ACMP1_MASK)
320 cmuClock_ACMP1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
321 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
322 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
323 (_CMU_HFPERCLKEN0_ACMP1_SHIFT << CMU_EN_BIT_POS) |
324 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
325 #endif
326
327 /** Peripheral reflex system clock. */
328 #if defined(_CMU_HFPERCLKEN0_PRS_MASK)
329 cmuClock_PRS = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
330 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
331 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
332 (_CMU_HFPERCLKEN0_PRS_SHIFT << CMU_EN_BIT_POS) |
333 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
334 #endif
335
336 /** Digital to analog converter 0 clock. */
337 #if defined(_CMU_HFPERCLKEN0_DAC0_MASK)
338 cmuClock_DAC0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
339 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
340 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
341 (_CMU_HFPERCLKEN0_DAC0_SHIFT << CMU_EN_BIT_POS) |
342 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
343 #endif
344
345 /** General purpose input/output clock. */
346 #if defined(GPIO_PRESENT)
347 cmuClock_GPIO = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
348 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
349 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
350 (_CMU_HFPERCLKEN0_GPIO_SHIFT << CMU_EN_BIT_POS) |
351 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
352 #endif
353
354 /** Voltage comparator clock. */
355 #if defined(VCMP_PRESENT)
356 cmuClock_VCMP = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
357 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
358 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
359 (_CMU_HFPERCLKEN0_VCMP_SHIFT << CMU_EN_BIT_POS) |
360 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
361 #endif
362
363 /** Analog to digital converter 0 clock. */
364 #if defined(_CMU_HFPERCLKEN0_ADC0_MASK)
365 cmuClock_ADC0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
366 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
367 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
368 (_CMU_HFPERCLKEN0_ADC0_SHIFT << CMU_EN_BIT_POS) |
369 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
370 #endif
371
372 /** I2C 0 clock. */
373 #if defined(_CMU_HFPERCLKEN0_I2C0_MASK)
374 cmuClock_I2C0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
375 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
376 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
377 (_CMU_HFPERCLKEN0_I2C0_SHIFT << CMU_EN_BIT_POS) |
378 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
379 #endif
380
381 /** I2C 1 clock. */
382 #if defined(_CMU_HFPERCLKEN0_I2C1_MASK)
383 cmuClock_I2C1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
384 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
385 (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
386 (_CMU_HFPERCLKEN0_I2C1_SHIFT << CMU_EN_BIT_POS) |
387 (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
388 #endif
389
390 /**********************/
391 /* HF core sub-branch */
392 /**********************/
393
394 /** Core clock */
395 cmuClock_CORE = (CMU_HFCORECLKDIV_REG << CMU_DIV_REG_POS) |
396 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
397 (CMU_NO_EN_REG << CMU_EN_REG_POS) |
398 (0 << CMU_EN_BIT_POS) |
399 (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
400
401 /** Advanced encryption standard accelerator clock. */
402 #if defined(AES_PRESENT)
403 cmuClock_AES = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
404 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
405 (CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
406 (_CMU_HFCORECLKEN0_AES_SHIFT << CMU_EN_BIT_POS) |
407 (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
408 #endif
409
410 /** Direct memory access controller clock. */
411 #if defined(DMA_PRESENT)
412 cmuClock_DMA = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
413 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
414 (CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
415 (_CMU_HFCORECLKEN0_DMA_SHIFT << CMU_EN_BIT_POS) |
416 (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
417 #endif
418 /** Low energy clocking module clock. */
419 cmuClock_CORELE = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
420 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
421 (CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
422 (_CMU_HFCORECLKEN0_LE_SHIFT << CMU_EN_BIT_POS) |
423 (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
424
425 /** External bus interface clock. */
426 #if defined(EBI_PRESENT)
427 cmuClock_EBI = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
428 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
429 (CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
430 (_CMU_HFCORECLKEN0_EBI_SHIFT << CMU_EN_BIT_POS) |
431 (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
432 #endif
433
434 #if defined(USB_PRESENT)
435 cmuClock_USBC = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
436 (CMU_USBCCLKSEL_REG << CMU_SEL_REG_POS) |
437 (CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
438 (_CMU_HFCORECLKEN0_USBC_SHIFT << CMU_EN_BIT_POS) |
439 (CMU_USBC_CLK_BRANCH << CMU_CLK_BRANCH_POS),
440
441 #endif
442
443 #if defined(USB_PRESENT)
444 cmuClock_USB = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
445 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
446 (CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
447 (_CMU_HFCORECLKEN0_USB_SHIFT << CMU_EN_BIT_POS) |
448 (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
449 #endif
450
451 /***************/
452 /* LF A branch */
453 /***************/
454
455 /** Low frequency A clock */
456 cmuClock_LFA = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
457 (CMU_LFACLKSEL_REG << CMU_SEL_REG_POS) |
458 (CMU_NO_EN_REG << CMU_EN_REG_POS) |
459 (0 << CMU_EN_BIT_POS) |
460 (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS),
461
462 /** Real time counter clock. */
463 #if defined(RTC_PRESENT)
464 cmuClock_RTC = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) |
465 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
466 (CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) |
467 (_CMU_LFACLKEN0_RTC_SHIFT << CMU_EN_BIT_POS) |
468 (CMU_RTC_CLK_BRANCH << CMU_CLK_BRANCH_POS),
469 #endif
470
471 /** Low energy timer 0 clock. */
472 #if defined(_CMU_LFACLKEN0_LETIMER0_MASK)
473 cmuClock_LETIMER0 = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) |
474 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
475 (CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) |
476 (_CMU_LFACLKEN0_LETIMER0_SHIFT << CMU_EN_BIT_POS) |
477 (CMU_LETIMER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
478 #endif
479
480 /** Liquid crystal display, pre FDIV clock. */
481 #if defined(_CMU_LFACLKEN0_LCD_MASK)
482 cmuClock_LCDpre = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) |
483 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
484 (CMU_NO_EN_REG << CMU_EN_REG_POS) |
485 (0 << CMU_EN_BIT_POS) |
486 (CMU_LCDPRE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
487
488 /** Liquid crystal display clock. Please notice that FDIV prescaler
489 * must be set by special API. */
490 cmuClock_LCD = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
491 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
492 (CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) |
493 (_CMU_LFACLKEN0_LCD_SHIFT << CMU_EN_BIT_POS) |
494 (CMU_LCD_CLK_BRANCH << CMU_CLK_BRANCH_POS),
495 #endif
496
497 /** Pulse counter 0 clock. */
498 #if defined(_CMU_PCNTCTRL_PCNT0CLKEN_MASK)
499 cmuClock_PCNT0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
500 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
501 (CMU_PCNT_EN_REG << CMU_EN_REG_POS) |
502 (_CMU_PCNTCTRL_PCNT0CLKEN_SHIFT << CMU_EN_BIT_POS) |
503 (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS),
504 #endif
505
506 /** Pulse counter 1 clock. */
507 #if defined(_CMU_PCNTCTRL_PCNT1CLKEN_MASK)
508 cmuClock_PCNT1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
509 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
510 (CMU_PCNT_EN_REG << CMU_EN_REG_POS) |
511 (_CMU_PCNTCTRL_PCNT1CLKEN_SHIFT << CMU_EN_BIT_POS) |
512 (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS),
513 #endif
514
515 /** Pulse counter 2 clock. */
516 #if defined(_CMU_PCNTCTRL_PCNT2CLKEN_MASK)
517 cmuClock_PCNT2 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
518 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
519 (CMU_PCNT_EN_REG << CMU_EN_REG_POS) |
520 (_CMU_PCNTCTRL_PCNT2CLKEN_SHIFT << CMU_EN_BIT_POS) |
521 (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS),
522 #endif
523 /** LESENSE clock. */
524 #if defined(_CMU_LFACLKEN0_LESENSE_MASK)
525 cmuClock_LESENSE = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) |
526 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
527 (CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) |
528 (_CMU_LFACLKEN0_LESENSE_SHIFT << CMU_EN_BIT_POS) |
529 (CMU_LESENSE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
530 #endif
531
532 /***************/
533 /* LF B branch */
534 /***************/
535
536 /** Low frequency B clock */
537 cmuClock_LFB = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
538 (CMU_LFBCLKSEL_REG << CMU_SEL_REG_POS) |
539 (CMU_NO_EN_REG << CMU_EN_REG_POS) |
540 (0 << CMU_EN_BIT_POS) |
541 (CMU_LFB_CLK_BRANCH << CMU_CLK_BRANCH_POS),
542
543 /** Low energy universal asynchronous receiver/transmitter 0 clock. */
544 #if defined(_CMU_LFBCLKEN0_LEUART0_MASK)
545 cmuClock_LEUART0 = (CMU_LFBPRESC0_REG << CMU_DIV_REG_POS) |
546 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
547 (CMU_LFBCLKEN0_EN_REG << CMU_EN_REG_POS) |
548 (_CMU_LFBCLKEN0_LEUART0_SHIFT << CMU_EN_BIT_POS) |
549 (CMU_LEUART0_CLK_BRANCH << CMU_CLK_BRANCH_POS),
550 #endif
551
552 /** Low energy universal asynchronous receiver/transmitter 1 clock. */
553 #if defined(_CMU_LFBCLKEN0_LEUART1_MASK)
554 cmuClock_LEUART1 = (CMU_LFBPRESC0_REG << CMU_DIV_REG_POS) |
555 (CMU_NOSEL_REG << CMU_SEL_REG_POS) |
556 (CMU_LFBCLKEN0_EN_REG << CMU_EN_REG_POS) |
557 (_CMU_LFBCLKEN0_LEUART1_SHIFT << CMU_EN_BIT_POS) |
558 (CMU_LEUART1_CLK_BRANCH << CMU_CLK_BRANCH_POS),
559 #endif
560 } CMU_Clock_TypeDef;
561
562
563 /** Oscillator types. */
564 typedef enum
565 {
566 cmuOsc_LFXO, /**< Low frequency crystal oscillator. */
567 cmuOsc_LFRCO, /**< Low frequency RC oscillator. */
568 cmuOsc_HFXO, /**< High frequency crystal oscillator. */
569 cmuOsc_HFRCO, /**< High frequency RC oscillator. */
570 cmuOsc_AUXHFRCO, /**< Auxiliary high frequency RC oscillator. */
571 #if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
572 cmuOsc_ULFRCO /**< Ultra low frequency RC oscillator. */
573 #endif
574 } CMU_Osc_TypeDef;
575
576
577 /** Selectable clock sources. */
578 typedef enum
579 {
580 cmuSelect_Error, /**< Usage error. */
581 cmuSelect_Disabled, /**< Clock selector disabled. */
582 cmuSelect_LFXO, /**< Low frequency crystal oscillator. */
583 cmuSelect_LFRCO, /**< Low frequency RC oscillator. */
584 cmuSelect_HFXO, /**< High frequency crystal oscillator. */
585 cmuSelect_HFRCO, /**< High frequency RC oscillator. */
586 cmuSelect_CORELEDIV2, /**< Core low energy clock divided by 2. */
587 cmuSelect_AUXHFRCO, /**< Auxilliary clock source can be used for debug clock */
588 cmuSelect_HFCLK, /**< Divided HFCLK on Giant for debug clock, undivided on Tiny Gecko and for USBC (not used on Gecko) */
589 #if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
590 cmuSelect_ULFRCO, /**< Ultra low frequency RC oscillator. */
591 #endif
592 } CMU_Select_TypeDef;
593
594
595 /*******************************************************************************
596 ***************************** PROTOTYPES **********************************
597 ******************************************************************************/
598
599 void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable);
600 uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock);
601 CMU_ClkDiv_TypeDef CMU_ClockDivGet(CMU_Clock_TypeDef clock);
602 CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock);
603 void CMU_ClockDivSet(CMU_Clock_TypeDef clock, CMU_ClkDiv_TypeDef div);
604 void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref);
605
606 CMU_HFRCOBand_TypeDef CMU_HFRCOBandGet(void);
607 void CMU_HFRCOBandSet(CMU_HFRCOBand_TypeDef band);
608 #if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
609 CMU_AUXHFRCOBand_TypeDef CMU_AUXHFRCOBandGet(void);
610 void CMU_AUXHFRCOBandSet(CMU_AUXHFRCOBand_TypeDef band);
611 #endif
612 void CMU_HFRCOStartupDelaySet(uint32_t delay);
613 uint32_t CMU_HFRCOStartupDelayGet(void);
614
615 void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait);
616 uint32_t CMU_OscillatorTuningGet(CMU_Osc_TypeDef osc);
617 void CMU_OscillatorTuningSet(CMU_Osc_TypeDef osc, uint32_t val);
618
619 bool CMU_PCNTClockExternalGet(unsigned int inst);
620 void CMU_PCNTClockExternalSet(unsigned int inst, bool external);
621
622 uint32_t CMU_LCDClkFDIVGet(void);
623 void CMU_LCDClkFDIVSet(uint32_t div);
624
625 void CMU_FreezeEnable(bool enable);
626 uint32_t CMU_Calibrate(uint32_t HFCycles, CMU_Osc_TypeDef reference);
627 void CMU_CalibrateConfig(uint32_t downCycles, CMU_Osc_TypeDef downSel,
628 CMU_Osc_TypeDef upSel);
629
630 /***************************************************************************//**
631 * @brief
632 * Clear one or more pending CMU interrupts.
633 *
634 * @param[in] flags
635 * CMU interrupt sources to clear.
636 ******************************************************************************/
CMU_IntClear(uint32_t flags)637 __STATIC_INLINE void CMU_IntClear(uint32_t flags)
638 {
639 CMU->IFC = flags;
640 }
641
642
643 /***************************************************************************//**
644 * @brief
645 * Disable one or more CMU interrupts.
646 *
647 * @param[in] flags
648 * CMU interrupt sources to disable.
649 ******************************************************************************/
CMU_IntDisable(uint32_t flags)650 __STATIC_INLINE void CMU_IntDisable(uint32_t flags)
651 {
652 CMU->IEN &= ~flags;
653 }
654
655
656 /***************************************************************************//**
657 * @brief
658 * Enable one or more CMU interrupts.
659 *
660 * @note
661 * Depending on the use, a pending interrupt may already be set prior to
662 * enabling the interrupt. Consider using CMU_IntClear() prior to enabling
663 * if such a pending interrupt should be ignored.
664 *
665 * @param[in] flags
666 * CMU interrupt sources to enable.
667 ******************************************************************************/
CMU_IntEnable(uint32_t flags)668 __STATIC_INLINE void CMU_IntEnable(uint32_t flags)
669 {
670 CMU->IEN |= flags;
671 }
672
673
674 /***************************************************************************//**
675 * @brief
676 * Get pending CMU interrupts.
677 *
678 * @return
679 * CMU interrupt sources pending.
680 ******************************************************************************/
CMU_IntGet(void)681 __STATIC_INLINE uint32_t CMU_IntGet(void)
682 {
683 return CMU->IF;
684 }
685
686
687 /***************************************************************************//**
688 * @brief
689 * Get enabled and pending CMU interrupt flags.
690 *
691 * @details
692 * Useful for handling more interrupt sources in the same interrupt handler.
693 *
694 * @note
695 * The event bits are not cleared by the use of this function.
696 *
697 * @return
698 * Pending and enabled CMU interrupt sources.
699 * The return value is the bitwise AND combination of
700 * - the OR combination of enabled interrupt sources in CMU_IEN_nnn
701 * register (CMU_IEN_nnn) and
702 * - the OR combination of valid interrupt flags of the CMU module
703 * (CMU_IF_nnn).
704 ******************************************************************************/
CMU_IntGetEnabled(void)705 __STATIC_INLINE uint32_t CMU_IntGetEnabled(void)
706 {
707 uint32_t tmp = 0U;
708
709
710 /* Store LESENSE->IEN in temporary variable in order to define explicit order
711 * of volatile accesses. */
712 tmp = CMU->IEN;
713
714 /* Bitwise AND of pending and enabled interrupts */
715 return CMU->IF & tmp;
716 }
717
718
719 /**************************************************************************//**
720 * @brief
721 * Set one or more pending CMU interrupts from SW.
722 *
723 * @param[in] flags
724 * CMU interrupt sources to set to pending.
725 *****************************************************************************/
CMU_IntSet(uint32_t flags)726 __STATIC_INLINE void CMU_IntSet(uint32_t flags)
727 {
728 CMU->IFS = flags;
729 }
730
731
732 /***************************************************************************//**
733 * @brief
734 * Lock the CMU in order to protect some of its registers against unintended
735 * modification.
736 *
737 * @details
738 * Please refer to the reference manual for CMU registers that will be
739 * locked.
740 *
741 * @note
742 * If locking the CMU registers, they must be unlocked prior to using any
743 * CMU API functions modifying CMU registers protected by the lock.
744 ******************************************************************************/
CMU_Lock(void)745 __STATIC_INLINE void CMU_Lock(void)
746 {
747 CMU->LOCK = CMU_LOCK_LOCKKEY_LOCK;
748 }
749
750
751 /***************************************************************************//**
752 * @brief
753 * Unlock the CMU so that writing to locked registers again is possible.
754 ******************************************************************************/
CMU_Unlock(void)755 __STATIC_INLINE void CMU_Unlock(void)
756 {
757 CMU->LOCK = CMU_LOCK_LOCKKEY_UNLOCK;
758 }
759
760
761 /***************************************************************************//**
762 * @brief
763 * Get calibration count register
764 * @note
765 * If continuous calibrartion mode is active, calibration busy will allmost
766 * always be on, and we just need to read the value, where the normal case
767 * would be that this function call has been triggered by the CALRDY
768 * interrupt flag.
769 * @return
770 * Calibration count, the number of UPSEL clocks (see CMU_CalibrateConfig)
771 * in the period of DOWNSEL oscillator clock cycles configured by a previous
772 * write operation to CMU->CALCNT
773 ******************************************************************************/
CMU_CalibrateCountGet(void)774 __STATIC_INLINE uint32_t CMU_CalibrateCountGet(void)
775 {
776 /* Wait until calibration completes, UNLESS continuous calibration mode is */
777 /* active */
778 #if defined (_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
779 if (!(CMU->CALCTRL & CMU_CALCTRL_CONT))
780 {
781 while (CMU->STATUS & CMU_STATUS_CALBSY)
782 ;
783 }
784 #else
785 while (CMU->STATUS & CMU_STATUS_CALBSY)
786 ;
787 #endif
788 return CMU->CALCNT;
789 }
790
791
792 /***************************************************************************//**
793 * @brief
794 * Starts calibration
795 * @note
796 * This call is usually invoked after CMU_CalibrateConfig() and possibly
797 * CMU_CalibrateCont()
798 ******************************************************************************/
CMU_CalibrateStart(void)799 __STATIC_INLINE void CMU_CalibrateStart(void)
800 {
801 CMU->CMD = CMU_CMD_CALSTART;
802 }
803
804
805 #if defined (_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
806 /***************************************************************************//**
807 * @brief
808 * Stop the calibration counters
809 ******************************************************************************/
CMU_CalibrateStop(void)810 __STATIC_INLINE void CMU_CalibrateStop(void)
811 {
812 CMU->CMD = CMU_CMD_CALSTOP;
813 }
814
815
816 /***************************************************************************//**
817 * @brief
818 * Configures continuous calibration mode
819 * @param[in] enable
820 * If true, enables continuous calibration, if false disables continuous
821 * calibrartion
822 ******************************************************************************/
CMU_CalibrateCont(bool enable)823 __STATIC_INLINE void CMU_CalibrateCont(bool enable)
824 {
825 BITBAND_Peripheral(&(CMU->CALCTRL), _CMU_CALCTRL_CONT_SHIFT, enable);
826 }
827 #endif
828
829 /** @} (end addtogroup CMU) */
830 /** @} (end addtogroup EM_Library) */
831
832 #ifdef __cplusplus
833 }
834 #endif
835
836 #endif /* __EM_CMU_H */
837