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