EFM32 Gecko Software Documentation  efm32g-doc-4.2.1
em_emu.c
Go to the documentation of this file.
1 /***************************************************************************/
33 #include <limits.h>
34 
35 #include "em_emu.h"
36 #if defined( EMU_PRESENT ) && ( EMU_COUNT > 0 )
37 
38 #include "em_cmu.h"
39 #include "em_system.h"
40 #include "em_assert.h"
41 
42 /***************************************************************************/
47 /***************************************************************************/
53 /* Consistency check, since restoring assumes similar bitpositions in */
54 /* CMU OSCENCMD and STATUS regs */
55 #if (CMU_STATUS_AUXHFRCOENS != CMU_OSCENCMD_AUXHFRCOEN)
56 #error Conflict in AUXHFRCOENS and AUXHFRCOEN bitpositions
57 #endif
58 #if (CMU_STATUS_HFXOENS != CMU_OSCENCMD_HFXOEN)
59 #error Conflict in HFXOENS and HFXOEN bitpositions
60 #endif
61 #if (CMU_STATUS_LFRCOENS != CMU_OSCENCMD_LFRCOEN)
62 #error Conflict in LFRCOENS and LFRCOEN bitpositions
63 #endif
64 #if (CMU_STATUS_LFXOENS != CMU_OSCENCMD_LFXOEN)
65 #error Conflict in LFXOENS and LFXOEN bitpositions
66 #endif
67 
68 
70 /* Fix for errata EMU_E107 - non-WIC interrupt masks. */
71 #if defined( _EFM32_GECKO_FAMILY )
72 #define ERRATA_FIX_EMU_E107_EN
73 #define NON_WIC_INT_MASK_0 (~(0x0dfc0323U))
74 #define NON_WIC_INT_MASK_1 (~(0x0U))
75 
76 #elif defined( _EFM32_TINY_FAMILY )
77 #define ERRATA_FIX_EMU_E107_EN
78 #define NON_WIC_INT_MASK_0 (~(0x001be323U))
79 #define NON_WIC_INT_MASK_1 (~(0x0U))
80 
81 #elif defined( _EFM32_GIANT_FAMILY )
82 #define ERRATA_FIX_EMU_E107_EN
83 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
84 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
85 
86 #elif defined( _EFM32_WONDER_FAMILY )
87 #define ERRATA_FIX_EMU_E107_EN
88 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
89 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
90 
91 #else
92 /* Zero Gecko and future families are not affected by errata EMU_E107 */
93 #endif
94 
95 /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */
96 #if defined( _EFM32_HAPPY_FAMILY )
97 #define ERRATA_FIX_EMU_E108_EN
98 #endif
99 
102 #if defined( _EMU_DCDCCTRL_MASK )
103 /* DCDCTODVDD output range min/max */
104 #define PWRCFG_DCDCTODVDD_VMIN 1200
105 #define PWRCFG_DCDCTODVDD_VMAX 3000
106 typedef enum
107 {
108  errataFixDcdcHsInit,
109  errataFixDcdcHsTrimSet,
110  errataFixDcdcHsLnWaitDone
111 } errataFixDcdcHs_TypeDef;
112 errataFixDcdcHs_TypeDef errataFixDcdcHsState = errataFixDcdcHsInit;
113 #endif
114 
115 /*******************************************************************************
116  ************************** LOCAL VARIABLES ********************************
117  ******************************************************************************/
118 
129 static uint32_t cmuStatus;
130 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
131 static uint16_t cmuHfclkStatus;
132 #endif
133 #if defined( _EMU_DCDCCTRL_MASK )
134 static uint16_t dcdcMaxCurrent_mA;
135 static uint16_t dcdcOutput_mVout;
136 #endif
137 
141 /*******************************************************************************
142  ************************** LOCAL FUNCTIONS ********************************
143  ******************************************************************************/
144 
147 /***************************************************************************/
151 static void emuRestore(void)
152 {
153  uint32_t oscEnCmd;
154  uint32_t cmuLocked;
155 
156  /* Although we could use the CMU API for most of the below handling, we */
157  /* would like this function to be as efficient as possible. */
158 
159  /* CMU registers may be locked */
160  cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
161  CMU_Unlock();
162 
163  /* AUXHFRCO are automatically disabled (except if using debugger). */
164  /* HFRCO, USHFRCO and HFXO are automatically disabled. */
165  /* LFRCO/LFXO may be disabled by SW in EM3. */
166  /* Restore according to status prior to entering energy mode. */
167  oscEnCmd = 0;
168  oscEnCmd |= ((cmuStatus & CMU_STATUS_HFRCOENS) ? CMU_OSCENCMD_HFRCOEN : 0);
169  oscEnCmd |= ((cmuStatus & CMU_STATUS_AUXHFRCOENS) ? CMU_OSCENCMD_AUXHFRCOEN : 0);
170  oscEnCmd |= ((cmuStatus & CMU_STATUS_LFRCOENS) ? CMU_OSCENCMD_LFRCOEN : 0);
171  oscEnCmd |= ((cmuStatus & CMU_STATUS_HFXOENS) ? CMU_OSCENCMD_HFXOEN : 0);
172  oscEnCmd |= ((cmuStatus & CMU_STATUS_LFXOENS) ? CMU_OSCENCMD_LFXOEN : 0);
173 #if defined( _CMU_STATUS_USHFRCOENS_MASK )
174  oscEnCmd |= ((cmuStatus & CMU_STATUS_USHFRCOENS) ? CMU_OSCENCMD_USHFRCOEN : 0);
175 #endif
176  CMU->OSCENCMD = oscEnCmd;
177 
178 
179 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
180  /* Restore oscillator used for clocking core */
181  switch (cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)
182  {
183  case CMU_HFCLKSTATUS_SELECTED_LFRCO:
184  /* HFRCO could only be selected if the autostart HFXO feature is not
185  * enabled, otherwise the HFXO would be started and selected automatically.
186  * Note: this error hook helps catching erroneous oscillator configurations,
187  * when the AUTOSTARTSELEM0EM1 is set in CMU_HFXOCTRL. */
188  if (!(CMU->HFXOCTRL & CMU_HFXOCTRL_AUTOSTARTSELEM0EM1))
189  {
190  /* Wait for LFRCO to stabilize */
191  while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
192  ;
193  CMU->HFCLKSEL = CMU_HFCLKSEL_HF_LFRCO;
194  }
195  else
196  {
197  EFM_ASSERT(0);
198  }
199  break;
200 
201  case CMU_HFCLKSTATUS_SELECTED_LFXO:
202  /* Wait for LFXO to stabilize */
203  while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
204  ;
205  CMU->HFCLKSEL = CMU_HFCLKSEL_HF_LFXO;
206  break;
207 
208  case CMU_HFCLKSTATUS_SELECTED_HFXO:
209  /* Wait for HFXO to stabilize */
210  while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
211  ;
212  CMU->HFCLKSEL = CMU_HFCLKSEL_HF_HFXO;
213  break;
214 
215  default: /* CMU_HFCLKSTATUS_SELECTED_HFRCO */
216  /* If core clock was HFRCO core clock, it is automatically restored to */
217  /* state prior to entering energy mode. No need for further action. */
218  break;
219  }
220 #else
221  switch (cmuStatus & (CMU_STATUS_HFRCOSEL
224 #if defined( CMU_STATUS_USHFRCODIV2SEL )
225  | CMU_STATUS_USHFRCODIV2SEL
226 #endif
228  {
229  case CMU_STATUS_LFRCOSEL:
230  /* Wait for LFRCO to stabilize */
231  while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
232  ;
234  break;
235 
236  case CMU_STATUS_LFXOSEL:
237  /* Wait for LFXO to stabilize */
238  while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
239  ;
240  CMU->CMD = CMU_CMD_HFCLKSEL_LFXO;
241  break;
242 
243  case CMU_STATUS_HFXOSEL:
244  /* Wait for HFXO to stabilize */
245  while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
246  ;
247  CMU->CMD = CMU_CMD_HFCLKSEL_HFXO;
248  break;
249 
250 #if defined( CMU_STATUS_USHFRCODIV2SEL )
251  case CMU_STATUS_USHFRCODIV2SEL:
252  /* Wait for USHFRCO to stabilize */
253  while (!(CMU->STATUS & CMU_STATUS_USHFRCORDY))
254  ;
255  CMU->CMD = _CMU_CMD_HFCLKSEL_USHFRCODIV2;
256  break;
257 #endif
258 
259  default: /* CMU_STATUS_HFRCOSEL */
260  /* If core clock was HFRCO core clock, it is automatically restored to */
261  /* state prior to entering energy mode. No need for further action. */
262  break;
263  }
264 
265  /* If HFRCO was disabled before entering Energy Mode, turn it off again */
266  /* as it is automatically enabled by wake up */
267  if ( ! (cmuStatus & CMU_STATUS_HFRCOENS) )
268  {
269  CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
270  }
271 #endif
272  /* Restore CMU register locking */
273  if (cmuLocked)
274  {
275  CMU_Lock();
276  }
277 }
278 
279 
280 #if defined( ERRATA_FIX_EMU_E107_EN )
281 /* Get enable conditions for errata EMU_E107 fix. */
282 static __INLINE bool getErrataFixEmuE107En(void)
283 {
284  /* SYSTEM_ChipRevisionGet could have been used here, but we would like a
285  * faster implementation in this case.
286  */
287  uint16_t majorMinorRev;
288 
289  /* CHIP MAJOR bit [3:0] */
290  majorMinorRev = ((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK)
292  << 8;
293  /* CHIP MINOR bit [7:4] */
294  majorMinorRev |= ((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK)
296  << 4;
297  /* CHIP MINOR bit [3:0] */
298  majorMinorRev |= (ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK)
300 
301 #if defined( _EFM32_GECKO_FAMILY )
302  return (majorMinorRev <= 0x0103);
303 #elif defined( _EFM32_TINY_FAMILY )
304  return (majorMinorRev <= 0x0102);
305 #elif defined( _EFM32_GIANT_FAMILY )
306  return (majorMinorRev <= 0x0103) || (majorMinorRev == 0x0204);
307 #elif defined( _EFM32_WONDER_FAMILY )
308  return (majorMinorRev == 0x0100);
309 #else
310  /* Zero Gecko and future families are not affected by errata EMU_E107 */
311  return false;
312 #endif
313 }
314 #endif
315 
316 
317 #if defined( _EMU_DCDCCTRL_MASK )
318 /* LP prepare / LN restore P/NFET count */
319 static void maxCurrentUpdate(void);
320 #define DCDC_LP_PFET_CNT 7
321 #define DCDC_LP_NFET_CNT 15
322 void dcdcFetCntSet(bool lpModeSet)
323 {
324  uint32_t tmp;
325  static uint32_t emuDcdcMiscCtrlReg;
326 
327  if (lpModeSet)
328  {
329  emuDcdcMiscCtrlReg = EMU->DCDCMISCCTRL;
330  tmp = EMU->DCDCMISCCTRL
331  & ~(_EMU_DCDCMISCCTRL_PFETCNT_MASK | _EMU_DCDCMISCCTRL_NFETCNT_MASK);
332  tmp |= (DCDC_LP_PFET_CNT << _EMU_DCDCMISCCTRL_PFETCNT_SHIFT)
333  | (DCDC_LP_NFET_CNT << _EMU_DCDCMISCCTRL_NFETCNT_SHIFT);
334  EMU->DCDCMISCCTRL = tmp;
335  maxCurrentUpdate();
336  }
337  else
338  {
339  EMU->DCDCMISCCTRL = emuDcdcMiscCtrlReg;
340  maxCurrentUpdate();
341  }
342 }
343 
344 void dcdcHsFixLnBlock(void)
345 {
346 #define EMU_DCDCSTATUS (* (volatile uint32_t *)(EMU_BASE + 0x7C))
347  if (errataFixDcdcHsState == errataFixDcdcHsTrimSet)
348  {
349  /* Wait for LNRUNNING */
350  if ((EMU->DCDCCTRL & ~_EMU_DCDCCTRL_DCDCMODE_MASK) == EMU_DCDCCTRL_DCDCMODE_LOWNOISE)
351  {
352  while (!(EMU_DCDCSTATUS & (0x1 << 16)));
353  }
354  errataFixDcdcHsState = errataFixDcdcHsLnWaitDone;
355  }
356 }
357 #endif
358 
359 
363 /*******************************************************************************
364  ************************** GLOBAL FUNCTIONS *******************************
365  ******************************************************************************/
366 
367 /***************************************************************************/
413 void EMU_EnterEM2(bool restore)
414 {
415 #if defined( ERRATA_FIX_EMU_E107_EN )
416  bool errataFixEmuE107En;
417  uint32_t nonWicIntEn[2];
418 #endif
419 
420  /* Auto-update CMU status just in case before entering energy mode. */
421  /* This variable is normally kept up-to-date by the CMU API. */
422  cmuStatus = CMU->STATUS;
423 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
424  cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);
425 #endif
426 
427  /* Enter Cortex deep sleep mode */
428  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
429 
430  /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
431  Disable the enabled non-WIC interrupts. */
432 #if defined( ERRATA_FIX_EMU_E107_EN )
433  errataFixEmuE107En = getErrataFixEmuE107En();
434  if (errataFixEmuE107En)
435  {
436  nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
437  NVIC->ICER[0] = nonWicIntEn[0];
438 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
439  nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
440  NVIC->ICER[1] = nonWicIntEn[1];
441 #endif
442  }
443 #endif
444 
445 #if defined( _EMU_DCDCCTRL_MASK )
446  dcdcFetCntSet(true);
447  dcdcHsFixLnBlock();
448 #endif
449 
450  __WFI();
451 
452 #if defined( _EMU_DCDCCTRL_MASK )
453  dcdcFetCntSet(false);
454 #endif
455 
456  /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
457 #if defined( ERRATA_FIX_EMU_E107_EN )
458  if (errataFixEmuE107En)
459  {
460  NVIC->ISER[0] = nonWicIntEn[0];
461 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
462  NVIC->ISER[1] = nonWicIntEn[1];
463 #endif
464  }
465 #endif
466 
467  /* Restore oscillators/clocks if specified */
468  if (restore)
469  {
470  emuRestore();
471  }
472  /* If not restoring, and original clock was not HFRCO, we have to */
473  /* update CMSIS core clock variable since core clock has changed */
474  /* to using HFRCO. */
475 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
476  else if ((cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)
477  != CMU_HFCLKSTATUS_SELECTED_HFRCO)
478 #else
479  else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
480 #endif
481  {
483  }
484 }
485 
486 
487 /***************************************************************************/
529 void EMU_EnterEM3(bool restore)
530 {
531  uint32_t cmuLocked;
532 
533 #if defined( ERRATA_FIX_EMU_E107_EN )
534  bool errataFixEmuE107En;
535  uint32_t nonWicIntEn[2];
536 #endif
537 
538  /* Auto-update CMU status just in case before entering energy mode. */
539  /* This variable is normally kept up-to-date by the CMU API. */
540  cmuStatus = CMU->STATUS;
541 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
542  cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);
543 #endif
544 
545  /* CMU registers may be locked */
546  cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
547  CMU_Unlock();
548 
549  /* Disable LF oscillators */
551 
552  /* Restore CMU register locking */
553  if (cmuLocked)
554  {
555  CMU_Lock();
556  }
557 
558  /* Enter Cortex deep sleep mode */
559  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
560 
561  /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
562  Disable the enabled non-WIC interrupts. */
563 #if defined( ERRATA_FIX_EMU_E107_EN )
564  errataFixEmuE107En = getErrataFixEmuE107En();
565  if (errataFixEmuE107En)
566  {
567  nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
568  NVIC->ICER[0] = nonWicIntEn[0];
569 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
570  nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
571  NVIC->ICER[1] = nonWicIntEn[1];
572 #endif
573 
574  }
575 #endif
576 
577 #if defined( _EMU_DCDCCTRL_MASK )
578  dcdcFetCntSet(true);
579  dcdcHsFixLnBlock();
580 #endif
581 
582  __WFI();
583 
584 #if defined( _EMU_DCDCCTRL_MASK )
585  dcdcFetCntSet(false);
586 #endif
587 
588  /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
589 #if defined( ERRATA_FIX_EMU_E107_EN )
590  if (errataFixEmuE107En)
591  {
592  NVIC->ISER[0] = nonWicIntEn[0];
593 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
594  NVIC->ISER[1] = nonWicIntEn[1];
595 #endif
596  }
597 #endif
598 
599  /* Restore oscillators/clocks if specified */
600  if (restore)
601  {
602  emuRestore();
603  }
604  /* If not restoring, and original clock was not HFRCO, we have to */
605  /* update CMSIS core clock variable since core clock has changed */
606  /* to using HFRCO. */
607 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
608  else if ((cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)
609  != CMU_HFCLKSTATUS_SELECTED_HFRCO)
610 #else
611  else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
612 #endif
613  {
615  }
616 }
617 
618 
619 /***************************************************************************/
626 void EMU_EnterEM4(void)
627 {
628  int i;
629 
630 #if defined( _EMU_EM4CTRL_EM4ENTRY_SHIFT )
631  uint32_t em4seq2 = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4ENTRY_MASK)
632  | (2 << _EMU_EM4CTRL_EM4ENTRY_SHIFT);
633  uint32_t em4seq3 = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4ENTRY_MASK)
634  | (3 << _EMU_EM4CTRL_EM4ENTRY_SHIFT);
635 #else
636  uint32_t em4seq2 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK)
637  | (2 << _EMU_CTRL_EM4CTRL_SHIFT);
638  uint32_t em4seq3 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK)
639  | (3 << _EMU_CTRL_EM4CTRL_SHIFT);
640 #endif
641 
642  /* Make sure register write lock is disabled */
643  EMU_Unlock();
644 
645 #if defined( ERRATA_FIX_EMU_E108_EN )
646  /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */
647  __disable_irq();
648  *(volatile uint32_t *)0x400C80E4 = 0;
649 #endif
650 
651 #if defined( _EMU_DCDCCTRL_MASK )
652  dcdcFetCntSet(true);
653  dcdcHsFixLnBlock();
654 #endif
655 
656  for (i = 0; i < 4; i++)
657  {
658 #if defined( _EMU_EM4CTRL_EM4ENTRY_SHIFT )
659  EMU->EM4CTRL = em4seq2;
660  EMU->EM4CTRL = em4seq3;
661  }
662  EMU->EM4CTRL = em4seq2;
663 #else
664  EMU->CTRL = em4seq2;
665  EMU->CTRL = em4seq3;
666  }
667  EMU->CTRL = em4seq2;
668 #endif
669 }
670 
671 
672 /***************************************************************************/
687 void EMU_MemPwrDown(uint32_t blocks)
688 {
689 #if defined( _EMU_MEMCTRL_POWERDOWN_MASK )
690  EFM_ASSERT(blocks <= (_EMU_MEMCTRL_POWERDOWN_MASK
692  EMU->MEMCTRL = blocks;
693 
694 #elif defined( _EMU_MEMCTRL_RAMPOWERDOWN_MASK ) \
695  && defined( _EMU_MEMCTRL_RAMHPOWERDOWN_MASK ) \
696  && defined( _EMU_MEMCTRL_SEQRAMPOWERDOWN_MASK )
697  EFM_ASSERT((blocks & (_EMU_MEMCTRL_RAMPOWERDOWN_MASK
698  | _EMU_MEMCTRL_RAMHPOWERDOWN_MASK
699  | _EMU_MEMCTRL_SEQRAMPOWERDOWN_MASK))
700  == blocks);
701  EMU->MEMCTRL = blocks;
702 
703 #elif defined( _EMU_MEMCTRL_RAMPOWERDOWN_MASK )
704  EFM_ASSERT((blocks & _EMU_MEMCTRL_RAMPOWERDOWN_MASK) == blocks);
705  EMU->MEMCTRL = blocks;
706 
707 #elif defined( _EMU_RAM0CTRL_RAMPOWERDOWN_MASK )
708  EFM_ASSERT((blocks & _EMU_RAM0CTRL_RAMPOWERDOWN_MASK) == blocks);
709  EMU->RAM0CTRL = blocks;
710 
711 #else
712  (void)blocks;
713 #endif
714 }
715 
716 
717 /***************************************************************************/
737 {
738  /* Fetch current configuration */
739  cmuStatus = CMU->STATUS;
740 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
741  cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);
742 #endif
743 }
744 
745 
746 /***************************************************************************/
754 {
755 #if defined( _EMU_CTRL_EMVREG_MASK )
756  EMU->CTRL = em23Init->em23VregFullEn ? (EMU->CTRL | EMU_CTRL_EMVREG)
757  : (EMU->CTRL & ~EMU_CTRL_EMVREG);
758 #elif defined( _EMU_CTRL_EM23VREG_MASK )
759  EMU->CTRL = em23Init->em23VregFullEn ? (EMU->CTRL | EMU_CTRL_EM23VREG)
760  : (EMU->CTRL & ~EMU_CTRL_EM23VREG);
761 #else
762  (void)em23Init;
763 #endif
764 }
765 
766 
767 #if defined( _EMU_EM4CONF_MASK ) || defined( _EMU_EM4CTRL_MASK )
768 /***************************************************************************/
775 void EMU_EM4Init(EMU_EM4Init_TypeDef *em4Init)
776 {
777 #if defined( _EMU_EM4CONF_MASK )
778  /* Init for platforms with EMU->EM4CONF register */
779  uint32_t em4conf = EMU->EM4CONF;
780 
781  /* Clear fields that will be reconfigured */
782  em4conf &= ~(_EMU_EM4CONF_LOCKCONF_MASK
783  | _EMU_EM4CONF_OSC_MASK
784  | _EMU_EM4CONF_BURTCWU_MASK
785  | _EMU_EM4CONF_VREGEN_MASK);
786 
787  /* Configure new settings */
788  em4conf |= (em4Init->lockConfig << _EMU_EM4CONF_LOCKCONF_SHIFT)
789  | (em4Init->osc)
790  | (em4Init->buRtcWakeup << _EMU_EM4CONF_BURTCWU_SHIFT)
791  | (em4Init->vreg << _EMU_EM4CONF_VREGEN_SHIFT);
792 
793  /* Apply configuration. Note that lock can be set after this stage. */
794  EMU->EM4CONF = em4conf;
795 
796 #elif defined( _EMU_EM4CTRL_MASK )
797  /* Init for platforms with EMU->EM4CTRL register */
798 
799  uint32_t em4ctrl = EMU->EM4CTRL;
800 
801  em4ctrl &= ~(_EMU_EM4CTRL_RETAINLFXO_MASK
802  | _EMU_EM4CTRL_RETAINLFRCO_MASK
803  | _EMU_EM4CTRL_RETAINULFRCO_MASK
804  | _EMU_EM4CTRL_EM4STATE_MASK
805  | _EMU_EM4CTRL_EM4IORETMODE_MASK);
806 
807  em4ctrl |= (em4Init->retainLfxo ? EMU_EM4CTRL_RETAINLFXO : 0)
808  | (em4Init->retainLfrco ? EMU_EM4CTRL_RETAINLFRCO : 0)
809  | (em4Init->retainUlfrco ? EMU_EM4CTRL_RETAINULFRCO : 0)
810  | (em4Init->em4State ? EMU_EM4CTRL_EM4STATE_EM4H : 0)
811  | (em4Init->pinRetentionMode);
812 
813  EMU->EM4CTRL = em4ctrl;
814 #endif
815 }
816 #endif
817 
818 
819 #if defined( BU_PRESENT )
820 /***************************************************************************/
827 void EMU_BUPDInit(EMU_BUPDInit_TypeDef *bupdInit)
828 {
829  uint32_t reg;
830 
831  /* Set power connection configuration */
832  reg = EMU->PWRCONF & ~(_EMU_PWRCONF_PWRRES_MASK
833  | _EMU_PWRCONF_VOUTSTRONG_MASK
834  | _EMU_PWRCONF_VOUTMED_MASK
835  | _EMU_PWRCONF_VOUTWEAK_MASK);
836 
837  reg |= bupdInit->resistor
838  | (bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)
839  | (bupdInit->voutMed << _EMU_PWRCONF_VOUTMED_SHIFT)
840  | (bupdInit->voutWeak << _EMU_PWRCONF_VOUTWEAK_SHIFT);
841 
842  EMU->PWRCONF = reg;
843 
844  /* Set backup domain inactive mode configuration */
845  reg = EMU->BUINACT & ~(_EMU_BUINACT_PWRCON_MASK);
846  reg |= (bupdInit->inactivePower);
847  EMU->BUINACT = reg;
848 
849  /* Set backup domain active mode configuration */
850  reg = EMU->BUACT & ~(_EMU_BUACT_PWRCON_MASK);
851  reg |= (bupdInit->activePower);
852  EMU->BUACT = reg;
853 
854  /* Set power control configuration */
855  reg = EMU->BUCTRL & ~(_EMU_BUCTRL_PROBE_MASK
856  | _EMU_BUCTRL_BODCAL_MASK
857  | _EMU_BUCTRL_STATEN_MASK
858  | _EMU_BUCTRL_EN_MASK);
859 
860  /* Note use of ->enable to both enable BUPD, use BU_VIN pin input and
861  release reset */
862  reg |= bupdInit->probe
863  | (bupdInit->bodCal << _EMU_BUCTRL_BODCAL_SHIFT)
864  | (bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)
865  | (bupdInit->enable << _EMU_BUCTRL_EN_SHIFT);
866 
867  /* Enable configuration */
868  EMU->BUCTRL = reg;
869 
870  /* If enable is true, enable BU_VIN input power pin, if not disable it */
871  EMU_BUPinEnable(bupdInit->enable);
872 
873  /* If enable is true, release BU reset, if not keep reset asserted */
874  BUS_RegBitWrite(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);
875 }
876 
877 
878 /***************************************************************************/
886 void EMU_BUThresholdSet(EMU_BODMode_TypeDef mode, uint32_t value)
887 {
888  EFM_ASSERT(value<8);
889  EFM_ASSERT(value<=(_EMU_BUACT_BUEXTHRES_MASK>>_EMU_BUACT_BUEXTHRES_SHIFT));
890 
891  switch(mode)
892  {
893  case emuBODMode_Active:
894  EMU->BUACT = (EMU->BUACT & ~_EMU_BUACT_BUEXTHRES_MASK)
895  | (value<<_EMU_BUACT_BUEXTHRES_SHIFT);
896  break;
897  case emuBODMode_Inactive:
898  EMU->BUINACT = (EMU->BUINACT & ~_EMU_BUINACT_BUENTHRES_MASK)
899  | (value<<_EMU_BUINACT_BUENTHRES_SHIFT);
900  break;
901  }
902 }
903 
904 
905 /***************************************************************************/
913 void EMU_BUThresRangeSet(EMU_BODMode_TypeDef mode, uint32_t value)
914 {
915  EFM_ASSERT(value < 4);
916  EFM_ASSERT(value<=(_EMU_BUACT_BUEXRANGE_MASK>>_EMU_BUACT_BUEXRANGE_SHIFT));
917 
918  switch(mode)
919  {
920  case emuBODMode_Active:
921  EMU->BUACT = (EMU->BUACT & ~_EMU_BUACT_BUEXRANGE_MASK)
922  | (value<<_EMU_BUACT_BUEXRANGE_SHIFT);
923  break;
924  case emuBODMode_Inactive:
925  EMU->BUINACT = (EMU->BUINACT & ~_EMU_BUINACT_BUENRANGE_MASK)
926  | (value<<_EMU_BUINACT_BUENRANGE_SHIFT);
927  break;
928  }
929 }
930 #endif
931 
932 
933 #if defined( _EMU_DCDCCTRL_MASK )
934 
937 /***************************************************************************/
945 static bool ConstCalibrationLoad(void)
946 {
947  uint32_t val;
948  volatile uint32_t *reg;
949 
950  /* DI calib data in flash */
951  volatile uint32_t* const diCal_EMU_DCDCLNFREQCTRL = (volatile uint32_t *)(0x0FE08038);
952  volatile uint32_t* const diCal_EMU_DCDCLNVCTRL = (volatile uint32_t *)(0x0FE08040);
953  volatile uint32_t* const diCal_EMU_DCDCLPCTRL = (volatile uint32_t *)(0x0FE08048);
954  volatile uint32_t* const diCal_EMU_DCDCLPVCTRL = (volatile uint32_t *)(0x0FE08050);
955  volatile uint32_t* const diCal_EMU_DCDCTRIM0 = (volatile uint32_t *)(0x0FE08058);
956  volatile uint32_t* const diCal_EMU_DCDCTRIM1 = (volatile uint32_t *)(0x0FE08060);
957 
958  if (DEVINFO->DCDCLPVCTRL0 != UINT_MAX)
959  {
960  val = *(diCal_EMU_DCDCLNFREQCTRL + 1);
961  reg = (volatile uint32_t *)*diCal_EMU_DCDCLNFREQCTRL;
962  *reg = val;
963 
964  val = *(diCal_EMU_DCDCLNVCTRL + 1);
965  reg = (volatile uint32_t *)*diCal_EMU_DCDCLNVCTRL;
966  *reg = val;
967 
968  val = *(diCal_EMU_DCDCLPCTRL + 1);
969  reg = (volatile uint32_t *)*diCal_EMU_DCDCLPCTRL;
970  *reg = val;
971 
972  val = *(diCal_EMU_DCDCLPVCTRL + 1);
973  reg = (volatile uint32_t *)*diCal_EMU_DCDCLPVCTRL;
974  *reg = val;
975 
976  val = *(diCal_EMU_DCDCTRIM0 + 1);
977  reg = (volatile uint32_t *)*diCal_EMU_DCDCTRIM0;
978  *reg = val;
979 
980  val = *(diCal_EMU_DCDCTRIM1 + 1);
981  reg = (volatile uint32_t *)*diCal_EMU_DCDCTRIM1;
982  *reg = val;
983 
984  return true;
985  }
986  EFM_ASSERT(false);
987  /* Return when assertions are disabled */
988  return false;
989 }
990 
991 
992 /***************************************************************************/
997 void ValidatedConfigSet(void)
998 {
999 #define EMU_DCDCSMCTRL (* (volatile uint32_t *)(EMU_BASE + 0x44))
1000 
1001  uint32_t dcdcTiming;
1004 
1005  /* Enable duty cycling of the bias */
1006  EMU->DCDCLPCTRL |= EMU_DCDCLPCTRL_LPVREFDUTYEN;
1007 
1008  /* Set low-noise RCO for EFM32 and EFR32 */
1009 #if defined( _EFR_DEVICE )
1010  /* 7MHz is recommended for all EFR32 parts with DCDC */
1011  EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
1012  | (EMU_DcdcLnRcoBand_7MHz << _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);
1013 #else
1014  /* 3MHz is recommended for all EFM32 parts with DCDC */
1015  EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
1016  | (EMU_DcdcLnRcoBand_3MHz << _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);
1017 #endif
1018 
1019  EMU->DCDCTIMING &= ~_EMU_DCDCTIMING_DUTYSCALE_MASK;
1020 
1021  family = SYSTEM_GetFamily();
1022  SYSTEM_ChipRevisionGet(&rev);
1023  if ((((family >= systemPartFamilyMighty1P)
1024  && (family <= systemPartFamilyFlex1V))
1025  || (family == systemPartFamilyEfm32Pearl1B)
1026  || (family == systemPartFamilyEfm32Jade1B))
1027  && ((rev.major == 1) && (rev.minor < 3))
1028  && (errataFixDcdcHsState == errataFixDcdcHsInit))
1029  {
1030  /* LPCMPWAITDIS = 1 */
1031  EMU_DCDCSMCTRL |= 1;
1032 
1033  dcdcTiming = EMU->DCDCTIMING;
1034  dcdcTiming &= ~(_EMU_DCDCTIMING_LPINITWAIT_MASK
1035  |_EMU_DCDCTIMING_LNWAIT_MASK
1036  |_EMU_DCDCTIMING_BYPWAIT_MASK);
1037 
1038  dcdcTiming |= ((180 << _EMU_DCDCTIMING_LPINITWAIT_SHIFT)
1039  | (12 << _EMU_DCDCTIMING_LNWAIT_SHIFT)
1040  | (180 << _EMU_DCDCTIMING_BYPWAIT_SHIFT));
1041  EMU->DCDCTIMING = dcdcTiming;
1042 
1043  errataFixDcdcHsState = errataFixDcdcHsTrimSet;
1044  }
1045 }
1046 
1047 
1048 /***************************************************************************/
1053 static void maxCurrentUpdate(void)
1054 {
1055  uint32_t lncLimImSel;
1056  uint32_t lpcLimImSel;
1057  uint32_t pFetCnt;
1058 
1059  pFetCnt = (EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_PFETCNT_MASK)
1060  >> _EMU_DCDCMISCCTRL_PFETCNT_SHIFT;
1061 
1062  /* Equation from Reference Manual section 11.5.20, in the register
1063  field description for LNCLIMILIMSEL and LPCLIMILIMSEL. */
1064  lncLimImSel = (dcdcMaxCurrent_mA / (5 * (pFetCnt + 1))) - 1;
1065  /* 80mA as recommended in Application Note AN0948 */
1066  lpcLimImSel = (80 / (5 * (pFetCnt + 1))) - 1;
1067 
1068  lncLimImSel <<= _EMU_DCDCMISCCTRL_LNCLIMILIMSEL_SHIFT;
1069  lpcLimImSel <<= _EMU_DCDCMISCCTRL_LPCLIMILIMSEL_SHIFT;
1070  EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_LNCLIMILIMSEL_MASK
1071  | _EMU_DCDCMISCCTRL_LPCLIMILIMSEL_MASK))
1072  | (lncLimImSel | lpcLimImSel);
1073 }
1074 
1075 
1076 /***************************************************************************/
1084 static void maxCurrentSet(uint32_t mAmaxCurrent)
1085 {
1086  dcdcMaxCurrent_mA = mAmaxCurrent;
1087  maxCurrentUpdate();
1088 }
1089 
1090 
1091 /***************************************************************************/
1101 static bool LpCmpHystCalibrationLoad(bool lpAttenuation, uint32_t lpCmpBias)
1102 {
1103  uint8_t devinfoRev;
1104  uint32_t lpcmpHystSel;
1105 
1106  /* Get calib data revision */
1107  devinfoRev = SYSTEM_GetDevinfoRev();
1108 
1109  /* Load LPATT indexed calibration data */
1110  if (devinfoRev < 4)
1111  {
1112  lpcmpHystSel = DEVINFO->DCDCLPCMPHYSSEL0;
1113 
1114  if (lpAttenuation)
1115  {
1116  lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT1_MASK)
1117  >> _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT1_SHIFT;
1118  }
1119  else
1120  {
1121  lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT0_MASK)
1122  >> _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT0_SHIFT;
1123  }
1124  }
1125  /* devinfoRev >= 4
1126  Load LPCMPBIAS indexed calibration data */
1127  else
1128  {
1129  lpcmpHystSel = DEVINFO->DCDCLPCMPHYSSEL1;
1130  switch (lpCmpBias)
1131  {
1132  case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0:
1133  lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS0_MASK)
1134  >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS0_SHIFT;
1135  break;
1136 
1137  case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1:
1138  lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS1_MASK)
1139  >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS1_SHIFT;
1140  break;
1141 
1142  case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS2:
1143  lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS2_MASK)
1144  >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS2_SHIFT;
1145  break;
1146 
1147  case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS3:
1148  lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS3_MASK)
1149  >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS3_SHIFT;
1150  break;
1151 
1152  default:
1153  EFM_ASSERT(false);
1154  /* Return when assertions are disabled */
1155  return false;
1156  }
1157  }
1158 
1159  /* Make sure the sel value is within the field range. */
1160  lpcmpHystSel <<= _EMU_DCDCLPCTRL_LPCMPHYSSEL_SHIFT;
1161  if (lpcmpHystSel & ~_EMU_DCDCLPCTRL_LPCMPHYSSEL_MASK)
1162  {
1163  EFM_ASSERT(false);
1164  /* Return when assertions are disabled */
1165  return false;
1166  }
1167  EMU->DCDCLPCTRL = (EMU->DCDCLPCTRL & ~_EMU_DCDCLPCTRL_LPCMPHYSSEL_MASK) | lpcmpHystSel;
1168 
1169  return true;
1170 }
1171 
1172 
1175 /***************************************************************************/
1182 void EMU_DCDCModeSet(EMU_DcdcMode_TypeDef dcdcMode)
1183 {
1184  while(EMU->DCDCSYNC & EMU_DCDCSYNC_DCDCCTRLBUSY);
1185  BUS_RegBitWrite(&EMU->DCDCCLIMCTRL, _EMU_DCDCCLIMCTRL_BYPLIMEN_SHIFT, dcdcMode == emuDcdcMode_Bypass ? 0 : 1);
1186  EMU->DCDCCTRL = (EMU->DCDCCTRL & ~_EMU_DCDCCTRL_DCDCMODE_MASK) | dcdcMode;
1187 }
1188 
1189 
1190 /***************************************************************************/
1204 bool EMU_DCDCInit(EMU_DCDCInit_TypeDef *dcdcInit)
1205 {
1206  uint32_t lpCmpBiasSel;
1207 
1208  /* Set external power configuration. This enables writing to the other
1209  DCDC registers. */
1210  EMU->PWRCFG = dcdcInit->powerConfig;
1211 
1212  /* EMU->PWRCFG is write-once and POR reset only. Check that
1213  we could set the desired power configuration. */
1214  if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) != dcdcInit->powerConfig)
1215  {
1216  /* If this assert triggers unexpectedly, please power cycle the
1217  kit to reset the power configuration. */
1218  EFM_ASSERT(false);
1219  /* Return when assertions are disabled */
1220  return false;
1221  }
1222 
1223  /* Load DCDC calibration data from the DI page */
1224  ConstCalibrationLoad();
1225 
1226  /* Check current parameters */
1227  EFM_ASSERT(dcdcInit->maxCurrent_mA <= 200);
1228  EFM_ASSERT(dcdcInit->em01LoadCurrent_mA <= dcdcInit->maxCurrent_mA);
1229 
1230  /* DCDC low-noise supports max 200mA */
1231  if (dcdcInit->dcdcMode == emuDcdcMode_LowNoise)
1232  {
1233  EFM_ASSERT(dcdcInit->em01LoadCurrent_mA <= 200);
1234  }
1235 
1236  /* EM2, 3 and 4 current above 100uA is not supported */
1237  EFM_ASSERT(dcdcInit->em234LoadCurrent_uA <= 100);
1238 
1239  /* Decode LP comparator bias for EM0/1 and EM2/3 */
1240  lpCmpBiasSel = EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1;
1241  if (dcdcInit->em234LoadCurrent_uA <= 10)
1242  {
1243  lpCmpBiasSel = EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0;
1244  }
1245 
1246  /* Set DCDC low-power mode comparator bias selection */
1247  EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_LPCMPBIAS_MASK
1248  | _EMU_DCDCMISCCTRL_LNFORCECCM_MASK))
1249  | ((uint32_t)lpCmpBiasSel
1250  | (uint32_t)dcdcInit->lnTransientMode);
1251 
1252  /* Set recommended and validated current optimization settings */
1253  ValidatedConfigSet();
1254 
1255  /* Set the maximum current that the DCDC can draw from the power source */
1256  maxCurrentSet(dcdcInit->maxCurrent_mA);
1257 
1258  /* Optimize LN slice based on given load current estimate */
1259  EMU_DCDCOptimizeSlice(dcdcInit->em01LoadCurrent_mA);
1260 
1261  /* Set DCDC output voltage */
1262  dcdcOutput_mVout = dcdcInit->mVout;
1263  if (!EMU_DCDCOutputVoltageSet(dcdcOutput_mVout, true, true))
1264  {
1265  EFM_ASSERT(false);
1266  /* Return when assertions are disabled */
1267  return false;
1268  }
1269 
1270  /* Set EM0 DCDC operating mode. Output voltage set in EMU_DCDCOutputVoltageSet()
1271  above takes effect if mode is changed from bypass here. */
1272  EMU_DCDCModeSet(dcdcInit->dcdcMode);
1273 
1274  /* Select analog peripheral power supply */
1275  BUS_RegBitWrite(&EMU->PWRCTRL, _EMU_PWRCTRL_ANASW_SHIFT, dcdcInit->anaPeripheralPower ? 1 : 0);
1276 
1277  return true;
1278 }
1279 
1280 
1281 /***************************************************************************/
1291 bool EMU_DCDCOutputVoltageSet(uint32_t mV,
1292  bool setLpVoltage,
1293  bool setLnVoltage)
1294 {
1295 #if defined( _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_MASK )
1296 
1297  bool validOutVoltage;
1298  uint8_t lnMode;
1299  bool attSet;
1300  uint32_t attMask;
1301  uint32_t vrefLow = 0;
1302  uint32_t vrefHigh = 0;
1303  uint32_t vrefVal = 0;
1304  uint32_t mVlow = 0;
1305  uint32_t mVhigh = 0;
1306  uint32_t vrefShift;
1307  uint32_t lpcmpBias;
1308  volatile uint32_t* ctrlReg;
1309 
1310  /* Check that the set voltage is within valid range.
1311  Voltages are obtained from the datasheet. */
1312  validOutVoltage = false;
1313  if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) == EMU_PWRCFG_PWRCFG_DCDCTODVDD)
1314  {
1315  validOutVoltage = ((mV >= PWRCFG_DCDCTODVDD_VMIN)
1316  && (mV <= PWRCFG_DCDCTODVDD_VMAX));
1317  }
1318 
1319  if (!validOutVoltage)
1320  {
1321  EFM_ASSERT(false);
1322  /* Return when assertions are disabled */
1323  return false;
1324  }
1325 
1326  /* Populate both LP and LN registers, set control reg pointer and VREF shift. */
1327  for (lnMode = 0; lnMode <= 1; lnMode++)
1328  {
1329  if (((lnMode == 0) && !setLpVoltage)
1330  || ((lnMode == 1) && !setLnVoltage))
1331  {
1332  continue;
1333  }
1334 
1335  ctrlReg = (lnMode ? &EMU->DCDCLNVCTRL : &EMU->DCDCLPVCTRL);
1336  vrefShift = (lnMode ? _EMU_DCDCLNVCTRL_LNVREF_SHIFT
1337  : _EMU_DCDCLPVCTRL_LPVREF_SHIFT);
1338 
1339  /* Set attenuation to use */
1340  attSet = (mV > 1800);
1341  if (attSet)
1342  {
1343  mVlow = 1800;
1344  mVhigh = 3000;
1345  attMask = (lnMode ? EMU_DCDCLNVCTRL_LNATT : EMU_DCDCLPVCTRL_LPATT);
1346  }
1347  else
1348  {
1349  mVlow = 1200;
1350  mVhigh = 1800;
1351  attMask = 0;
1352  }
1353 
1354  /* Get 2-point calib data from DEVINFO, calculate trimming and set voltege */
1355  if (lnMode)
1356  {
1357  /* Set low-noise DCDC output voltage tuning */
1358  if (attSet)
1359  {
1360  vrefLow = DEVINFO->DCDCLNVCTRL0;
1361  vrefHigh = (vrefLow & _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_MASK)
1362  >> _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_SHIFT;
1363  vrefLow = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V8LNATT1_MASK)
1364  >> _DEVINFO_DCDCLNVCTRL0_1V8LNATT1_SHIFT;
1365  }
1366  else
1367  {
1368  vrefLow = DEVINFO->DCDCLNVCTRL0;
1369  vrefHigh = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V8LNATT0_MASK)
1370  >> _DEVINFO_DCDCLNVCTRL0_1V8LNATT0_SHIFT;
1371  vrefLow = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V2LNATT0_MASK)
1372  >> _DEVINFO_DCDCLNVCTRL0_1V2LNATT0_SHIFT;
1373  }
1374  }
1375  else
1376  {
1377  /* Set low-power DCDC output voltage tuning */
1378 
1379  /* Get LPCMPBIAS and make sure masks are not overlayed */
1380  lpcmpBias = EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LPCMPBIAS_MASK;
1381  EFM_ASSERT(!(_EMU_DCDCMISCCTRL_LPCMPBIAS_MASK & attMask));
1382  switch (attMask | lpcmpBias)
1383  {
1384  case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0:
1385  vrefLow = DEVINFO->DCDCLPVCTRL2;
1386  vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_MASK)
1387  >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_SHIFT;
1388  vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_MASK)
1389  >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_SHIFT;
1390  break;
1391 
1392  case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1:
1393  vrefLow = DEVINFO->DCDCLPVCTRL2;
1394  vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_MASK)
1395  >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_SHIFT;
1396  vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_MASK)
1397  >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_SHIFT;
1398  break;
1399 
1400  case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS2:
1401  vrefLow = DEVINFO->DCDCLPVCTRL3;
1402  vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_MASK)
1403  >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_SHIFT;
1404  vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_MASK)
1405  >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_SHIFT;
1406  break;
1407 
1408  case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS3:
1409  vrefLow = DEVINFO->DCDCLPVCTRL3;
1410  vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_MASK)
1411  >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_SHIFT;
1412  vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_MASK)
1413  >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_SHIFT;
1414  break;
1415 
1416  case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0:
1417  vrefLow = DEVINFO->DCDCLPVCTRL0;
1418  vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS0_MASK)
1419  >> _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS0_SHIFT;
1420  vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS0_MASK)
1421  >> _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS0_SHIFT;
1422  break;
1423 
1424  case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1:
1425  vrefLow = DEVINFO->DCDCLPVCTRL0;
1426  vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS1_MASK)
1427  >> _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS1_SHIFT;
1428  vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS1_MASK)
1429  >> _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS1_SHIFT;
1430  break;
1431 
1432  case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS2:
1433  vrefLow = DEVINFO->DCDCLPVCTRL1;
1434  vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS2_MASK)
1435  >> _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS2_SHIFT;
1436  vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS2_MASK)
1437  >> _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS2_SHIFT;
1438  break;
1439 
1440  case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS3:
1441  vrefLow = DEVINFO->DCDCLPVCTRL1;
1442  vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS3_MASK)
1443  >> _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS3_SHIFT;
1444  vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS3_MASK)
1445  >> _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS3_SHIFT;
1446  break;
1447 
1448  default:
1449  EFM_ASSERT(false);
1450  break;
1451  }
1452 
1453  /* Load LP comparator hysteresis calibration */
1454  if(!(LpCmpHystCalibrationLoad(attSet, lpcmpBias >> _EMU_DCDCMISCCTRL_LPCMPBIAS_SHIFT)))
1455  {
1456  EFM_ASSERT(false);
1457  /* Return when assertions are disabled */
1458  return false;
1459  }
1460  } /* Low-nise / low-power mode */
1461 
1462 
1463  /* Check for valid 2-point trim values */
1464  if ((vrefLow == 0xFF) && (vrefHigh == 0xFF))
1465  {
1466  EFM_ASSERT(false);
1467  /* Return when assertions are disabled */
1468  return false;
1469  }
1470 
1471  /* Calculate and set voltage trim */
1472  vrefVal = ((mV - mVlow) * (vrefHigh - vrefLow)) / (mVhigh - mVlow);
1473  vrefVal += vrefLow;
1474 
1475  /* Range check */
1476  if ((vrefVal > vrefHigh) || (vrefVal < vrefLow))
1477  {
1478  EFM_ASSERT(false);
1479  /* Return when assertions are disabled */
1480  return false;
1481  }
1482 
1483  /* Update DCDCLNVCTRL/DCDCLPVCTRL */
1484  *ctrlReg = (vrefVal << vrefShift) | attMask;
1485  }
1486 #endif
1487  return true;
1488 }
1489 
1490 
1491 /***************************************************************************/
1499 void EMU_DCDCOptimizeSlice(uint32_t mAEm0LoadCurrent)
1500 {
1501  uint32_t sliceCount = 0;
1502  uint32_t rcoBand = (EMU->DCDCLNFREQCTRL & _EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
1503  >> _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT;
1504 
1505  /* Set recommended slice count */
1506  if ((EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK) && (rcoBand >= EMU_DcdcLnRcoBand_5MHz))
1507  {
1508  if (mAEm0LoadCurrent < 20)
1509  {
1510  sliceCount = 4;
1511  }
1512  else if ((mAEm0LoadCurrent >= 20) && (mAEm0LoadCurrent < 40))
1513  {
1514  sliceCount = 8;
1515  }
1516  else
1517  {
1518  sliceCount = 16;
1519  }
1520  }
1521  else if ((!(EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK)) && (rcoBand <= EMU_DcdcLnRcoBand_4MHz))
1522  {
1523  if (mAEm0LoadCurrent < 10)
1524  {
1525  sliceCount = 4;
1526  }
1527  else if ((mAEm0LoadCurrent >= 10) && (mAEm0LoadCurrent < 20))
1528  {
1529  sliceCount = 8;
1530  }
1531  else
1532  {
1533  sliceCount = 16;
1534  }
1535  }
1536  else if ((EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK) && (rcoBand <= EMU_DcdcLnRcoBand_4MHz))
1537  {
1538  if (mAEm0LoadCurrent < 40)
1539  {
1540  sliceCount = 8;
1541  }
1542  else
1543  {
1544  sliceCount = 16;
1545  }
1546  }
1547  else
1548  {
1549  /* This configuration is not recommended. EMU_DCDCInit() applies a recommended
1550  configuration. */
1551  EFM_ASSERT(false);
1552  }
1553 
1554  /* The selected silices are PSLICESEL + 1 */
1555  sliceCount--;
1556 
1557  /* Apply slice count to both N and P slice */
1558  sliceCount = (sliceCount << _EMU_DCDCMISCCTRL_PFETCNT_SHIFT
1559  | sliceCount << _EMU_DCDCMISCCTRL_NFETCNT_SHIFT);
1560  EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_PFETCNT_MASK
1561  | _EMU_DCDCMISCCTRL_NFETCNT_MASK))
1562  | sliceCount;
1563 
1564  /* Update current limit configuration as it depends on the slice configuration. */
1565  maxCurrentUpdate();
1566 }
1567 
1568 /***************************************************************************/
1575 void EMU_DCDCLnRcoBandSet(EMU_DcdcLnRcoBand_TypeDef band)
1576 {
1577  EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
1578  | (band << _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);
1579 }
1580 
1581 /***************************************************************************/
1594 bool EMU_DCDCPowerOff(void)
1595 {
1596  /* Set power configuration to hard bypass */
1597  EMU->PWRCFG = 0xF;
1598  if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) != 0xF)
1599  {
1600  EFM_ASSERT(false);
1601  /* Return when assertions are disabled */
1602  return false;
1603  }
1604 
1605  /* Set DCDC to OFF and disable LP in EM2/3/4 */
1606  EMU->DCDCCTRL = EMU_DCDCCTRL_DCDCMODE_OFF;
1607  return true;
1608 }
1609 #endif
1610 
1611 
1612 #if defined( EMU_STATUS_VMONRDY )
1613 
1614 __STATIC_INLINE uint32_t vmonMilliVoltToCoarseThreshold(int mV)
1615 {
1616  return (mV - 1200) / 200;
1617 }
1618 
1619 __STATIC_INLINE uint32_t vmonMilliVoltToFineThreshold(int mV, uint32_t coarseThreshold)
1620 {
1621  return (mV - 1200 - (coarseThreshold * 200)) / 20;
1622 }
1625 /***************************************************************************/
1637 void EMU_VmonInit(EMU_VmonInit_TypeDef *vmonInit)
1638 {
1639  uint32_t thresholdCoarse, thresholdFine;
1640  EFM_ASSERT((vmonInit->threshold >= 1200) && (vmonInit->threshold <= 3980));
1641 
1642  thresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->threshold);
1643  thresholdFine = vmonMilliVoltToFineThreshold(vmonInit->threshold, thresholdCoarse);
1644 
1645  switch(vmonInit->channel)
1646  {
1647  case emuVmonChannel_AVDD:
1648  EMU->VMONAVDDCTRL = (thresholdCoarse << _EMU_VMONAVDDCTRL_RISETHRESCOARSE_SHIFT)
1649  | (thresholdFine << _EMU_VMONAVDDCTRL_RISETHRESFINE_SHIFT)
1650  | (thresholdCoarse << _EMU_VMONAVDDCTRL_FALLTHRESCOARSE_SHIFT)
1651  | (thresholdFine << _EMU_VMONAVDDCTRL_FALLTHRESFINE_SHIFT)
1652  | (vmonInit->riseWakeup ? EMU_VMONAVDDCTRL_RISEWU : 0)
1653  | (vmonInit->fallWakeup ? EMU_VMONAVDDCTRL_FALLWU : 0)
1654  | (vmonInit->enable ? EMU_VMONAVDDCTRL_EN : 0);
1655  break;
1656  case emuVmonChannel_ALTAVDD:
1657  EMU->VMONALTAVDDCTRL = (thresholdCoarse << _EMU_VMONALTAVDDCTRL_THRESCOARSE_SHIFT)
1658  | (thresholdFine << _EMU_VMONALTAVDDCTRL_THRESFINE_SHIFT)
1659  | (vmonInit->riseWakeup ? EMU_VMONALTAVDDCTRL_RISEWU : 0)
1660  | (vmonInit->fallWakeup ? EMU_VMONALTAVDDCTRL_FALLWU : 0)
1661  | (vmonInit->enable ? EMU_VMONALTAVDDCTRL_EN : 0);
1662  break;
1663  case emuVmonChannel_DVDD:
1664  EMU->VMONDVDDCTRL = (thresholdCoarse << _EMU_VMONDVDDCTRL_THRESCOARSE_SHIFT)
1665  | (thresholdFine << _EMU_VMONDVDDCTRL_THRESFINE_SHIFT)
1666  | (vmonInit->riseWakeup ? EMU_VMONDVDDCTRL_RISEWU : 0)
1667  | (vmonInit->fallWakeup ? EMU_VMONDVDDCTRL_FALLWU : 0)
1668  | (vmonInit->enable ? EMU_VMONDVDDCTRL_EN : 0);
1669  break;
1670  case emuVmonChannel_IOVDD0:
1671  EMU->VMONIO0CTRL = (thresholdCoarse << _EMU_VMONIO0CTRL_THRESCOARSE_SHIFT)
1672  | (thresholdFine << _EMU_VMONIO0CTRL_THRESFINE_SHIFT)
1673  | (vmonInit->retDisable ? EMU_VMONIO0CTRL_RETDIS : 0)
1674  | (vmonInit->riseWakeup ? EMU_VMONIO0CTRL_RISEWU : 0)
1675  | (vmonInit->fallWakeup ? EMU_VMONIO0CTRL_FALLWU : 0)
1676  | (vmonInit->enable ? EMU_VMONIO0CTRL_EN : 0);
1677  break;
1678  default:
1679  EFM_ASSERT(false);
1680  return;
1681  }
1682 }
1683 
1684 /***************************************************************************/
1695 void EMU_VmonHystInit(EMU_VmonHystInit_TypeDef *vmonInit)
1696 {
1697  uint32_t riseThresholdCoarse, riseThresholdFine, fallThresholdCoarse, fallThresholdFine;
1698  /* VMON supports voltages between 1200 mV and 3980 mV (inclusive) in 20 mV increments */
1699  EFM_ASSERT((vmonInit->riseThreshold >= 1200) && (vmonInit->riseThreshold < 4000));
1700  EFM_ASSERT((vmonInit->fallThreshold >= 1200) && (vmonInit->fallThreshold < 4000));
1701  /* Fall threshold has to be lower than rise threshold */
1702  EFM_ASSERT(vmonInit->fallThreshold <= vmonInit->riseThreshold);
1703 
1704  riseThresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->riseThreshold);
1705  riseThresholdFine = vmonMilliVoltToFineThreshold(vmonInit->riseThreshold, riseThresholdCoarse);
1706  fallThresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->fallThreshold);
1707  fallThresholdFine = vmonMilliVoltToFineThreshold(vmonInit->fallThreshold, fallThresholdCoarse);
1708 
1709  switch(vmonInit->channel)
1710  {
1711  case emuVmonChannel_AVDD:
1712  EMU->VMONAVDDCTRL = (riseThresholdCoarse << _EMU_VMONAVDDCTRL_RISETHRESCOARSE_SHIFT)
1713  | (riseThresholdFine << _EMU_VMONAVDDCTRL_RISETHRESFINE_SHIFT)
1714  | (fallThresholdCoarse << _EMU_VMONAVDDCTRL_FALLTHRESCOARSE_SHIFT)
1715  | (fallThresholdFine << _EMU_VMONAVDDCTRL_FALLTHRESFINE_SHIFT)
1716  | (vmonInit->riseWakeup ? EMU_VMONAVDDCTRL_RISEWU : 0)
1717  | (vmonInit->fallWakeup ? EMU_VMONAVDDCTRL_FALLWU : 0)
1718  | (vmonInit->enable ? EMU_VMONAVDDCTRL_EN : 0);
1719  break;
1720  default:
1721  EFM_ASSERT(false);
1722  return;
1723  }
1724 }
1725 
1726 /***************************************************************************/
1736 void EMU_VmonEnable(EMU_VmonChannel_TypeDef channel, bool enable)
1737 {
1738  uint32_t volatile * reg;
1739  uint32_t bit;
1740 
1741  switch(channel)
1742  {
1743  case emuVmonChannel_AVDD:
1744  reg = &(EMU->VMONAVDDCTRL);
1745  bit = _EMU_VMONAVDDCTRL_EN_SHIFT;
1746  break;
1747  case emuVmonChannel_ALTAVDD:
1748  reg = &(EMU->VMONALTAVDDCTRL);
1749  bit = _EMU_VMONALTAVDDCTRL_EN_SHIFT;
1750  break;
1751  case emuVmonChannel_DVDD:
1752  reg = &(EMU->VMONDVDDCTRL);
1753  bit = _EMU_VMONDVDDCTRL_EN_SHIFT;
1754  break;
1755  case emuVmonChannel_IOVDD0:
1756  reg = &(EMU->VMONIO0CTRL);
1757  bit = _EMU_VMONIO0CTRL_EN_SHIFT;
1758  break;
1759  default:
1760  EFM_ASSERT(false);
1761  return;
1762  }
1763 
1764  BUS_RegBitWrite(reg, bit, enable);
1765 }
1766 
1767 /***************************************************************************/
1777 bool EMU_VmonChannelStatusGet(EMU_VmonChannel_TypeDef channel)
1778 {
1779  uint32_t bit;
1780  switch(channel)
1781  {
1782  case emuVmonChannel_AVDD:
1783  bit = _EMU_STATUS_VMONAVDD_SHIFT;
1784  break;
1785  case emuVmonChannel_ALTAVDD:
1786  bit = _EMU_STATUS_VMONALTAVDD_SHIFT;
1787  break;
1788  case emuVmonChannel_DVDD:
1789  bit = _EMU_STATUS_VMONDVDD_SHIFT;
1790  break;
1791  case emuVmonChannel_IOVDD0:
1792  bit = _EMU_STATUS_VMONIO0_SHIFT;
1793  break;
1794  default:
1795  EFM_ASSERT(false);
1796  bit = 0;
1797  }
1798 
1799  return BUS_RegBitRead(&EMU->STATUS, bit);
1800 }
1801 #endif /* EMU_STATUS_VMONRDY */
1802 
1805 #endif /* __EM_EMU_H */
Clock management unit (CMU) API.
#define CMU_STATUS_HFXOENS
Definition: efm32g_cmu.h:440
__STATIC_INLINE void CMU_Lock(void)
Lock the CMU in order to protect some of its registers against unintended modification.
Definition: em_cmu.h:1318
Emlib peripheral API "assert" implementation.
#define CMU_STATUS_LFRCORDY
Definition: efm32g_cmu.h:465
void EMU_EnterEM4(void)
Enter energy mode 4 (EM4).
Definition: em_emu.c:626
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev)
Get chip major/minor revision.
Definition: em_system.c:58
#define CMU_STATUS_HFRCOENS
Definition: efm32g_cmu.h:430
void EMU_MemPwrDown(uint32_t blocks)
Power down memory block.
Definition: em_emu.c:687
#define CMU_OSCENCMD_AUXHFRCOEN
Definition: efm32g_cmu.h:347
#define CMU_LOCK_LOCKKEY_LOCKED
Definition: efm32g_cmu.h:1036
#define CMU_STATUS_LFRCOENS
Definition: efm32g_cmu.h:460
void EMU_EnterEM3(bool restore)
Enter energy mode 3 (EM3).
Definition: em_emu.c:529
void EMU_EnterEM2(bool restore)
Enter energy mode 2 (EM2).
Definition: em_emu.c:413
#define CMU_STATUS_LFXOSEL
Definition: efm32g_cmu.h:495
#define EMU_CTRL_EMVREG
Definition: efm32g_emu.h:58
#define CMU_OSCENCMD_HFRCODIS
Definition: efm32g_cmu.h:332
#define _ROMTABLE_PID0_REVMAJOR_MASK
#define DEVINFO
__STATIC_INLINE unsigned int BUS_RegBitRead(volatile const uint32_t *addr, unsigned int bit)
Perform a single-bit read operation on a peripheral register.
Definition: em_bus.h:185
#define _ROMTABLE_PID2_REVMINORMSB_SHIFT
#define _ROMTABLE_PID0_REVMAJOR_SHIFT
#define EMU
__STATIC_INLINE void EMU_Unlock(void)
Unlock the EMU so that writing to locked registers again is possible.
Definition: em_emu.h:660
#define CMU_STATUS_HFXOSEL
Definition: efm32g_cmu.h:485
#define _ROMTABLE_PID2_REVMINORMSB_MASK
#define RMU
#define _EMU_MEMCTRL_POWERDOWN_SHIFT
Definition: efm32g_emu.h:80
EMU_BODMode_TypeDef
Definition: em_emu.h:121
__STATIC_INLINE SYSTEM_PartFamily_TypeDef SYSTEM_GetFamily(void)
Get family identifier of the MCU.
Definition: em_system.h:364
#define CMU_STATUS_LFRCOSEL
Definition: efm32g_cmu.h:490
#define CMU_OSCENCMD_LFRCOEN
Definition: efm32g_cmu.h:357
#define CMU_CMD_HFCLKSEL_LFXO
Definition: efm32g_cmu.h:392
#define CMU_STATUS_LFXOENS
Definition: efm32g_cmu.h:470
#define CMU_CMD_HFCLKSEL_LFRCO
Definition: efm32g_cmu.h:391
#define CMU_OSCENCMD_LFRCODIS
Definition: efm32g_cmu.h:362
#define CMU_OSCENCMD_LFXOEN
Definition: efm32g_cmu.h:367
#define ROMTABLE
#define _EMU_MEMCTRL_POWERDOWN_MASK
Definition: efm32g_emu.h:81
void EMU_EM23Init(EMU_EM23Init_TypeDef *em23Init)
Update EMU module with Energy Mode 2 and 3 configuration.
Definition: em_emu.c:753
#define CMU_OSCENCMD_HFRCOEN
Definition: efm32g_cmu.h:327
#define _EMU_CTRL_EM4CTRL_MASK
Definition: efm32g_emu.h:73
#define CMU_OSCENCMD_HFXOEN
Definition: efm32g_cmu.h:337
Energy management unit (EMU) peripheral API.
#define CMU
#define _ROMTABLE_PID3_REVMINORLSB_MASK
#define _EMU_CTRL_EM4CTRL_SHIFT
Definition: efm32g_emu.h:72
System API.
#define CMU_OSCENCMD_LFXODIS
Definition: efm32g_cmu.h:372
#define CMU_STATUS_AUXHFRCOENS
Definition: efm32g_cmu.h:450
static __INLINE void SystemCoreClockUpdate(void)
Update CMSIS SystemCoreClock variable.
#define _ROMTABLE_PID3_REVMINORLSB_SHIFT
#define CMU_STATUS_LFXORDY
Definition: efm32g_cmu.h:475
#define CMU_CMD_HFCLKSEL_HFXO
Definition: efm32g_cmu.h:390
__STATIC_INLINE void BUS_RegBitWrite(volatile uint32_t *addr, unsigned int bit, unsigned int val)
Perform a single-bit write operation on a peripheral register.
Definition: em_bus.h:146
#define CMU_STATUS_HFRCOSEL
Definition: efm32g_cmu.h:480
#define CMU_STATUS_HFXORDY
Definition: efm32g_cmu.h:445
void EMU_UpdateOscConfig(void)
Update EMU module with CMU oscillator selection/enable status.
Definition: em_emu.c:736
__STATIC_INLINE void CMU_Unlock(void)
Unlock the CMU so that writing to locked registers again is possible.
Definition: em_cmu.h:1374
SYSTEM_PartFamily_TypeDef
Definition: em_system.h:58