em_emu.c
Go to the documentation of this file.00001
00034 #include "em_emu.h"
00035 #if defined( EMU_PRESENT )
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
00091
00092
00093
00094
00105 static uint16_t cmuStatus;
00109
00110
00111
00112
00115
00119 static void EMU_Restore(void)
00120 {
00121 uint32_t cmuLocked;
00122
00123
00124
00125
00126
00127 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
00128 CMU_Unlock();
00129
00130
00131
00132
00133
00134 CMU->OSCENCMD = cmuStatus & (CMU_STATUS_AUXHFRCOENS |
00135 CMU_STATUS_HFXOENS |
00136 CMU_STATUS_LFRCOENS |
00137 CMU_STATUS_LFXOENS);
00138
00139
00140 switch (cmuStatus & (CMU_STATUS_HFXOSEL | CMU_STATUS_HFRCOSEL |
00141 CMU_STATUS_LFXOSEL | CMU_STATUS_LFRCOSEL))
00142 {
00143 case CMU_STATUS_LFRCOSEL:
00144
00145 while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
00146 ;
00147 CMU->CMD = CMU_CMD_HFCLKSEL_LFRCO;
00148 break;
00149
00150 case CMU_STATUS_LFXOSEL:
00151
00152 while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
00153 ;
00154 CMU->CMD = CMU_CMD_HFCLKSEL_LFXO;
00155 break;
00156
00157 case CMU_STATUS_HFXOSEL:
00158
00159 while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
00160 ;
00161 CMU->CMD = CMU_CMD_HFCLKSEL_HFXO;
00162 break;
00163
00164 default:
00165
00166
00167 break;
00168 }
00169
00170
00171
00172 if ( ! (cmuStatus & CMU_STATUS_HFRCOENS) )
00173 {
00174 CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
00175 }
00176
00177
00178 if (cmuLocked)
00179 {
00180 CMU_Lock();
00181 }
00182 }
00183
00184
00185
00186 #if defined(ERRATA_FIX_EMU_E107_EN)
00187 static __INLINE bool getErrataFixEmuE107En(void)
00188 {
00189
00190 uint16_t majorMinorRev;
00191
00192
00193 majorMinorRev = (((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) >> _ROMTABLE_PID0_REVMAJOR_SHIFT) << 8);
00194
00195 majorMinorRev |= (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK) >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);
00196
00197 majorMinorRev |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
00198
00199 #if defined(_EFM32_GECKO_FAMILY)
00200 return (majorMinorRev <= 0x0103);
00201 #elif defined(_EFM32_TINY_FAMILY)
00202 return (majorMinorRev <= 0x0102);
00203 #elif defined(_EFM32_GIANT_FAMILY)
00204 return (majorMinorRev <= 0x0103) || (majorMinorRev == 0x0204);
00205 #elif defined(_EFM32_WONDER_FAMILY)
00206 return (majorMinorRev == 0x0100);
00207 #else
00208
00209 return false;
00210 #endif
00211 }
00212 #endif
00213
00217
00218
00219
00220
00221
00262 void EMU_EnterEM2(bool restore)
00263 {
00264 #if defined(ERRATA_FIX_EMU_E107_EN)
00265 bool errataFixEmuE107En;
00266 uint32_t nonWicIntEn[2];
00267 #endif
00268
00269
00270
00271 cmuStatus = (uint16_t)(CMU->STATUS);
00272
00273
00274 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
00275
00276
00277
00278 #if defined(ERRATA_FIX_EMU_E107_EN)
00279 errataFixEmuE107En = getErrataFixEmuE107En();
00280 if (errataFixEmuE107En)
00281 {
00282 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
00283 NVIC->ICER[0] = nonWicIntEn[0];
00284 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
00285 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
00286 NVIC->ICER[1] = nonWicIntEn[1];
00287 #endif
00288 }
00289 #endif
00290
00291 __WFI();
00292
00293
00294 #if defined(ERRATA_FIX_EMU_E107_EN)
00295 if (errataFixEmuE107En)
00296 {
00297 NVIC->ISER[0] = nonWicIntEn[0];
00298 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
00299 NVIC->ISER[1] = nonWicIntEn[1];
00300 #endif
00301 }
00302 #endif
00303
00304
00305 if (restore)
00306 {
00307 EMU_Restore();
00308 }
00309
00310
00311
00312 else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
00313 {
00314 SystemCoreClockUpdate();
00315 }
00316 }
00317
00318
00319
00361 void EMU_EnterEM3(bool restore)
00362 {
00363 uint32_t cmuLocked;
00364
00365 #if defined(ERRATA_FIX_EMU_E107_EN)
00366 bool errataFixEmuE107En;
00367 uint32_t nonWicIntEn[2];
00368 #endif
00369
00370
00371
00372 cmuStatus = (uint16_t)(CMU->STATUS);
00373
00374
00375 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
00376 CMU_Unlock();
00377
00378
00379 CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS | CMU_OSCENCMD_LFRCODIS;
00380
00381
00382 if (cmuLocked)
00383 {
00384 CMU_Lock();
00385 }
00386
00387
00388 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
00389
00390
00391
00392 #if defined(ERRATA_FIX_EMU_E107_EN)
00393 errataFixEmuE107En = getErrataFixEmuE107En();
00394 if (errataFixEmuE107En)
00395 {
00396 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
00397 NVIC->ICER[0] = nonWicIntEn[0];
00398 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
00399 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
00400 NVIC->ICER[1] = nonWicIntEn[1];
00401 #endif
00402
00403 }
00404 #endif
00405
00406 __WFI();
00407
00408
00409 #if defined(ERRATA_FIX_EMU_E107_EN)
00410 if (errataFixEmuE107En)
00411 {
00412 NVIC->ISER[0] = nonWicIntEn[0];
00413 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
00414 NVIC->ISER[1] = nonWicIntEn[1];
00415 #endif
00416 }
00417 #endif
00418
00419
00420 if (restore)
00421 {
00422 EMU_Restore();
00423 }
00424
00425
00426
00427 else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
00428 {
00429 SystemCoreClockUpdate();
00430 }
00431 }
00432
00433
00434
00441 void EMU_EnterEM4(void)
00442 {
00443 int i;
00444
00445
00446 EMU->LOCK = EMU_LOCK_LOCKKEY_UNLOCK;
00447
00448 for (i = 0; i < 4; i++)
00449 {
00450 EMU->CTRL = (2 << _EMU_CTRL_EM4CTRL_SHIFT);
00451 EMU->CTRL = (3 << _EMU_CTRL_EM4CTRL_SHIFT);
00452 }
00453 EMU->CTRL = (2 << _EMU_CTRL_EM4CTRL_SHIFT);
00454 }
00455
00456
00457
00472 void EMU_MemPwrDown(uint32_t blocks)
00473 {
00474 #if defined(_EMU_MEMCTRL_RESETVALUE)
00475 EFM_ASSERT(blocks <= _EMU_MEMCTRL_MASK);
00476
00477 EMU->MEMCTRL = blocks;
00478 #else
00479 (void)blocks;
00480 #endif
00481 }
00482
00483
00484
00503 void EMU_UpdateOscConfig(void)
00504 {
00505
00506 cmuStatus = (uint16_t)(CMU->STATUS);
00507 }
00508
00509
00510 #if defined( _EMU_EM4CONF_MASK )
00511
00518 void EMU_EM4Init(EMU_EM4Init_TypeDef *em4init)
00519 {
00520 uint32_t em4conf = EMU->EM4CONF;
00521
00522
00523 em4conf &= ~(
00524 _EMU_EM4CONF_LOCKCONF_MASK|
00525 _EMU_EM4CONF_OSC_MASK|
00526 _EMU_EM4CONF_BURTCWU_MASK|
00527 _EMU_EM4CONF_VREGEN_MASK);
00528
00529
00530 em4conf |= (
00531 (em4init->lockConfig << _EMU_EM4CONF_LOCKCONF_SHIFT)|
00532 (em4init->osc)|
00533 (em4init->buRtcWakeup << _EMU_EM4CONF_BURTCWU_SHIFT)|
00534 (em4init->vreg << _EMU_EM4CONF_VREGEN_SHIFT));
00535
00536
00537 EMU->EM4CONF = em4conf;
00538 }
00539
00540
00541
00548 void EMU_BUPDInit(EMU_BUPDInit_TypeDef *bupdInit)
00549 {
00550 uint32_t reg;
00551
00552
00553 reg = EMU->PWRCONF & ~(
00554 _EMU_PWRCONF_PWRRES_MASK|
00555 _EMU_PWRCONF_VOUTSTRONG_MASK|
00556 _EMU_PWRCONF_VOUTMED_MASK|
00557 _EMU_PWRCONF_VOUTWEAK_MASK);
00558
00559 reg |= (bupdInit->resistor|
00560 (bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)|
00561 (bupdInit->voutMed << _EMU_PWRCONF_VOUTMED_SHIFT)|
00562 (bupdInit->voutWeak << _EMU_PWRCONF_VOUTWEAK_SHIFT));
00563
00564 EMU->PWRCONF = reg;
00565
00566
00567 reg = EMU->BUINACT & ~(_EMU_BUINACT_PWRCON_MASK);
00568 reg |= (bupdInit->inactivePower);
00569 EMU->BUINACT = reg;
00570
00571
00572 reg = EMU->BUACT & ~(_EMU_BUACT_PWRCON_MASK);
00573 reg |= (bupdInit->activePower);
00574 EMU->BUACT = reg;
00575
00576
00577 reg = EMU->BUCTRL & ~(
00578 _EMU_BUCTRL_PROBE_MASK|
00579 _EMU_BUCTRL_BODCAL_MASK|
00580 _EMU_BUCTRL_STATEN_MASK|
00581 _EMU_BUCTRL_EN_MASK);
00582
00583
00584
00585 reg |= (bupdInit->probe|
00586 (bupdInit->bodCal << _EMU_BUCTRL_BODCAL_SHIFT)|
00587 (bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)|
00588 (bupdInit->enable << _EMU_BUCTRL_EN_SHIFT));
00589
00590
00591 EMU->BUCTRL = reg;
00592
00593
00594 EMU_BUPinEnable(bupdInit->enable);
00595
00596
00597 BITBAND_Peripheral(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);
00598 }
00599
00600
00601
00609 void EMU_BUThresholdSet(EMU_BODMode_TypeDef mode, uint32_t value)
00610 {
00611 EFM_ASSERT(value<=(_EMU_BUACT_BUEXTHRES_MASK>>_EMU_BUACT_BUEXTHRES_SHIFT));
00612
00613 switch(mode)
00614 {
00615 case emuBODMode_Active:
00616 EMU->BUACT = (EMU->BUACT & ~(_EMU_BUACT_BUEXTHRES_MASK))|(value<<_EMU_BUACT_BUEXTHRES_SHIFT);
00617 break;
00618 case emuBODMode_Inactive:
00619 EMU->BUINACT = (EMU->BUINACT & ~(_EMU_BUINACT_BUENTHRES_MASK))|(value<<_EMU_BUINACT_BUENTHRES_SHIFT);
00620 break;
00621 }
00622 }
00623
00624
00625
00633 void EMU_BUThresRangeSet(EMU_BODMode_TypeDef mode, uint32_t value)
00634 {
00635 EFM_ASSERT(value<=(_EMU_BUACT_BUEXRANGE_MASK>>_EMU_BUACT_BUEXRANGE_SHIFT));
00636
00637 switch(mode)
00638 {
00639 case emuBODMode_Active:
00640 EMU->BUACT = (EMU->BUACT & ~(_EMU_BUACT_BUEXRANGE_MASK))|(value<<_EMU_BUACT_BUEXRANGE_SHIFT);
00641 break;
00642 case emuBODMode_Inactive:
00643 EMU->BUINACT = (EMU->BUINACT & ~(_EMU_BUINACT_BUENRANGE_MASK))|(value<<_EMU_BUINACT_BUENRANGE_SHIFT);
00644 break;
00645 }
00646 }
00647
00648 #endif
00649
00650
00653 #endif