added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
bogdanm
Date:
Thu Oct 01 15:25:22 2015 +0300
Revision:
0:9b334a45a8ff
Child:
50:a417edff4437
Initial commit on mbed-dev

Replaces mbed-src (now inactive)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 0:9b334a45a8ff 1 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 2 * @file em_emu.c
bogdanm 0:9b334a45a8ff 3 * @brief Energy Management Unit (EMU) Peripheral API
bogdanm 0:9b334a45a8ff 4 * @version 3.20.12
bogdanm 0:9b334a45a8ff 5 *******************************************************************************
bogdanm 0:9b334a45a8ff 6 * @section License
bogdanm 0:9b334a45a8ff 7 * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
bogdanm 0:9b334a45a8ff 8 *******************************************************************************
bogdanm 0:9b334a45a8ff 9 *
bogdanm 0:9b334a45a8ff 10 * Permission is granted to anyone to use this software for any purpose,
bogdanm 0:9b334a45a8ff 11 * including commercial applications, and to alter it and redistribute it
bogdanm 0:9b334a45a8ff 12 * freely, subject to the following restrictions:
bogdanm 0:9b334a45a8ff 13 *
bogdanm 0:9b334a45a8ff 14 * 1. The origin of this software must not be misrepresented; you must not
bogdanm 0:9b334a45a8ff 15 * claim that you wrote the original software.
bogdanm 0:9b334a45a8ff 16 * 2. Altered source versions must be plainly marked as such, and must not be
bogdanm 0:9b334a45a8ff 17 * misrepresented as being the original software.
bogdanm 0:9b334a45a8ff 18 * 3. This notice may not be removed or altered from any source distribution.
bogdanm 0:9b334a45a8ff 19 *
bogdanm 0:9b334a45a8ff 20 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
bogdanm 0:9b334a45a8ff 21 * obligation to support this Software. Silicon Labs is providing the
bogdanm 0:9b334a45a8ff 22 * Software "AS IS", with no express or implied warranties of any kind,
bogdanm 0:9b334a45a8ff 23 * including, but not limited to, any implied warranties of merchantability
bogdanm 0:9b334a45a8ff 24 * or fitness for any particular purpose or warranties against infringement
bogdanm 0:9b334a45a8ff 25 * of any proprietary rights of a third party.
bogdanm 0:9b334a45a8ff 26 *
bogdanm 0:9b334a45a8ff 27 * Silicon Labs will not be liable for any consequential, incidental, or
bogdanm 0:9b334a45a8ff 28 * special damages, or any other relief, or for any claim by any third party,
bogdanm 0:9b334a45a8ff 29 * arising from your use of this Software.
bogdanm 0:9b334a45a8ff 30 *
bogdanm 0:9b334a45a8ff 31 ******************************************************************************/
bogdanm 0:9b334a45a8ff 32
bogdanm 0:9b334a45a8ff 33
bogdanm 0:9b334a45a8ff 34 #include "em_emu.h"
bogdanm 0:9b334a45a8ff 35 #if defined( EMU_PRESENT ) && ( EMU_COUNT > 0 )
bogdanm 0:9b334a45a8ff 36
bogdanm 0:9b334a45a8ff 37 #include "em_cmu.h"
bogdanm 0:9b334a45a8ff 38 #include "em_system.h"
bogdanm 0:9b334a45a8ff 39 #include "em_assert.h"
bogdanm 0:9b334a45a8ff 40
bogdanm 0:9b334a45a8ff 41 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 42 * @addtogroup EM_Library
bogdanm 0:9b334a45a8ff 43 * @{
bogdanm 0:9b334a45a8ff 44 ******************************************************************************/
bogdanm 0:9b334a45a8ff 45
bogdanm 0:9b334a45a8ff 46 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 47 * @addtogroup EMU
bogdanm 0:9b334a45a8ff 48 * @brief Energy Management Unit (EMU) Peripheral API
bogdanm 0:9b334a45a8ff 49 * @{
bogdanm 0:9b334a45a8ff 50 ******************************************************************************/
bogdanm 0:9b334a45a8ff 51
bogdanm 0:9b334a45a8ff 52 /* Consistency check, since restoring assumes similar bitpositions in */
bogdanm 0:9b334a45a8ff 53 /* CMU OSCENCMD and STATUS regs */
bogdanm 0:9b334a45a8ff 54 #if (CMU_STATUS_AUXHFRCOENS != CMU_OSCENCMD_AUXHFRCOEN)
bogdanm 0:9b334a45a8ff 55 #error Conflict in AUXHFRCOENS and AUXHFRCOEN bitpositions
bogdanm 0:9b334a45a8ff 56 #endif
bogdanm 0:9b334a45a8ff 57 #if (CMU_STATUS_HFXOENS != CMU_OSCENCMD_HFXOEN)
bogdanm 0:9b334a45a8ff 58 #error Conflict in HFXOENS and HFXOEN bitpositions
bogdanm 0:9b334a45a8ff 59 #endif
bogdanm 0:9b334a45a8ff 60 #if (CMU_STATUS_LFRCOENS != CMU_OSCENCMD_LFRCOEN)
bogdanm 0:9b334a45a8ff 61 #error Conflict in LFRCOENS and LFRCOEN bitpositions
bogdanm 0:9b334a45a8ff 62 #endif
bogdanm 0:9b334a45a8ff 63 #if (CMU_STATUS_LFXOENS != CMU_OSCENCMD_LFXOEN)
bogdanm 0:9b334a45a8ff 64 #error Conflict in LFXOENS and LFXOEN bitpositions
bogdanm 0:9b334a45a8ff 65 #endif
bogdanm 0:9b334a45a8ff 66
bogdanm 0:9b334a45a8ff 67
bogdanm 0:9b334a45a8ff 68 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
bogdanm 0:9b334a45a8ff 69 /* Fix for errata EMU_E107 - non-WIC interrupt masks. */
bogdanm 0:9b334a45a8ff 70 #if defined(_EFM32_GECKO_FAMILY)
bogdanm 0:9b334a45a8ff 71 #define ERRATA_FIX_EMU_E107_EN
bogdanm 0:9b334a45a8ff 72 #define NON_WIC_INT_MASK_0 (~(0x0dfc0323U))
bogdanm 0:9b334a45a8ff 73 #define NON_WIC_INT_MASK_1 (~(0x0U))
bogdanm 0:9b334a45a8ff 74 #elif defined(_EFM32_TINY_FAMILY)
bogdanm 0:9b334a45a8ff 75 #define ERRATA_FIX_EMU_E107_EN
bogdanm 0:9b334a45a8ff 76 #define NON_WIC_INT_MASK_0 (~(0x001be323U))
bogdanm 0:9b334a45a8ff 77 #define NON_WIC_INT_MASK_1 (~(0x0U))
bogdanm 0:9b334a45a8ff 78 #elif defined(_EFM32_GIANT_FAMILY)
bogdanm 0:9b334a45a8ff 79 #define ERRATA_FIX_EMU_E107_EN
bogdanm 0:9b334a45a8ff 80 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
bogdanm 0:9b334a45a8ff 81 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
bogdanm 0:9b334a45a8ff 82 #elif defined(_EFM32_WONDER_FAMILY)
bogdanm 0:9b334a45a8ff 83 #define ERRATA_FIX_EMU_E107_EN
bogdanm 0:9b334a45a8ff 84 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
bogdanm 0:9b334a45a8ff 85 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
bogdanm 0:9b334a45a8ff 86 #else
bogdanm 0:9b334a45a8ff 87 /* Zero Gecko and future families are not affected by errata EMU_E107 */
bogdanm 0:9b334a45a8ff 88 #endif
bogdanm 0:9b334a45a8ff 89
bogdanm 0:9b334a45a8ff 90 /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */
bogdanm 0:9b334a45a8ff 91 #if defined(_EFM32_HAPPY_FAMILY)
bogdanm 0:9b334a45a8ff 92 #define ERRATA_FIX_EMU_E108_EN
bogdanm 0:9b334a45a8ff 93 #endif
bogdanm 0:9b334a45a8ff 94 /** @endcond */
bogdanm 0:9b334a45a8ff 95
bogdanm 0:9b334a45a8ff 96 /*******************************************************************************
bogdanm 0:9b334a45a8ff 97 ************************** LOCAL VARIABLES ********************************
bogdanm 0:9b334a45a8ff 98 ******************************************************************************/
bogdanm 0:9b334a45a8ff 99
bogdanm 0:9b334a45a8ff 100 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
bogdanm 0:9b334a45a8ff 101 /**
bogdanm 0:9b334a45a8ff 102 * CMU configured oscillator selection and oscillator enable status. When a
bogdanm 0:9b334a45a8ff 103 * user configures oscillators, this varaiable shall shadow the configuration.
bogdanm 0:9b334a45a8ff 104 * It is used by the EMU module in order to be able to restore the oscillator
bogdanm 0:9b334a45a8ff 105 * config after having been in certain energy modes (since HW may automatically
bogdanm 0:9b334a45a8ff 106 * alter config when going into an energy mode). It is the responsibility of
bogdanm 0:9b334a45a8ff 107 * the CMU module to keep it up-to-date (or a user if not using the CMU API
bogdanm 0:9b334a45a8ff 108 * for oscillator control).
bogdanm 0:9b334a45a8ff 109 */
bogdanm 0:9b334a45a8ff 110 static uint32_t cmuStatus;
bogdanm 0:9b334a45a8ff 111 /** @endcond */
bogdanm 0:9b334a45a8ff 112
bogdanm 0:9b334a45a8ff 113
bogdanm 0:9b334a45a8ff 114 /*******************************************************************************
bogdanm 0:9b334a45a8ff 115 ************************** LOCAL FUNCTIONS ********************************
bogdanm 0:9b334a45a8ff 116 ******************************************************************************/
bogdanm 0:9b334a45a8ff 117
bogdanm 0:9b334a45a8ff 118 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
bogdanm 0:9b334a45a8ff 119
bogdanm 0:9b334a45a8ff 120 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 121 * @brief
bogdanm 0:9b334a45a8ff 122 * Restore oscillators and core clock after having been in EM2 or EM3.
bogdanm 0:9b334a45a8ff 123 ******************************************************************************/
bogdanm 0:9b334a45a8ff 124 static void EMU_Restore(void)
bogdanm 0:9b334a45a8ff 125 {
bogdanm 0:9b334a45a8ff 126 uint32_t oscEnCmd;
bogdanm 0:9b334a45a8ff 127 uint32_t cmuLocked;
bogdanm 0:9b334a45a8ff 128 uint32_t statusClkSelMask;
bogdanm 0:9b334a45a8ff 129
bogdanm 0:9b334a45a8ff 130 /* Although we could use the CMU API for most of the below handling, we */
bogdanm 0:9b334a45a8ff 131 /* would like this function to be as efficient as possible. */
bogdanm 0:9b334a45a8ff 132
bogdanm 0:9b334a45a8ff 133 /* CMU registers may be locked */
bogdanm 0:9b334a45a8ff 134 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
bogdanm 0:9b334a45a8ff 135 CMU_Unlock();
bogdanm 0:9b334a45a8ff 136
bogdanm 0:9b334a45a8ff 137 /* AUXHFRCO are automatically disabled (except if using debugger). */
bogdanm 0:9b334a45a8ff 138 /* HFRCO, USHFRCO and HFXO are automatically disabled. */
bogdanm 0:9b334a45a8ff 139 /* LFRCO/LFXO may be disabled by SW in EM3. */
bogdanm 0:9b334a45a8ff 140 /* Restore according to status prior to entering energy mode. */
bogdanm 0:9b334a45a8ff 141 oscEnCmd = 0;
bogdanm 0:9b334a45a8ff 142 oscEnCmd |= ((cmuStatus & CMU_STATUS_HFRCOENS) ? CMU_OSCENCMD_HFRCOEN : 0);
bogdanm 0:9b334a45a8ff 143 oscEnCmd |= ((cmuStatus & CMU_STATUS_AUXHFRCOENS) ? CMU_OSCENCMD_AUXHFRCOEN : 0);
bogdanm 0:9b334a45a8ff 144 oscEnCmd |= ((cmuStatus & CMU_STATUS_LFRCOENS) ? CMU_OSCENCMD_LFRCOEN : 0);
bogdanm 0:9b334a45a8ff 145 oscEnCmd |= ((cmuStatus & CMU_STATUS_HFXOENS) ? CMU_OSCENCMD_HFXOEN : 0);
bogdanm 0:9b334a45a8ff 146 oscEnCmd |= ((cmuStatus & CMU_STATUS_LFXOENS) ? CMU_OSCENCMD_LFXOEN : 0);
bogdanm 0:9b334a45a8ff 147 #if defined( _CMU_STATUS_USHFRCOENS_MASK )
bogdanm 0:9b334a45a8ff 148 oscEnCmd |= ((cmuStatus & CMU_STATUS_USHFRCOENS) ? CMU_OSCENCMD_USHFRCOEN : 0);
bogdanm 0:9b334a45a8ff 149 #endif
bogdanm 0:9b334a45a8ff 150 CMU->OSCENCMD = oscEnCmd;
bogdanm 0:9b334a45a8ff 151
bogdanm 0:9b334a45a8ff 152 statusClkSelMask =
bogdanm 0:9b334a45a8ff 153 (CMU_STATUS_HFRCOSEL |
bogdanm 0:9b334a45a8ff 154 CMU_STATUS_HFXOSEL |
bogdanm 0:9b334a45a8ff 155 CMU_STATUS_LFRCOSEL |
bogdanm 0:9b334a45a8ff 156 #if defined( CMU_STATUS_USHFRCODIV2SEL )
bogdanm 0:9b334a45a8ff 157 CMU_STATUS_USHFRCODIV2SEL |
bogdanm 0:9b334a45a8ff 158 #endif
bogdanm 0:9b334a45a8ff 159 CMU_STATUS_LFXOSEL);
bogdanm 0:9b334a45a8ff 160
bogdanm 0:9b334a45a8ff 161 /* Restore oscillator used for clocking core */
bogdanm 0:9b334a45a8ff 162 switch (cmuStatus & statusClkSelMask)
bogdanm 0:9b334a45a8ff 163 {
bogdanm 0:9b334a45a8ff 164 case CMU_STATUS_LFRCOSEL:
bogdanm 0:9b334a45a8ff 165 /* Wait for LFRCO to stabilize */
bogdanm 0:9b334a45a8ff 166 while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
bogdanm 0:9b334a45a8ff 167 ;
bogdanm 0:9b334a45a8ff 168 CMU->CMD = CMU_CMD_HFCLKSEL_LFRCO;
bogdanm 0:9b334a45a8ff 169 break;
bogdanm 0:9b334a45a8ff 170
bogdanm 0:9b334a45a8ff 171 case CMU_STATUS_LFXOSEL:
bogdanm 0:9b334a45a8ff 172 /* Wait for LFXO to stabilize */
bogdanm 0:9b334a45a8ff 173 while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
bogdanm 0:9b334a45a8ff 174 ;
bogdanm 0:9b334a45a8ff 175 CMU->CMD = CMU_CMD_HFCLKSEL_LFXO;
bogdanm 0:9b334a45a8ff 176 break;
bogdanm 0:9b334a45a8ff 177
bogdanm 0:9b334a45a8ff 178 case CMU_STATUS_HFXOSEL:
bogdanm 0:9b334a45a8ff 179 /* Wait for HFXO to stabilize */
bogdanm 0:9b334a45a8ff 180 while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
bogdanm 0:9b334a45a8ff 181 ;
bogdanm 0:9b334a45a8ff 182 CMU->CMD = CMU_CMD_HFCLKSEL_HFXO;
bogdanm 0:9b334a45a8ff 183 break;
bogdanm 0:9b334a45a8ff 184
bogdanm 0:9b334a45a8ff 185 #if defined( CMU_STATUS_USHFRCODIV2SEL )
bogdanm 0:9b334a45a8ff 186 case CMU_STATUS_USHFRCODIV2SEL:
bogdanm 0:9b334a45a8ff 187 /* Wait for USHFRCO to stabilize */
bogdanm 0:9b334a45a8ff 188 while (!(CMU->STATUS & CMU_STATUS_USHFRCORDY))
bogdanm 0:9b334a45a8ff 189 ;
bogdanm 0:9b334a45a8ff 190 CMU->CMD = _CMU_CMD_HFCLKSEL_USHFRCODIV2;
bogdanm 0:9b334a45a8ff 191 break;
bogdanm 0:9b334a45a8ff 192 #endif
bogdanm 0:9b334a45a8ff 193
bogdanm 0:9b334a45a8ff 194 default: /* CMU_STATUS_HFRCOSEL */
bogdanm 0:9b334a45a8ff 195 /* If core clock was HFRCO core clock, it is automatically restored to */
bogdanm 0:9b334a45a8ff 196 /* state prior to entering energy mode. No need for further action. */
bogdanm 0:9b334a45a8ff 197 break;
bogdanm 0:9b334a45a8ff 198 }
bogdanm 0:9b334a45a8ff 199
bogdanm 0:9b334a45a8ff 200 /* If HFRCO was disabled before entering Energy Mode, turn it off again */
bogdanm 0:9b334a45a8ff 201 /* as it is automatically enabled by wake up */
bogdanm 0:9b334a45a8ff 202 if ( ! (cmuStatus & CMU_STATUS_HFRCOENS) )
bogdanm 0:9b334a45a8ff 203 {
bogdanm 0:9b334a45a8ff 204 CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
bogdanm 0:9b334a45a8ff 205 }
bogdanm 0:9b334a45a8ff 206
bogdanm 0:9b334a45a8ff 207 /* Restore CMU register locking */
bogdanm 0:9b334a45a8ff 208 if (cmuLocked)
bogdanm 0:9b334a45a8ff 209 {
bogdanm 0:9b334a45a8ff 210 CMU_Lock();
bogdanm 0:9b334a45a8ff 211 }
bogdanm 0:9b334a45a8ff 212 }
bogdanm 0:9b334a45a8ff 213
bogdanm 0:9b334a45a8ff 214
bogdanm 0:9b334a45a8ff 215 /* Get enable conditions for errata EMU_E107 fix. */
bogdanm 0:9b334a45a8ff 216 #if defined(ERRATA_FIX_EMU_E107_EN)
bogdanm 0:9b334a45a8ff 217 static __INLINE bool getErrataFixEmuE107En(void)
bogdanm 0:9b334a45a8ff 218 {
bogdanm 0:9b334a45a8ff 219 /* SYSTEM_ChipRevisionGet could have been used here, but we would like a faster implementation in this case. */
bogdanm 0:9b334a45a8ff 220 uint16_t majorMinorRev;
bogdanm 0:9b334a45a8ff 221
bogdanm 0:9b334a45a8ff 222 /* CHIP MAJOR bit [3:0] */
bogdanm 0:9b334a45a8ff 223 majorMinorRev = (((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) >> _ROMTABLE_PID0_REVMAJOR_SHIFT) << 8);
bogdanm 0:9b334a45a8ff 224 /* CHIP MINOR bit [7:4] */
bogdanm 0:9b334a45a8ff 225 majorMinorRev |= (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK) >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);
bogdanm 0:9b334a45a8ff 226 /* CHIP MINOR bit [3:0] */
bogdanm 0:9b334a45a8ff 227 majorMinorRev |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
bogdanm 0:9b334a45a8ff 228
bogdanm 0:9b334a45a8ff 229 #if defined(_EFM32_GECKO_FAMILY)
bogdanm 0:9b334a45a8ff 230 return (majorMinorRev <= 0x0103);
bogdanm 0:9b334a45a8ff 231 #elif defined(_EFM32_TINY_FAMILY)
bogdanm 0:9b334a45a8ff 232 return (majorMinorRev <= 0x0102);
bogdanm 0:9b334a45a8ff 233 #elif defined(_EFM32_GIANT_FAMILY)
bogdanm 0:9b334a45a8ff 234 return (majorMinorRev <= 0x0103) || (majorMinorRev == 0x0204);
bogdanm 0:9b334a45a8ff 235 #elif defined(_EFM32_WONDER_FAMILY)
bogdanm 0:9b334a45a8ff 236 return (majorMinorRev == 0x0100);
bogdanm 0:9b334a45a8ff 237 #else
bogdanm 0:9b334a45a8ff 238 /* Zero Gecko and future families are not affected by errata EMU_E107 */
bogdanm 0:9b334a45a8ff 239 return false;
bogdanm 0:9b334a45a8ff 240 #endif
bogdanm 0:9b334a45a8ff 241 }
bogdanm 0:9b334a45a8ff 242 #endif
bogdanm 0:9b334a45a8ff 243
bogdanm 0:9b334a45a8ff 244 /** @endcond */
bogdanm 0:9b334a45a8ff 245
bogdanm 0:9b334a45a8ff 246
bogdanm 0:9b334a45a8ff 247 /*******************************************************************************
bogdanm 0:9b334a45a8ff 248 ************************** GLOBAL FUNCTIONS *******************************
bogdanm 0:9b334a45a8ff 249 ******************************************************************************/
bogdanm 0:9b334a45a8ff 250
bogdanm 0:9b334a45a8ff 251 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 252 * @brief
bogdanm 0:9b334a45a8ff 253 * Enter energy mode 2 (EM2).
bogdanm 0:9b334a45a8ff 254 *
bogdanm 0:9b334a45a8ff 255 * @details
bogdanm 0:9b334a45a8ff 256 * When entering EM2, the high frequency clocks are disabled, ie HFXO, HFRCO
bogdanm 0:9b334a45a8ff 257 * and AUXHFRCO (for AUXHFRCO, see exception note below). When re-entering
bogdanm 0:9b334a45a8ff 258 * EM0, HFRCO is re-enabled and the core will be clocked by the configured
bogdanm 0:9b334a45a8ff 259 * HFRCO band. This ensures a quick wakeup from EM2.
bogdanm 0:9b334a45a8ff 260 *
bogdanm 0:9b334a45a8ff 261 * However, prior to entering EM2, the core may have been using another
bogdanm 0:9b334a45a8ff 262 * oscillator than HFRCO. The @p restore parameter gives the user the option
bogdanm 0:9b334a45a8ff 263 * to restore all HF oscillators according to state prior to entering EM2,
bogdanm 0:9b334a45a8ff 264 * as well as the clock used to clock the core. This restore procedure is
bogdanm 0:9b334a45a8ff 265 * handled by SW. However, since handled by SW, it will not be restored
bogdanm 0:9b334a45a8ff 266 * before completing the interrupt function(s) waking up the core!
bogdanm 0:9b334a45a8ff 267 *
bogdanm 0:9b334a45a8ff 268 * @note
bogdanm 0:9b334a45a8ff 269 * If restoring core clock to use the HFXO oscillator, which has been
bogdanm 0:9b334a45a8ff 270 * disabled during EM2 mode, this function will stall until the oscillator
bogdanm 0:9b334a45a8ff 271 * has stabilized. Stalling time can be reduced by adding interrupt
bogdanm 0:9b334a45a8ff 272 * support detecting stable oscillator, and an asynchronous switch to the
bogdanm 0:9b334a45a8ff 273 * original oscillator. See CMU documentation. Such a feature is however
bogdanm 0:9b334a45a8ff 274 * outside the scope of the implementation in this function.
bogdanm 0:9b334a45a8ff 275 * @par
bogdanm 0:9b334a45a8ff 276 * If HFXO is re-enabled by this function, and NOT used to clock the core,
bogdanm 0:9b334a45a8ff 277 * this function will not wait for HFXO to stabilize. This must be considered
bogdanm 0:9b334a45a8ff 278 * by the application if trying to use features relying on that oscillator
bogdanm 0:9b334a45a8ff 279 * upon return.
bogdanm 0:9b334a45a8ff 280 * @par
bogdanm 0:9b334a45a8ff 281 * If a debugger is attached, the AUXHFRCO will not be disabled if enabled
bogdanm 0:9b334a45a8ff 282 * upon entering EM2. It will thus remain enabled when returning to EM0
bogdanm 0:9b334a45a8ff 283 * regardless of the @p restore parameter.
bogdanm 0:9b334a45a8ff 284 *
bogdanm 0:9b334a45a8ff 285 * @param[in] restore
bogdanm 0:9b334a45a8ff 286 * @li true - restore oscillators and clocks, see function details.
bogdanm 0:9b334a45a8ff 287 * @li false - do not restore oscillators and clocks, see function details.
bogdanm 0:9b334a45a8ff 288 * @par
bogdanm 0:9b334a45a8ff 289 * The @p restore option should only be used if all clock control is done
bogdanm 0:9b334a45a8ff 290 * via the CMU API.
bogdanm 0:9b334a45a8ff 291 ******************************************************************************/
bogdanm 0:9b334a45a8ff 292 void EMU_EnterEM2(bool restore)
bogdanm 0:9b334a45a8ff 293 {
bogdanm 0:9b334a45a8ff 294 #if defined(ERRATA_FIX_EMU_E107_EN)
bogdanm 0:9b334a45a8ff 295 bool errataFixEmuE107En;
bogdanm 0:9b334a45a8ff 296 uint32_t nonWicIntEn[2];
bogdanm 0:9b334a45a8ff 297 #endif
bogdanm 0:9b334a45a8ff 298
bogdanm 0:9b334a45a8ff 299 /* Auto-update CMU status just in case before entering energy mode. */
bogdanm 0:9b334a45a8ff 300 /* This variable is normally kept up-to-date by the CMU API. */
bogdanm 0:9b334a45a8ff 301 cmuStatus = CMU->STATUS;
bogdanm 0:9b334a45a8ff 302
bogdanm 0:9b334a45a8ff 303 /* Enter Cortex-M3 deep sleep mode */
bogdanm 0:9b334a45a8ff 304 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
bogdanm 0:9b334a45a8ff 305
bogdanm 0:9b334a45a8ff 306 /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
bogdanm 0:9b334a45a8ff 307 Disable the enabled non-WIC interrupts. */
bogdanm 0:9b334a45a8ff 308 #if defined(ERRATA_FIX_EMU_E107_EN)
bogdanm 0:9b334a45a8ff 309 errataFixEmuE107En = getErrataFixEmuE107En();
bogdanm 0:9b334a45a8ff 310 if (errataFixEmuE107En)
bogdanm 0:9b334a45a8ff 311 {
bogdanm 0:9b334a45a8ff 312 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
bogdanm 0:9b334a45a8ff 313 NVIC->ICER[0] = nonWicIntEn[0];
bogdanm 0:9b334a45a8ff 314 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
bogdanm 0:9b334a45a8ff 315 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
bogdanm 0:9b334a45a8ff 316 NVIC->ICER[1] = nonWicIntEn[1];
bogdanm 0:9b334a45a8ff 317 #endif
bogdanm 0:9b334a45a8ff 318 }
bogdanm 0:9b334a45a8ff 319 #endif
bogdanm 0:9b334a45a8ff 320
bogdanm 0:9b334a45a8ff 321 __WFI();
bogdanm 0:9b334a45a8ff 322
bogdanm 0:9b334a45a8ff 323 /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
bogdanm 0:9b334a45a8ff 324 #if defined(ERRATA_FIX_EMU_E107_EN)
bogdanm 0:9b334a45a8ff 325 if (errataFixEmuE107En)
bogdanm 0:9b334a45a8ff 326 {
bogdanm 0:9b334a45a8ff 327 NVIC->ISER[0] = nonWicIntEn[0];
bogdanm 0:9b334a45a8ff 328 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
bogdanm 0:9b334a45a8ff 329 NVIC->ISER[1] = nonWicIntEn[1];
bogdanm 0:9b334a45a8ff 330 #endif
bogdanm 0:9b334a45a8ff 331 }
bogdanm 0:9b334a45a8ff 332 #endif
bogdanm 0:9b334a45a8ff 333
bogdanm 0:9b334a45a8ff 334 /* Restore oscillators/clocks if specified */
bogdanm 0:9b334a45a8ff 335 if (restore)
bogdanm 0:9b334a45a8ff 336 {
bogdanm 0:9b334a45a8ff 337 EMU_Restore();
bogdanm 0:9b334a45a8ff 338 }
bogdanm 0:9b334a45a8ff 339 /* If not restoring, and original clock was not HFRCO, we have to */
bogdanm 0:9b334a45a8ff 340 /* update CMSIS core clock variable since core clock has changed */
bogdanm 0:9b334a45a8ff 341 /* to using HFRCO. */
bogdanm 0:9b334a45a8ff 342 else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
bogdanm 0:9b334a45a8ff 343 {
bogdanm 0:9b334a45a8ff 344 SystemCoreClockUpdate();
bogdanm 0:9b334a45a8ff 345 }
bogdanm 0:9b334a45a8ff 346 }
bogdanm 0:9b334a45a8ff 347
bogdanm 0:9b334a45a8ff 348
bogdanm 0:9b334a45a8ff 349 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 350 * @brief
bogdanm 0:9b334a45a8ff 351 * Enter energy mode 3 (EM3).
bogdanm 0:9b334a45a8ff 352 *
bogdanm 0:9b334a45a8ff 353 * @details
bogdanm 0:9b334a45a8ff 354 * When entering EM3, the high frequency clocks are disabled by HW, ie HFXO,
bogdanm 0:9b334a45a8ff 355 * HFRCO and AUXHFRCO (for AUXHFRCO, see exception note below). In addition,
bogdanm 0:9b334a45a8ff 356 * the low frequency clocks, ie LFXO and LFRCO are disabled by SW. When
bogdanm 0:9b334a45a8ff 357 * re-entering EM0, HFRCO is re-enabled and the core will be clocked by the
bogdanm 0:9b334a45a8ff 358 * configured HFRCO band. This ensures a quick wakeup from EM3.
bogdanm 0:9b334a45a8ff 359 *
bogdanm 0:9b334a45a8ff 360 * However, prior to entering EM3, the core may have been using another
bogdanm 0:9b334a45a8ff 361 * oscillator than HFRCO. The @p restore parameter gives the user the option
bogdanm 0:9b334a45a8ff 362 * to restore all HF/LF oscillators according to state prior to entering EM3,
bogdanm 0:9b334a45a8ff 363 * as well as the clock used to clock the core. This restore procedure is
bogdanm 0:9b334a45a8ff 364 * handled by SW. However, since handled by SW, it will not be restored
bogdanm 0:9b334a45a8ff 365 * before completing the interrupt function(s) waking up the core!
bogdanm 0:9b334a45a8ff 366 *
bogdanm 0:9b334a45a8ff 367 * @note
bogdanm 0:9b334a45a8ff 368 * If restoring core clock to use an oscillator other than HFRCO, this
bogdanm 0:9b334a45a8ff 369 * function will stall until the oscillator has stabilized. Stalling time
bogdanm 0:9b334a45a8ff 370 * can be reduced by adding interrupt support detecting stable oscillator,
bogdanm 0:9b334a45a8ff 371 * and an asynchronous switch to the original oscillator. See CMU
bogdanm 0:9b334a45a8ff 372 * documentation. Such a feature is however outside the scope of the
bogdanm 0:9b334a45a8ff 373 * implementation in this function.
bogdanm 0:9b334a45a8ff 374 * @par
bogdanm 0:9b334a45a8ff 375 * If HFXO/LFXO/LFRCO are re-enabled by this function, and NOT used to clock
bogdanm 0:9b334a45a8ff 376 * the core, this function will not wait for those oscillators to stabilize.
bogdanm 0:9b334a45a8ff 377 * This must be considered by the application if trying to use features
bogdanm 0:9b334a45a8ff 378 * relying on those oscillators upon return.
bogdanm 0:9b334a45a8ff 379 * @par
bogdanm 0:9b334a45a8ff 380 * If a debugger is attached, the AUXHFRCO will not be disabled if enabled
bogdanm 0:9b334a45a8ff 381 * upon entering EM3. It will thus remain enabled when returning to EM0
bogdanm 0:9b334a45a8ff 382 * regardless of the @p restore parameter.
bogdanm 0:9b334a45a8ff 383 *
bogdanm 0:9b334a45a8ff 384 * @param[in] restore
bogdanm 0:9b334a45a8ff 385 * @li true - restore oscillators and clocks, see function details.
bogdanm 0:9b334a45a8ff 386 * @li false - do not restore oscillators and clocks, see function details.
bogdanm 0:9b334a45a8ff 387 * @par
bogdanm 0:9b334a45a8ff 388 * The @p restore option should only be used if all clock control is done
bogdanm 0:9b334a45a8ff 389 * via the CMU API.
bogdanm 0:9b334a45a8ff 390 ******************************************************************************/
bogdanm 0:9b334a45a8ff 391 void EMU_EnterEM3(bool restore)
bogdanm 0:9b334a45a8ff 392 {
bogdanm 0:9b334a45a8ff 393 uint32_t cmuLocked;
bogdanm 0:9b334a45a8ff 394
bogdanm 0:9b334a45a8ff 395 #if defined(ERRATA_FIX_EMU_E107_EN)
bogdanm 0:9b334a45a8ff 396 bool errataFixEmuE107En;
bogdanm 0:9b334a45a8ff 397 uint32_t nonWicIntEn[2];
bogdanm 0:9b334a45a8ff 398 #endif
bogdanm 0:9b334a45a8ff 399
bogdanm 0:9b334a45a8ff 400 /* Auto-update CMU status just in case before entering energy mode. */
bogdanm 0:9b334a45a8ff 401 /* This variable is normally kept up-to-date by the CMU API. */
bogdanm 0:9b334a45a8ff 402 cmuStatus = CMU->STATUS;
bogdanm 0:9b334a45a8ff 403
bogdanm 0:9b334a45a8ff 404 /* CMU registers may be locked */
bogdanm 0:9b334a45a8ff 405 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
bogdanm 0:9b334a45a8ff 406 CMU_Unlock();
bogdanm 0:9b334a45a8ff 407
bogdanm 0:9b334a45a8ff 408 /* Disable LF oscillators */
bogdanm 0:9b334a45a8ff 409 CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS | CMU_OSCENCMD_LFRCODIS;
bogdanm 0:9b334a45a8ff 410
bogdanm 0:9b334a45a8ff 411 /* Restore CMU register locking */
bogdanm 0:9b334a45a8ff 412 if (cmuLocked)
bogdanm 0:9b334a45a8ff 413 {
bogdanm 0:9b334a45a8ff 414 CMU_Lock();
bogdanm 0:9b334a45a8ff 415 }
bogdanm 0:9b334a45a8ff 416
bogdanm 0:9b334a45a8ff 417 /* Enter Cortex-M3 deep sleep mode */
bogdanm 0:9b334a45a8ff 418 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
bogdanm 0:9b334a45a8ff 419
bogdanm 0:9b334a45a8ff 420 /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
bogdanm 0:9b334a45a8ff 421 Disable the enabled non-WIC interrupts. */
bogdanm 0:9b334a45a8ff 422 #if defined(ERRATA_FIX_EMU_E107_EN)
bogdanm 0:9b334a45a8ff 423 errataFixEmuE107En = getErrataFixEmuE107En();
bogdanm 0:9b334a45a8ff 424 if (errataFixEmuE107En)
bogdanm 0:9b334a45a8ff 425 {
bogdanm 0:9b334a45a8ff 426 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
bogdanm 0:9b334a45a8ff 427 NVIC->ICER[0] = nonWicIntEn[0];
bogdanm 0:9b334a45a8ff 428 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
bogdanm 0:9b334a45a8ff 429 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
bogdanm 0:9b334a45a8ff 430 NVIC->ICER[1] = nonWicIntEn[1];
bogdanm 0:9b334a45a8ff 431 #endif
bogdanm 0:9b334a45a8ff 432
bogdanm 0:9b334a45a8ff 433 }
bogdanm 0:9b334a45a8ff 434 #endif
bogdanm 0:9b334a45a8ff 435
bogdanm 0:9b334a45a8ff 436 __WFI();
bogdanm 0:9b334a45a8ff 437
bogdanm 0:9b334a45a8ff 438 /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
bogdanm 0:9b334a45a8ff 439 #if defined(ERRATA_FIX_EMU_E107_EN)
bogdanm 0:9b334a45a8ff 440 if (errataFixEmuE107En)
bogdanm 0:9b334a45a8ff 441 {
bogdanm 0:9b334a45a8ff 442 NVIC->ISER[0] = nonWicIntEn[0];
bogdanm 0:9b334a45a8ff 443 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
bogdanm 0:9b334a45a8ff 444 NVIC->ISER[1] = nonWicIntEn[1];
bogdanm 0:9b334a45a8ff 445 #endif
bogdanm 0:9b334a45a8ff 446 }
bogdanm 0:9b334a45a8ff 447 #endif
bogdanm 0:9b334a45a8ff 448
bogdanm 0:9b334a45a8ff 449 /* Restore oscillators/clocks if specified */
bogdanm 0:9b334a45a8ff 450 if (restore)
bogdanm 0:9b334a45a8ff 451 {
bogdanm 0:9b334a45a8ff 452 EMU_Restore();
bogdanm 0:9b334a45a8ff 453 }
bogdanm 0:9b334a45a8ff 454 /* If not restoring, and original clock was not HFRCO, we have to */
bogdanm 0:9b334a45a8ff 455 /* update CMSIS core clock variable since core clock has changed */
bogdanm 0:9b334a45a8ff 456 /* to using HFRCO. */
bogdanm 0:9b334a45a8ff 457 else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
bogdanm 0:9b334a45a8ff 458 {
bogdanm 0:9b334a45a8ff 459 SystemCoreClockUpdate();
bogdanm 0:9b334a45a8ff 460 }
bogdanm 0:9b334a45a8ff 461 }
bogdanm 0:9b334a45a8ff 462
bogdanm 0:9b334a45a8ff 463
bogdanm 0:9b334a45a8ff 464 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 465 * @brief
bogdanm 0:9b334a45a8ff 466 * Enter energy mode 4 (EM4).
bogdanm 0:9b334a45a8ff 467 *
bogdanm 0:9b334a45a8ff 468 * @note
bogdanm 0:9b334a45a8ff 469 * Only a power on reset or external reset pin can wake the device from EM4.
bogdanm 0:9b334a45a8ff 470 ******************************************************************************/
bogdanm 0:9b334a45a8ff 471 void EMU_EnterEM4(void)
bogdanm 0:9b334a45a8ff 472 {
bogdanm 0:9b334a45a8ff 473 int i;
bogdanm 0:9b334a45a8ff 474 uint32_t em4seq2;
bogdanm 0:9b334a45a8ff 475 uint32_t em4seq3;
bogdanm 0:9b334a45a8ff 476
bogdanm 0:9b334a45a8ff 477 em4seq2 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK) | (2 << _EMU_CTRL_EM4CTRL_SHIFT);
bogdanm 0:9b334a45a8ff 478 em4seq3 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK) | (3 << _EMU_CTRL_EM4CTRL_SHIFT);
bogdanm 0:9b334a45a8ff 479
bogdanm 0:9b334a45a8ff 480 /* Make sure register write lock is disabled */
bogdanm 0:9b334a45a8ff 481 EMU_Unlock();
bogdanm 0:9b334a45a8ff 482
bogdanm 0:9b334a45a8ff 483 #if defined(ERRATA_FIX_EMU_E108_EN)
bogdanm 0:9b334a45a8ff 484 /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */
bogdanm 0:9b334a45a8ff 485 __disable_irq();
bogdanm 0:9b334a45a8ff 486 *(volatile uint32_t *)0x400C80E4 = 0;
bogdanm 0:9b334a45a8ff 487 #endif
bogdanm 0:9b334a45a8ff 488
bogdanm 0:9b334a45a8ff 489 for (i = 0; i < 4; i++)
bogdanm 0:9b334a45a8ff 490 {
bogdanm 0:9b334a45a8ff 491 EMU->CTRL = em4seq2;
bogdanm 0:9b334a45a8ff 492 EMU->CTRL = em4seq3;
bogdanm 0:9b334a45a8ff 493 }
bogdanm 0:9b334a45a8ff 494 EMU->CTRL = em4seq2;
bogdanm 0:9b334a45a8ff 495 }
bogdanm 0:9b334a45a8ff 496
bogdanm 0:9b334a45a8ff 497
bogdanm 0:9b334a45a8ff 498 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 499 * @brief
bogdanm 0:9b334a45a8ff 500 * Power down memory block.
bogdanm 0:9b334a45a8ff 501 *
bogdanm 0:9b334a45a8ff 502 * @param[in] blocks
bogdanm 0:9b334a45a8ff 503 * Specifies a logical OR of bits indicating memory blocks to power down.
bogdanm 0:9b334a45a8ff 504 * Bit 0 selects block 1, bit 1 selects block 2, etc. Memory block 0 cannot
bogdanm 0:9b334a45a8ff 505 * be disabled. Please refer to the EFM32 reference manual for available
bogdanm 0:9b334a45a8ff 506 * memory blocks for a device.
bogdanm 0:9b334a45a8ff 507 *
bogdanm 0:9b334a45a8ff 508 * @note
bogdanm 0:9b334a45a8ff 509 * Only a reset can make the specified memory block(s) available for use
bogdanm 0:9b334a45a8ff 510 * after having been powered down. Function will be void for devices not
bogdanm 0:9b334a45a8ff 511 * supporting this feature.
bogdanm 0:9b334a45a8ff 512 ******************************************************************************/
bogdanm 0:9b334a45a8ff 513 void EMU_MemPwrDown(uint32_t blocks)
bogdanm 0:9b334a45a8ff 514 {
bogdanm 0:9b334a45a8ff 515 #if defined(_EMU_MEMCTRL_RESETVALUE)
bogdanm 0:9b334a45a8ff 516 EFM_ASSERT(blocks <= _EMU_MEMCTRL_MASK);
bogdanm 0:9b334a45a8ff 517
bogdanm 0:9b334a45a8ff 518 EMU->MEMCTRL = blocks;
bogdanm 0:9b334a45a8ff 519 #else
bogdanm 0:9b334a45a8ff 520 (void)blocks;
bogdanm 0:9b334a45a8ff 521 #endif
bogdanm 0:9b334a45a8ff 522 }
bogdanm 0:9b334a45a8ff 523
bogdanm 0:9b334a45a8ff 524
bogdanm 0:9b334a45a8ff 525 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 526 * @brief
bogdanm 0:9b334a45a8ff 527 * Update EMU module with CMU oscillator selection/enable status.
bogdanm 0:9b334a45a8ff 528 *
bogdanm 0:9b334a45a8ff 529 * @details
bogdanm 0:9b334a45a8ff 530 * When entering EM2 and EM3, the HW may change the core clock oscillator
bogdanm 0:9b334a45a8ff 531 * used, as well as disabling some oscillators. The user may optionally select
bogdanm 0:9b334a45a8ff 532 * to restore the oscillators after waking up from EM2 and EM3 through the
bogdanm 0:9b334a45a8ff 533 * SW API.
bogdanm 0:9b334a45a8ff 534 *
bogdanm 0:9b334a45a8ff 535 * However, in order to support this in a safe way, the EMU module must
bogdanm 0:9b334a45a8ff 536 * be kept up-to-date on the actual selected configuration. The CMU
bogdanm 0:9b334a45a8ff 537 * module must keep the EMU module up-to-date.
bogdanm 0:9b334a45a8ff 538 *
bogdanm 0:9b334a45a8ff 539 * This function is mainly intended for internal use by the CMU module,
bogdanm 0:9b334a45a8ff 540 * but if the applications changes oscillator configurations without
bogdanm 0:9b334a45a8ff 541 * using the CMU API, this function can be used to keep the EMU module
bogdanm 0:9b334a45a8ff 542 * up-to-date.
bogdanm 0:9b334a45a8ff 543 ******************************************************************************/
bogdanm 0:9b334a45a8ff 544 void EMU_UpdateOscConfig(void)
bogdanm 0:9b334a45a8ff 545 {
bogdanm 0:9b334a45a8ff 546 /* Fetch current configuration */
bogdanm 0:9b334a45a8ff 547 cmuStatus = CMU->STATUS;
bogdanm 0:9b334a45a8ff 548 }
bogdanm 0:9b334a45a8ff 549
bogdanm 0:9b334a45a8ff 550
bogdanm 0:9b334a45a8ff 551 #if defined( _EMU_CTRL_EMVREG_MASK ) || defined( _EMU_CTRL_EM23VREG_MASK )
bogdanm 0:9b334a45a8ff 552 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 553 * @brief
bogdanm 0:9b334a45a8ff 554 * Update EMU module with Energy Mode 2 and 3 configuration
bogdanm 0:9b334a45a8ff 555 *
bogdanm 0:9b334a45a8ff 556 * @param[in] em23Init
bogdanm 0:9b334a45a8ff 557 * Energy Mode 2 and 3 configuration structure
bogdanm 0:9b334a45a8ff 558 ******************************************************************************/
bogdanm 0:9b334a45a8ff 559 void EMU_EM23Init(EMU_EM23Init_TypeDef *em23Init)
bogdanm 0:9b334a45a8ff 560 {
bogdanm 0:9b334a45a8ff 561 #if defined( _EMU_CTRL_EMVREG_MASK )
bogdanm 0:9b334a45a8ff 562 EMU->CTRL = em23Init->em23Vreg ? (EMU->CTRL | EMU_CTRL_EMVREG) : (EMU->CTRL & ~EMU_CTRL_EMVREG);
bogdanm 0:9b334a45a8ff 563 #elif defined( _EMU_CTRL_EM23VREG_MASK )
bogdanm 0:9b334a45a8ff 564 EMU->CTRL = em23Init->em23Vreg ? (EMU->CTRL | EMU_CTRL_EM23VREG) : (EMU->CTRL & ~EMU_CTRL_EM23VREG);
bogdanm 0:9b334a45a8ff 565 #endif
bogdanm 0:9b334a45a8ff 566 }
bogdanm 0:9b334a45a8ff 567 #endif
bogdanm 0:9b334a45a8ff 568
bogdanm 0:9b334a45a8ff 569
bogdanm 0:9b334a45a8ff 570 #if defined( _EMU_EM4CONF_MASK )
bogdanm 0:9b334a45a8ff 571 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 572 * @brief
bogdanm 0:9b334a45a8ff 573 * Update EMU module with Energy Mode 4 configuration
bogdanm 0:9b334a45a8ff 574 *
bogdanm 0:9b334a45a8ff 575 * @param[in] em4Init
bogdanm 0:9b334a45a8ff 576 * Energy Mode 4 configuration structure
bogdanm 0:9b334a45a8ff 577 ******************************************************************************/
bogdanm 0:9b334a45a8ff 578 void EMU_EM4Init(EMU_EM4Init_TypeDef *em4Init)
bogdanm 0:9b334a45a8ff 579 {
bogdanm 0:9b334a45a8ff 580 uint32_t em4conf = EMU->EM4CONF;
bogdanm 0:9b334a45a8ff 581
bogdanm 0:9b334a45a8ff 582 /* Clear fields that will be reconfigured */
bogdanm 0:9b334a45a8ff 583 em4conf &= ~(
bogdanm 0:9b334a45a8ff 584 _EMU_EM4CONF_LOCKCONF_MASK |
bogdanm 0:9b334a45a8ff 585 _EMU_EM4CONF_OSC_MASK |
bogdanm 0:9b334a45a8ff 586 _EMU_EM4CONF_BURTCWU_MASK |
bogdanm 0:9b334a45a8ff 587 _EMU_EM4CONF_VREGEN_MASK);
bogdanm 0:9b334a45a8ff 588
bogdanm 0:9b334a45a8ff 589 /* Configure new settings */
bogdanm 0:9b334a45a8ff 590 em4conf |= (
bogdanm 0:9b334a45a8ff 591 (em4Init->lockConfig << _EMU_EM4CONF_LOCKCONF_SHIFT) |
bogdanm 0:9b334a45a8ff 592 (em4Init->osc) |
bogdanm 0:9b334a45a8ff 593 (em4Init->buRtcWakeup << _EMU_EM4CONF_BURTCWU_SHIFT) |
bogdanm 0:9b334a45a8ff 594 (em4Init->vreg << _EMU_EM4CONF_VREGEN_SHIFT));
bogdanm 0:9b334a45a8ff 595
bogdanm 0:9b334a45a8ff 596 /* Apply configuration. Note that lock can be set after this stage. */
bogdanm 0:9b334a45a8ff 597 EMU->EM4CONF = em4conf;
bogdanm 0:9b334a45a8ff 598 }
bogdanm 0:9b334a45a8ff 599 #endif
bogdanm 0:9b334a45a8ff 600
bogdanm 0:9b334a45a8ff 601
bogdanm 0:9b334a45a8ff 602 #if defined( BU_PRESENT )
bogdanm 0:9b334a45a8ff 603
bogdanm 0:9b334a45a8ff 604 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 605 * @brief
bogdanm 0:9b334a45a8ff 606 * Configure Backup Power Domain settings
bogdanm 0:9b334a45a8ff 607 *
bogdanm 0:9b334a45a8ff 608 * @param[in] bupdInit
bogdanm 0:9b334a45a8ff 609 * Backup power domain initialization structure
bogdanm 0:9b334a45a8ff 610 ******************************************************************************/
bogdanm 0:9b334a45a8ff 611 void EMU_BUPDInit(EMU_BUPDInit_TypeDef *bupdInit)
bogdanm 0:9b334a45a8ff 612 {
bogdanm 0:9b334a45a8ff 613 uint32_t reg;
bogdanm 0:9b334a45a8ff 614
bogdanm 0:9b334a45a8ff 615 /* Set power connection configuration */
bogdanm 0:9b334a45a8ff 616 reg = EMU->PWRCONF & ~(
bogdanm 0:9b334a45a8ff 617 _EMU_PWRCONF_PWRRES_MASK|
bogdanm 0:9b334a45a8ff 618 _EMU_PWRCONF_VOUTSTRONG_MASK|
bogdanm 0:9b334a45a8ff 619 _EMU_PWRCONF_VOUTMED_MASK|
bogdanm 0:9b334a45a8ff 620 _EMU_PWRCONF_VOUTWEAK_MASK);
bogdanm 0:9b334a45a8ff 621
bogdanm 0:9b334a45a8ff 622 reg |= (bupdInit->resistor|
bogdanm 0:9b334a45a8ff 623 (bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)|
bogdanm 0:9b334a45a8ff 624 (bupdInit->voutMed << _EMU_PWRCONF_VOUTMED_SHIFT)|
bogdanm 0:9b334a45a8ff 625 (bupdInit->voutWeak << _EMU_PWRCONF_VOUTWEAK_SHIFT));
bogdanm 0:9b334a45a8ff 626
bogdanm 0:9b334a45a8ff 627 EMU->PWRCONF = reg;
bogdanm 0:9b334a45a8ff 628
bogdanm 0:9b334a45a8ff 629 /* Set backup domain inactive mode configuration */
bogdanm 0:9b334a45a8ff 630 reg = EMU->BUINACT & ~(_EMU_BUINACT_PWRCON_MASK);
bogdanm 0:9b334a45a8ff 631 reg |= (bupdInit->inactivePower);
bogdanm 0:9b334a45a8ff 632 EMU->BUINACT = reg;
bogdanm 0:9b334a45a8ff 633
bogdanm 0:9b334a45a8ff 634 /* Set backup domain active mode configuration */
bogdanm 0:9b334a45a8ff 635 reg = EMU->BUACT & ~(_EMU_BUACT_PWRCON_MASK);
bogdanm 0:9b334a45a8ff 636 reg |= (bupdInit->activePower);
bogdanm 0:9b334a45a8ff 637 EMU->BUACT = reg;
bogdanm 0:9b334a45a8ff 638
bogdanm 0:9b334a45a8ff 639 /* Set power control configuration */
bogdanm 0:9b334a45a8ff 640 reg = EMU->BUCTRL & ~(
bogdanm 0:9b334a45a8ff 641 _EMU_BUCTRL_PROBE_MASK|
bogdanm 0:9b334a45a8ff 642 _EMU_BUCTRL_BODCAL_MASK|
bogdanm 0:9b334a45a8ff 643 _EMU_BUCTRL_STATEN_MASK|
bogdanm 0:9b334a45a8ff 644 _EMU_BUCTRL_EN_MASK);
bogdanm 0:9b334a45a8ff 645
bogdanm 0:9b334a45a8ff 646 /* Note use of ->enable to both enable BUPD, use BU_VIN pin input and
bogdanm 0:9b334a45a8ff 647 release reset */
bogdanm 0:9b334a45a8ff 648 reg |= (bupdInit->probe|
bogdanm 0:9b334a45a8ff 649 (bupdInit->bodCal << _EMU_BUCTRL_BODCAL_SHIFT)|
bogdanm 0:9b334a45a8ff 650 (bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)|
bogdanm 0:9b334a45a8ff 651 (bupdInit->enable << _EMU_BUCTRL_EN_SHIFT));
bogdanm 0:9b334a45a8ff 652
bogdanm 0:9b334a45a8ff 653 /* Enable configuration */
bogdanm 0:9b334a45a8ff 654 EMU->BUCTRL = reg;
bogdanm 0:9b334a45a8ff 655
bogdanm 0:9b334a45a8ff 656 /* If enable is true, enable BU_VIN input power pin, if not disable it */
bogdanm 0:9b334a45a8ff 657 EMU_BUPinEnable(bupdInit->enable);
bogdanm 0:9b334a45a8ff 658
bogdanm 0:9b334a45a8ff 659 /* If enable is true, release BU reset, if not keep reset asserted */
bogdanm 0:9b334a45a8ff 660 BITBAND_Peripheral(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);
bogdanm 0:9b334a45a8ff 661 }
bogdanm 0:9b334a45a8ff 662
bogdanm 0:9b334a45a8ff 663
bogdanm 0:9b334a45a8ff 664 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 665 * @brief
bogdanm 0:9b334a45a8ff 666 * Configure Backup Power Domain BOD Threshold value
bogdanm 0:9b334a45a8ff 667 * @note
bogdanm 0:9b334a45a8ff 668 * These values are precalibrated
bogdanm 0:9b334a45a8ff 669 * @param[in] mode Active or Inactive mode
bogdanm 0:9b334a45a8ff 670 * @param[in] value
bogdanm 0:9b334a45a8ff 671 ******************************************************************************/
bogdanm 0:9b334a45a8ff 672 void EMU_BUThresholdSet(EMU_BODMode_TypeDef mode, uint32_t value)
bogdanm 0:9b334a45a8ff 673 {
bogdanm 0:9b334a45a8ff 674 EFM_ASSERT(value<=(_EMU_BUACT_BUEXTHRES_MASK>>_EMU_BUACT_BUEXTHRES_SHIFT));
bogdanm 0:9b334a45a8ff 675
bogdanm 0:9b334a45a8ff 676 switch(mode)
bogdanm 0:9b334a45a8ff 677 {
bogdanm 0:9b334a45a8ff 678 case emuBODMode_Active:
bogdanm 0:9b334a45a8ff 679 EMU->BUACT = (EMU->BUACT & ~(_EMU_BUACT_BUEXTHRES_MASK))|(value<<_EMU_BUACT_BUEXTHRES_SHIFT);
bogdanm 0:9b334a45a8ff 680 break;
bogdanm 0:9b334a45a8ff 681 case emuBODMode_Inactive:
bogdanm 0:9b334a45a8ff 682 EMU->BUINACT = (EMU->BUINACT & ~(_EMU_BUINACT_BUENTHRES_MASK))|(value<<_EMU_BUINACT_BUENTHRES_SHIFT);
bogdanm 0:9b334a45a8ff 683 break;
bogdanm 0:9b334a45a8ff 684 }
bogdanm 0:9b334a45a8ff 685 }
bogdanm 0:9b334a45a8ff 686
bogdanm 0:9b334a45a8ff 687
bogdanm 0:9b334a45a8ff 688 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 689 * @brief
bogdanm 0:9b334a45a8ff 690 * Configure Backup Power Domain BOD Threshold Range
bogdanm 0:9b334a45a8ff 691 * @note
bogdanm 0:9b334a45a8ff 692 * These values are precalibrated
bogdanm 0:9b334a45a8ff 693 * @param[in] mode Active or Inactive mode
bogdanm 0:9b334a45a8ff 694 * @param[in] value
bogdanm 0:9b334a45a8ff 695 ******************************************************************************/
bogdanm 0:9b334a45a8ff 696 void EMU_BUThresRangeSet(EMU_BODMode_TypeDef mode, uint32_t value)
bogdanm 0:9b334a45a8ff 697 {
bogdanm 0:9b334a45a8ff 698 EFM_ASSERT(value<=(_EMU_BUACT_BUEXRANGE_MASK>>_EMU_BUACT_BUEXRANGE_SHIFT));
bogdanm 0:9b334a45a8ff 699
bogdanm 0:9b334a45a8ff 700 switch(mode)
bogdanm 0:9b334a45a8ff 701 {
bogdanm 0:9b334a45a8ff 702 case emuBODMode_Active:
bogdanm 0:9b334a45a8ff 703 EMU->BUACT = (EMU->BUACT & ~(_EMU_BUACT_BUEXRANGE_MASK))|(value<<_EMU_BUACT_BUEXRANGE_SHIFT);
bogdanm 0:9b334a45a8ff 704 break;
bogdanm 0:9b334a45a8ff 705 case emuBODMode_Inactive:
bogdanm 0:9b334a45a8ff 706 EMU->BUINACT = (EMU->BUINACT & ~(_EMU_BUINACT_BUENRANGE_MASK))|(value<<_EMU_BUINACT_BUENRANGE_SHIFT);
bogdanm 0:9b334a45a8ff 707 break;
bogdanm 0:9b334a45a8ff 708 }
bogdanm 0:9b334a45a8ff 709 }
bogdanm 0:9b334a45a8ff 710
bogdanm 0:9b334a45a8ff 711 #endif
bogdanm 0:9b334a45a8ff 712
bogdanm 0:9b334a45a8ff 713
bogdanm 0:9b334a45a8ff 714 /** @} (end addtogroup EMU) */
bogdanm 0:9b334a45a8ff 715 /** @} (end addtogroup EM_Library) */
bogdanm 0:9b334a45a8ff 716 #endif /* __EM_EMU_H */