added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
144:ef7eb2e8f9f7
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2 * @file em_emu.c
<> 144:ef7eb2e8f9f7 3 * @brief Energy Management Unit (EMU) Peripheral API
<> 144:ef7eb2e8f9f7 4 * @version 4.2.1
<> 144:ef7eb2e8f9f7 5 *******************************************************************************
<> 144:ef7eb2e8f9f7 6 * @section License
<> 144:ef7eb2e8f9f7 7 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
<> 144:ef7eb2e8f9f7 8 *******************************************************************************
<> 144:ef7eb2e8f9f7 9 *
<> 144:ef7eb2e8f9f7 10 * Permission is granted to anyone to use this software for any purpose,
<> 144:ef7eb2e8f9f7 11 * including commercial applications, and to alter it and redistribute it
<> 144:ef7eb2e8f9f7 12 * freely, subject to the following restrictions:
<> 144:ef7eb2e8f9f7 13 *
<> 144:ef7eb2e8f9f7 14 * 1. The origin of this software must not be misrepresented; you must not
<> 144:ef7eb2e8f9f7 15 * claim that you wrote the original software.
<> 144:ef7eb2e8f9f7 16 * 2. Altered source versions must be plainly marked as such, and must not be
<> 144:ef7eb2e8f9f7 17 * misrepresented as being the original software.
<> 144:ef7eb2e8f9f7 18 * 3. This notice may not be removed or altered from any source distribution.
<> 144:ef7eb2e8f9f7 19 *
<> 144:ef7eb2e8f9f7 20 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
<> 144:ef7eb2e8f9f7 21 * obligation to support this Software. Silicon Labs is providing the
<> 144:ef7eb2e8f9f7 22 * Software "AS IS", with no express or implied warranties of any kind,
<> 144:ef7eb2e8f9f7 23 * including, but not limited to, any implied warranties of merchantability
<> 144:ef7eb2e8f9f7 24 * or fitness for any particular purpose or warranties against infringement
<> 144:ef7eb2e8f9f7 25 * of any proprietary rights of a third party.
<> 144:ef7eb2e8f9f7 26 *
<> 144:ef7eb2e8f9f7 27 * Silicon Labs will not be liable for any consequential, incidental, or
<> 144:ef7eb2e8f9f7 28 * special damages, or any other relief, or for any claim by any third party,
<> 144:ef7eb2e8f9f7 29 * arising from your use of this Software.
<> 144:ef7eb2e8f9f7 30 *
<> 144:ef7eb2e8f9f7 31 ******************************************************************************/
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 #include <limits.h>
<> 144:ef7eb2e8f9f7 34
<> 144:ef7eb2e8f9f7 35 #include "em_emu.h"
<> 144:ef7eb2e8f9f7 36 #if defined( EMU_PRESENT ) && ( EMU_COUNT > 0 )
<> 144:ef7eb2e8f9f7 37
<> 144:ef7eb2e8f9f7 38 #include "em_cmu.h"
<> 144:ef7eb2e8f9f7 39 #include "em_system.h"
<> 144:ef7eb2e8f9f7 40 #include "em_assert.h"
<> 144:ef7eb2e8f9f7 41
<> 144:ef7eb2e8f9f7 42 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 43 * @addtogroup EM_Library
<> 144:ef7eb2e8f9f7 44 * @{
<> 144:ef7eb2e8f9f7 45 ******************************************************************************/
<> 144:ef7eb2e8f9f7 46
<> 144:ef7eb2e8f9f7 47 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 48 * @addtogroup EMU
<> 144:ef7eb2e8f9f7 49 * @brief Energy Management Unit (EMU) Peripheral API
<> 144:ef7eb2e8f9f7 50 * @{
<> 144:ef7eb2e8f9f7 51 ******************************************************************************/
<> 144:ef7eb2e8f9f7 52
<> 144:ef7eb2e8f9f7 53 /* Consistency check, since restoring assumes similar bitpositions in */
<> 144:ef7eb2e8f9f7 54 /* CMU OSCENCMD and STATUS regs */
<> 144:ef7eb2e8f9f7 55 #if (CMU_STATUS_AUXHFRCOENS != CMU_OSCENCMD_AUXHFRCOEN)
<> 144:ef7eb2e8f9f7 56 #error Conflict in AUXHFRCOENS and AUXHFRCOEN bitpositions
<> 144:ef7eb2e8f9f7 57 #endif
<> 144:ef7eb2e8f9f7 58 #if (CMU_STATUS_HFXOENS != CMU_OSCENCMD_HFXOEN)
<> 144:ef7eb2e8f9f7 59 #error Conflict in HFXOENS and HFXOEN bitpositions
<> 144:ef7eb2e8f9f7 60 #endif
<> 144:ef7eb2e8f9f7 61 #if (CMU_STATUS_LFRCOENS != CMU_OSCENCMD_LFRCOEN)
<> 144:ef7eb2e8f9f7 62 #error Conflict in LFRCOENS and LFRCOEN bitpositions
<> 144:ef7eb2e8f9f7 63 #endif
<> 144:ef7eb2e8f9f7 64 #if (CMU_STATUS_LFXOENS != CMU_OSCENCMD_LFXOEN)
<> 144:ef7eb2e8f9f7 65 #error Conflict in LFXOENS and LFXOEN bitpositions
<> 144:ef7eb2e8f9f7 66 #endif
<> 144:ef7eb2e8f9f7 67
<> 144:ef7eb2e8f9f7 68
<> 144:ef7eb2e8f9f7 69 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 70 /* Fix for errata EMU_E107 - non-WIC interrupt masks. */
<> 144:ef7eb2e8f9f7 71 #if defined( _EFM32_GECKO_FAMILY )
<> 144:ef7eb2e8f9f7 72 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 73 #define NON_WIC_INT_MASK_0 (~(0x0dfc0323U))
<> 144:ef7eb2e8f9f7 74 #define NON_WIC_INT_MASK_1 (~(0x0U))
<> 144:ef7eb2e8f9f7 75
<> 144:ef7eb2e8f9f7 76 #elif defined( _EFM32_TINY_FAMILY )
<> 144:ef7eb2e8f9f7 77 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 78 #define NON_WIC_INT_MASK_0 (~(0x001be323U))
<> 144:ef7eb2e8f9f7 79 #define NON_WIC_INT_MASK_1 (~(0x0U))
<> 144:ef7eb2e8f9f7 80
<> 144:ef7eb2e8f9f7 81 #elif defined( _EFM32_GIANT_FAMILY )
<> 144:ef7eb2e8f9f7 82 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 83 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
<> 144:ef7eb2e8f9f7 84 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
<> 144:ef7eb2e8f9f7 85
<> 144:ef7eb2e8f9f7 86 #elif defined( _EFM32_WONDER_FAMILY )
<> 144:ef7eb2e8f9f7 87 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 88 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
<> 144:ef7eb2e8f9f7 89 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
<> 144:ef7eb2e8f9f7 90
<> 144:ef7eb2e8f9f7 91 #else
<> 144:ef7eb2e8f9f7 92 /* Zero Gecko and future families are not affected by errata EMU_E107 */
<> 144:ef7eb2e8f9f7 93 #endif
<> 144:ef7eb2e8f9f7 94
<> 144:ef7eb2e8f9f7 95 /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */
<> 144:ef7eb2e8f9f7 96 #if defined( _EFM32_HAPPY_FAMILY )
<> 144:ef7eb2e8f9f7 97 #define ERRATA_FIX_EMU_E108_EN
<> 144:ef7eb2e8f9f7 98 #endif
<> 144:ef7eb2e8f9f7 99 /** @endcond */
<> 144:ef7eb2e8f9f7 100
<> 144:ef7eb2e8f9f7 101
<> 144:ef7eb2e8f9f7 102 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 103 /* DCDCTODVDD output range min/max */
<> 144:ef7eb2e8f9f7 104 #define PWRCFG_DCDCTODVDD_VMIN 1200
<> 144:ef7eb2e8f9f7 105 #define PWRCFG_DCDCTODVDD_VMAX 3000
<> 144:ef7eb2e8f9f7 106 typedef enum
<> 144:ef7eb2e8f9f7 107 {
<> 144:ef7eb2e8f9f7 108 errataFixDcdcHsInit,
<> 144:ef7eb2e8f9f7 109 errataFixDcdcHsTrimSet,
<> 144:ef7eb2e8f9f7 110 errataFixDcdcHsLnWaitDone
<> 144:ef7eb2e8f9f7 111 } errataFixDcdcHs_TypeDef;
<> 144:ef7eb2e8f9f7 112 errataFixDcdcHs_TypeDef errataFixDcdcHsState = errataFixDcdcHsInit;
<> 144:ef7eb2e8f9f7 113 #endif
<> 144:ef7eb2e8f9f7 114
<> 144:ef7eb2e8f9f7 115 /*******************************************************************************
<> 144:ef7eb2e8f9f7 116 ************************** LOCAL VARIABLES ********************************
<> 144:ef7eb2e8f9f7 117 ******************************************************************************/
<> 144:ef7eb2e8f9f7 118
<> 144:ef7eb2e8f9f7 119 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 120 /**
<> 144:ef7eb2e8f9f7 121 * CMU configured oscillator selection and oscillator enable status. When a
<> 144:ef7eb2e8f9f7 122 * user configures oscillators, this varaiable shall shadow the configuration.
<> 144:ef7eb2e8f9f7 123 * It is used by the EMU module in order to be able to restore the oscillator
<> 144:ef7eb2e8f9f7 124 * config after having been in certain energy modes (since HW may automatically
<> 144:ef7eb2e8f9f7 125 * alter config when going into an energy mode). It is the responsibility of
<> 144:ef7eb2e8f9f7 126 * the CMU module to keep it up-to-date (or a user if not using the CMU API
<> 144:ef7eb2e8f9f7 127 * for oscillator control).
<> 144:ef7eb2e8f9f7 128 */
<> 144:ef7eb2e8f9f7 129 static uint32_t cmuStatus;
<> 144:ef7eb2e8f9f7 130 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 131 static uint16_t cmuHfclkStatus;
<> 144:ef7eb2e8f9f7 132 #endif
<> 144:ef7eb2e8f9f7 133 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 134 static uint16_t dcdcMaxCurrent_mA;
<> 144:ef7eb2e8f9f7 135 static uint16_t dcdcOutput_mVout;
<> 144:ef7eb2e8f9f7 136 #endif
<> 144:ef7eb2e8f9f7 137
<> 144:ef7eb2e8f9f7 138 /** @endcond */
<> 144:ef7eb2e8f9f7 139
<> 144:ef7eb2e8f9f7 140
<> 144:ef7eb2e8f9f7 141 /*******************************************************************************
<> 144:ef7eb2e8f9f7 142 ************************** LOCAL FUNCTIONS ********************************
<> 144:ef7eb2e8f9f7 143 ******************************************************************************/
<> 144:ef7eb2e8f9f7 144
<> 144:ef7eb2e8f9f7 145 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 146
<> 144:ef7eb2e8f9f7 147 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 148 * @brief
<> 144:ef7eb2e8f9f7 149 * Restore oscillators and core clock after having been in EM2 or EM3.
<> 144:ef7eb2e8f9f7 150 ******************************************************************************/
<> 144:ef7eb2e8f9f7 151 static void emuRestore(void)
<> 144:ef7eb2e8f9f7 152 {
<> 144:ef7eb2e8f9f7 153 uint32_t oscEnCmd;
<> 144:ef7eb2e8f9f7 154 uint32_t cmuLocked;
<> 144:ef7eb2e8f9f7 155
<> 144:ef7eb2e8f9f7 156 /* Although we could use the CMU API for most of the below handling, we */
<> 144:ef7eb2e8f9f7 157 /* would like this function to be as efficient as possible. */
<> 144:ef7eb2e8f9f7 158
<> 144:ef7eb2e8f9f7 159 /* CMU registers may be locked */
<> 144:ef7eb2e8f9f7 160 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
<> 144:ef7eb2e8f9f7 161 CMU_Unlock();
<> 144:ef7eb2e8f9f7 162
<> 144:ef7eb2e8f9f7 163 /* AUXHFRCO are automatically disabled (except if using debugger). */
<> 144:ef7eb2e8f9f7 164 /* HFRCO, USHFRCO and HFXO are automatically disabled. */
<> 144:ef7eb2e8f9f7 165 /* LFRCO/LFXO may be disabled by SW in EM3. */
<> 144:ef7eb2e8f9f7 166 /* Restore according to status prior to entering energy mode. */
<> 144:ef7eb2e8f9f7 167 oscEnCmd = 0;
<> 144:ef7eb2e8f9f7 168 oscEnCmd |= ((cmuStatus & CMU_STATUS_HFRCOENS) ? CMU_OSCENCMD_HFRCOEN : 0);
<> 144:ef7eb2e8f9f7 169 oscEnCmd |= ((cmuStatus & CMU_STATUS_AUXHFRCOENS) ? CMU_OSCENCMD_AUXHFRCOEN : 0);
<> 144:ef7eb2e8f9f7 170 oscEnCmd |= ((cmuStatus & CMU_STATUS_LFRCOENS) ? CMU_OSCENCMD_LFRCOEN : 0);
<> 144:ef7eb2e8f9f7 171 oscEnCmd |= ((cmuStatus & CMU_STATUS_HFXOENS) ? CMU_OSCENCMD_HFXOEN : 0);
<> 144:ef7eb2e8f9f7 172 oscEnCmd |= ((cmuStatus & CMU_STATUS_LFXOENS) ? CMU_OSCENCMD_LFXOEN : 0);
<> 144:ef7eb2e8f9f7 173 #if defined( _CMU_STATUS_USHFRCOENS_MASK )
<> 144:ef7eb2e8f9f7 174 oscEnCmd |= ((cmuStatus & CMU_STATUS_USHFRCOENS) ? CMU_OSCENCMD_USHFRCOEN : 0);
<> 144:ef7eb2e8f9f7 175 #endif
<> 144:ef7eb2e8f9f7 176 CMU->OSCENCMD = oscEnCmd;
<> 144:ef7eb2e8f9f7 177
<> 144:ef7eb2e8f9f7 178
<> 144:ef7eb2e8f9f7 179 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 180 /* Restore oscillator used for clocking core */
<> 144:ef7eb2e8f9f7 181 switch (cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)
<> 144:ef7eb2e8f9f7 182 {
<> 144:ef7eb2e8f9f7 183 case CMU_HFCLKSTATUS_SELECTED_LFRCO:
<> 144:ef7eb2e8f9f7 184 /* HFRCO could only be selected if the autostart HFXO feature is not
<> 144:ef7eb2e8f9f7 185 * enabled, otherwise the HFXO would be started and selected automatically.
<> 144:ef7eb2e8f9f7 186 * Note: this error hook helps catching erroneous oscillator configurations,
<> 144:ef7eb2e8f9f7 187 * when the AUTOSTARTSELEM0EM1 is set in CMU_HFXOCTRL. */
<> 144:ef7eb2e8f9f7 188 if (!(CMU->HFXOCTRL & CMU_HFXOCTRL_AUTOSTARTSELEM0EM1))
<> 144:ef7eb2e8f9f7 189 {
<> 144:ef7eb2e8f9f7 190 /* Wait for LFRCO to stabilize */
<> 144:ef7eb2e8f9f7 191 while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
<> 144:ef7eb2e8f9f7 192 ;
<> 144:ef7eb2e8f9f7 193 CMU->HFCLKSEL = CMU_HFCLKSEL_HF_LFRCO;
<> 144:ef7eb2e8f9f7 194 }
<> 144:ef7eb2e8f9f7 195 else
<> 144:ef7eb2e8f9f7 196 {
<> 144:ef7eb2e8f9f7 197 EFM_ASSERT(0);
<> 144:ef7eb2e8f9f7 198 }
<> 144:ef7eb2e8f9f7 199 break;
<> 144:ef7eb2e8f9f7 200
<> 144:ef7eb2e8f9f7 201 case CMU_HFCLKSTATUS_SELECTED_LFXO:
<> 144:ef7eb2e8f9f7 202 /* Wait for LFXO to stabilize */
<> 144:ef7eb2e8f9f7 203 while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
<> 144:ef7eb2e8f9f7 204 ;
<> 144:ef7eb2e8f9f7 205 CMU->HFCLKSEL = CMU_HFCLKSEL_HF_LFXO;
<> 144:ef7eb2e8f9f7 206 break;
<> 144:ef7eb2e8f9f7 207
<> 144:ef7eb2e8f9f7 208 case CMU_HFCLKSTATUS_SELECTED_HFXO:
<> 144:ef7eb2e8f9f7 209 /* Wait for HFXO to stabilize */
<> 144:ef7eb2e8f9f7 210 while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
<> 144:ef7eb2e8f9f7 211 ;
<> 144:ef7eb2e8f9f7 212 CMU->HFCLKSEL = CMU_HFCLKSEL_HF_HFXO;
<> 144:ef7eb2e8f9f7 213 break;
<> 144:ef7eb2e8f9f7 214
<> 144:ef7eb2e8f9f7 215 default: /* CMU_HFCLKSTATUS_SELECTED_HFRCO */
<> 144:ef7eb2e8f9f7 216 /* If core clock was HFRCO core clock, it is automatically restored to */
<> 144:ef7eb2e8f9f7 217 /* state prior to entering energy mode. No need for further action. */
<> 144:ef7eb2e8f9f7 218 break;
<> 144:ef7eb2e8f9f7 219 }
<> 144:ef7eb2e8f9f7 220 #else
<> 144:ef7eb2e8f9f7 221 switch (cmuStatus & (CMU_STATUS_HFRCOSEL
<> 144:ef7eb2e8f9f7 222 | CMU_STATUS_HFXOSEL
<> 144:ef7eb2e8f9f7 223 | CMU_STATUS_LFRCOSEL
<> 144:ef7eb2e8f9f7 224 #if defined( CMU_STATUS_USHFRCODIV2SEL )
<> 144:ef7eb2e8f9f7 225 | CMU_STATUS_USHFRCODIV2SEL
<> 144:ef7eb2e8f9f7 226 #endif
<> 144:ef7eb2e8f9f7 227 | CMU_STATUS_LFXOSEL))
<> 144:ef7eb2e8f9f7 228 {
<> 144:ef7eb2e8f9f7 229 case CMU_STATUS_LFRCOSEL:
<> 144:ef7eb2e8f9f7 230 /* Wait for LFRCO to stabilize */
<> 144:ef7eb2e8f9f7 231 while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
<> 144:ef7eb2e8f9f7 232 ;
<> 144:ef7eb2e8f9f7 233 CMU->CMD = CMU_CMD_HFCLKSEL_LFRCO;
<> 144:ef7eb2e8f9f7 234 break;
<> 144:ef7eb2e8f9f7 235
<> 144:ef7eb2e8f9f7 236 case CMU_STATUS_LFXOSEL:
<> 144:ef7eb2e8f9f7 237 /* Wait for LFXO to stabilize */
<> 144:ef7eb2e8f9f7 238 while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
<> 144:ef7eb2e8f9f7 239 ;
<> 144:ef7eb2e8f9f7 240 CMU->CMD = CMU_CMD_HFCLKSEL_LFXO;
<> 144:ef7eb2e8f9f7 241 break;
<> 144:ef7eb2e8f9f7 242
<> 144:ef7eb2e8f9f7 243 case CMU_STATUS_HFXOSEL:
<> 144:ef7eb2e8f9f7 244 /* Wait for HFXO to stabilize */
<> 144:ef7eb2e8f9f7 245 while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
<> 144:ef7eb2e8f9f7 246 ;
<> 144:ef7eb2e8f9f7 247 CMU->CMD = CMU_CMD_HFCLKSEL_HFXO;
<> 144:ef7eb2e8f9f7 248 break;
<> 144:ef7eb2e8f9f7 249
<> 144:ef7eb2e8f9f7 250 #if defined( CMU_STATUS_USHFRCODIV2SEL )
<> 144:ef7eb2e8f9f7 251 case CMU_STATUS_USHFRCODIV2SEL:
<> 144:ef7eb2e8f9f7 252 /* Wait for USHFRCO to stabilize */
<> 144:ef7eb2e8f9f7 253 while (!(CMU->STATUS & CMU_STATUS_USHFRCORDY))
<> 144:ef7eb2e8f9f7 254 ;
<> 144:ef7eb2e8f9f7 255 CMU->CMD = _CMU_CMD_HFCLKSEL_USHFRCODIV2;
<> 144:ef7eb2e8f9f7 256 break;
<> 144:ef7eb2e8f9f7 257 #endif
<> 144:ef7eb2e8f9f7 258
<> 144:ef7eb2e8f9f7 259 default: /* CMU_STATUS_HFRCOSEL */
<> 144:ef7eb2e8f9f7 260 /* If core clock was HFRCO core clock, it is automatically restored to */
<> 144:ef7eb2e8f9f7 261 /* state prior to entering energy mode. No need for further action. */
<> 144:ef7eb2e8f9f7 262 break;
<> 144:ef7eb2e8f9f7 263 }
<> 144:ef7eb2e8f9f7 264
<> 144:ef7eb2e8f9f7 265 /* If HFRCO was disabled before entering Energy Mode, turn it off again */
<> 144:ef7eb2e8f9f7 266 /* as it is automatically enabled by wake up */
<> 144:ef7eb2e8f9f7 267 if ( ! (cmuStatus & CMU_STATUS_HFRCOENS) )
<> 144:ef7eb2e8f9f7 268 {
<> 144:ef7eb2e8f9f7 269 CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
<> 144:ef7eb2e8f9f7 270 }
<> 144:ef7eb2e8f9f7 271 #endif
<> 144:ef7eb2e8f9f7 272 /* Restore CMU register locking */
<> 144:ef7eb2e8f9f7 273 if (cmuLocked)
<> 144:ef7eb2e8f9f7 274 {
<> 144:ef7eb2e8f9f7 275 CMU_Lock();
<> 144:ef7eb2e8f9f7 276 }
<> 144:ef7eb2e8f9f7 277 }
<> 144:ef7eb2e8f9f7 278
<> 144:ef7eb2e8f9f7 279
<> 144:ef7eb2e8f9f7 280 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 281 /* Get enable conditions for errata EMU_E107 fix. */
<> 144:ef7eb2e8f9f7 282 static __INLINE bool getErrataFixEmuE107En(void)
<> 144:ef7eb2e8f9f7 283 {
<> 144:ef7eb2e8f9f7 284 /* SYSTEM_ChipRevisionGet could have been used here, but we would like a
<> 144:ef7eb2e8f9f7 285 * faster implementation in this case.
<> 144:ef7eb2e8f9f7 286 */
<> 144:ef7eb2e8f9f7 287 uint16_t majorMinorRev;
<> 144:ef7eb2e8f9f7 288
<> 144:ef7eb2e8f9f7 289 /* CHIP MAJOR bit [3:0] */
<> 144:ef7eb2e8f9f7 290 majorMinorRev = ((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK)
<> 144:ef7eb2e8f9f7 291 >> _ROMTABLE_PID0_REVMAJOR_SHIFT)
<> 144:ef7eb2e8f9f7 292 << 8;
<> 144:ef7eb2e8f9f7 293 /* CHIP MINOR bit [7:4] */
<> 144:ef7eb2e8f9f7 294 majorMinorRev |= ((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK)
<> 144:ef7eb2e8f9f7 295 >> _ROMTABLE_PID2_REVMINORMSB_SHIFT)
<> 144:ef7eb2e8f9f7 296 << 4;
<> 144:ef7eb2e8f9f7 297 /* CHIP MINOR bit [3:0] */
<> 144:ef7eb2e8f9f7 298 majorMinorRev |= (ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK)
<> 144:ef7eb2e8f9f7 299 >> _ROMTABLE_PID3_REVMINORLSB_SHIFT;
<> 144:ef7eb2e8f9f7 300
<> 144:ef7eb2e8f9f7 301 #if defined( _EFM32_GECKO_FAMILY )
<> 144:ef7eb2e8f9f7 302 return (majorMinorRev <= 0x0103);
<> 144:ef7eb2e8f9f7 303 #elif defined( _EFM32_TINY_FAMILY )
<> 144:ef7eb2e8f9f7 304 return (majorMinorRev <= 0x0102);
<> 144:ef7eb2e8f9f7 305 #elif defined( _EFM32_GIANT_FAMILY )
<> 144:ef7eb2e8f9f7 306 return (majorMinorRev <= 0x0103) || (majorMinorRev == 0x0204);
<> 144:ef7eb2e8f9f7 307 #elif defined( _EFM32_WONDER_FAMILY )
<> 144:ef7eb2e8f9f7 308 return (majorMinorRev == 0x0100);
<> 144:ef7eb2e8f9f7 309 #else
<> 144:ef7eb2e8f9f7 310 /* Zero Gecko and future families are not affected by errata EMU_E107 */
<> 144:ef7eb2e8f9f7 311 return false;
<> 144:ef7eb2e8f9f7 312 #endif
<> 144:ef7eb2e8f9f7 313 }
<> 144:ef7eb2e8f9f7 314 #endif
<> 144:ef7eb2e8f9f7 315
<> 144:ef7eb2e8f9f7 316
<> 144:ef7eb2e8f9f7 317 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 318 /* LP prepare / LN restore P/NFET count */
<> 144:ef7eb2e8f9f7 319 static void maxCurrentUpdate(void);
<> 144:ef7eb2e8f9f7 320 #define DCDC_LP_PFET_CNT 7
<> 144:ef7eb2e8f9f7 321 #define DCDC_LP_NFET_CNT 15
<> 144:ef7eb2e8f9f7 322 void dcdcFetCntSet(bool lpModeSet)
<> 144:ef7eb2e8f9f7 323 {
<> 144:ef7eb2e8f9f7 324 uint32_t tmp;
<> 144:ef7eb2e8f9f7 325 static uint32_t emuDcdcMiscCtrlReg;
<> 144:ef7eb2e8f9f7 326
<> 144:ef7eb2e8f9f7 327 if (lpModeSet)
<> 144:ef7eb2e8f9f7 328 {
<> 144:ef7eb2e8f9f7 329 emuDcdcMiscCtrlReg = EMU->DCDCMISCCTRL;
<> 144:ef7eb2e8f9f7 330 tmp = EMU->DCDCMISCCTRL
<> 144:ef7eb2e8f9f7 331 & ~(_EMU_DCDCMISCCTRL_PFETCNT_MASK | _EMU_DCDCMISCCTRL_NFETCNT_MASK);
<> 144:ef7eb2e8f9f7 332 tmp |= (DCDC_LP_PFET_CNT << _EMU_DCDCMISCCTRL_PFETCNT_SHIFT)
<> 144:ef7eb2e8f9f7 333 | (DCDC_LP_NFET_CNT << _EMU_DCDCMISCCTRL_NFETCNT_SHIFT);
<> 144:ef7eb2e8f9f7 334 EMU->DCDCMISCCTRL = tmp;
<> 144:ef7eb2e8f9f7 335 maxCurrentUpdate();
<> 144:ef7eb2e8f9f7 336 }
<> 144:ef7eb2e8f9f7 337 else
<> 144:ef7eb2e8f9f7 338 {
<> 144:ef7eb2e8f9f7 339 EMU->DCDCMISCCTRL = emuDcdcMiscCtrlReg;
<> 144:ef7eb2e8f9f7 340 maxCurrentUpdate();
<> 144:ef7eb2e8f9f7 341 }
<> 144:ef7eb2e8f9f7 342 }
<> 144:ef7eb2e8f9f7 343
<> 144:ef7eb2e8f9f7 344 void dcdcHsFixLnBlock(void)
<> 144:ef7eb2e8f9f7 345 {
<> 144:ef7eb2e8f9f7 346 #define EMU_DCDCSTATUS (* (volatile uint32_t *)(EMU_BASE + 0x7C))
<> 144:ef7eb2e8f9f7 347 if (errataFixDcdcHsState == errataFixDcdcHsTrimSet)
<> 144:ef7eb2e8f9f7 348 {
<> 144:ef7eb2e8f9f7 349 /* Wait for LNRUNNING */
<> 144:ef7eb2e8f9f7 350 if ((EMU->DCDCCTRL & ~_EMU_DCDCCTRL_DCDCMODE_MASK) == EMU_DCDCCTRL_DCDCMODE_LOWNOISE)
<> 144:ef7eb2e8f9f7 351 {
<> 144:ef7eb2e8f9f7 352 while (!(EMU_DCDCSTATUS & (0x1 << 16)));
<> 144:ef7eb2e8f9f7 353 }
<> 144:ef7eb2e8f9f7 354 errataFixDcdcHsState = errataFixDcdcHsLnWaitDone;
<> 144:ef7eb2e8f9f7 355 }
<> 144:ef7eb2e8f9f7 356 }
<> 144:ef7eb2e8f9f7 357 #endif
<> 144:ef7eb2e8f9f7 358
<> 144:ef7eb2e8f9f7 359
<> 144:ef7eb2e8f9f7 360 /** @endcond */
<> 144:ef7eb2e8f9f7 361
<> 144:ef7eb2e8f9f7 362
<> 144:ef7eb2e8f9f7 363 /*******************************************************************************
<> 144:ef7eb2e8f9f7 364 ************************** GLOBAL FUNCTIONS *******************************
<> 144:ef7eb2e8f9f7 365 ******************************************************************************/
<> 144:ef7eb2e8f9f7 366
<> 144:ef7eb2e8f9f7 367 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 368 * @brief
<> 144:ef7eb2e8f9f7 369 * Enter energy mode 2 (EM2).
<> 144:ef7eb2e8f9f7 370 *
<> 144:ef7eb2e8f9f7 371 * @details
<> 144:ef7eb2e8f9f7 372 * When entering EM2, the high frequency clocks are disabled, ie HFXO, HFRCO
<> 144:ef7eb2e8f9f7 373 * and AUXHFRCO (for AUXHFRCO, see exception note below). When re-entering
<> 144:ef7eb2e8f9f7 374 * EM0, HFRCO is re-enabled and the core will be clocked by the configured
<> 144:ef7eb2e8f9f7 375 * HFRCO band. This ensures a quick wakeup from EM2.
<> 144:ef7eb2e8f9f7 376 *
<> 144:ef7eb2e8f9f7 377 * However, prior to entering EM2, the core may have been using another
<> 144:ef7eb2e8f9f7 378 * oscillator than HFRCO. The @p restore parameter gives the user the option
<> 144:ef7eb2e8f9f7 379 * to restore all HF oscillators according to state prior to entering EM2,
<> 144:ef7eb2e8f9f7 380 * as well as the clock used to clock the core. This restore procedure is
<> 144:ef7eb2e8f9f7 381 * handled by SW. However, since handled by SW, it will not be restored
<> 144:ef7eb2e8f9f7 382 * before completing the interrupt function(s) waking up the core!
<> 144:ef7eb2e8f9f7 383 *
<> 144:ef7eb2e8f9f7 384 * @note
<> 144:ef7eb2e8f9f7 385 * If restoring core clock to use the HFXO oscillator, which has been
<> 144:ef7eb2e8f9f7 386 * disabled during EM2 mode, this function will stall until the oscillator
<> 144:ef7eb2e8f9f7 387 * has stabilized. Stalling time can be reduced by adding interrupt
<> 144:ef7eb2e8f9f7 388 * support detecting stable oscillator, and an asynchronous switch to the
<> 144:ef7eb2e8f9f7 389 * original oscillator. See CMU documentation. Such a feature is however
<> 144:ef7eb2e8f9f7 390 * outside the scope of the implementation in this function.
<> 144:ef7eb2e8f9f7 391 * @par
<> 144:ef7eb2e8f9f7 392 * If HFXO is re-enabled by this function, and NOT used to clock the core,
<> 144:ef7eb2e8f9f7 393 * this function will not wait for HFXO to stabilize. This must be considered
<> 144:ef7eb2e8f9f7 394 * by the application if trying to use features relying on that oscillator
<> 144:ef7eb2e8f9f7 395 * upon return.
<> 144:ef7eb2e8f9f7 396 * @par
<> 144:ef7eb2e8f9f7 397 * If a debugger is attached, the AUXHFRCO will not be disabled if enabled
<> 144:ef7eb2e8f9f7 398 * upon entering EM2. It will thus remain enabled when returning to EM0
<> 144:ef7eb2e8f9f7 399 * regardless of the @p restore parameter.
<> 144:ef7eb2e8f9f7 400 * @par
<> 144:ef7eb2e8f9f7 401 * If HFXO autostart and select is enabled by using CMU_HFXOAutostartEnable(),
<> 144:ef7eb2e8f9f7 402 * the starting and selecting of the core clocks will be identical to the user
<> 144:ef7eb2e8f9f7 403 * independently of the value of the @p restore parameter when waking up on
<> 144:ef7eb2e8f9f7 404 * the wakeup sources corresponding to the autostart and select setting.
<> 144:ef7eb2e8f9f7 405 *
<> 144:ef7eb2e8f9f7 406 * @param[in] restore
<> 144:ef7eb2e8f9f7 407 * @li true - restore oscillators and clocks, see function details.
<> 144:ef7eb2e8f9f7 408 * @li false - do not restore oscillators and clocks, see function details.
<> 144:ef7eb2e8f9f7 409 * @par
<> 144:ef7eb2e8f9f7 410 * The @p restore option should only be used if all clock control is done
<> 144:ef7eb2e8f9f7 411 * via the CMU API.
<> 144:ef7eb2e8f9f7 412 ******************************************************************************/
<> 144:ef7eb2e8f9f7 413 void EMU_EnterEM2(bool restore)
<> 144:ef7eb2e8f9f7 414 {
<> 144:ef7eb2e8f9f7 415 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 416 bool errataFixEmuE107En;
<> 144:ef7eb2e8f9f7 417 uint32_t nonWicIntEn[2];
<> 144:ef7eb2e8f9f7 418 #endif
<> 144:ef7eb2e8f9f7 419
<> 144:ef7eb2e8f9f7 420 /* Auto-update CMU status just in case before entering energy mode. */
<> 144:ef7eb2e8f9f7 421 /* This variable is normally kept up-to-date by the CMU API. */
<> 144:ef7eb2e8f9f7 422 cmuStatus = CMU->STATUS;
<> 144:ef7eb2e8f9f7 423 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 424 cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);
<> 144:ef7eb2e8f9f7 425 #endif
<> 144:ef7eb2e8f9f7 426
<> 144:ef7eb2e8f9f7 427 /* Enter Cortex deep sleep mode */
<> 144:ef7eb2e8f9f7 428 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
<> 144:ef7eb2e8f9f7 429
<> 144:ef7eb2e8f9f7 430 /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
<> 144:ef7eb2e8f9f7 431 Disable the enabled non-WIC interrupts. */
<> 144:ef7eb2e8f9f7 432 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 433 errataFixEmuE107En = getErrataFixEmuE107En();
<> 144:ef7eb2e8f9f7 434 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 435 {
<> 144:ef7eb2e8f9f7 436 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
<> 144:ef7eb2e8f9f7 437 NVIC->ICER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 438 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 439 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
<> 144:ef7eb2e8f9f7 440 NVIC->ICER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 441 #endif
<> 144:ef7eb2e8f9f7 442 }
<> 144:ef7eb2e8f9f7 443 #endif
<> 144:ef7eb2e8f9f7 444
<> 144:ef7eb2e8f9f7 445 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 446 dcdcFetCntSet(true);
<> 144:ef7eb2e8f9f7 447 dcdcHsFixLnBlock();
<> 144:ef7eb2e8f9f7 448 #endif
<> 144:ef7eb2e8f9f7 449
<> 144:ef7eb2e8f9f7 450 __WFI();
<> 144:ef7eb2e8f9f7 451
<> 144:ef7eb2e8f9f7 452 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 453 dcdcFetCntSet(false);
<> 144:ef7eb2e8f9f7 454 #endif
<> 144:ef7eb2e8f9f7 455
<> 144:ef7eb2e8f9f7 456 /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
<> 144:ef7eb2e8f9f7 457 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 458 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 459 {
<> 144:ef7eb2e8f9f7 460 NVIC->ISER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 461 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 462 NVIC->ISER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 463 #endif
<> 144:ef7eb2e8f9f7 464 }
<> 144:ef7eb2e8f9f7 465 #endif
<> 144:ef7eb2e8f9f7 466
<> 144:ef7eb2e8f9f7 467 /* Restore oscillators/clocks if specified */
<> 144:ef7eb2e8f9f7 468 if (restore)
<> 144:ef7eb2e8f9f7 469 {
<> 144:ef7eb2e8f9f7 470 emuRestore();
<> 144:ef7eb2e8f9f7 471 }
<> 144:ef7eb2e8f9f7 472 /* If not restoring, and original clock was not HFRCO, we have to */
<> 144:ef7eb2e8f9f7 473 /* update CMSIS core clock variable since core clock has changed */
<> 144:ef7eb2e8f9f7 474 /* to using HFRCO. */
<> 144:ef7eb2e8f9f7 475 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 476 else if ((cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)
<> 144:ef7eb2e8f9f7 477 != CMU_HFCLKSTATUS_SELECTED_HFRCO)
<> 144:ef7eb2e8f9f7 478 #else
<> 144:ef7eb2e8f9f7 479 else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
<> 144:ef7eb2e8f9f7 480 #endif
<> 144:ef7eb2e8f9f7 481 {
<> 144:ef7eb2e8f9f7 482 SystemCoreClockUpdate();
<> 144:ef7eb2e8f9f7 483 }
<> 144:ef7eb2e8f9f7 484 }
<> 144:ef7eb2e8f9f7 485
<> 144:ef7eb2e8f9f7 486
<> 144:ef7eb2e8f9f7 487 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 488 * @brief
<> 144:ef7eb2e8f9f7 489 * Enter energy mode 3 (EM3).
<> 144:ef7eb2e8f9f7 490 *
<> 144:ef7eb2e8f9f7 491 * @details
<> 144:ef7eb2e8f9f7 492 * When entering EM3, the high frequency clocks are disabled by HW, ie HFXO,
<> 144:ef7eb2e8f9f7 493 * HFRCO and AUXHFRCO (for AUXHFRCO, see exception note below). In addition,
<> 144:ef7eb2e8f9f7 494 * the low frequency clocks, ie LFXO and LFRCO are disabled by SW. When
<> 144:ef7eb2e8f9f7 495 * re-entering EM0, HFRCO is re-enabled and the core will be clocked by the
<> 144:ef7eb2e8f9f7 496 * configured HFRCO band. This ensures a quick wakeup from EM3.
<> 144:ef7eb2e8f9f7 497 *
<> 144:ef7eb2e8f9f7 498 * However, prior to entering EM3, the core may have been using another
<> 144:ef7eb2e8f9f7 499 * oscillator than HFRCO. The @p restore parameter gives the user the option
<> 144:ef7eb2e8f9f7 500 * to restore all HF/LF oscillators according to state prior to entering EM3,
<> 144:ef7eb2e8f9f7 501 * as well as the clock used to clock the core. This restore procedure is
<> 144:ef7eb2e8f9f7 502 * handled by SW. However, since handled by SW, it will not be restored
<> 144:ef7eb2e8f9f7 503 * before completing the interrupt function(s) waking up the core!
<> 144:ef7eb2e8f9f7 504 *
<> 144:ef7eb2e8f9f7 505 * @note
<> 144:ef7eb2e8f9f7 506 * If restoring core clock to use an oscillator other than HFRCO, this
<> 144:ef7eb2e8f9f7 507 * function will stall until the oscillator has stabilized. Stalling time
<> 144:ef7eb2e8f9f7 508 * can be reduced by adding interrupt support detecting stable oscillator,
<> 144:ef7eb2e8f9f7 509 * and an asynchronous switch to the original oscillator. See CMU
<> 144:ef7eb2e8f9f7 510 * documentation. Such a feature is however outside the scope of the
<> 144:ef7eb2e8f9f7 511 * implementation in this function.
<> 144:ef7eb2e8f9f7 512 * @par
<> 144:ef7eb2e8f9f7 513 * If HFXO/LFXO/LFRCO are re-enabled by this function, and NOT used to clock
<> 144:ef7eb2e8f9f7 514 * the core, this function will not wait for those oscillators to stabilize.
<> 144:ef7eb2e8f9f7 515 * This must be considered by the application if trying to use features
<> 144:ef7eb2e8f9f7 516 * relying on those oscillators upon return.
<> 144:ef7eb2e8f9f7 517 * @par
<> 144:ef7eb2e8f9f7 518 * If a debugger is attached, the AUXHFRCO will not be disabled if enabled
<> 144:ef7eb2e8f9f7 519 * upon entering EM3. It will thus remain enabled when returning to EM0
<> 144:ef7eb2e8f9f7 520 * regardless of the @p restore parameter.
<> 144:ef7eb2e8f9f7 521 *
<> 144:ef7eb2e8f9f7 522 * @param[in] restore
<> 144:ef7eb2e8f9f7 523 * @li true - restore oscillators and clocks, see function details.
<> 144:ef7eb2e8f9f7 524 * @li false - do not restore oscillators and clocks, see function details.
<> 144:ef7eb2e8f9f7 525 * @par
<> 144:ef7eb2e8f9f7 526 * The @p restore option should only be used if all clock control is done
<> 144:ef7eb2e8f9f7 527 * via the CMU API.
<> 144:ef7eb2e8f9f7 528 ******************************************************************************/
<> 144:ef7eb2e8f9f7 529 void EMU_EnterEM3(bool restore)
<> 144:ef7eb2e8f9f7 530 {
<> 144:ef7eb2e8f9f7 531 uint32_t cmuLocked;
<> 144:ef7eb2e8f9f7 532
<> 144:ef7eb2e8f9f7 533 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 534 bool errataFixEmuE107En;
<> 144:ef7eb2e8f9f7 535 uint32_t nonWicIntEn[2];
<> 144:ef7eb2e8f9f7 536 #endif
<> 144:ef7eb2e8f9f7 537
<> 144:ef7eb2e8f9f7 538 /* Auto-update CMU status just in case before entering energy mode. */
<> 144:ef7eb2e8f9f7 539 /* This variable is normally kept up-to-date by the CMU API. */
<> 144:ef7eb2e8f9f7 540 cmuStatus = CMU->STATUS;
<> 144:ef7eb2e8f9f7 541 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 542 cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);
<> 144:ef7eb2e8f9f7 543 #endif
<> 144:ef7eb2e8f9f7 544
<> 144:ef7eb2e8f9f7 545 /* CMU registers may be locked */
<> 144:ef7eb2e8f9f7 546 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
<> 144:ef7eb2e8f9f7 547 CMU_Unlock();
<> 144:ef7eb2e8f9f7 548
<> 144:ef7eb2e8f9f7 549 /* Disable LF oscillators */
<> 144:ef7eb2e8f9f7 550 CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS | CMU_OSCENCMD_LFRCODIS;
<> 144:ef7eb2e8f9f7 551
<> 144:ef7eb2e8f9f7 552 /* Restore CMU register locking */
<> 144:ef7eb2e8f9f7 553 if (cmuLocked)
<> 144:ef7eb2e8f9f7 554 {
<> 144:ef7eb2e8f9f7 555 CMU_Lock();
<> 144:ef7eb2e8f9f7 556 }
<> 144:ef7eb2e8f9f7 557
<> 144:ef7eb2e8f9f7 558 /* Enter Cortex deep sleep mode */
<> 144:ef7eb2e8f9f7 559 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
<> 144:ef7eb2e8f9f7 560
<> 144:ef7eb2e8f9f7 561 /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
<> 144:ef7eb2e8f9f7 562 Disable the enabled non-WIC interrupts. */
<> 144:ef7eb2e8f9f7 563 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 564 errataFixEmuE107En = getErrataFixEmuE107En();
<> 144:ef7eb2e8f9f7 565 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 566 {
<> 144:ef7eb2e8f9f7 567 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
<> 144:ef7eb2e8f9f7 568 NVIC->ICER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 569 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 570 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
<> 144:ef7eb2e8f9f7 571 NVIC->ICER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 572 #endif
<> 144:ef7eb2e8f9f7 573
<> 144:ef7eb2e8f9f7 574 }
<> 144:ef7eb2e8f9f7 575 #endif
<> 144:ef7eb2e8f9f7 576
<> 144:ef7eb2e8f9f7 577 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 578 dcdcFetCntSet(true);
<> 144:ef7eb2e8f9f7 579 dcdcHsFixLnBlock();
<> 144:ef7eb2e8f9f7 580 #endif
<> 144:ef7eb2e8f9f7 581
<> 144:ef7eb2e8f9f7 582 __WFI();
<> 144:ef7eb2e8f9f7 583
<> 144:ef7eb2e8f9f7 584 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 585 dcdcFetCntSet(false);
<> 144:ef7eb2e8f9f7 586 #endif
<> 144:ef7eb2e8f9f7 587
<> 144:ef7eb2e8f9f7 588 /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
<> 144:ef7eb2e8f9f7 589 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 590 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 591 {
<> 144:ef7eb2e8f9f7 592 NVIC->ISER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 593 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 594 NVIC->ISER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 595 #endif
<> 144:ef7eb2e8f9f7 596 }
<> 144:ef7eb2e8f9f7 597 #endif
<> 144:ef7eb2e8f9f7 598
<> 144:ef7eb2e8f9f7 599 /* Restore oscillators/clocks if specified */
<> 144:ef7eb2e8f9f7 600 if (restore)
<> 144:ef7eb2e8f9f7 601 {
<> 144:ef7eb2e8f9f7 602 emuRestore();
<> 144:ef7eb2e8f9f7 603 }
<> 144:ef7eb2e8f9f7 604 /* If not restoring, and original clock was not HFRCO, we have to */
<> 144:ef7eb2e8f9f7 605 /* update CMSIS core clock variable since core clock has changed */
<> 144:ef7eb2e8f9f7 606 /* to using HFRCO. */
<> 144:ef7eb2e8f9f7 607 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 608 else if ((cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)
<> 144:ef7eb2e8f9f7 609 != CMU_HFCLKSTATUS_SELECTED_HFRCO)
<> 144:ef7eb2e8f9f7 610 #else
<> 144:ef7eb2e8f9f7 611 else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
<> 144:ef7eb2e8f9f7 612 #endif
<> 144:ef7eb2e8f9f7 613 {
<> 144:ef7eb2e8f9f7 614 SystemCoreClockUpdate();
<> 144:ef7eb2e8f9f7 615 }
<> 144:ef7eb2e8f9f7 616 }
<> 144:ef7eb2e8f9f7 617
<> 144:ef7eb2e8f9f7 618
<> 144:ef7eb2e8f9f7 619 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 620 * @brief
<> 144:ef7eb2e8f9f7 621 * Enter energy mode 4 (EM4).
<> 144:ef7eb2e8f9f7 622 *
<> 144:ef7eb2e8f9f7 623 * @note
<> 144:ef7eb2e8f9f7 624 * Only a power on reset or external reset pin can wake the device from EM4.
<> 144:ef7eb2e8f9f7 625 ******************************************************************************/
<> 144:ef7eb2e8f9f7 626 void EMU_EnterEM4(void)
<> 144:ef7eb2e8f9f7 627 {
<> 144:ef7eb2e8f9f7 628 int i;
<> 144:ef7eb2e8f9f7 629
<> 144:ef7eb2e8f9f7 630 #if defined( _EMU_EM4CTRL_EM4ENTRY_SHIFT )
<> 144:ef7eb2e8f9f7 631 uint32_t em4seq2 = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4ENTRY_MASK)
<> 144:ef7eb2e8f9f7 632 | (2 << _EMU_EM4CTRL_EM4ENTRY_SHIFT);
<> 144:ef7eb2e8f9f7 633 uint32_t em4seq3 = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4ENTRY_MASK)
<> 144:ef7eb2e8f9f7 634 | (3 << _EMU_EM4CTRL_EM4ENTRY_SHIFT);
<> 144:ef7eb2e8f9f7 635 #else
<> 144:ef7eb2e8f9f7 636 uint32_t em4seq2 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK)
<> 144:ef7eb2e8f9f7 637 | (2 << _EMU_CTRL_EM4CTRL_SHIFT);
<> 144:ef7eb2e8f9f7 638 uint32_t em4seq3 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK)
<> 144:ef7eb2e8f9f7 639 | (3 << _EMU_CTRL_EM4CTRL_SHIFT);
<> 144:ef7eb2e8f9f7 640 #endif
<> 144:ef7eb2e8f9f7 641
<> 144:ef7eb2e8f9f7 642 /* Make sure register write lock is disabled */
<> 144:ef7eb2e8f9f7 643 EMU_Unlock();
<> 144:ef7eb2e8f9f7 644
<> 144:ef7eb2e8f9f7 645 #if defined( ERRATA_FIX_EMU_E108_EN )
<> 144:ef7eb2e8f9f7 646 /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */
<> 144:ef7eb2e8f9f7 647 __disable_irq();
<> 144:ef7eb2e8f9f7 648 *(volatile uint32_t *)0x400C80E4 = 0;
<> 144:ef7eb2e8f9f7 649 #endif
<> 144:ef7eb2e8f9f7 650
<> 144:ef7eb2e8f9f7 651 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 652 dcdcFetCntSet(true);
<> 144:ef7eb2e8f9f7 653 dcdcHsFixLnBlock();
<> 144:ef7eb2e8f9f7 654 #endif
<> 144:ef7eb2e8f9f7 655
<> 144:ef7eb2e8f9f7 656 for (i = 0; i < 4; i++)
<> 144:ef7eb2e8f9f7 657 {
<> 144:ef7eb2e8f9f7 658 #if defined( _EMU_EM4CTRL_EM4ENTRY_SHIFT )
<> 144:ef7eb2e8f9f7 659 EMU->EM4CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 660 EMU->EM4CTRL = em4seq3;
<> 144:ef7eb2e8f9f7 661 }
<> 144:ef7eb2e8f9f7 662 EMU->EM4CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 663 #else
<> 144:ef7eb2e8f9f7 664 EMU->CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 665 EMU->CTRL = em4seq3;
<> 144:ef7eb2e8f9f7 666 }
<> 144:ef7eb2e8f9f7 667 EMU->CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 668 #endif
<> 144:ef7eb2e8f9f7 669 }
<> 144:ef7eb2e8f9f7 670
<> 144:ef7eb2e8f9f7 671
<> 144:ef7eb2e8f9f7 672 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 673 * @brief
<> 144:ef7eb2e8f9f7 674 * Power down memory block.
<> 144:ef7eb2e8f9f7 675 *
<> 144:ef7eb2e8f9f7 676 * @param[in] blocks
<> 144:ef7eb2e8f9f7 677 * Specifies a logical OR of bits indicating memory blocks to power down.
<> 144:ef7eb2e8f9f7 678 * Bit 0 selects block 1, bit 1 selects block 2, etc. Memory block 0 cannot
<> 144:ef7eb2e8f9f7 679 * be disabled. Please refer to the reference manual for available
<> 144:ef7eb2e8f9f7 680 * memory blocks for a device.
<> 144:ef7eb2e8f9f7 681 *
<> 144:ef7eb2e8f9f7 682 * @note
<> 144:ef7eb2e8f9f7 683 * Only a reset can make the specified memory block(s) available for use
<> 144:ef7eb2e8f9f7 684 * after having been powered down. Function will be void for devices not
<> 144:ef7eb2e8f9f7 685 * supporting this feature.
<> 144:ef7eb2e8f9f7 686 ******************************************************************************/
<> 144:ef7eb2e8f9f7 687 void EMU_MemPwrDown(uint32_t blocks)
<> 144:ef7eb2e8f9f7 688 {
<> 144:ef7eb2e8f9f7 689 #if defined( _EMU_MEMCTRL_POWERDOWN_MASK )
<> 144:ef7eb2e8f9f7 690 EFM_ASSERT(blocks <= (_EMU_MEMCTRL_POWERDOWN_MASK
<> 144:ef7eb2e8f9f7 691 >> _EMU_MEMCTRL_POWERDOWN_SHIFT));
<> 144:ef7eb2e8f9f7 692 EMU->MEMCTRL = blocks;
<> 144:ef7eb2e8f9f7 693
<> 144:ef7eb2e8f9f7 694 #elif defined( _EMU_MEMCTRL_RAMPOWERDOWN_MASK ) \
<> 144:ef7eb2e8f9f7 695 && defined( _EMU_MEMCTRL_RAMHPOWERDOWN_MASK ) \
<> 144:ef7eb2e8f9f7 696 && defined( _EMU_MEMCTRL_SEQRAMPOWERDOWN_MASK )
<> 144:ef7eb2e8f9f7 697 EFM_ASSERT((blocks & (_EMU_MEMCTRL_RAMPOWERDOWN_MASK
<> 144:ef7eb2e8f9f7 698 | _EMU_MEMCTRL_RAMHPOWERDOWN_MASK
<> 144:ef7eb2e8f9f7 699 | _EMU_MEMCTRL_SEQRAMPOWERDOWN_MASK))
<> 144:ef7eb2e8f9f7 700 == blocks);
<> 144:ef7eb2e8f9f7 701 EMU->MEMCTRL = blocks;
<> 144:ef7eb2e8f9f7 702
<> 144:ef7eb2e8f9f7 703 #elif defined( _EMU_MEMCTRL_RAMPOWERDOWN_MASK )
<> 144:ef7eb2e8f9f7 704 EFM_ASSERT((blocks & _EMU_MEMCTRL_RAMPOWERDOWN_MASK) == blocks);
<> 144:ef7eb2e8f9f7 705 EMU->MEMCTRL = blocks;
<> 144:ef7eb2e8f9f7 706
<> 144:ef7eb2e8f9f7 707 #elif defined( _EMU_RAM0CTRL_RAMPOWERDOWN_MASK )
<> 144:ef7eb2e8f9f7 708 EFM_ASSERT((blocks & _EMU_RAM0CTRL_RAMPOWERDOWN_MASK) == blocks);
<> 144:ef7eb2e8f9f7 709 EMU->RAM0CTRL = blocks;
<> 144:ef7eb2e8f9f7 710
<> 144:ef7eb2e8f9f7 711 #else
<> 144:ef7eb2e8f9f7 712 (void)blocks;
<> 144:ef7eb2e8f9f7 713 #endif
<> 144:ef7eb2e8f9f7 714 }
<> 144:ef7eb2e8f9f7 715
<> 144:ef7eb2e8f9f7 716
<> 144:ef7eb2e8f9f7 717 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 718 * @brief
<> 144:ef7eb2e8f9f7 719 * Update EMU module with CMU oscillator selection/enable status.
<> 144:ef7eb2e8f9f7 720 *
<> 144:ef7eb2e8f9f7 721 * @details
<> 144:ef7eb2e8f9f7 722 * When entering EM2 and EM3, the HW may change the core clock oscillator
<> 144:ef7eb2e8f9f7 723 * used, as well as disabling some oscillators. The user may optionally select
<> 144:ef7eb2e8f9f7 724 * to restore the oscillators after waking up from EM2 and EM3 through the
<> 144:ef7eb2e8f9f7 725 * SW API.
<> 144:ef7eb2e8f9f7 726 *
<> 144:ef7eb2e8f9f7 727 * However, in order to support this in a safe way, the EMU module must
<> 144:ef7eb2e8f9f7 728 * be kept up-to-date on the actual selected configuration. The CMU
<> 144:ef7eb2e8f9f7 729 * module must keep the EMU module up-to-date.
<> 144:ef7eb2e8f9f7 730 *
<> 144:ef7eb2e8f9f7 731 * This function is mainly intended for internal use by the CMU module,
<> 144:ef7eb2e8f9f7 732 * but if the applications changes oscillator configurations without
<> 144:ef7eb2e8f9f7 733 * using the CMU API, this function can be used to keep the EMU module
<> 144:ef7eb2e8f9f7 734 * up-to-date.
<> 144:ef7eb2e8f9f7 735 ******************************************************************************/
<> 144:ef7eb2e8f9f7 736 void EMU_UpdateOscConfig(void)
<> 144:ef7eb2e8f9f7 737 {
<> 144:ef7eb2e8f9f7 738 /* Fetch current configuration */
<> 144:ef7eb2e8f9f7 739 cmuStatus = CMU->STATUS;
<> 144:ef7eb2e8f9f7 740 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 741 cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);
<> 144:ef7eb2e8f9f7 742 #endif
<> 144:ef7eb2e8f9f7 743 }
<> 144:ef7eb2e8f9f7 744
<> 144:ef7eb2e8f9f7 745
<> 144:ef7eb2e8f9f7 746 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 747 * @brief
<> 144:ef7eb2e8f9f7 748 * Update EMU module with Energy Mode 2 and 3 configuration
<> 144:ef7eb2e8f9f7 749 *
<> 144:ef7eb2e8f9f7 750 * @param[in] em23Init
<> 144:ef7eb2e8f9f7 751 * Energy Mode 2 and 3 configuration structure
<> 144:ef7eb2e8f9f7 752 ******************************************************************************/
<> 144:ef7eb2e8f9f7 753 void EMU_EM23Init(EMU_EM23Init_TypeDef *em23Init)
<> 144:ef7eb2e8f9f7 754 {
<> 144:ef7eb2e8f9f7 755 #if defined( _EMU_CTRL_EMVREG_MASK )
<> 144:ef7eb2e8f9f7 756 EMU->CTRL = em23Init->em23VregFullEn ? (EMU->CTRL | EMU_CTRL_EMVREG)
<> 144:ef7eb2e8f9f7 757 : (EMU->CTRL & ~EMU_CTRL_EMVREG);
<> 144:ef7eb2e8f9f7 758 #elif defined( _EMU_CTRL_EM23VREG_MASK )
<> 144:ef7eb2e8f9f7 759 EMU->CTRL = em23Init->em23VregFullEn ? (EMU->CTRL | EMU_CTRL_EM23VREG)
<> 144:ef7eb2e8f9f7 760 : (EMU->CTRL & ~EMU_CTRL_EM23VREG);
<> 144:ef7eb2e8f9f7 761 #else
<> 144:ef7eb2e8f9f7 762 (void)em23Init;
<> 144:ef7eb2e8f9f7 763 #endif
<> 144:ef7eb2e8f9f7 764 }
<> 144:ef7eb2e8f9f7 765
<> 144:ef7eb2e8f9f7 766
<> 144:ef7eb2e8f9f7 767 #if defined( _EMU_EM4CONF_MASK ) || defined( _EMU_EM4CTRL_MASK )
<> 144:ef7eb2e8f9f7 768 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 769 * @brief
<> 144:ef7eb2e8f9f7 770 * Update EMU module with Energy Mode 4 configuration
<> 144:ef7eb2e8f9f7 771 *
<> 144:ef7eb2e8f9f7 772 * @param[in] em4Init
<> 144:ef7eb2e8f9f7 773 * Energy Mode 4 configuration structure
<> 144:ef7eb2e8f9f7 774 ******************************************************************************/
<> 144:ef7eb2e8f9f7 775 void EMU_EM4Init(EMU_EM4Init_TypeDef *em4Init)
<> 144:ef7eb2e8f9f7 776 {
<> 144:ef7eb2e8f9f7 777 #if defined( _EMU_EM4CONF_MASK )
<> 144:ef7eb2e8f9f7 778 /* Init for platforms with EMU->EM4CONF register */
<> 144:ef7eb2e8f9f7 779 uint32_t em4conf = EMU->EM4CONF;
<> 144:ef7eb2e8f9f7 780
<> 144:ef7eb2e8f9f7 781 /* Clear fields that will be reconfigured */
<> 144:ef7eb2e8f9f7 782 em4conf &= ~(_EMU_EM4CONF_LOCKCONF_MASK
<> 144:ef7eb2e8f9f7 783 | _EMU_EM4CONF_OSC_MASK
<> 144:ef7eb2e8f9f7 784 | _EMU_EM4CONF_BURTCWU_MASK
<> 144:ef7eb2e8f9f7 785 | _EMU_EM4CONF_VREGEN_MASK);
<> 144:ef7eb2e8f9f7 786
<> 144:ef7eb2e8f9f7 787 /* Configure new settings */
<> 144:ef7eb2e8f9f7 788 em4conf |= (em4Init->lockConfig << _EMU_EM4CONF_LOCKCONF_SHIFT)
<> 144:ef7eb2e8f9f7 789 | (em4Init->osc)
<> 144:ef7eb2e8f9f7 790 | (em4Init->buRtcWakeup << _EMU_EM4CONF_BURTCWU_SHIFT)
<> 144:ef7eb2e8f9f7 791 | (em4Init->vreg << _EMU_EM4CONF_VREGEN_SHIFT);
<> 144:ef7eb2e8f9f7 792
<> 144:ef7eb2e8f9f7 793 /* Apply configuration. Note that lock can be set after this stage. */
<> 144:ef7eb2e8f9f7 794 EMU->EM4CONF = em4conf;
<> 144:ef7eb2e8f9f7 795
<> 144:ef7eb2e8f9f7 796 #elif defined( _EMU_EM4CTRL_MASK )
<> 144:ef7eb2e8f9f7 797 /* Init for platforms with EMU->EM4CTRL register */
<> 144:ef7eb2e8f9f7 798
<> 144:ef7eb2e8f9f7 799 uint32_t em4ctrl = EMU->EM4CTRL;
<> 144:ef7eb2e8f9f7 800
<> 144:ef7eb2e8f9f7 801 em4ctrl &= ~(_EMU_EM4CTRL_RETAINLFXO_MASK
<> 144:ef7eb2e8f9f7 802 | _EMU_EM4CTRL_RETAINLFRCO_MASK
<> 144:ef7eb2e8f9f7 803 | _EMU_EM4CTRL_RETAINULFRCO_MASK
<> 144:ef7eb2e8f9f7 804 | _EMU_EM4CTRL_EM4STATE_MASK
<> 144:ef7eb2e8f9f7 805 | _EMU_EM4CTRL_EM4IORETMODE_MASK);
<> 144:ef7eb2e8f9f7 806
<> 144:ef7eb2e8f9f7 807 em4ctrl |= (em4Init->retainLfxo ? EMU_EM4CTRL_RETAINLFXO : 0)
<> 144:ef7eb2e8f9f7 808 | (em4Init->retainLfrco ? EMU_EM4CTRL_RETAINLFRCO : 0)
<> 144:ef7eb2e8f9f7 809 | (em4Init->retainUlfrco ? EMU_EM4CTRL_RETAINULFRCO : 0)
<> 144:ef7eb2e8f9f7 810 | (em4Init->em4State ? EMU_EM4CTRL_EM4STATE_EM4H : 0)
<> 144:ef7eb2e8f9f7 811 | (em4Init->pinRetentionMode);
<> 144:ef7eb2e8f9f7 812
<> 144:ef7eb2e8f9f7 813 EMU->EM4CTRL = em4ctrl;
<> 144:ef7eb2e8f9f7 814 #endif
<> 144:ef7eb2e8f9f7 815 }
<> 144:ef7eb2e8f9f7 816 #endif
<> 144:ef7eb2e8f9f7 817
<> 144:ef7eb2e8f9f7 818
<> 144:ef7eb2e8f9f7 819 #if defined( BU_PRESENT )
<> 144:ef7eb2e8f9f7 820 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 821 * @brief
<> 144:ef7eb2e8f9f7 822 * Configure Backup Power Domain settings
<> 144:ef7eb2e8f9f7 823 *
<> 144:ef7eb2e8f9f7 824 * @param[in] bupdInit
<> 144:ef7eb2e8f9f7 825 * Backup power domain initialization structure
<> 144:ef7eb2e8f9f7 826 ******************************************************************************/
<> 144:ef7eb2e8f9f7 827 void EMU_BUPDInit(EMU_BUPDInit_TypeDef *bupdInit)
<> 144:ef7eb2e8f9f7 828 {
<> 144:ef7eb2e8f9f7 829 uint32_t reg;
<> 144:ef7eb2e8f9f7 830
<> 144:ef7eb2e8f9f7 831 /* Set power connection configuration */
<> 144:ef7eb2e8f9f7 832 reg = EMU->PWRCONF & ~(_EMU_PWRCONF_PWRRES_MASK
<> 144:ef7eb2e8f9f7 833 | _EMU_PWRCONF_VOUTSTRONG_MASK
<> 144:ef7eb2e8f9f7 834 | _EMU_PWRCONF_VOUTMED_MASK
<> 144:ef7eb2e8f9f7 835 | _EMU_PWRCONF_VOUTWEAK_MASK);
<> 144:ef7eb2e8f9f7 836
<> 144:ef7eb2e8f9f7 837 reg |= bupdInit->resistor
<> 144:ef7eb2e8f9f7 838 | (bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)
<> 144:ef7eb2e8f9f7 839 | (bupdInit->voutMed << _EMU_PWRCONF_VOUTMED_SHIFT)
<> 144:ef7eb2e8f9f7 840 | (bupdInit->voutWeak << _EMU_PWRCONF_VOUTWEAK_SHIFT);
<> 144:ef7eb2e8f9f7 841
<> 144:ef7eb2e8f9f7 842 EMU->PWRCONF = reg;
<> 144:ef7eb2e8f9f7 843
<> 144:ef7eb2e8f9f7 844 /* Set backup domain inactive mode configuration */
<> 144:ef7eb2e8f9f7 845 reg = EMU->BUINACT & ~(_EMU_BUINACT_PWRCON_MASK);
<> 144:ef7eb2e8f9f7 846 reg |= (bupdInit->inactivePower);
<> 144:ef7eb2e8f9f7 847 EMU->BUINACT = reg;
<> 144:ef7eb2e8f9f7 848
<> 144:ef7eb2e8f9f7 849 /* Set backup domain active mode configuration */
<> 144:ef7eb2e8f9f7 850 reg = EMU->BUACT & ~(_EMU_BUACT_PWRCON_MASK);
<> 144:ef7eb2e8f9f7 851 reg |= (bupdInit->activePower);
<> 144:ef7eb2e8f9f7 852 EMU->BUACT = reg;
<> 144:ef7eb2e8f9f7 853
<> 144:ef7eb2e8f9f7 854 /* Set power control configuration */
<> 144:ef7eb2e8f9f7 855 reg = EMU->BUCTRL & ~(_EMU_BUCTRL_PROBE_MASK
<> 144:ef7eb2e8f9f7 856 | _EMU_BUCTRL_BODCAL_MASK
<> 144:ef7eb2e8f9f7 857 | _EMU_BUCTRL_STATEN_MASK
<> 144:ef7eb2e8f9f7 858 | _EMU_BUCTRL_EN_MASK);
<> 144:ef7eb2e8f9f7 859
<> 144:ef7eb2e8f9f7 860 /* Note use of ->enable to both enable BUPD, use BU_VIN pin input and
<> 144:ef7eb2e8f9f7 861 release reset */
<> 144:ef7eb2e8f9f7 862 reg |= bupdInit->probe
<> 144:ef7eb2e8f9f7 863 | (bupdInit->bodCal << _EMU_BUCTRL_BODCAL_SHIFT)
<> 144:ef7eb2e8f9f7 864 | (bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)
<> 144:ef7eb2e8f9f7 865 | (bupdInit->enable << _EMU_BUCTRL_EN_SHIFT);
<> 144:ef7eb2e8f9f7 866
<> 144:ef7eb2e8f9f7 867 /* Enable configuration */
<> 144:ef7eb2e8f9f7 868 EMU->BUCTRL = reg;
<> 144:ef7eb2e8f9f7 869
<> 144:ef7eb2e8f9f7 870 /* If enable is true, enable BU_VIN input power pin, if not disable it */
<> 144:ef7eb2e8f9f7 871 EMU_BUPinEnable(bupdInit->enable);
<> 144:ef7eb2e8f9f7 872
<> 144:ef7eb2e8f9f7 873 /* If enable is true, release BU reset, if not keep reset asserted */
<> 144:ef7eb2e8f9f7 874 BUS_RegBitWrite(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);
<> 144:ef7eb2e8f9f7 875 }
<> 144:ef7eb2e8f9f7 876
<> 144:ef7eb2e8f9f7 877
<> 144:ef7eb2e8f9f7 878 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 879 * @brief
<> 144:ef7eb2e8f9f7 880 * Configure Backup Power Domain BOD Threshold value
<> 144:ef7eb2e8f9f7 881 * @note
<> 144:ef7eb2e8f9f7 882 * These values are precalibrated
<> 144:ef7eb2e8f9f7 883 * @param[in] mode Active or Inactive mode
<> 144:ef7eb2e8f9f7 884 * @param[in] value
<> 144:ef7eb2e8f9f7 885 ******************************************************************************/
<> 144:ef7eb2e8f9f7 886 void EMU_BUThresholdSet(EMU_BODMode_TypeDef mode, uint32_t value)
<> 144:ef7eb2e8f9f7 887 {
<> 144:ef7eb2e8f9f7 888 EFM_ASSERT(value<8);
<> 144:ef7eb2e8f9f7 889 EFM_ASSERT(value<=(_EMU_BUACT_BUEXTHRES_MASK>>_EMU_BUACT_BUEXTHRES_SHIFT));
<> 144:ef7eb2e8f9f7 890
<> 144:ef7eb2e8f9f7 891 switch(mode)
<> 144:ef7eb2e8f9f7 892 {
<> 144:ef7eb2e8f9f7 893 case emuBODMode_Active:
<> 144:ef7eb2e8f9f7 894 EMU->BUACT = (EMU->BUACT & ~_EMU_BUACT_BUEXTHRES_MASK)
<> 144:ef7eb2e8f9f7 895 | (value<<_EMU_BUACT_BUEXTHRES_SHIFT);
<> 144:ef7eb2e8f9f7 896 break;
<> 144:ef7eb2e8f9f7 897 case emuBODMode_Inactive:
<> 144:ef7eb2e8f9f7 898 EMU->BUINACT = (EMU->BUINACT & ~_EMU_BUINACT_BUENTHRES_MASK)
<> 144:ef7eb2e8f9f7 899 | (value<<_EMU_BUINACT_BUENTHRES_SHIFT);
<> 144:ef7eb2e8f9f7 900 break;
<> 144:ef7eb2e8f9f7 901 }
<> 144:ef7eb2e8f9f7 902 }
<> 144:ef7eb2e8f9f7 903
<> 144:ef7eb2e8f9f7 904
<> 144:ef7eb2e8f9f7 905 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 906 * @brief
<> 144:ef7eb2e8f9f7 907 * Configure Backup Power Domain BOD Threshold Range
<> 144:ef7eb2e8f9f7 908 * @note
<> 144:ef7eb2e8f9f7 909 * These values are precalibrated
<> 144:ef7eb2e8f9f7 910 * @param[in] mode Active or Inactive mode
<> 144:ef7eb2e8f9f7 911 * @param[in] value
<> 144:ef7eb2e8f9f7 912 ******************************************************************************/
<> 144:ef7eb2e8f9f7 913 void EMU_BUThresRangeSet(EMU_BODMode_TypeDef mode, uint32_t value)
<> 144:ef7eb2e8f9f7 914 {
<> 144:ef7eb2e8f9f7 915 EFM_ASSERT(value < 4);
<> 144:ef7eb2e8f9f7 916 EFM_ASSERT(value<=(_EMU_BUACT_BUEXRANGE_MASK>>_EMU_BUACT_BUEXRANGE_SHIFT));
<> 144:ef7eb2e8f9f7 917
<> 144:ef7eb2e8f9f7 918 switch(mode)
<> 144:ef7eb2e8f9f7 919 {
<> 144:ef7eb2e8f9f7 920 case emuBODMode_Active:
<> 144:ef7eb2e8f9f7 921 EMU->BUACT = (EMU->BUACT & ~_EMU_BUACT_BUEXRANGE_MASK)
<> 144:ef7eb2e8f9f7 922 | (value<<_EMU_BUACT_BUEXRANGE_SHIFT);
<> 144:ef7eb2e8f9f7 923 break;
<> 144:ef7eb2e8f9f7 924 case emuBODMode_Inactive:
<> 144:ef7eb2e8f9f7 925 EMU->BUINACT = (EMU->BUINACT & ~_EMU_BUINACT_BUENRANGE_MASK)
<> 144:ef7eb2e8f9f7 926 | (value<<_EMU_BUINACT_BUENRANGE_SHIFT);
<> 144:ef7eb2e8f9f7 927 break;
<> 144:ef7eb2e8f9f7 928 }
<> 144:ef7eb2e8f9f7 929 }
<> 144:ef7eb2e8f9f7 930 #endif
<> 144:ef7eb2e8f9f7 931
<> 144:ef7eb2e8f9f7 932
<> 144:ef7eb2e8f9f7 933 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 934
<> 144:ef7eb2e8f9f7 935 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 936
<> 144:ef7eb2e8f9f7 937 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 938 * @brief
<> 144:ef7eb2e8f9f7 939 * Load DCDC calibration constants from DI page. Const means calibration
<> 144:ef7eb2e8f9f7 940 * data that does not change depending on other configuration parameters.
<> 144:ef7eb2e8f9f7 941 *
<> 144:ef7eb2e8f9f7 942 * @return
<> 144:ef7eb2e8f9f7 943 * False if calibration registers are locked
<> 144:ef7eb2e8f9f7 944 ******************************************************************************/
<> 144:ef7eb2e8f9f7 945 static bool ConstCalibrationLoad(void)
<> 144:ef7eb2e8f9f7 946 {
<> 144:ef7eb2e8f9f7 947 uint32_t val;
<> 144:ef7eb2e8f9f7 948 volatile uint32_t *reg;
<> 144:ef7eb2e8f9f7 949
<> 144:ef7eb2e8f9f7 950 /* DI calib data in flash */
<> 144:ef7eb2e8f9f7 951 volatile uint32_t* const diCal_EMU_DCDCLNFREQCTRL = (volatile uint32_t *)(0x0FE08038);
<> 144:ef7eb2e8f9f7 952 volatile uint32_t* const diCal_EMU_DCDCLNVCTRL = (volatile uint32_t *)(0x0FE08040);
<> 144:ef7eb2e8f9f7 953 volatile uint32_t* const diCal_EMU_DCDCLPCTRL = (volatile uint32_t *)(0x0FE08048);
<> 144:ef7eb2e8f9f7 954 volatile uint32_t* const diCal_EMU_DCDCLPVCTRL = (volatile uint32_t *)(0x0FE08050);
<> 144:ef7eb2e8f9f7 955 volatile uint32_t* const diCal_EMU_DCDCTRIM0 = (volatile uint32_t *)(0x0FE08058);
<> 144:ef7eb2e8f9f7 956 volatile uint32_t* const diCal_EMU_DCDCTRIM1 = (volatile uint32_t *)(0x0FE08060);
<> 144:ef7eb2e8f9f7 957
<> 144:ef7eb2e8f9f7 958 if (DEVINFO->DCDCLPVCTRL0 != UINT_MAX)
<> 144:ef7eb2e8f9f7 959 {
<> 144:ef7eb2e8f9f7 960 val = *(diCal_EMU_DCDCLNFREQCTRL + 1);
<> 144:ef7eb2e8f9f7 961 reg = (volatile uint32_t *)*diCal_EMU_DCDCLNFREQCTRL;
<> 144:ef7eb2e8f9f7 962 *reg = val;
<> 144:ef7eb2e8f9f7 963
<> 144:ef7eb2e8f9f7 964 val = *(diCal_EMU_DCDCLNVCTRL + 1);
<> 144:ef7eb2e8f9f7 965 reg = (volatile uint32_t *)*diCal_EMU_DCDCLNVCTRL;
<> 144:ef7eb2e8f9f7 966 *reg = val;
<> 144:ef7eb2e8f9f7 967
<> 144:ef7eb2e8f9f7 968 val = *(diCal_EMU_DCDCLPCTRL + 1);
<> 144:ef7eb2e8f9f7 969 reg = (volatile uint32_t *)*diCal_EMU_DCDCLPCTRL;
<> 144:ef7eb2e8f9f7 970 *reg = val;
<> 144:ef7eb2e8f9f7 971
<> 144:ef7eb2e8f9f7 972 val = *(diCal_EMU_DCDCLPVCTRL + 1);
<> 144:ef7eb2e8f9f7 973 reg = (volatile uint32_t *)*diCal_EMU_DCDCLPVCTRL;
<> 144:ef7eb2e8f9f7 974 *reg = val;
<> 144:ef7eb2e8f9f7 975
<> 144:ef7eb2e8f9f7 976 val = *(diCal_EMU_DCDCTRIM0 + 1);
<> 144:ef7eb2e8f9f7 977 reg = (volatile uint32_t *)*diCal_EMU_DCDCTRIM0;
<> 144:ef7eb2e8f9f7 978 *reg = val;
<> 144:ef7eb2e8f9f7 979
<> 144:ef7eb2e8f9f7 980 val = *(diCal_EMU_DCDCTRIM1 + 1);
<> 144:ef7eb2e8f9f7 981 reg = (volatile uint32_t *)*diCal_EMU_DCDCTRIM1;
<> 144:ef7eb2e8f9f7 982 *reg = val;
<> 144:ef7eb2e8f9f7 983
<> 144:ef7eb2e8f9f7 984 return true;
<> 144:ef7eb2e8f9f7 985 }
<> 144:ef7eb2e8f9f7 986 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 987 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 988 return false;
<> 144:ef7eb2e8f9f7 989 }
<> 144:ef7eb2e8f9f7 990
<> 144:ef7eb2e8f9f7 991
<> 144:ef7eb2e8f9f7 992 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 993 * @brief
<> 144:ef7eb2e8f9f7 994 * Set recommended and validated current optimization settings
<> 144:ef7eb2e8f9f7 995 *
<> 144:ef7eb2e8f9f7 996 ******************************************************************************/
<> 144:ef7eb2e8f9f7 997 void ValidatedConfigSet(void)
<> 144:ef7eb2e8f9f7 998 {
<> 144:ef7eb2e8f9f7 999 #define EMU_DCDCSMCTRL (* (volatile uint32_t *)(EMU_BASE + 0x44))
<> 144:ef7eb2e8f9f7 1000
<> 144:ef7eb2e8f9f7 1001 uint32_t dcdcTiming;
<> 144:ef7eb2e8f9f7 1002 SYSTEM_PartFamily_TypeDef family;
<> 144:ef7eb2e8f9f7 1003 SYSTEM_ChipRevision_TypeDef rev;
<> 144:ef7eb2e8f9f7 1004
<> 144:ef7eb2e8f9f7 1005 /* Enable duty cycling of the bias */
<> 144:ef7eb2e8f9f7 1006 EMU->DCDCLPCTRL |= EMU_DCDCLPCTRL_LPVREFDUTYEN;
<> 144:ef7eb2e8f9f7 1007
<> 144:ef7eb2e8f9f7 1008 /* Set low-noise RCO for EFM32 and EFR32 */
<> 144:ef7eb2e8f9f7 1009 #if defined( _EFR_DEVICE )
<> 144:ef7eb2e8f9f7 1010 /* 7MHz is recommended for all EFR32 parts with DCDC */
<> 144:ef7eb2e8f9f7 1011 EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
<> 144:ef7eb2e8f9f7 1012 | (EMU_DcdcLnRcoBand_7MHz << _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);
<> 144:ef7eb2e8f9f7 1013 #else
<> 144:ef7eb2e8f9f7 1014 /* 3MHz is recommended for all EFM32 parts with DCDC */
<> 144:ef7eb2e8f9f7 1015 EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
<> 144:ef7eb2e8f9f7 1016 | (EMU_DcdcLnRcoBand_3MHz << _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);
<> 144:ef7eb2e8f9f7 1017 #endif
<> 144:ef7eb2e8f9f7 1018
<> 144:ef7eb2e8f9f7 1019 EMU->DCDCTIMING &= ~_EMU_DCDCTIMING_DUTYSCALE_MASK;
<> 144:ef7eb2e8f9f7 1020
<> 144:ef7eb2e8f9f7 1021 family = SYSTEM_GetFamily();
<> 144:ef7eb2e8f9f7 1022 SYSTEM_ChipRevisionGet(&rev);
<> 144:ef7eb2e8f9f7 1023 if ((((family >= systemPartFamilyMighty1P)
<> 144:ef7eb2e8f9f7 1024 && (family <= systemPartFamilyFlex1V))
<> 144:ef7eb2e8f9f7 1025 || (family == systemPartFamilyEfm32Pearl1B)
<> 144:ef7eb2e8f9f7 1026 || (family == systemPartFamilyEfm32Jade1B))
<> 144:ef7eb2e8f9f7 1027 && ((rev.major == 1) && (rev.minor < 3))
<> 144:ef7eb2e8f9f7 1028 && (errataFixDcdcHsState == errataFixDcdcHsInit))
<> 144:ef7eb2e8f9f7 1029 {
<> 144:ef7eb2e8f9f7 1030 /* LPCMPWAITDIS = 1 */
<> 144:ef7eb2e8f9f7 1031 EMU_DCDCSMCTRL |= 1;
<> 144:ef7eb2e8f9f7 1032
<> 144:ef7eb2e8f9f7 1033 dcdcTiming = EMU->DCDCTIMING;
<> 144:ef7eb2e8f9f7 1034 dcdcTiming &= ~(_EMU_DCDCTIMING_LPINITWAIT_MASK
<> 144:ef7eb2e8f9f7 1035 |_EMU_DCDCTIMING_LNWAIT_MASK
<> 144:ef7eb2e8f9f7 1036 |_EMU_DCDCTIMING_BYPWAIT_MASK);
<> 144:ef7eb2e8f9f7 1037
<> 144:ef7eb2e8f9f7 1038 dcdcTiming |= ((180 << _EMU_DCDCTIMING_LPINITWAIT_SHIFT)
<> 144:ef7eb2e8f9f7 1039 | (12 << _EMU_DCDCTIMING_LNWAIT_SHIFT)
<> 144:ef7eb2e8f9f7 1040 | (180 << _EMU_DCDCTIMING_BYPWAIT_SHIFT));
<> 144:ef7eb2e8f9f7 1041 EMU->DCDCTIMING = dcdcTiming;
<> 144:ef7eb2e8f9f7 1042
<> 144:ef7eb2e8f9f7 1043 errataFixDcdcHsState = errataFixDcdcHsTrimSet;
<> 144:ef7eb2e8f9f7 1044 }
<> 144:ef7eb2e8f9f7 1045 }
<> 144:ef7eb2e8f9f7 1046
<> 144:ef7eb2e8f9f7 1047
<> 144:ef7eb2e8f9f7 1048 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1049 * @brief
<> 144:ef7eb2e8f9f7 1050 * Calculate and update EMU->DCDCMISCCTRL for maximum DCDC current based
<> 144:ef7eb2e8f9f7 1051 * on the slice configuration and user set maximum.
<> 144:ef7eb2e8f9f7 1052 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1053 static void maxCurrentUpdate(void)
<> 144:ef7eb2e8f9f7 1054 {
<> 144:ef7eb2e8f9f7 1055 uint32_t lncLimImSel;
<> 144:ef7eb2e8f9f7 1056 uint32_t lpcLimImSel;
<> 144:ef7eb2e8f9f7 1057 uint32_t pFetCnt;
<> 144:ef7eb2e8f9f7 1058
<> 144:ef7eb2e8f9f7 1059 pFetCnt = (EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_PFETCNT_MASK)
<> 144:ef7eb2e8f9f7 1060 >> _EMU_DCDCMISCCTRL_PFETCNT_SHIFT;
<> 144:ef7eb2e8f9f7 1061
<> 144:ef7eb2e8f9f7 1062 /* Equation from Reference Manual section 11.5.20, in the register
<> 144:ef7eb2e8f9f7 1063 field description for LNCLIMILIMSEL and LPCLIMILIMSEL. */
<> 144:ef7eb2e8f9f7 1064 lncLimImSel = (dcdcMaxCurrent_mA / (5 * (pFetCnt + 1))) - 1;
<> 144:ef7eb2e8f9f7 1065 /* 80mA as recommended in Application Note AN0948 */
<> 144:ef7eb2e8f9f7 1066 lpcLimImSel = (80 / (5 * (pFetCnt + 1))) - 1;
<> 144:ef7eb2e8f9f7 1067
<> 144:ef7eb2e8f9f7 1068 lncLimImSel <<= _EMU_DCDCMISCCTRL_LNCLIMILIMSEL_SHIFT;
<> 144:ef7eb2e8f9f7 1069 lpcLimImSel <<= _EMU_DCDCMISCCTRL_LPCLIMILIMSEL_SHIFT;
<> 144:ef7eb2e8f9f7 1070 EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_LNCLIMILIMSEL_MASK
<> 144:ef7eb2e8f9f7 1071 | _EMU_DCDCMISCCTRL_LPCLIMILIMSEL_MASK))
<> 144:ef7eb2e8f9f7 1072 | (lncLimImSel | lpcLimImSel);
<> 144:ef7eb2e8f9f7 1073 }
<> 144:ef7eb2e8f9f7 1074
<> 144:ef7eb2e8f9f7 1075
<> 144:ef7eb2e8f9f7 1076 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1077 * @brief
<> 144:ef7eb2e8f9f7 1078 * Set static variable that holds the user set maximum current. Update
<> 144:ef7eb2e8f9f7 1079 * DCDC configuration.
<> 144:ef7eb2e8f9f7 1080 *
<> 144:ef7eb2e8f9f7 1081 * @param[in] mAmaxCurrent
<> 144:ef7eb2e8f9f7 1082 * Maximum allowed current drawn by the DCDC from VREGVDD in mA.
<> 144:ef7eb2e8f9f7 1083 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1084 static void maxCurrentSet(uint32_t mAmaxCurrent)
<> 144:ef7eb2e8f9f7 1085 {
<> 144:ef7eb2e8f9f7 1086 dcdcMaxCurrent_mA = mAmaxCurrent;
<> 144:ef7eb2e8f9f7 1087 maxCurrentUpdate();
<> 144:ef7eb2e8f9f7 1088 }
<> 144:ef7eb2e8f9f7 1089
<> 144:ef7eb2e8f9f7 1090
<> 144:ef7eb2e8f9f7 1091 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1092 * @brief
<> 144:ef7eb2e8f9f7 1093 * Load EMU_DCDCLPCTRL_LPCMPHYSSEL depending on LP bias, LP feedback
<> 144:ef7eb2e8f9f7 1094 * attenuation and DEVINFOREV.
<> 144:ef7eb2e8f9f7 1095 *
<> 144:ef7eb2e8f9f7 1096 * @param[in] attSet
<> 144:ef7eb2e8f9f7 1097 * LP feedback attenuation.
<> 144:ef7eb2e8f9f7 1098 * @param[in] lpCmpBias
<> 144:ef7eb2e8f9f7 1099 * lpCmpBias selection
<> 144:ef7eb2e8f9f7 1100 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1101 static bool LpCmpHystCalibrationLoad(bool lpAttenuation, uint32_t lpCmpBias)
<> 144:ef7eb2e8f9f7 1102 {
<> 144:ef7eb2e8f9f7 1103 uint8_t devinfoRev;
<> 144:ef7eb2e8f9f7 1104 uint32_t lpcmpHystSel;
<> 144:ef7eb2e8f9f7 1105
<> 144:ef7eb2e8f9f7 1106 /* Get calib data revision */
<> 144:ef7eb2e8f9f7 1107 devinfoRev = SYSTEM_GetDevinfoRev();
<> 144:ef7eb2e8f9f7 1108
<> 144:ef7eb2e8f9f7 1109 /* Load LPATT indexed calibration data */
<> 144:ef7eb2e8f9f7 1110 if (devinfoRev < 4)
<> 144:ef7eb2e8f9f7 1111 {
<> 144:ef7eb2e8f9f7 1112 lpcmpHystSel = DEVINFO->DCDCLPCMPHYSSEL0;
<> 144:ef7eb2e8f9f7 1113
<> 144:ef7eb2e8f9f7 1114 if (lpAttenuation)
<> 144:ef7eb2e8f9f7 1115 {
<> 144:ef7eb2e8f9f7 1116 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT1_MASK)
<> 144:ef7eb2e8f9f7 1117 >> _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT1_SHIFT;
<> 144:ef7eb2e8f9f7 1118 }
<> 144:ef7eb2e8f9f7 1119 else
<> 144:ef7eb2e8f9f7 1120 {
<> 144:ef7eb2e8f9f7 1121 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT0_MASK)
<> 144:ef7eb2e8f9f7 1122 >> _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT0_SHIFT;
<> 144:ef7eb2e8f9f7 1123 }
<> 144:ef7eb2e8f9f7 1124 }
<> 144:ef7eb2e8f9f7 1125 /* devinfoRev >= 4
<> 144:ef7eb2e8f9f7 1126 Load LPCMPBIAS indexed calibration data */
<> 144:ef7eb2e8f9f7 1127 else
<> 144:ef7eb2e8f9f7 1128 {
<> 144:ef7eb2e8f9f7 1129 lpcmpHystSel = DEVINFO->DCDCLPCMPHYSSEL1;
<> 144:ef7eb2e8f9f7 1130 switch (lpCmpBias)
<> 144:ef7eb2e8f9f7 1131 {
<> 144:ef7eb2e8f9f7 1132 case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0:
<> 144:ef7eb2e8f9f7 1133 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1134 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1135 break;
<> 144:ef7eb2e8f9f7 1136
<> 144:ef7eb2e8f9f7 1137 case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1:
<> 144:ef7eb2e8f9f7 1138 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1139 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1140 break;
<> 144:ef7eb2e8f9f7 1141
<> 144:ef7eb2e8f9f7 1142 case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS2:
<> 144:ef7eb2e8f9f7 1143 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1144 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1145 break;
<> 144:ef7eb2e8f9f7 1146
<> 144:ef7eb2e8f9f7 1147 case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS3:
<> 144:ef7eb2e8f9f7 1148 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1149 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1150 break;
<> 144:ef7eb2e8f9f7 1151
<> 144:ef7eb2e8f9f7 1152 default:
<> 144:ef7eb2e8f9f7 1153 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1154 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1155 return false;
<> 144:ef7eb2e8f9f7 1156 }
<> 144:ef7eb2e8f9f7 1157 }
<> 144:ef7eb2e8f9f7 1158
<> 144:ef7eb2e8f9f7 1159 /* Make sure the sel value is within the field range. */
<> 144:ef7eb2e8f9f7 1160 lpcmpHystSel <<= _EMU_DCDCLPCTRL_LPCMPHYSSEL_SHIFT;
<> 144:ef7eb2e8f9f7 1161 if (lpcmpHystSel & ~_EMU_DCDCLPCTRL_LPCMPHYSSEL_MASK)
<> 144:ef7eb2e8f9f7 1162 {
<> 144:ef7eb2e8f9f7 1163 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1164 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1165 return false;
<> 144:ef7eb2e8f9f7 1166 }
<> 144:ef7eb2e8f9f7 1167 EMU->DCDCLPCTRL = (EMU->DCDCLPCTRL & ~_EMU_DCDCLPCTRL_LPCMPHYSSEL_MASK) | lpcmpHystSel;
<> 144:ef7eb2e8f9f7 1168
<> 144:ef7eb2e8f9f7 1169 return true;
<> 144:ef7eb2e8f9f7 1170 }
<> 144:ef7eb2e8f9f7 1171
<> 144:ef7eb2e8f9f7 1172
<> 144:ef7eb2e8f9f7 1173 /** @endcond */
<> 144:ef7eb2e8f9f7 1174
<> 144:ef7eb2e8f9f7 1175 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1176 * @brief
<> 144:ef7eb2e8f9f7 1177 * Set DCDC regulator operating mode
<> 144:ef7eb2e8f9f7 1178 *
<> 144:ef7eb2e8f9f7 1179 * @param[in] dcdcMode
<> 144:ef7eb2e8f9f7 1180 * DCDC mode
<> 144:ef7eb2e8f9f7 1181 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1182 void EMU_DCDCModeSet(EMU_DcdcMode_TypeDef dcdcMode)
<> 144:ef7eb2e8f9f7 1183 {
<> 144:ef7eb2e8f9f7 1184 while(EMU->DCDCSYNC & EMU_DCDCSYNC_DCDCCTRLBUSY);
<> 144:ef7eb2e8f9f7 1185 BUS_RegBitWrite(&EMU->DCDCCLIMCTRL, _EMU_DCDCCLIMCTRL_BYPLIMEN_SHIFT, dcdcMode == emuDcdcMode_Bypass ? 0 : 1);
<> 144:ef7eb2e8f9f7 1186 EMU->DCDCCTRL = (EMU->DCDCCTRL & ~_EMU_DCDCCTRL_DCDCMODE_MASK) | dcdcMode;
<> 144:ef7eb2e8f9f7 1187 }
<> 144:ef7eb2e8f9f7 1188
<> 144:ef7eb2e8f9f7 1189
<> 144:ef7eb2e8f9f7 1190 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1191 * @brief
<> 144:ef7eb2e8f9f7 1192 * Configure DCDC regulator
<> 144:ef7eb2e8f9f7 1193 *
<> 144:ef7eb2e8f9f7 1194 * @note
<> 144:ef7eb2e8f9f7 1195 * Use the function EMU_DCDCPowerDown() to if the power circuit is configured
<> 144:ef7eb2e8f9f7 1196 * for NODCDC as decribed in Section 11.3.4.3 in the Reference Manual.
<> 144:ef7eb2e8f9f7 1197 *
<> 144:ef7eb2e8f9f7 1198 * @param[in] dcdcInit
<> 144:ef7eb2e8f9f7 1199 * DCDC initialization structure
<> 144:ef7eb2e8f9f7 1200 *
<> 144:ef7eb2e8f9f7 1201 * @return
<> 144:ef7eb2e8f9f7 1202 * True if initialization parameters are valid
<> 144:ef7eb2e8f9f7 1203 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1204 bool EMU_DCDCInit(EMU_DCDCInit_TypeDef *dcdcInit)
<> 144:ef7eb2e8f9f7 1205 {
<> 144:ef7eb2e8f9f7 1206 uint32_t lpCmpBiasSel;
<> 144:ef7eb2e8f9f7 1207
<> 144:ef7eb2e8f9f7 1208 /* Set external power configuration. This enables writing to the other
<> 144:ef7eb2e8f9f7 1209 DCDC registers. */
<> 144:ef7eb2e8f9f7 1210 EMU->PWRCFG = dcdcInit->powerConfig;
<> 144:ef7eb2e8f9f7 1211
<> 144:ef7eb2e8f9f7 1212 /* EMU->PWRCFG is write-once and POR reset only. Check that
<> 144:ef7eb2e8f9f7 1213 we could set the desired power configuration. */
<> 144:ef7eb2e8f9f7 1214 if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) != dcdcInit->powerConfig)
<> 144:ef7eb2e8f9f7 1215 {
<> 144:ef7eb2e8f9f7 1216 /* If this assert triggers unexpectedly, please power cycle the
<> 144:ef7eb2e8f9f7 1217 kit to reset the power configuration. */
<> 144:ef7eb2e8f9f7 1218 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1219 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1220 return false;
<> 144:ef7eb2e8f9f7 1221 }
<> 144:ef7eb2e8f9f7 1222
<> 144:ef7eb2e8f9f7 1223 /* Load DCDC calibration data from the DI page */
<> 144:ef7eb2e8f9f7 1224 ConstCalibrationLoad();
<> 144:ef7eb2e8f9f7 1225
<> 144:ef7eb2e8f9f7 1226 /* Check current parameters */
<> 144:ef7eb2e8f9f7 1227 EFM_ASSERT(dcdcInit->maxCurrent_mA <= 200);
<> 144:ef7eb2e8f9f7 1228 EFM_ASSERT(dcdcInit->em01LoadCurrent_mA <= dcdcInit->maxCurrent_mA);
<> 144:ef7eb2e8f9f7 1229
<> 144:ef7eb2e8f9f7 1230 /* DCDC low-noise supports max 200mA */
<> 144:ef7eb2e8f9f7 1231 if (dcdcInit->dcdcMode == emuDcdcMode_LowNoise)
<> 144:ef7eb2e8f9f7 1232 {
<> 144:ef7eb2e8f9f7 1233 EFM_ASSERT(dcdcInit->em01LoadCurrent_mA <= 200);
<> 144:ef7eb2e8f9f7 1234 }
<> 144:ef7eb2e8f9f7 1235
<> 144:ef7eb2e8f9f7 1236 /* EM2, 3 and 4 current above 100uA is not supported */
<> 144:ef7eb2e8f9f7 1237 EFM_ASSERT(dcdcInit->em234LoadCurrent_uA <= 100);
<> 144:ef7eb2e8f9f7 1238
<> 144:ef7eb2e8f9f7 1239 /* Decode LP comparator bias for EM0/1 and EM2/3 */
<> 144:ef7eb2e8f9f7 1240 lpCmpBiasSel = EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1;
<> 144:ef7eb2e8f9f7 1241 if (dcdcInit->em234LoadCurrent_uA <= 10)
<> 144:ef7eb2e8f9f7 1242 {
<> 144:ef7eb2e8f9f7 1243 lpCmpBiasSel = EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0;
<> 144:ef7eb2e8f9f7 1244 }
<> 144:ef7eb2e8f9f7 1245
<> 144:ef7eb2e8f9f7 1246 /* Set DCDC low-power mode comparator bias selection */
<> 144:ef7eb2e8f9f7 1247 EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_LPCMPBIAS_MASK
<> 144:ef7eb2e8f9f7 1248 | _EMU_DCDCMISCCTRL_LNFORCECCM_MASK))
<> 144:ef7eb2e8f9f7 1249 | ((uint32_t)lpCmpBiasSel
<> 144:ef7eb2e8f9f7 1250 | (uint32_t)dcdcInit->lnTransientMode);
<> 144:ef7eb2e8f9f7 1251
<> 144:ef7eb2e8f9f7 1252 /* Set recommended and validated current optimization settings */
<> 144:ef7eb2e8f9f7 1253 ValidatedConfigSet();
<> 144:ef7eb2e8f9f7 1254
<> 144:ef7eb2e8f9f7 1255 /* Set the maximum current that the DCDC can draw from the power source */
<> 144:ef7eb2e8f9f7 1256 maxCurrentSet(dcdcInit->maxCurrent_mA);
<> 144:ef7eb2e8f9f7 1257
<> 144:ef7eb2e8f9f7 1258 /* Optimize LN slice based on given load current estimate */
<> 144:ef7eb2e8f9f7 1259 EMU_DCDCOptimizeSlice(dcdcInit->em01LoadCurrent_mA);
<> 144:ef7eb2e8f9f7 1260
<> 144:ef7eb2e8f9f7 1261 /* Set DCDC output voltage */
<> 144:ef7eb2e8f9f7 1262 dcdcOutput_mVout = dcdcInit->mVout;
<> 144:ef7eb2e8f9f7 1263 if (!EMU_DCDCOutputVoltageSet(dcdcOutput_mVout, true, true))
<> 144:ef7eb2e8f9f7 1264 {
<> 144:ef7eb2e8f9f7 1265 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1266 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1267 return false;
<> 144:ef7eb2e8f9f7 1268 }
<> 144:ef7eb2e8f9f7 1269
<> 144:ef7eb2e8f9f7 1270 /* Set EM0 DCDC operating mode. Output voltage set in EMU_DCDCOutputVoltageSet()
<> 144:ef7eb2e8f9f7 1271 above takes effect if mode is changed from bypass here. */
<> 144:ef7eb2e8f9f7 1272 EMU_DCDCModeSet(dcdcInit->dcdcMode);
<> 144:ef7eb2e8f9f7 1273
<> 144:ef7eb2e8f9f7 1274 /* Select analog peripheral power supply */
<> 144:ef7eb2e8f9f7 1275 BUS_RegBitWrite(&EMU->PWRCTRL, _EMU_PWRCTRL_ANASW_SHIFT, dcdcInit->anaPeripheralPower ? 1 : 0);
<> 144:ef7eb2e8f9f7 1276
<> 144:ef7eb2e8f9f7 1277 return true;
<> 144:ef7eb2e8f9f7 1278 }
<> 144:ef7eb2e8f9f7 1279
<> 144:ef7eb2e8f9f7 1280
<> 144:ef7eb2e8f9f7 1281 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1282 * @brief
<> 144:ef7eb2e8f9f7 1283 * Set DCDC output voltage
<> 144:ef7eb2e8f9f7 1284 *
<> 144:ef7eb2e8f9f7 1285 * @param[in] mV
<> 144:ef7eb2e8f9f7 1286 * Target DCDC output voltage in mV
<> 144:ef7eb2e8f9f7 1287 *
<> 144:ef7eb2e8f9f7 1288 * @return
<> 144:ef7eb2e8f9f7 1289 * True if the mV parameter is valid
<> 144:ef7eb2e8f9f7 1290 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1291 bool EMU_DCDCOutputVoltageSet(uint32_t mV,
<> 144:ef7eb2e8f9f7 1292 bool setLpVoltage,
<> 144:ef7eb2e8f9f7 1293 bool setLnVoltage)
<> 144:ef7eb2e8f9f7 1294 {
<> 144:ef7eb2e8f9f7 1295 #if defined( _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_MASK )
<> 144:ef7eb2e8f9f7 1296
<> 144:ef7eb2e8f9f7 1297 bool validOutVoltage;
<> 144:ef7eb2e8f9f7 1298 uint8_t lnMode;
<> 144:ef7eb2e8f9f7 1299 bool attSet;
<> 144:ef7eb2e8f9f7 1300 uint32_t attMask;
<> 144:ef7eb2e8f9f7 1301 uint32_t vrefLow = 0;
<> 144:ef7eb2e8f9f7 1302 uint32_t vrefHigh = 0;
<> 144:ef7eb2e8f9f7 1303 uint32_t vrefVal = 0;
<> 144:ef7eb2e8f9f7 1304 uint32_t mVlow = 0;
<> 144:ef7eb2e8f9f7 1305 uint32_t mVhigh = 0;
<> 144:ef7eb2e8f9f7 1306 uint32_t vrefShift;
<> 144:ef7eb2e8f9f7 1307 uint32_t lpcmpBias;
<> 144:ef7eb2e8f9f7 1308 volatile uint32_t* ctrlReg;
<> 144:ef7eb2e8f9f7 1309
<> 144:ef7eb2e8f9f7 1310 /* Check that the set voltage is within valid range.
<> 144:ef7eb2e8f9f7 1311 Voltages are obtained from the datasheet. */
<> 144:ef7eb2e8f9f7 1312 validOutVoltage = false;
<> 144:ef7eb2e8f9f7 1313 if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) == EMU_PWRCFG_PWRCFG_DCDCTODVDD)
<> 144:ef7eb2e8f9f7 1314 {
<> 144:ef7eb2e8f9f7 1315 validOutVoltage = ((mV >= PWRCFG_DCDCTODVDD_VMIN)
<> 144:ef7eb2e8f9f7 1316 && (mV <= PWRCFG_DCDCTODVDD_VMAX));
<> 144:ef7eb2e8f9f7 1317 }
<> 144:ef7eb2e8f9f7 1318
<> 144:ef7eb2e8f9f7 1319 if (!validOutVoltage)
<> 144:ef7eb2e8f9f7 1320 {
<> 144:ef7eb2e8f9f7 1321 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1322 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1323 return false;
<> 144:ef7eb2e8f9f7 1324 }
<> 144:ef7eb2e8f9f7 1325
<> 144:ef7eb2e8f9f7 1326 /* Populate both LP and LN registers, set control reg pointer and VREF shift. */
<> 144:ef7eb2e8f9f7 1327 for (lnMode = 0; lnMode <= 1; lnMode++)
<> 144:ef7eb2e8f9f7 1328 {
<> 144:ef7eb2e8f9f7 1329 if (((lnMode == 0) && !setLpVoltage)
<> 144:ef7eb2e8f9f7 1330 || ((lnMode == 1) && !setLnVoltage))
<> 144:ef7eb2e8f9f7 1331 {
<> 144:ef7eb2e8f9f7 1332 continue;
<> 144:ef7eb2e8f9f7 1333 }
<> 144:ef7eb2e8f9f7 1334
<> 144:ef7eb2e8f9f7 1335 ctrlReg = (lnMode ? &EMU->DCDCLNVCTRL : &EMU->DCDCLPVCTRL);
<> 144:ef7eb2e8f9f7 1336 vrefShift = (lnMode ? _EMU_DCDCLNVCTRL_LNVREF_SHIFT
<> 144:ef7eb2e8f9f7 1337 : _EMU_DCDCLPVCTRL_LPVREF_SHIFT);
<> 144:ef7eb2e8f9f7 1338
<> 144:ef7eb2e8f9f7 1339 /* Set attenuation to use */
<> 144:ef7eb2e8f9f7 1340 attSet = (mV > 1800);
<> 144:ef7eb2e8f9f7 1341 if (attSet)
<> 144:ef7eb2e8f9f7 1342 {
<> 144:ef7eb2e8f9f7 1343 mVlow = 1800;
<> 144:ef7eb2e8f9f7 1344 mVhigh = 3000;
<> 144:ef7eb2e8f9f7 1345 attMask = (lnMode ? EMU_DCDCLNVCTRL_LNATT : EMU_DCDCLPVCTRL_LPATT);
<> 144:ef7eb2e8f9f7 1346 }
<> 144:ef7eb2e8f9f7 1347 else
<> 144:ef7eb2e8f9f7 1348 {
<> 144:ef7eb2e8f9f7 1349 mVlow = 1200;
<> 144:ef7eb2e8f9f7 1350 mVhigh = 1800;
<> 144:ef7eb2e8f9f7 1351 attMask = 0;
<> 144:ef7eb2e8f9f7 1352 }
<> 144:ef7eb2e8f9f7 1353
<> 144:ef7eb2e8f9f7 1354 /* Get 2-point calib data from DEVINFO, calculate trimming and set voltege */
<> 144:ef7eb2e8f9f7 1355 if (lnMode)
<> 144:ef7eb2e8f9f7 1356 {
<> 144:ef7eb2e8f9f7 1357 /* Set low-noise DCDC output voltage tuning */
<> 144:ef7eb2e8f9f7 1358 if (attSet)
<> 144:ef7eb2e8f9f7 1359 {
<> 144:ef7eb2e8f9f7 1360 vrefLow = DEVINFO->DCDCLNVCTRL0;
<> 144:ef7eb2e8f9f7 1361 vrefHigh = (vrefLow & _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_MASK)
<> 144:ef7eb2e8f9f7 1362 >> _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_SHIFT;
<> 144:ef7eb2e8f9f7 1363 vrefLow = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V8LNATT1_MASK)
<> 144:ef7eb2e8f9f7 1364 >> _DEVINFO_DCDCLNVCTRL0_1V8LNATT1_SHIFT;
<> 144:ef7eb2e8f9f7 1365 }
<> 144:ef7eb2e8f9f7 1366 else
<> 144:ef7eb2e8f9f7 1367 {
<> 144:ef7eb2e8f9f7 1368 vrefLow = DEVINFO->DCDCLNVCTRL0;
<> 144:ef7eb2e8f9f7 1369 vrefHigh = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V8LNATT0_MASK)
<> 144:ef7eb2e8f9f7 1370 >> _DEVINFO_DCDCLNVCTRL0_1V8LNATT0_SHIFT;
<> 144:ef7eb2e8f9f7 1371 vrefLow = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V2LNATT0_MASK)
<> 144:ef7eb2e8f9f7 1372 >> _DEVINFO_DCDCLNVCTRL0_1V2LNATT0_SHIFT;
<> 144:ef7eb2e8f9f7 1373 }
<> 144:ef7eb2e8f9f7 1374 }
<> 144:ef7eb2e8f9f7 1375 else
<> 144:ef7eb2e8f9f7 1376 {
<> 144:ef7eb2e8f9f7 1377 /* Set low-power DCDC output voltage tuning */
<> 144:ef7eb2e8f9f7 1378
<> 144:ef7eb2e8f9f7 1379 /* Get LPCMPBIAS and make sure masks are not overlayed */
<> 144:ef7eb2e8f9f7 1380 lpcmpBias = EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LPCMPBIAS_MASK;
<> 144:ef7eb2e8f9f7 1381 EFM_ASSERT(!(_EMU_DCDCMISCCTRL_LPCMPBIAS_MASK & attMask));
<> 144:ef7eb2e8f9f7 1382 switch (attMask | lpcmpBias)
<> 144:ef7eb2e8f9f7 1383 {
<> 144:ef7eb2e8f9f7 1384 case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0:
<> 144:ef7eb2e8f9f7 1385 vrefLow = DEVINFO->DCDCLPVCTRL2;
<> 144:ef7eb2e8f9f7 1386 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1387 >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1388 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1389 >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1390 break;
<> 144:ef7eb2e8f9f7 1391
<> 144:ef7eb2e8f9f7 1392 case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1:
<> 144:ef7eb2e8f9f7 1393 vrefLow = DEVINFO->DCDCLPVCTRL2;
<> 144:ef7eb2e8f9f7 1394 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1395 >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1396 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1397 >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1398 break;
<> 144:ef7eb2e8f9f7 1399
<> 144:ef7eb2e8f9f7 1400 case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS2:
<> 144:ef7eb2e8f9f7 1401 vrefLow = DEVINFO->DCDCLPVCTRL3;
<> 144:ef7eb2e8f9f7 1402 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1403 >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1404 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1405 >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1406 break;
<> 144:ef7eb2e8f9f7 1407
<> 144:ef7eb2e8f9f7 1408 case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS3:
<> 144:ef7eb2e8f9f7 1409 vrefLow = DEVINFO->DCDCLPVCTRL3;
<> 144:ef7eb2e8f9f7 1410 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1411 >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1412 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1413 >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1414 break;
<> 144:ef7eb2e8f9f7 1415
<> 144:ef7eb2e8f9f7 1416 case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0:
<> 144:ef7eb2e8f9f7 1417 vrefLow = DEVINFO->DCDCLPVCTRL0;
<> 144:ef7eb2e8f9f7 1418 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1419 >> _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1420 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1421 >> _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1422 break;
<> 144:ef7eb2e8f9f7 1423
<> 144:ef7eb2e8f9f7 1424 case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1:
<> 144:ef7eb2e8f9f7 1425 vrefLow = DEVINFO->DCDCLPVCTRL0;
<> 144:ef7eb2e8f9f7 1426 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1427 >> _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1428 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1429 >> _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1430 break;
<> 144:ef7eb2e8f9f7 1431
<> 144:ef7eb2e8f9f7 1432 case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS2:
<> 144:ef7eb2e8f9f7 1433 vrefLow = DEVINFO->DCDCLPVCTRL1;
<> 144:ef7eb2e8f9f7 1434 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1435 >> _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1436 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1437 >> _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1438 break;
<> 144:ef7eb2e8f9f7 1439
<> 144:ef7eb2e8f9f7 1440 case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS3:
<> 144:ef7eb2e8f9f7 1441 vrefLow = DEVINFO->DCDCLPVCTRL1;
<> 144:ef7eb2e8f9f7 1442 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1443 >> _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1444 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1445 >> _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1446 break;
<> 144:ef7eb2e8f9f7 1447
<> 144:ef7eb2e8f9f7 1448 default:
<> 144:ef7eb2e8f9f7 1449 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1450 break;
<> 144:ef7eb2e8f9f7 1451 }
<> 144:ef7eb2e8f9f7 1452
<> 144:ef7eb2e8f9f7 1453 /* Load LP comparator hysteresis calibration */
<> 144:ef7eb2e8f9f7 1454 if(!(LpCmpHystCalibrationLoad(attSet, lpcmpBias >> _EMU_DCDCMISCCTRL_LPCMPBIAS_SHIFT)))
<> 144:ef7eb2e8f9f7 1455 {
<> 144:ef7eb2e8f9f7 1456 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1457 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1458 return false;
<> 144:ef7eb2e8f9f7 1459 }
<> 144:ef7eb2e8f9f7 1460 } /* Low-nise / low-power mode */
<> 144:ef7eb2e8f9f7 1461
<> 144:ef7eb2e8f9f7 1462
<> 144:ef7eb2e8f9f7 1463 /* Check for valid 2-point trim values */
<> 144:ef7eb2e8f9f7 1464 if ((vrefLow == 0xFF) && (vrefHigh == 0xFF))
<> 144:ef7eb2e8f9f7 1465 {
<> 144:ef7eb2e8f9f7 1466 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1467 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1468 return false;
<> 144:ef7eb2e8f9f7 1469 }
<> 144:ef7eb2e8f9f7 1470
<> 144:ef7eb2e8f9f7 1471 /* Calculate and set voltage trim */
<> 144:ef7eb2e8f9f7 1472 vrefVal = ((mV - mVlow) * (vrefHigh - vrefLow)) / (mVhigh - mVlow);
<> 144:ef7eb2e8f9f7 1473 vrefVal += vrefLow;
<> 144:ef7eb2e8f9f7 1474
<> 144:ef7eb2e8f9f7 1475 /* Range check */
<> 144:ef7eb2e8f9f7 1476 if ((vrefVal > vrefHigh) || (vrefVal < vrefLow))
<> 144:ef7eb2e8f9f7 1477 {
<> 144:ef7eb2e8f9f7 1478 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1479 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1480 return false;
<> 144:ef7eb2e8f9f7 1481 }
<> 144:ef7eb2e8f9f7 1482
<> 144:ef7eb2e8f9f7 1483 /* Update DCDCLNVCTRL/DCDCLPVCTRL */
<> 144:ef7eb2e8f9f7 1484 *ctrlReg = (vrefVal << vrefShift) | attMask;
<> 144:ef7eb2e8f9f7 1485 }
<> 144:ef7eb2e8f9f7 1486 #endif
<> 144:ef7eb2e8f9f7 1487 return true;
<> 144:ef7eb2e8f9f7 1488 }
<> 144:ef7eb2e8f9f7 1489
<> 144:ef7eb2e8f9f7 1490
<> 144:ef7eb2e8f9f7 1491 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1492 * @brief
<> 144:ef7eb2e8f9f7 1493 * Optimize DCDC slice count based on the estimated average load current
<> 144:ef7eb2e8f9f7 1494 * in EM0
<> 144:ef7eb2e8f9f7 1495 *
<> 144:ef7eb2e8f9f7 1496 * @param[in] mAEm0LoadCurrent
<> 144:ef7eb2e8f9f7 1497 * Estimated average EM0 load current in mA.
<> 144:ef7eb2e8f9f7 1498 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1499 void EMU_DCDCOptimizeSlice(uint32_t mAEm0LoadCurrent)
<> 144:ef7eb2e8f9f7 1500 {
<> 144:ef7eb2e8f9f7 1501 uint32_t sliceCount = 0;
<> 144:ef7eb2e8f9f7 1502 uint32_t rcoBand = (EMU->DCDCLNFREQCTRL & _EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
<> 144:ef7eb2e8f9f7 1503 >> _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT;
<> 144:ef7eb2e8f9f7 1504
<> 144:ef7eb2e8f9f7 1505 /* Set recommended slice count */
<> 144:ef7eb2e8f9f7 1506 if ((EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK) && (rcoBand >= EMU_DcdcLnRcoBand_5MHz))
<> 144:ef7eb2e8f9f7 1507 {
<> 144:ef7eb2e8f9f7 1508 if (mAEm0LoadCurrent < 20)
<> 144:ef7eb2e8f9f7 1509 {
<> 144:ef7eb2e8f9f7 1510 sliceCount = 4;
<> 144:ef7eb2e8f9f7 1511 }
<> 144:ef7eb2e8f9f7 1512 else if ((mAEm0LoadCurrent >= 20) && (mAEm0LoadCurrent < 40))
<> 144:ef7eb2e8f9f7 1513 {
<> 144:ef7eb2e8f9f7 1514 sliceCount = 8;
<> 144:ef7eb2e8f9f7 1515 }
<> 144:ef7eb2e8f9f7 1516 else
<> 144:ef7eb2e8f9f7 1517 {
<> 144:ef7eb2e8f9f7 1518 sliceCount = 16;
<> 144:ef7eb2e8f9f7 1519 }
<> 144:ef7eb2e8f9f7 1520 }
<> 144:ef7eb2e8f9f7 1521 else if ((!(EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK)) && (rcoBand <= EMU_DcdcLnRcoBand_4MHz))
<> 144:ef7eb2e8f9f7 1522 {
<> 144:ef7eb2e8f9f7 1523 if (mAEm0LoadCurrent < 10)
<> 144:ef7eb2e8f9f7 1524 {
<> 144:ef7eb2e8f9f7 1525 sliceCount = 4;
<> 144:ef7eb2e8f9f7 1526 }
<> 144:ef7eb2e8f9f7 1527 else if ((mAEm0LoadCurrent >= 10) && (mAEm0LoadCurrent < 20))
<> 144:ef7eb2e8f9f7 1528 {
<> 144:ef7eb2e8f9f7 1529 sliceCount = 8;
<> 144:ef7eb2e8f9f7 1530 }
<> 144:ef7eb2e8f9f7 1531 else
<> 144:ef7eb2e8f9f7 1532 {
<> 144:ef7eb2e8f9f7 1533 sliceCount = 16;
<> 144:ef7eb2e8f9f7 1534 }
<> 144:ef7eb2e8f9f7 1535 }
<> 144:ef7eb2e8f9f7 1536 else if ((EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK) && (rcoBand <= EMU_DcdcLnRcoBand_4MHz))
<> 144:ef7eb2e8f9f7 1537 {
<> 144:ef7eb2e8f9f7 1538 if (mAEm0LoadCurrent < 40)
<> 144:ef7eb2e8f9f7 1539 {
<> 144:ef7eb2e8f9f7 1540 sliceCount = 8;
<> 144:ef7eb2e8f9f7 1541 }
<> 144:ef7eb2e8f9f7 1542 else
<> 144:ef7eb2e8f9f7 1543 {
<> 144:ef7eb2e8f9f7 1544 sliceCount = 16;
<> 144:ef7eb2e8f9f7 1545 }
<> 144:ef7eb2e8f9f7 1546 }
<> 144:ef7eb2e8f9f7 1547 else
<> 144:ef7eb2e8f9f7 1548 {
<> 144:ef7eb2e8f9f7 1549 /* This configuration is not recommended. EMU_DCDCInit() applies a recommended
<> 144:ef7eb2e8f9f7 1550 configuration. */
<> 144:ef7eb2e8f9f7 1551 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1552 }
<> 144:ef7eb2e8f9f7 1553
<> 144:ef7eb2e8f9f7 1554 /* The selected silices are PSLICESEL + 1 */
<> 144:ef7eb2e8f9f7 1555 sliceCount--;
<> 144:ef7eb2e8f9f7 1556
<> 144:ef7eb2e8f9f7 1557 /* Apply slice count to both N and P slice */
<> 144:ef7eb2e8f9f7 1558 sliceCount = (sliceCount << _EMU_DCDCMISCCTRL_PFETCNT_SHIFT
<> 144:ef7eb2e8f9f7 1559 | sliceCount << _EMU_DCDCMISCCTRL_NFETCNT_SHIFT);
<> 144:ef7eb2e8f9f7 1560 EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_PFETCNT_MASK
<> 144:ef7eb2e8f9f7 1561 | _EMU_DCDCMISCCTRL_NFETCNT_MASK))
<> 144:ef7eb2e8f9f7 1562 | sliceCount;
<> 144:ef7eb2e8f9f7 1563
<> 144:ef7eb2e8f9f7 1564 /* Update current limit configuration as it depends on the slice configuration. */
<> 144:ef7eb2e8f9f7 1565 maxCurrentUpdate();
<> 144:ef7eb2e8f9f7 1566 }
<> 144:ef7eb2e8f9f7 1567
<> 144:ef7eb2e8f9f7 1568 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1569 * @brief
<> 144:ef7eb2e8f9f7 1570 * Set DCDC Low-noise RCO band.
<> 144:ef7eb2e8f9f7 1571 *
<> 144:ef7eb2e8f9f7 1572 * @param[in] band
<> 144:ef7eb2e8f9f7 1573 * RCO band to set.
<> 144:ef7eb2e8f9f7 1574 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1575 void EMU_DCDCLnRcoBandSet(EMU_DcdcLnRcoBand_TypeDef band)
<> 144:ef7eb2e8f9f7 1576 {
<> 144:ef7eb2e8f9f7 1577 EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
<> 144:ef7eb2e8f9f7 1578 | (band << _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);
<> 144:ef7eb2e8f9f7 1579 }
<> 144:ef7eb2e8f9f7 1580
<> 144:ef7eb2e8f9f7 1581 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1582 * @brief
<> 144:ef7eb2e8f9f7 1583 * Power off the DCDC regulator.
<> 144:ef7eb2e8f9f7 1584 *
<> 144:ef7eb2e8f9f7 1585 * @details
<> 144:ef7eb2e8f9f7 1586 * This function powers off the DCDC controller. This function should only be
<> 144:ef7eb2e8f9f7 1587 * used if the external power circuit is wired for no DCDC. If the external power
<> 144:ef7eb2e8f9f7 1588 * circuit is wired for DCDC usage, then use EMU_DCDCInit() and set the
<> 144:ef7eb2e8f9f7 1589 * DCDC in bypass mode to disable DCDC.
<> 144:ef7eb2e8f9f7 1590 *
<> 144:ef7eb2e8f9f7 1591 * @return
<> 144:ef7eb2e8f9f7 1592 * Return false if the DCDC could not be disabled.
<> 144:ef7eb2e8f9f7 1593 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1594 bool EMU_DCDCPowerOff(void)
<> 144:ef7eb2e8f9f7 1595 {
<> 144:ef7eb2e8f9f7 1596 /* Set power configuration to hard bypass */
<> 144:ef7eb2e8f9f7 1597 EMU->PWRCFG = 0xF;
<> 144:ef7eb2e8f9f7 1598 if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) != 0xF)
<> 144:ef7eb2e8f9f7 1599 {
<> 144:ef7eb2e8f9f7 1600 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1601 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1602 return false;
<> 144:ef7eb2e8f9f7 1603 }
<> 144:ef7eb2e8f9f7 1604
<> 144:ef7eb2e8f9f7 1605 /* Set DCDC to OFF and disable LP in EM2/3/4 */
<> 144:ef7eb2e8f9f7 1606 EMU->DCDCCTRL = EMU_DCDCCTRL_DCDCMODE_OFF;
<> 144:ef7eb2e8f9f7 1607 return true;
<> 144:ef7eb2e8f9f7 1608 }
<> 144:ef7eb2e8f9f7 1609 #endif
<> 144:ef7eb2e8f9f7 1610
<> 144:ef7eb2e8f9f7 1611
<> 144:ef7eb2e8f9f7 1612 #if defined( EMU_STATUS_VMONRDY )
<> 144:ef7eb2e8f9f7 1613 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 1614 __STATIC_INLINE uint32_t vmonMilliVoltToCoarseThreshold(int mV)
<> 144:ef7eb2e8f9f7 1615 {
<> 144:ef7eb2e8f9f7 1616 return (mV - 1200) / 200;
<> 144:ef7eb2e8f9f7 1617 }
<> 144:ef7eb2e8f9f7 1618
<> 144:ef7eb2e8f9f7 1619 __STATIC_INLINE uint32_t vmonMilliVoltToFineThreshold(int mV, uint32_t coarseThreshold)
<> 144:ef7eb2e8f9f7 1620 {
<> 144:ef7eb2e8f9f7 1621 return (mV - 1200 - (coarseThreshold * 200)) / 20;
<> 144:ef7eb2e8f9f7 1622 }
<> 144:ef7eb2e8f9f7 1623 /** @endcond */
<> 144:ef7eb2e8f9f7 1624
<> 144:ef7eb2e8f9f7 1625 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1626 * @brief
<> 144:ef7eb2e8f9f7 1627 * Initialize VMON channel.
<> 144:ef7eb2e8f9f7 1628 *
<> 144:ef7eb2e8f9f7 1629 * @details
<> 144:ef7eb2e8f9f7 1630 * Initialize a VMON channel without hysteresis. If the channel supports
<> 144:ef7eb2e8f9f7 1631 * separate rise and fall triggers, both thresholds will be set to the same
<> 144:ef7eb2e8f9f7 1632 * value.
<> 144:ef7eb2e8f9f7 1633 *
<> 144:ef7eb2e8f9f7 1634 * @param[in] vmonInit
<> 144:ef7eb2e8f9f7 1635 * VMON initialization struct
<> 144:ef7eb2e8f9f7 1636 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1637 void EMU_VmonInit(EMU_VmonInit_TypeDef *vmonInit)
<> 144:ef7eb2e8f9f7 1638 {
<> 144:ef7eb2e8f9f7 1639 uint32_t thresholdCoarse, thresholdFine;
<> 144:ef7eb2e8f9f7 1640 EFM_ASSERT((vmonInit->threshold >= 1200) && (vmonInit->threshold <= 3980));
<> 144:ef7eb2e8f9f7 1641
<> 144:ef7eb2e8f9f7 1642 thresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->threshold);
<> 144:ef7eb2e8f9f7 1643 thresholdFine = vmonMilliVoltToFineThreshold(vmonInit->threshold, thresholdCoarse);
<> 144:ef7eb2e8f9f7 1644
<> 144:ef7eb2e8f9f7 1645 switch(vmonInit->channel)
<> 144:ef7eb2e8f9f7 1646 {
<> 144:ef7eb2e8f9f7 1647 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 1648 EMU->VMONAVDDCTRL = (thresholdCoarse << _EMU_VMONAVDDCTRL_RISETHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 1649 | (thresholdFine << _EMU_VMONAVDDCTRL_RISETHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 1650 | (thresholdCoarse << _EMU_VMONAVDDCTRL_FALLTHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 1651 | (thresholdFine << _EMU_VMONAVDDCTRL_FALLTHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 1652 | (vmonInit->riseWakeup ? EMU_VMONAVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 1653 | (vmonInit->fallWakeup ? EMU_VMONAVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 1654 | (vmonInit->enable ? EMU_VMONAVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 1655 break;
<> 144:ef7eb2e8f9f7 1656 case emuVmonChannel_ALTAVDD:
<> 144:ef7eb2e8f9f7 1657 EMU->VMONALTAVDDCTRL = (thresholdCoarse << _EMU_VMONALTAVDDCTRL_THRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 1658 | (thresholdFine << _EMU_VMONALTAVDDCTRL_THRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 1659 | (vmonInit->riseWakeup ? EMU_VMONALTAVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 1660 | (vmonInit->fallWakeup ? EMU_VMONALTAVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 1661 | (vmonInit->enable ? EMU_VMONALTAVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 1662 break;
<> 144:ef7eb2e8f9f7 1663 case emuVmonChannel_DVDD:
<> 144:ef7eb2e8f9f7 1664 EMU->VMONDVDDCTRL = (thresholdCoarse << _EMU_VMONDVDDCTRL_THRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 1665 | (thresholdFine << _EMU_VMONDVDDCTRL_THRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 1666 | (vmonInit->riseWakeup ? EMU_VMONDVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 1667 | (vmonInit->fallWakeup ? EMU_VMONDVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 1668 | (vmonInit->enable ? EMU_VMONDVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 1669 break;
<> 144:ef7eb2e8f9f7 1670 case emuVmonChannel_IOVDD0:
<> 144:ef7eb2e8f9f7 1671 EMU->VMONIO0CTRL = (thresholdCoarse << _EMU_VMONIO0CTRL_THRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 1672 | (thresholdFine << _EMU_VMONIO0CTRL_THRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 1673 | (vmonInit->retDisable ? EMU_VMONIO0CTRL_RETDIS : 0)
<> 144:ef7eb2e8f9f7 1674 | (vmonInit->riseWakeup ? EMU_VMONIO0CTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 1675 | (vmonInit->fallWakeup ? EMU_VMONIO0CTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 1676 | (vmonInit->enable ? EMU_VMONIO0CTRL_EN : 0);
<> 144:ef7eb2e8f9f7 1677 break;
<> 144:ef7eb2e8f9f7 1678 default:
<> 144:ef7eb2e8f9f7 1679 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1680 return;
<> 144:ef7eb2e8f9f7 1681 }
<> 144:ef7eb2e8f9f7 1682 }
<> 144:ef7eb2e8f9f7 1683
<> 144:ef7eb2e8f9f7 1684 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1685 * @brief
<> 144:ef7eb2e8f9f7 1686 * Initialize VMON channel with hysteresis (separate rise and fall triggers).
<> 144:ef7eb2e8f9f7 1687 *
<> 144:ef7eb2e8f9f7 1688 * @details
<> 144:ef7eb2e8f9f7 1689 * Initialize a VMON channel which supports hysteresis. The AVDD channel is
<> 144:ef7eb2e8f9f7 1690 * the only channel to support separate rise and fall triggers.
<> 144:ef7eb2e8f9f7 1691 *
<> 144:ef7eb2e8f9f7 1692 * @param[in] vmonInit
<> 144:ef7eb2e8f9f7 1693 * VMON Hysteresis initialization struct
<> 144:ef7eb2e8f9f7 1694 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1695 void EMU_VmonHystInit(EMU_VmonHystInit_TypeDef *vmonInit)
<> 144:ef7eb2e8f9f7 1696 {
<> 144:ef7eb2e8f9f7 1697 uint32_t riseThresholdCoarse, riseThresholdFine, fallThresholdCoarse, fallThresholdFine;
<> 144:ef7eb2e8f9f7 1698 /* VMON supports voltages between 1200 mV and 3980 mV (inclusive) in 20 mV increments */
<> 144:ef7eb2e8f9f7 1699 EFM_ASSERT((vmonInit->riseThreshold >= 1200) && (vmonInit->riseThreshold < 4000));
<> 144:ef7eb2e8f9f7 1700 EFM_ASSERT((vmonInit->fallThreshold >= 1200) && (vmonInit->fallThreshold < 4000));
<> 144:ef7eb2e8f9f7 1701 /* Fall threshold has to be lower than rise threshold */
<> 144:ef7eb2e8f9f7 1702 EFM_ASSERT(vmonInit->fallThreshold <= vmonInit->riseThreshold);
<> 144:ef7eb2e8f9f7 1703
<> 144:ef7eb2e8f9f7 1704 riseThresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->riseThreshold);
<> 144:ef7eb2e8f9f7 1705 riseThresholdFine = vmonMilliVoltToFineThreshold(vmonInit->riseThreshold, riseThresholdCoarse);
<> 144:ef7eb2e8f9f7 1706 fallThresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->fallThreshold);
<> 144:ef7eb2e8f9f7 1707 fallThresholdFine = vmonMilliVoltToFineThreshold(vmonInit->fallThreshold, fallThresholdCoarse);
<> 144:ef7eb2e8f9f7 1708
<> 144:ef7eb2e8f9f7 1709 switch(vmonInit->channel)
<> 144:ef7eb2e8f9f7 1710 {
<> 144:ef7eb2e8f9f7 1711 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 1712 EMU->VMONAVDDCTRL = (riseThresholdCoarse << _EMU_VMONAVDDCTRL_RISETHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 1713 | (riseThresholdFine << _EMU_VMONAVDDCTRL_RISETHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 1714 | (fallThresholdCoarse << _EMU_VMONAVDDCTRL_FALLTHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 1715 | (fallThresholdFine << _EMU_VMONAVDDCTRL_FALLTHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 1716 | (vmonInit->riseWakeup ? EMU_VMONAVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 1717 | (vmonInit->fallWakeup ? EMU_VMONAVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 1718 | (vmonInit->enable ? EMU_VMONAVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 1719 break;
<> 144:ef7eb2e8f9f7 1720 default:
<> 144:ef7eb2e8f9f7 1721 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1722 return;
<> 144:ef7eb2e8f9f7 1723 }
<> 144:ef7eb2e8f9f7 1724 }
<> 144:ef7eb2e8f9f7 1725
<> 144:ef7eb2e8f9f7 1726 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1727 * @brief
<> 144:ef7eb2e8f9f7 1728 * Enable or disable a VMON channel
<> 144:ef7eb2e8f9f7 1729 *
<> 144:ef7eb2e8f9f7 1730 * @param[in] channel
<> 144:ef7eb2e8f9f7 1731 * VMON channel to enable/disable
<> 144:ef7eb2e8f9f7 1732 *
<> 144:ef7eb2e8f9f7 1733 * @param[in] enable
<> 144:ef7eb2e8f9f7 1734 * Whether to enable or disable
<> 144:ef7eb2e8f9f7 1735 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1736 void EMU_VmonEnable(EMU_VmonChannel_TypeDef channel, bool enable)
<> 144:ef7eb2e8f9f7 1737 {
<> 144:ef7eb2e8f9f7 1738 uint32_t volatile * reg;
<> 144:ef7eb2e8f9f7 1739 uint32_t bit;
<> 144:ef7eb2e8f9f7 1740
<> 144:ef7eb2e8f9f7 1741 switch(channel)
<> 144:ef7eb2e8f9f7 1742 {
<> 144:ef7eb2e8f9f7 1743 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 1744 reg = &(EMU->VMONAVDDCTRL);
<> 144:ef7eb2e8f9f7 1745 bit = _EMU_VMONAVDDCTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 1746 break;
<> 144:ef7eb2e8f9f7 1747 case emuVmonChannel_ALTAVDD:
<> 144:ef7eb2e8f9f7 1748 reg = &(EMU->VMONALTAVDDCTRL);
<> 144:ef7eb2e8f9f7 1749 bit = _EMU_VMONALTAVDDCTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 1750 break;
<> 144:ef7eb2e8f9f7 1751 case emuVmonChannel_DVDD:
<> 144:ef7eb2e8f9f7 1752 reg = &(EMU->VMONDVDDCTRL);
<> 144:ef7eb2e8f9f7 1753 bit = _EMU_VMONDVDDCTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 1754 break;
<> 144:ef7eb2e8f9f7 1755 case emuVmonChannel_IOVDD0:
<> 144:ef7eb2e8f9f7 1756 reg = &(EMU->VMONIO0CTRL);
<> 144:ef7eb2e8f9f7 1757 bit = _EMU_VMONIO0CTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 1758 break;
<> 144:ef7eb2e8f9f7 1759 default:
<> 144:ef7eb2e8f9f7 1760 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1761 return;
<> 144:ef7eb2e8f9f7 1762 }
<> 144:ef7eb2e8f9f7 1763
<> 144:ef7eb2e8f9f7 1764 BUS_RegBitWrite(reg, bit, enable);
<> 144:ef7eb2e8f9f7 1765 }
<> 144:ef7eb2e8f9f7 1766
<> 144:ef7eb2e8f9f7 1767 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1768 * @brief
<> 144:ef7eb2e8f9f7 1769 * Get the status of a voltage monitor channel.
<> 144:ef7eb2e8f9f7 1770 *
<> 144:ef7eb2e8f9f7 1771 * @param[in] channel
<> 144:ef7eb2e8f9f7 1772 * VMON channel to get status for
<> 144:ef7eb2e8f9f7 1773 *
<> 144:ef7eb2e8f9f7 1774 * @return
<> 144:ef7eb2e8f9f7 1775 * Status of the selected VMON channel. True if channel is triggered.
<> 144:ef7eb2e8f9f7 1776 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1777 bool EMU_VmonChannelStatusGet(EMU_VmonChannel_TypeDef channel)
<> 144:ef7eb2e8f9f7 1778 {
<> 144:ef7eb2e8f9f7 1779 uint32_t bit;
<> 144:ef7eb2e8f9f7 1780 switch(channel)
<> 144:ef7eb2e8f9f7 1781 {
<> 144:ef7eb2e8f9f7 1782 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 1783 bit = _EMU_STATUS_VMONAVDD_SHIFT;
<> 144:ef7eb2e8f9f7 1784 break;
<> 144:ef7eb2e8f9f7 1785 case emuVmonChannel_ALTAVDD:
<> 144:ef7eb2e8f9f7 1786 bit = _EMU_STATUS_VMONALTAVDD_SHIFT;
<> 144:ef7eb2e8f9f7 1787 break;
<> 144:ef7eb2e8f9f7 1788 case emuVmonChannel_DVDD:
<> 144:ef7eb2e8f9f7 1789 bit = _EMU_STATUS_VMONDVDD_SHIFT;
<> 144:ef7eb2e8f9f7 1790 break;
<> 144:ef7eb2e8f9f7 1791 case emuVmonChannel_IOVDD0:
<> 144:ef7eb2e8f9f7 1792 bit = _EMU_STATUS_VMONIO0_SHIFT;
<> 144:ef7eb2e8f9f7 1793 break;
<> 144:ef7eb2e8f9f7 1794 default:
<> 144:ef7eb2e8f9f7 1795 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1796 bit = 0;
<> 144:ef7eb2e8f9f7 1797 }
<> 144:ef7eb2e8f9f7 1798
<> 144:ef7eb2e8f9f7 1799 return BUS_RegBitRead(&EMU->STATUS, bit);
<> 144:ef7eb2e8f9f7 1800 }
<> 144:ef7eb2e8f9f7 1801 #endif /* EMU_STATUS_VMONRDY */
<> 144:ef7eb2e8f9f7 1802
<> 144:ef7eb2e8f9f7 1803 /** @} (end addtogroup EMU) */
<> 144:ef7eb2e8f9f7 1804 /** @} (end addtogroup EM_Library) */
<> 144:ef7eb2e8f9f7 1805 #endif /* __EM_EMU_H */