em_emu.c
Go to the documentation of this file.00001
00034 #include "em_emu.h"
00035 #if defined( EMU_PRESENT ) && ( EMU_COUNT > 0 )
00036
00037 #include "em_cmu.h"
00038 #include "em_system.h"
00039 #include "em_assert.h"
00040
00041
00046
00052
00053
00054 #if (CMU_STATUS_AUXHFRCOENS != CMU_OSCENCMD_AUXHFRCOEN)
00055 #error Conflict in AUXHFRCOENS and AUXHFRCOEN bitpositions
00056 #endif
00057 #if (CMU_STATUS_HFXOENS != CMU_OSCENCMD_HFXOEN)
00058 #error Conflict in HFXOENS and HFXOEN bitpositions
00059 #endif
00060 #if (CMU_STATUS_LFRCOENS != CMU_OSCENCMD_LFRCOEN)
00061 #error Conflict in LFRCOENS and LFRCOEN bitpositions
00062 #endif
00063 #if (CMU_STATUS_LFXOENS != CMU_OSCENCMD_LFXOEN)
00064 #error Conflict in LFXOENS and LFXOEN bitpositions
00065 #endif
00066
00067
00069
00070 #if defined(_EFM32_GECKO_FAMILY)
00071 #define ERRATA_FIX_EMU_E107_EN
00072 #define NON_WIC_INT_MASK_0 (~(0x0dfc0323U))
00073 #define NON_WIC_INT_MASK_1 (~(0x0U))
00074 #elif defined(_EFM32_TINY_FAMILY)
00075 #define ERRATA_FIX_EMU_E107_EN
00076 #define NON_WIC_INT_MASK_0 (~(0x001be323U))
00077 #define NON_WIC_INT_MASK_1 (~(0x0U))
00078 #elif defined(_EFM32_GIANT_FAMILY)
00079 #define ERRATA_FIX_EMU_E107_EN
00080 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
00081 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
00082 #elif defined(_EFM32_WONDER_FAMILY)
00083 #define ERRATA_FIX_EMU_E107_EN
00084 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
00085 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
00086 #else
00087
00088 #endif
00089
00090
00091 #if defined(_EFM32_HAPPY_FAMILY)
00092 #define ERRATA_FIX_EMU_E108_EN
00093 #endif
00094
00096
00097
00098
00099
00110 static uint32_t cmuStatus;
00114
00115
00116
00117
00120
00124 static void EMU_Restore(void)
00125 {
00126 uint32_t oscEnCmd;
00127 uint32_t cmuLocked;
00128 uint32_t statusClkSelMask;
00129
00130
00131
00132
00133
00134 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
00135 CMU_Unlock();
00136
00137
00138
00139
00140
00141 oscEnCmd = 0;
00142 oscEnCmd |= ((cmuStatus & CMU_STATUS_HFRCOENS) ? CMU_OSCENCMD_HFRCOEN : 0);
00143 oscEnCmd |= ((cmuStatus & CMU_STATUS_AUXHFRCOENS) ? CMU_OSCENCMD_AUXHFRCOEN : 0);
00144 oscEnCmd |= ((cmuStatus & CMU_STATUS_LFRCOENS) ? CMU_OSCENCMD_LFRCOEN : 0);
00145 oscEnCmd |= ((cmuStatus & CMU_STATUS_HFXOENS) ? CMU_OSCENCMD_HFXOEN : 0);
00146 oscEnCmd |= ((cmuStatus & CMU_STATUS_LFXOENS) ? CMU_OSCENCMD_LFXOEN : 0);
00147 #if defined( _CMU_STATUS_USHFRCOENS_MASK )
00148 oscEnCmd |= ((cmuStatus & CMU_STATUS_USHFRCOENS) ? CMU_OSCENCMD_USHFRCOEN : 0);
00149 #endif
00150 CMU->OSCENCMD = oscEnCmd;
00151
00152 statusClkSelMask =
00153 (CMU_STATUS_HFRCOSEL |
00154 CMU_STATUS_HFXOSEL |
00155 CMU_STATUS_LFRCOSEL |
00156 #if defined( CMU_STATUS_USHFRCODIV2SEL )
00157 CMU_STATUS_USHFRCODIV2SEL |
00158 #endif
00159 CMU_STATUS_LFXOSEL);
00160
00161
00162 switch (cmuStatus & statusClkSelMask)
00163 {
00164 case CMU_STATUS_LFRCOSEL:
00165
00166 while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
00167 ;
00168 CMU->CMD = CMU_CMD_HFCLKSEL_LFRCO;
00169 break;
00170
00171 case CMU_STATUS_LFXOSEL:
00172
00173 while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
00174 ;
00175 CMU->CMD = CMU_CMD_HFCLKSEL_LFXO;
00176 break;
00177
00178 case CMU_STATUS_HFXOSEL:
00179
00180 while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
00181 ;
00182 CMU->CMD = CMU_CMD_HFCLKSEL_HFXO;
00183 break;
00184
00185 #if defined( CMU_STATUS_USHFRCODIV2SEL )
00186 case CMU_STATUS_USHFRCODIV2SEL:
00187
00188 while (!(CMU->STATUS & CMU_STATUS_USHFRCORDY))
00189 ;
00190 CMU->CMD = _CMU_CMD_HFCLKSEL_USHFRCODIV2;
00191 break;
00192 #endif
00193
00194 default:
00195
00196
00197 break;
00198 }
00199
00200
00201
00202 if ( ! (cmuStatus & CMU_STATUS_HFRCOENS) )
00203 {
00204 CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
00205 }
00206
00207
00208 if (cmuLocked)
00209 {
00210 CMU_Lock();
00211 }
00212 }
00213
00214
00215
00216 #if defined(ERRATA_FIX_EMU_E107_EN)
00217 static __INLINE bool getErrataFixEmuE107En(void)
00218 {
00219
00220 uint16_t majorMinorRev;
00221
00222
00223 majorMinorRev = (((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) >> _ROMTABLE_PID0_REVMAJOR_SHIFT) << 8);
00224
00225 majorMinorRev |= (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK) >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);
00226
00227 majorMinorRev |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
00228
00229 #if defined(_EFM32_GECKO_FAMILY)
00230 return (majorMinorRev <= 0x0103);
00231 #elif defined(_EFM32_TINY_FAMILY)
00232 return (majorMinorRev <= 0x0102);
00233 #elif defined(_EFM32_GIANT_FAMILY)
00234 return (majorMinorRev <= 0x0103) || (majorMinorRev == 0x0204);
00235 #elif defined(_EFM32_WONDER_FAMILY)
00236 return (majorMinorRev == 0x0100);
00237 #else
00238
00239 return false;
00240 #endif
00241 }
00242 #endif
00243
00247
00248
00249
00250
00251
00292 void EMU_EnterEM2(bool restore)
00293 {
00294 #if defined(ERRATA_FIX_EMU_E107_EN)
00295 bool errataFixEmuE107En;
00296 uint32_t nonWicIntEn[2];
00297 #endif
00298
00299
00300
00301 cmuStatus = CMU->STATUS;
00302
00303
00304 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
00305
00306
00307
00308 #if defined(ERRATA_FIX_EMU_E107_EN)
00309 errataFixEmuE107En = getErrataFixEmuE107En();
00310 if (errataFixEmuE107En)
00311 {
00312 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
00313 NVIC->ICER[0] = nonWicIntEn[0];
00314 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
00315 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
00316 NVIC->ICER[1] = nonWicIntEn[1];
00317 #endif
00318 }
00319 #endif
00320
00321 __WFI();
00322
00323
00324 #if defined(ERRATA_FIX_EMU_E107_EN)
00325 if (errataFixEmuE107En)
00326 {
00327 NVIC->ISER[0] = nonWicIntEn[0];
00328 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
00329 NVIC->ISER[1] = nonWicIntEn[1];
00330 #endif
00331 }
00332 #endif
00333
00334
00335 if (restore)
00336 {
00337 EMU_Restore();
00338 }
00339
00340
00341
00342 else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
00343 {
00344 SystemCoreClockUpdate();
00345 }
00346 }
00347
00348
00349
00391 void EMU_EnterEM3(bool restore)
00392 {
00393 uint32_t cmuLocked;
00394
00395 #if defined(ERRATA_FIX_EMU_E107_EN)
00396 bool errataFixEmuE107En;
00397 uint32_t nonWicIntEn[2];
00398 #endif
00399
00400
00401
00402 cmuStatus = CMU->STATUS;
00403
00404
00405 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
00406 CMU_Unlock();
00407
00408
00409 CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS | CMU_OSCENCMD_LFRCODIS;
00410
00411
00412 if (cmuLocked)
00413 {
00414 CMU_Lock();
00415 }
00416
00417
00418 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
00419
00420
00421
00422 #if defined(ERRATA_FIX_EMU_E107_EN)
00423 errataFixEmuE107En = getErrataFixEmuE107En();
00424 if (errataFixEmuE107En)
00425 {
00426 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
00427 NVIC->ICER[0] = nonWicIntEn[0];
00428 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
00429 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
00430 NVIC->ICER[1] = nonWicIntEn[1];
00431 #endif
00432
00433 }
00434 #endif
00435
00436 __WFI();
00437
00438
00439 #if defined(ERRATA_FIX_EMU_E107_EN)
00440 if (errataFixEmuE107En)
00441 {
00442 NVIC->ISER[0] = nonWicIntEn[0];
00443 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
00444 NVIC->ISER[1] = nonWicIntEn[1];
00445 #endif
00446 }
00447 #endif
00448
00449
00450 if (restore)
00451 {
00452 EMU_Restore();
00453 }
00454
00455
00456
00457 else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
00458 {
00459 SystemCoreClockUpdate();
00460 }
00461 }
00462
00463
00464
00471 void EMU_EnterEM4(void)
00472 {
00473 int i;
00474 uint32_t em4seq2;
00475 uint32_t em4seq3;
00476
00477 em4seq2 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK) | (2 << _EMU_CTRL_EM4CTRL_SHIFT);
00478 em4seq3 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK) | (3 << _EMU_CTRL_EM4CTRL_SHIFT);
00479
00480
00481 EMU_Unlock();
00482
00483 #if defined(ERRATA_FIX_EMU_E108_EN)
00484
00485 __disable_irq();
00486 *(volatile uint32_t *)0x400C80E4 = 0;
00487 #endif
00488
00489 for (i = 0; i < 4; i++)
00490 {
00491 EMU->CTRL = em4seq2;
00492 EMU->CTRL = em4seq3;
00493 }
00494 EMU->CTRL = em4seq2;
00495 }
00496
00497
00498
00513 void EMU_MemPwrDown(uint32_t blocks)
00514 {
00515 #if defined(_EMU_MEMCTRL_RESETVALUE)
00516 EFM_ASSERT(blocks <= _EMU_MEMCTRL_MASK);
00517
00518 EMU->MEMCTRL = blocks;
00519 #else
00520 (void)blocks;
00521 #endif
00522 }
00523
00524
00525
00544 void EMU_UpdateOscConfig(void)
00545 {
00546
00547 cmuStatus = CMU->STATUS;
00548 }
00549
00550
00551 #if defined( _EMU_CTRL_EMVREG_MASK ) || defined( _EMU_CTRL_EM23VREG_MASK )
00552
00559 void EMU_EM23Init(EMU_EM23Init_TypeDef *em23Init)
00560 {
00561 #if defined( _EMU_CTRL_EMVREG_MASK )
00562 EMU->CTRL = em23Init->em23Vreg ? (EMU->CTRL | EMU_CTRL_EMVREG) : (EMU->CTRL & ~EMU_CTRL_EMVREG);
00563 #elif defined( _EMU_CTRL_EM23VREG_MASK )
00564 EMU->CTRL = em23Init->em23Vreg ? (EMU->CTRL | EMU_CTRL_EM23VREG) : (EMU->CTRL & ~EMU_CTRL_EM23VREG);
00565 #endif
00566 }
00567 #endif
00568
00569
00570 #if defined( _EMU_EM4CONF_MASK )
00571
00578 void EMU_EM4Init(EMU_EM4Init_TypeDef *em4Init)
00579 {
00580 uint32_t em4conf = EMU->EM4CONF;
00581
00582
00583 em4conf &= ~(
00584 _EMU_EM4CONF_LOCKCONF_MASK |
00585 _EMU_EM4CONF_OSC_MASK |
00586 _EMU_EM4CONF_BURTCWU_MASK |
00587 _EMU_EM4CONF_VREGEN_MASK);
00588
00589
00590 em4conf |= (
00591 (em4Init->lockConfig << _EMU_EM4CONF_LOCKCONF_SHIFT) |
00592 (em4Init->osc) |
00593 (em4Init->buRtcWakeup << _EMU_EM4CONF_BURTCWU_SHIFT) |
00594 (em4Init->vreg << _EMU_EM4CONF_VREGEN_SHIFT));
00595
00596
00597 EMU->EM4CONF = em4conf;
00598 }
00599 #endif
00600
00601
00602 #if defined( BU_PRESENT )
00603
00604
00611 void EMU_BUPDInit(EMU_BUPDInit_TypeDef *bupdInit)
00612 {
00613 uint32_t reg;
00614
00615
00616 reg = EMU->PWRCONF & ~(
00617 _EMU_PWRCONF_PWRRES_MASK|
00618 _EMU_PWRCONF_VOUTSTRONG_MASK|
00619 _EMU_PWRCONF_VOUTMED_MASK|
00620 _EMU_PWRCONF_VOUTWEAK_MASK);
00621
00622 reg |= (bupdInit->resistor|
00623 (bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)|
00624 (bupdInit->voutMed << _EMU_PWRCONF_VOUTMED_SHIFT)|
00625 (bupdInit->voutWeak << _EMU_PWRCONF_VOUTWEAK_SHIFT));
00626
00627 EMU->PWRCONF = reg;
00628
00629
00630 reg = EMU->BUINACT & ~(_EMU_BUINACT_PWRCON_MASK);
00631 reg |= (bupdInit->inactivePower);
00632 EMU->BUINACT = reg;
00633
00634
00635 reg = EMU->BUACT & ~(_EMU_BUACT_PWRCON_MASK);
00636 reg |= (bupdInit->activePower);
00637 EMU->BUACT = reg;
00638
00639
00640 reg = EMU->BUCTRL & ~(
00641 _EMU_BUCTRL_PROBE_MASK|
00642 _EMU_BUCTRL_BODCAL_MASK|
00643 _EMU_BUCTRL_STATEN_MASK|
00644 _EMU_BUCTRL_EN_MASK);
00645
00646
00647
00648 reg |= (bupdInit->probe|
00649 (bupdInit->bodCal << _EMU_BUCTRL_BODCAL_SHIFT)|
00650 (bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)|
00651 (bupdInit->enable << _EMU_BUCTRL_EN_SHIFT));
00652
00653
00654 EMU->BUCTRL = reg;
00655
00656
00657 EMU_BUPinEnable(bupdInit->enable);
00658
00659
00660 BITBAND_Peripheral(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);
00661 }
00662
00663
00664
00672 void EMU_BUThresholdSet(EMU_BODMode_TypeDef mode, uint32_t value)
00673 {
00674 EFM_ASSERT(value<=(_EMU_BUACT_BUEXTHRES_MASK>>_EMU_BUACT_BUEXTHRES_SHIFT));
00675
00676 switch(mode)
00677 {
00678 case emuBODMode_Active:
00679 EMU->BUACT = (EMU->BUACT & ~(_EMU_BUACT_BUEXTHRES_MASK))|(value<<_EMU_BUACT_BUEXTHRES_SHIFT);
00680 break;
00681 case emuBODMode_Inactive:
00682 EMU->BUINACT = (EMU->BUINACT & ~(_EMU_BUINACT_BUENTHRES_MASK))|(value<<_EMU_BUINACT_BUENTHRES_SHIFT);
00683 break;
00684 }
00685 }
00686
00687
00688
00696 void EMU_BUThresRangeSet(EMU_BODMode_TypeDef mode, uint32_t value)
00697 {
00698 EFM_ASSERT(value<=(_EMU_BUACT_BUEXRANGE_MASK>>_EMU_BUACT_BUEXRANGE_SHIFT));
00699
00700 switch(mode)
00701 {
00702 case emuBODMode_Active:
00703 EMU->BUACT = (EMU->BUACT & ~(_EMU_BUACT_BUEXRANGE_MASK))|(value<<_EMU_BUACT_BUEXRANGE_SHIFT);
00704 break;
00705 case emuBODMode_Inactive:
00706 EMU->BUINACT = (EMU->BUINACT & ~(_EMU_BUINACT_BUENRANGE_MASK))|(value<<_EMU_BUINACT_BUENRANGE_SHIFT);
00707 break;
00708 }
00709 }
00710
00711 #endif
00712
00713
00716 #endif