1 /***************************************************************************//**
\r
3 * @brief Energy Management Unit (EMU) Peripheral API
\r
5 *******************************************************************************
\r
7 * <b>(C) Copyright 2014 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.
\r
16 * 2. Altered source versions must be plainly marked as such, and must not be
\r
17 * misrepresented as being the original software.
\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
35 #if defined( EMU_PRESENT ) && ( EMU_COUNT > 0 )
\r
38 #include "em_system.h"
\r
39 #include "em_assert.h"
\r
41 /***************************************************************************//**
\r
42 * @addtogroup EM_Library
\r
44 ******************************************************************************/
\r
46 /***************************************************************************//**
\r
48 * @brief Energy Management Unit (EMU) Peripheral API
\r
50 ******************************************************************************/
\r
52 /* Consistency check, since restoring assumes similar bitpositions in */
\r
53 /* CMU OSCENCMD and STATUS regs */
\r
54 #if (CMU_STATUS_AUXHFRCOENS != CMU_OSCENCMD_AUXHFRCOEN)
\r
55 #error Conflict in AUXHFRCOENS and AUXHFRCOEN bitpositions
\r
57 #if (CMU_STATUS_HFXOENS != CMU_OSCENCMD_HFXOEN)
\r
58 #error Conflict in HFXOENS and HFXOEN bitpositions
\r
60 #if (CMU_STATUS_LFRCOENS != CMU_OSCENCMD_LFRCOEN)
\r
61 #error Conflict in LFRCOENS and LFRCOEN bitpositions
\r
63 #if (CMU_STATUS_LFXOENS != CMU_OSCENCMD_LFXOEN)
\r
64 #error Conflict in LFXOENS and LFXOEN bitpositions
\r
68 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
\r
69 /* Fix for errata EMU_E107 - non-WIC interrupt masks. */
\r
70 #if defined(_EFM32_GECKO_FAMILY)
\r
71 #define ERRATA_FIX_EMU_E107_EN
\r
72 #define NON_WIC_INT_MASK_0 (~(0x0dfc0323U))
\r
73 #define NON_WIC_INT_MASK_1 (~(0x0U))
\r
74 #elif defined(_EFM32_TINY_FAMILY)
\r
75 #define ERRATA_FIX_EMU_E107_EN
\r
76 #define NON_WIC_INT_MASK_0 (~(0x001be323U))
\r
77 #define NON_WIC_INT_MASK_1 (~(0x0U))
\r
78 #elif defined(_EFM32_GIANT_FAMILY)
\r
79 #define ERRATA_FIX_EMU_E107_EN
\r
80 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
\r
81 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
\r
82 #elif defined(_EFM32_WONDER_FAMILY)
\r
83 #define ERRATA_FIX_EMU_E107_EN
\r
84 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
\r
85 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
\r
87 /* Zero Gecko and future families are not affected by errata EMU_E107 */
\r
90 /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */
\r
91 #if defined(_EFM32_HAPPY_FAMILY)
\r
92 #define ERRATA_FIX_EMU_E108_EN
\r
96 /*******************************************************************************
\r
97 ************************** LOCAL VARIABLES ********************************
\r
98 ******************************************************************************/
\r
100 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
\r
102 * CMU configured oscillator selection and oscillator enable status. When a
\r
103 * user configures oscillators, this varaiable shall shadow the configuration.
\r
104 * It is used by the EMU module in order to be able to restore the oscillator
\r
105 * config after having been in certain energy modes (since HW may automatically
\r
106 * alter config when going into an energy mode). It is the responsibility of
\r
107 * the CMU module to keep it up-to-date (or a user if not using the CMU API
\r
108 * for oscillator control).
\r
110 static uint32_t cmuStatus;
\r
114 /*******************************************************************************
\r
115 ************************** LOCAL FUNCTIONS ********************************
\r
116 ******************************************************************************/
\r
118 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
\r
120 /***************************************************************************//**
\r
122 * Restore oscillators and core clock after having been in EM2 or EM3.
\r
123 ******************************************************************************/
\r
124 static void EMU_Restore(void)
\r
127 uint32_t cmuLocked;
\r
128 uint32_t statusClkSelMask;
\r
130 /* Although we could use the CMU API for most of the below handling, we */
\r
131 /* would like this function to be as efficient as possible. */
\r
133 /* CMU registers may be locked */
\r
134 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
\r
137 /* AUXHFRCO are automatically disabled (except if using debugger). */
\r
138 /* HFRCO, USHFRCO and HFXO are automatically disabled. */
\r
139 /* LFRCO/LFXO may be disabled by SW in EM3. */
\r
140 /* Restore according to status prior to entering energy mode. */
\r
142 oscEnCmd |= ((cmuStatus & CMU_STATUS_HFRCOENS) ? CMU_OSCENCMD_HFRCOEN : 0);
\r
143 oscEnCmd |= ((cmuStatus & CMU_STATUS_AUXHFRCOENS) ? CMU_OSCENCMD_AUXHFRCOEN : 0);
\r
144 oscEnCmd |= ((cmuStatus & CMU_STATUS_LFRCOENS) ? CMU_OSCENCMD_LFRCOEN : 0);
\r
145 oscEnCmd |= ((cmuStatus & CMU_STATUS_HFXOENS) ? CMU_OSCENCMD_HFXOEN : 0);
\r
146 oscEnCmd |= ((cmuStatus & CMU_STATUS_LFXOENS) ? CMU_OSCENCMD_LFXOEN : 0);
\r
147 #if defined( _CMU_STATUS_USHFRCOENS_MASK )
\r
148 oscEnCmd |= ((cmuStatus & CMU_STATUS_USHFRCOENS) ? CMU_OSCENCMD_USHFRCOEN : 0);
\r
150 CMU->OSCENCMD = oscEnCmd;
\r
153 (CMU_STATUS_HFRCOSEL |
\r
154 CMU_STATUS_HFXOSEL |
\r
155 CMU_STATUS_LFRCOSEL |
\r
156 #if defined( CMU_STATUS_USHFRCODIV2SEL )
\r
157 CMU_STATUS_USHFRCODIV2SEL |
\r
159 CMU_STATUS_LFXOSEL);
\r
161 /* Restore oscillator used for clocking core */
\r
162 switch (cmuStatus & statusClkSelMask)
\r
164 case CMU_STATUS_LFRCOSEL:
\r
165 /* Wait for LFRCO to stabilize */
\r
166 while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
\r
168 CMU->CMD = CMU_CMD_HFCLKSEL_LFRCO;
\r
171 case CMU_STATUS_LFXOSEL:
\r
172 /* Wait for LFXO to stabilize */
\r
173 while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
\r
175 CMU->CMD = CMU_CMD_HFCLKSEL_LFXO;
\r
178 case CMU_STATUS_HFXOSEL:
\r
179 /* Wait for HFXO to stabilize */
\r
180 while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
\r
182 CMU->CMD = CMU_CMD_HFCLKSEL_HFXO;
\r
185 #if defined( CMU_STATUS_USHFRCODIV2SEL )
\r
186 case CMU_STATUS_USHFRCODIV2SEL:
\r
187 /* Wait for USHFRCO to stabilize */
\r
188 while (!(CMU->STATUS & CMU_STATUS_USHFRCORDY))
\r
190 CMU->CMD = _CMU_CMD_HFCLKSEL_USHFRCODIV2;
\r
194 default: /* CMU_STATUS_HFRCOSEL */
\r
195 /* If core clock was HFRCO core clock, it is automatically restored to */
\r
196 /* state prior to entering energy mode. No need for further action. */
\r
200 /* If HFRCO was disabled before entering Energy Mode, turn it off again */
\r
201 /* as it is automatically enabled by wake up */
\r
202 if ( ! (cmuStatus & CMU_STATUS_HFRCOENS) )
\r
204 CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
\r
207 /* Restore CMU register locking */
\r
215 /* Get enable conditions for errata EMU_E107 fix. */
\r
216 #if defined(ERRATA_FIX_EMU_E107_EN)
\r
217 static __INLINE bool getErrataFixEmuE107En(void)
\r
219 /* SYSTEM_ChipRevisionGet could have been used here, but we would like a faster implementation in this case. */
\r
220 uint16_t majorMinorRev;
\r
222 /* CHIP MAJOR bit [3:0] */
\r
223 majorMinorRev = (((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) >> _ROMTABLE_PID0_REVMAJOR_SHIFT) << 8);
\r
224 /* CHIP MINOR bit [7:4] */
\r
225 majorMinorRev |= (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK) >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);
\r
226 /* CHIP MINOR bit [3:0] */
\r
227 majorMinorRev |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
\r
229 #if defined(_EFM32_GECKO_FAMILY)
\r
230 return (majorMinorRev <= 0x0103);
\r
231 #elif defined(_EFM32_TINY_FAMILY)
\r
232 return (majorMinorRev <= 0x0102);
\r
233 #elif defined(_EFM32_GIANT_FAMILY)
\r
234 return (majorMinorRev <= 0x0103) || (majorMinorRev == 0x0204);
\r
235 #elif defined(_EFM32_WONDER_FAMILY)
\r
236 return (majorMinorRev == 0x0100);
\r
238 /* Zero Gecko and future families are not affected by errata EMU_E107 */
\r
247 /*******************************************************************************
\r
248 ************************** GLOBAL FUNCTIONS *******************************
\r
249 ******************************************************************************/
\r
251 /***************************************************************************//**
\r
253 * Enter energy mode 2 (EM2).
\r
256 * When entering EM2, the high frequency clocks are disabled, ie HFXO, HFRCO
\r
257 * and AUXHFRCO (for AUXHFRCO, see exception note below). When re-entering
\r
258 * EM0, HFRCO is re-enabled and the core will be clocked by the configured
\r
259 * HFRCO band. This ensures a quick wakeup from EM2.
\r
261 * However, prior to entering EM2, the core may have been using another
\r
262 * oscillator than HFRCO. The @p restore parameter gives the user the option
\r
263 * to restore all HF oscillators according to state prior to entering EM2,
\r
264 * as well as the clock used to clock the core. This restore procedure is
\r
265 * handled by SW. However, since handled by SW, it will not be restored
\r
266 * before completing the interrupt function(s) waking up the core!
\r
269 * If restoring core clock to use the HFXO oscillator, which has been
\r
270 * disabled during EM2 mode, this function will stall until the oscillator
\r
271 * has stabilized. Stalling time can be reduced by adding interrupt
\r
272 * support detecting stable oscillator, and an asynchronous switch to the
\r
273 * original oscillator. See CMU documentation. Such a feature is however
\r
274 * outside the scope of the implementation in this function.
\r
276 * If HFXO is re-enabled by this function, and NOT used to clock the core,
\r
277 * this function will not wait for HFXO to stabilize. This must be considered
\r
278 * by the application if trying to use features relying on that oscillator
\r
281 * If a debugger is attached, the AUXHFRCO will not be disabled if enabled
\r
282 * upon entering EM2. It will thus remain enabled when returning to EM0
\r
283 * regardless of the @p restore parameter.
\r
285 * @param[in] restore
\r
286 * @li true - restore oscillators and clocks, see function details.
\r
287 * @li false - do not restore oscillators and clocks, see function details.
\r
289 * The @p restore option should only be used if all clock control is done
\r
291 ******************************************************************************/
\r
292 void EMU_EnterEM2(bool restore)
\r
294 #if defined(ERRATA_FIX_EMU_E107_EN)
\r
295 bool errataFixEmuE107En;
\r
296 uint32_t nonWicIntEn[2];
\r
299 /* Auto-update CMU status just in case before entering energy mode. */
\r
300 /* This variable is normally kept up-to-date by the CMU API. */
\r
301 cmuStatus = CMU->STATUS;
\r
303 /* Enter Cortex-M3 deep sleep mode */
\r
304 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
\r
306 /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
\r
307 Disable the enabled non-WIC interrupts. */
\r
308 #if defined(ERRATA_FIX_EMU_E107_EN)
\r
309 errataFixEmuE107En = getErrataFixEmuE107En();
\r
310 if (errataFixEmuE107En)
\r
312 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
\r
313 NVIC->ICER[0] = nonWicIntEn[0];
\r
314 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
\r
315 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
\r
316 NVIC->ICER[1] = nonWicIntEn[1];
\r
323 /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
\r
324 #if defined(ERRATA_FIX_EMU_E107_EN)
\r
325 if (errataFixEmuE107En)
\r
327 NVIC->ISER[0] = nonWicIntEn[0];
\r
328 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
\r
329 NVIC->ISER[1] = nonWicIntEn[1];
\r
334 /* Restore oscillators/clocks if specified */
\r
339 /* If not restoring, and original clock was not HFRCO, we have to */
\r
340 /* update CMSIS core clock variable since core clock has changed */
\r
341 /* to using HFRCO. */
\r
342 else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
\r
344 SystemCoreClockUpdate();
\r
349 /***************************************************************************//**
\r
351 * Enter energy mode 3 (EM3).
\r
354 * When entering EM3, the high frequency clocks are disabled by HW, ie HFXO,
\r
355 * HFRCO and AUXHFRCO (for AUXHFRCO, see exception note below). In addition,
\r
356 * the low frequency clocks, ie LFXO and LFRCO are disabled by SW. When
\r
357 * re-entering EM0, HFRCO is re-enabled and the core will be clocked by the
\r
358 * configured HFRCO band. This ensures a quick wakeup from EM3.
\r
360 * However, prior to entering EM3, the core may have been using another
\r
361 * oscillator than HFRCO. The @p restore parameter gives the user the option
\r
362 * to restore all HF/LF oscillators according to state prior to entering EM3,
\r
363 * as well as the clock used to clock the core. This restore procedure is
\r
364 * handled by SW. However, since handled by SW, it will not be restored
\r
365 * before completing the interrupt function(s) waking up the core!
\r
368 * If restoring core clock to use an oscillator other than HFRCO, this
\r
369 * function will stall until the oscillator has stabilized. Stalling time
\r
370 * can be reduced by adding interrupt support detecting stable oscillator,
\r
371 * and an asynchronous switch to the original oscillator. See CMU
\r
372 * documentation. Such a feature is however outside the scope of the
\r
373 * implementation in this function.
\r
375 * If HFXO/LFXO/LFRCO are re-enabled by this function, and NOT used to clock
\r
376 * the core, this function will not wait for those oscillators to stabilize.
\r
377 * This must be considered by the application if trying to use features
\r
378 * relying on those oscillators upon return.
\r
380 * If a debugger is attached, the AUXHFRCO will not be disabled if enabled
\r
381 * upon entering EM3. It will thus remain enabled when returning to EM0
\r
382 * regardless of the @p restore parameter.
\r
384 * @param[in] restore
\r
385 * @li true - restore oscillators and clocks, see function details.
\r
386 * @li false - do not restore oscillators and clocks, see function details.
\r
388 * The @p restore option should only be used if all clock control is done
\r
390 ******************************************************************************/
\r
391 void EMU_EnterEM3(bool restore)
\r
393 uint32_t cmuLocked;
\r
395 #if defined(ERRATA_FIX_EMU_E107_EN)
\r
396 bool errataFixEmuE107En;
\r
397 uint32_t nonWicIntEn[2];
\r
400 /* Auto-update CMU status just in case before entering energy mode. */
\r
401 /* This variable is normally kept up-to-date by the CMU API. */
\r
402 cmuStatus = CMU->STATUS;
\r
404 /* CMU registers may be locked */
\r
405 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
\r
408 /* Disable LF oscillators */
\r
409 CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS | CMU_OSCENCMD_LFRCODIS;
\r
411 /* Restore CMU register locking */
\r
417 /* Enter Cortex-M3 deep sleep mode */
\r
418 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
\r
420 /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
\r
421 Disable the enabled non-WIC interrupts. */
\r
422 #if defined(ERRATA_FIX_EMU_E107_EN)
\r
423 errataFixEmuE107En = getErrataFixEmuE107En();
\r
424 if (errataFixEmuE107En)
\r
426 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
\r
427 NVIC->ICER[0] = nonWicIntEn[0];
\r
428 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
\r
429 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
\r
430 NVIC->ICER[1] = nonWicIntEn[1];
\r
438 /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
\r
439 #if defined(ERRATA_FIX_EMU_E107_EN)
\r
440 if (errataFixEmuE107En)
\r
442 NVIC->ISER[0] = nonWicIntEn[0];
\r
443 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
\r
444 NVIC->ISER[1] = nonWicIntEn[1];
\r
449 /* Restore oscillators/clocks if specified */
\r
454 /* If not restoring, and original clock was not HFRCO, we have to */
\r
455 /* update CMSIS core clock variable since core clock has changed */
\r
456 /* to using HFRCO. */
\r
457 else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
\r
459 SystemCoreClockUpdate();
\r
464 /***************************************************************************//**
\r
466 * Enter energy mode 4 (EM4).
\r
469 * Only a power on reset or external reset pin can wake the device from EM4.
\r
470 ******************************************************************************/
\r
471 void EMU_EnterEM4(void)
\r
477 em4seq2 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK) | (2 << _EMU_CTRL_EM4CTRL_SHIFT);
\r
478 em4seq3 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK) | (3 << _EMU_CTRL_EM4CTRL_SHIFT);
\r
480 /* Make sure register write lock is disabled */
\r
483 #if defined(ERRATA_FIX_EMU_E108_EN)
\r
484 /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */
\r
486 *(volatile uint32_t *)0x400C80E4 = 0;
\r
489 for (i = 0; i < 4; i++)
\r
491 EMU->CTRL = em4seq2;
\r
492 EMU->CTRL = em4seq3;
\r
494 EMU->CTRL = em4seq2;
\r
498 /***************************************************************************//**
\r
500 * Power down memory block.
\r
502 * @param[in] blocks
\r
503 * Specifies a logical OR of bits indicating memory blocks to power down.
\r
504 * Bit 0 selects block 1, bit 1 selects block 2, etc. Memory block 0 cannot
\r
505 * be disabled. Please refer to the EFM32 reference manual for available
\r
506 * memory blocks for a device.
\r
509 * Only a reset can make the specified memory block(s) available for use
\r
510 * after having been powered down. Function will be void for devices not
\r
511 * supporting this feature.
\r
512 ******************************************************************************/
\r
513 void EMU_MemPwrDown(uint32_t blocks)
\r
515 #if defined(_EMU_MEMCTRL_RESETVALUE)
\r
516 EFM_ASSERT(blocks <= _EMU_MEMCTRL_MASK);
\r
518 EMU->MEMCTRL = blocks;
\r
525 /***************************************************************************//**
\r
527 * Update EMU module with CMU oscillator selection/enable status.
\r
530 * When entering EM2 and EM3, the HW may change the core clock oscillator
\r
531 * used, as well as disabling some oscillators. The user may optionally select
\r
532 * to restore the oscillators after waking up from EM2 and EM3 through the
\r
535 * However, in order to support this in a safe way, the EMU module must
\r
536 * be kept up-to-date on the actual selected configuration. The CMU
\r
537 * module must keep the EMU module up-to-date.
\r
539 * This function is mainly intended for internal use by the CMU module,
\r
540 * but if the applications changes oscillator configurations without
\r
541 * using the CMU API, this function can be used to keep the EMU module
\r
543 ******************************************************************************/
\r
544 void EMU_UpdateOscConfig(void)
\r
546 /* Fetch current configuration */
\r
547 cmuStatus = CMU->STATUS;
\r
551 #if defined( _EMU_CTRL_EMVREG_MASK ) || defined( _EMU_CTRL_EM23VREG_MASK )
\r
552 /***************************************************************************//**
\r
554 * Update EMU module with Energy Mode 2 and 3 configuration
\r
556 * @param[in] em23Init
\r
557 * Energy Mode 2 and 3 configuration structure
\r
558 ******************************************************************************/
\r
559 void EMU_EM23Init(EMU_EM23Init_TypeDef *em23Init)
\r
561 #if defined( _EMU_CTRL_EMVREG_MASK )
\r
562 EMU->CTRL = em23Init->em23Vreg ? (EMU->CTRL | EMU_CTRL_EMVREG) : (EMU->CTRL & ~EMU_CTRL_EMVREG);
\r
563 #elif defined( _EMU_CTRL_EM23VREG_MASK )
\r
564 EMU->CTRL = em23Init->em23Vreg ? (EMU->CTRL | EMU_CTRL_EM23VREG) : (EMU->CTRL & ~EMU_CTRL_EM23VREG);
\r
570 #if defined( _EMU_EM4CONF_MASK )
\r
571 /***************************************************************************//**
\r
573 * Update EMU module with Energy Mode 4 configuration
\r
575 * @param[in] em4Init
\r
576 * Energy Mode 4 configuration structure
\r
577 ******************************************************************************/
\r
578 void EMU_EM4Init(EMU_EM4Init_TypeDef *em4Init)
\r
580 uint32_t em4conf = EMU->EM4CONF;
\r
582 /* Clear fields that will be reconfigured */
\r
584 _EMU_EM4CONF_LOCKCONF_MASK |
\r
585 _EMU_EM4CONF_OSC_MASK |
\r
586 _EMU_EM4CONF_BURTCWU_MASK |
\r
587 _EMU_EM4CONF_VREGEN_MASK);
\r
589 /* Configure new settings */
\r
591 (em4Init->lockConfig << _EMU_EM4CONF_LOCKCONF_SHIFT) |
\r
593 (em4Init->buRtcWakeup << _EMU_EM4CONF_BURTCWU_SHIFT) |
\r
594 (em4Init->vreg << _EMU_EM4CONF_VREGEN_SHIFT));
\r
596 /* Apply configuration. Note that lock can be set after this stage. */
\r
597 EMU->EM4CONF = em4conf;
\r
602 #if defined( BU_PRESENT )
\r
604 /***************************************************************************//**
\r
606 * Configure Backup Power Domain settings
\r
608 * @param[in] bupdInit
\r
609 * Backup power domain initialization structure
\r
610 ******************************************************************************/
\r
611 void EMU_BUPDInit(EMU_BUPDInit_TypeDef *bupdInit)
\r
615 /* Set power connection configuration */
\r
616 reg = EMU->PWRCONF & ~(
\r
617 _EMU_PWRCONF_PWRRES_MASK|
\r
618 _EMU_PWRCONF_VOUTSTRONG_MASK|
\r
619 _EMU_PWRCONF_VOUTMED_MASK|
\r
620 _EMU_PWRCONF_VOUTWEAK_MASK);
\r
622 reg |= (bupdInit->resistor|
\r
623 (bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)|
\r
624 (bupdInit->voutMed << _EMU_PWRCONF_VOUTMED_SHIFT)|
\r
625 (bupdInit->voutWeak << _EMU_PWRCONF_VOUTWEAK_SHIFT));
\r
627 EMU->PWRCONF = reg;
\r
629 /* Set backup domain inactive mode configuration */
\r
630 reg = EMU->BUINACT & ~(_EMU_BUINACT_PWRCON_MASK);
\r
631 reg |= (bupdInit->inactivePower);
\r
632 EMU->BUINACT = reg;
\r
634 /* Set backup domain active mode configuration */
\r
635 reg = EMU->BUACT & ~(_EMU_BUACT_PWRCON_MASK);
\r
636 reg |= (bupdInit->activePower);
\r
639 /* Set power control configuration */
\r
640 reg = EMU->BUCTRL & ~(
\r
641 _EMU_BUCTRL_PROBE_MASK|
\r
642 _EMU_BUCTRL_BODCAL_MASK|
\r
643 _EMU_BUCTRL_STATEN_MASK|
\r
644 _EMU_BUCTRL_EN_MASK);
\r
646 /* Note use of ->enable to both enable BUPD, use BU_VIN pin input and
\r
648 reg |= (bupdInit->probe|
\r
649 (bupdInit->bodCal << _EMU_BUCTRL_BODCAL_SHIFT)|
\r
650 (bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)|
\r
651 (bupdInit->enable << _EMU_BUCTRL_EN_SHIFT));
\r
653 /* Enable configuration */
\r
656 /* If enable is true, enable BU_VIN input power pin, if not disable it */
\r
657 EMU_BUPinEnable(bupdInit->enable);
\r
659 /* If enable is true, release BU reset, if not keep reset asserted */
\r
660 BITBAND_Peripheral(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);
\r
664 /***************************************************************************//**
\r
666 * Configure Backup Power Domain BOD Threshold value
\r
668 * These values are precalibrated
\r
669 * @param[in] mode Active or Inactive mode
\r
671 ******************************************************************************/
\r
672 void EMU_BUThresholdSet(EMU_BODMode_TypeDef mode, uint32_t value)
\r
674 EFM_ASSERT(value<=(_EMU_BUACT_BUEXTHRES_MASK>>_EMU_BUACT_BUEXTHRES_SHIFT));
\r
678 case emuBODMode_Active:
\r
679 EMU->BUACT = (EMU->BUACT & ~(_EMU_BUACT_BUEXTHRES_MASK))|(value<<_EMU_BUACT_BUEXTHRES_SHIFT);
\r
681 case emuBODMode_Inactive:
\r
682 EMU->BUINACT = (EMU->BUINACT & ~(_EMU_BUINACT_BUENTHRES_MASK))|(value<<_EMU_BUINACT_BUENTHRES_SHIFT);
\r
688 /***************************************************************************//**
\r
690 * Configure Backup Power Domain BOD Threshold Range
\r
692 * These values are precalibrated
\r
693 * @param[in] mode Active or Inactive mode
\r
695 ******************************************************************************/
\r
696 void EMU_BUThresRangeSet(EMU_BODMode_TypeDef mode, uint32_t value)
\r
698 EFM_ASSERT(value<=(_EMU_BUACT_BUEXRANGE_MASK>>_EMU_BUACT_BUEXRANGE_SHIFT));
\r
702 case emuBODMode_Active:
\r
703 EMU->BUACT = (EMU->BUACT & ~(_EMU_BUACT_BUEXRANGE_MASK))|(value<<_EMU_BUACT_BUEXRANGE_SHIFT);
\r
705 case emuBODMode_Inactive:
\r
706 EMU->BUINACT = (EMU->BUINACT & ~(_EMU_BUINACT_BUENRANGE_MASK))|(value<<_EMU_BUINACT_BUENRANGE_SHIFT);
\r
714 /** @} (end addtogroup EMU) */
\r
715 /** @} (end addtogroup EM_Library) */
\r
716 #endif /* __EM_EMU_H */
\r