EFM32 Giant Gecko Software Documentation  efm32gg-doc-5.1.2
em_adc.c
Go to the documentation of this file.
1 /***************************************************************************/
33 #include "em_adc.h"
34 #if defined( ADC_COUNT ) && ( ADC_COUNT > 0 )
35 
36 #include "em_assert.h"
37 #include "em_cmu.h"
38 #include <stddef.h>
39 
40 /***************************************************************************/
45 /***************************************************************************/
55 /*******************************************************************************
56  ******************************* DEFINES ***********************************
57  ******************************************************************************/
58 
62 #define ADC_REF_VALID(ref) ((ref) == ADC0)
63 
65 #if defined( _SILICON_LABS_32B_SERIES_0 )
66 #define ADC_MAX_CLOCK 13000000
67 #else
68 #define ADC_MAX_CLOCK 16000000
69 #endif
70 
72 #define ADC_MIN_CLOCK 32000
73 
75 #if defined( _DEVINFO_ADC0CAL0_1V25_GAIN_MASK )
76 #define DEVINFO_ADC0_GAIN1V25_MASK _DEVINFO_ADC0CAL0_1V25_GAIN_MASK
77 #elif defined( _DEVINFO_ADC0CAL0_GAIN1V25_MASK )
78 #define DEVINFO_ADC0_GAIN1V25_MASK _DEVINFO_ADC0CAL0_GAIN1V25_MASK
79 #endif
80 
81 #if defined( _DEVINFO_ADC0CAL0_1V25_GAIN_SHIFT )
82 #define DEVINFO_ADC0_GAIN1V25_SHIFT _DEVINFO_ADC0CAL0_1V25_GAIN_SHIFT
83 #elif defined( _DEVINFO_ADC0CAL0_GAIN1V25_SHIFT )
84 #define DEVINFO_ADC0_GAIN1V25_SHIFT _DEVINFO_ADC0CAL0_GAIN1V25_SHIFT
85 #endif
86 
87 #if defined( _DEVINFO_ADC0CAL0_1V25_OFFSET_MASK )
88 #define DEVINFO_ADC0_OFFSET1V25_MASK _DEVINFO_ADC0CAL0_1V25_OFFSET_MASK
89 #elif defined( _DEVINFO_ADC0CAL0_OFFSET1V25_MASK )
90 #define DEVINFO_ADC0_OFFSET1V25_MASK _DEVINFO_ADC0CAL0_OFFSET1V25_MASK
91 #endif
92 
93 #if defined( _DEVINFO_ADC0CAL0_1V25_OFFSET_SHIFT )
94 #define DEVINFO_ADC0_OFFSET1V25_SHIFT _DEVINFO_ADC0CAL0_1V25_OFFSET_SHIFT
95 #elif defined( _DEVINFO_ADC0CAL0_OFFSET1V25_SHIFT )
96 #define DEVINFO_ADC0_OFFSET1V25_SHIFT _DEVINFO_ADC0CAL0_OFFSET1V25_SHIFT
97 #endif
98 
99 #if defined( _DEVINFO_ADC0CAL0_2V5_GAIN_MASK )
100 #define DEVINFO_ADC0_GAIN2V5_MASK _DEVINFO_ADC0CAL0_2V5_GAIN_MASK
101 #elif defined( _DEVINFO_ADC0CAL0_GAIN2V5_MASK )
102 #define DEVINFO_ADC0_GAIN2V5_MASK _DEVINFO_ADC0CAL0_GAIN2V5_MASK
103 #endif
104 
105 #if defined( _DEVINFO_ADC0CAL0_2V5_GAIN_SHIFT )
106 #define DEVINFO_ADC0_GAIN2V5_SHIFT _DEVINFO_ADC0CAL0_2V5_GAIN_SHIFT
107 #elif defined( _DEVINFO_ADC0CAL0_GAIN2V5_SHIFT )
108 #define DEVINFO_ADC0_GAIN2V5_SHIFT _DEVINFO_ADC0CAL0_GAIN2V5_SHIFT
109 #endif
110 
111 #if defined( _DEVINFO_ADC0CAL0_2V5_OFFSET_MASK )
112 #define DEVINFO_ADC0_OFFSET2V5_MASK _DEVINFO_ADC0CAL0_2V5_OFFSET_MASK
113 #elif defined( _DEVINFO_ADC0CAL0_OFFSET2V5_MASK )
114 #define DEVINFO_ADC0_OFFSET2V5_MASK _DEVINFO_ADC0CAL0_OFFSET2V5_MASK
115 #endif
116 
117 #if defined( _DEVINFO_ADC0CAL0_2V5_OFFSET_SHIFT )
118 #define DEVINFO_ADC0_OFFSET2V5_SHIFT _DEVINFO_ADC0CAL0_2V5_OFFSET_SHIFT
119 #elif defined( _DEVINFO_ADC0CAL0_OFFSET2V5_SHIFT )
120 #define DEVINFO_ADC0_OFFSET2V5_SHIFT _DEVINFO_ADC0CAL0_OFFSET2V5_SHIFT
121 #endif
122 
123 #if defined( _DEVINFO_ADC0CAL1_VDD_GAIN_MASK )
124 #define DEVINFO_ADC0_GAINVDD_MASK _DEVINFO_ADC0CAL1_VDD_GAIN_MASK
125 #elif defined( _DEVINFO_ADC0CAL1_GAINVDD_MASK )
126 #define DEVINFO_ADC0_GAINVDD_MASK _DEVINFO_ADC0CAL1_GAINVDD_MASK
127 #endif
128 
129 #if defined( _DEVINFO_ADC0CAL1_VDD_GAIN_SHIFT )
130 #define DEVINFO_ADC0_GAINVDD_SHIFT _DEVINFO_ADC0CAL1_VDD_GAIN_SHIFT
131 #elif defined( _DEVINFO_ADC0CAL1_GAINVDD_SHIFT )
132 #define DEVINFO_ADC0_GAINVDD_SHIFT _DEVINFO_ADC0CAL1_GAINVDD_SHIFT
133 #endif
134 
135 #if defined( _DEVINFO_ADC0CAL1_VDD_OFFSET_MASK )
136 #define DEVINFO_ADC0_OFFSETVDD_MASK _DEVINFO_ADC0CAL1_VDD_OFFSET_MASK
137 #elif defined( _DEVINFO_ADC0CAL1_OFFSETVDD_MASK )
138 #define DEVINFO_ADC0_OFFSETVDD_MASK _DEVINFO_ADC0CAL1_OFFSETVDD_MASK
139 #endif
140 
141 #if defined( _DEVINFO_ADC0CAL1_VDD_OFFSET_SHIFT )
142 #define DEVINFO_ADC0_OFFSETVDD_SHIFT _DEVINFO_ADC0CAL1_VDD_OFFSET_SHIFT
143 #elif defined( _DEVINFO_ADC0CAL1_OFFSETVDD_SHIFT )
144 #define DEVINFO_ADC0_OFFSETVDD_SHIFT _DEVINFO_ADC0CAL1_OFFSETVDD_SHIFT
145 #endif
146 
147 #if defined( _DEVINFO_ADC0CAL1_5VDIFF_GAIN_MASK )
148 #define DEVINFO_ADC0_GAIN5VDIFF_MASK _DEVINFO_ADC0CAL1_5VDIFF_GAIN_MASK
149 #elif defined( _DEVINFO_ADC0CAL1_GAIN5VDIFF_MASK )
150 #define DEVINFO_ADC0_GAIN5VDIFF_MASK _DEVINFO_ADC0CAL1_GAIN5VDIFF_MASK
151 #endif
152 
153 #if defined( _DEVINFO_ADC0CAL1_5VDIFF_GAIN_SHIFT )
154 #define DEVINFO_ADC0_GAIN5VDIFF_SHIFT _DEVINFO_ADC0CAL1_5VDIFF_GAIN_SHIFT
155 #elif defined( _DEVINFO_ADC0CAL1_GAIN5VDIFF_SHIFT )
156 #define DEVINFO_ADC0_GAIN5VDIFF_SHIFT _DEVINFO_ADC0CAL1_GAIN5VDIFF_SHIFT
157 #endif
158 
159 #if defined( _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_MASK )
160 #define DEVINFO_ADC0_OFFSET5VDIFF_MASK _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_MASK
161 #elif defined( _DEVINFO_ADC0CAL1_OFFSET5VDIFF_MASK )
162 #define DEVINFO_ADC0_OFFSET5VDIFF_MASK _DEVINFO_ADC0CAL1_OFFSET5VDIFF_MASK
163 #endif
164 
165 #if defined( _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_SHIFT )
166 #define DEVINFO_ADC0_OFFSET5VDIFF_SHIFT _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_SHIFT
167 #elif defined( _DEVINFO_ADC0CAL1_OFFSET5VDIFF_SHIFT )
168 #define DEVINFO_ADC0_OFFSET5VDIFF_SHIFT _DEVINFO_ADC0CAL1_OFFSET5VDIFF_SHIFT
169 #endif
170 
171 #if defined( _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_MASK )
172 #define DEVINFO_ADC0_OFFSET2XVDD_MASK _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_MASK
173 #elif defined( _DEVINFO_ADC0CAL2_OFFSET2XVDD_MASK )
174 #define DEVINFO_ADC0_OFFSET2XVDD_MASK _DEVINFO_ADC0CAL2_OFFSET2XVDD_MASK
175 #endif
176 
177 #if defined( _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_SHIFT )
178 #define DEVINFO_ADC0_OFFSET2XVDD_SHIFT _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_SHIFT
179 #elif defined( _DEVINFO_ADC0CAL2_OFFSET2XVDD_SHIFT )
180 #define DEVINFO_ADC0_OFFSET2XVDD_SHIFT _DEVINFO_ADC0CAL2_OFFSET2XVDD_SHIFT
181 #endif
182 
183 #if defined( _SILICON_LABS_32B_SERIES_1 )
184 #define FIX_ADC_TEMP_BIAS_EN
185 #endif
186 
189 /*******************************************************************************
190  *************************** LOCAL FUNCTIONS *******************************
191  ******************************************************************************/
192 
195 /***************************************************************************/
215 static void ADC_LoadDevinfoCal(ADC_TypeDef *adc,
216  ADC_Ref_TypeDef ref,
217  bool setScanCal)
218 {
219  uint32_t calReg;
220  uint32_t newCal;
221  uint32_t mask;
222  uint32_t shift;
223 
224  if (setScanCal)
225  {
227  mask = ~(_ADC_CAL_SCANOFFSET_MASK
228 #if defined( _ADC_CAL_SCANOFFSETINV_MASK )
229  | _ADC_CAL_SCANOFFSETINV_MASK
230 #endif
232  }
233  else
234  {
237 #if defined( _ADC_CAL_SINGLEOFFSETINV_MASK )
238  | _ADC_CAL_SINGLEOFFSETINV_MASK
239 #endif
241  }
242 
243  calReg = adc->CAL & mask;
244  newCal = 0;
245 
246  switch (ref)
247  {
248  case adcRef1V25:
249  newCal |= ((DEVINFO->ADC0CAL0 & DEVINFO_ADC0_GAIN1V25_MASK)
250  >> DEVINFO_ADC0_GAIN1V25_SHIFT)
252  newCal |= ((DEVINFO->ADC0CAL0 & DEVINFO_ADC0_OFFSET1V25_MASK)
253  >> DEVINFO_ADC0_OFFSET1V25_SHIFT)
255 #if defined( _ADC_CAL_SINGLEOFFSETINV_MASK )
256  newCal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_NEGSEOFFSET1V25_MASK)
257  >> _DEVINFO_ADC0CAL0_NEGSEOFFSET1V25_SHIFT)
258  << _ADC_CAL_SINGLEOFFSETINV_SHIFT;
259 #endif
260  break;
261 
262  case adcRef2V5:
263  newCal |= ((DEVINFO->ADC0CAL0 & DEVINFO_ADC0_GAIN2V5_MASK)
264  >> DEVINFO_ADC0_GAIN2V5_SHIFT)
266  newCal |= ((DEVINFO->ADC0CAL0 & DEVINFO_ADC0_OFFSET2V5_MASK)
267  >> DEVINFO_ADC0_OFFSET2V5_SHIFT)
269 #if defined( _ADC_CAL_SINGLEOFFSETINV_MASK )
270  newCal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_NEGSEOFFSET2V5_MASK)
271  >> _DEVINFO_ADC0CAL0_NEGSEOFFSET2V5_SHIFT)
272  << _ADC_CAL_SINGLEOFFSETINV_SHIFT;
273 #endif
274  break;
275 
276  case adcRefVDD:
277  newCal |= ((DEVINFO->ADC0CAL1 & DEVINFO_ADC0_GAINVDD_MASK)
278  >> DEVINFO_ADC0_GAINVDD_SHIFT)
280  newCal |= ((DEVINFO->ADC0CAL1 & DEVINFO_ADC0_OFFSETVDD_MASK)
281  >> DEVINFO_ADC0_OFFSETVDD_SHIFT)
283 #if defined( _ADC_CAL_SINGLEOFFSETINV_MASK )
284  newCal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_NEGSEOFFSETVDD_MASK)
285  >> _DEVINFO_ADC0CAL1_NEGSEOFFSETVDD_SHIFT)
286  << _ADC_CAL_SINGLEOFFSETINV_SHIFT;
287 #endif
288  break;
289 
290  case adcRef5VDIFF:
291  newCal |= ((DEVINFO->ADC0CAL1 & DEVINFO_ADC0_GAIN5VDIFF_MASK)
292  >> DEVINFO_ADC0_GAIN5VDIFF_SHIFT)
294  newCal |= ((DEVINFO->ADC0CAL1 & DEVINFO_ADC0_OFFSET5VDIFF_MASK)
295  >> DEVINFO_ADC0_OFFSET5VDIFF_SHIFT)
297 #if defined( _ADC_CAL_SINGLEOFFSETINV_MASK )
298  newCal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_NEGSEOFFSET5VDIFF_MASK)
299  >> _DEVINFO_ADC0CAL1_NEGSEOFFSET5VDIFF_SHIFT)
300  << _ADC_CAL_SINGLEOFFSETINV_SHIFT;
301 #endif
302  break;
303 
304  case adcRef2xVDD:
305  /* There is no gain calibration for this reference */
306  newCal |= ((DEVINFO->ADC0CAL2 & DEVINFO_ADC0_OFFSET2XVDD_MASK)
307  >> DEVINFO_ADC0_OFFSET2XVDD_SHIFT)
309 #if defined( _ADC_CAL_SINGLEOFFSETINV_MASK )
310  newCal |= ((DEVINFO->ADC0CAL2 & _DEVINFO_ADC0CAL2_NEGSEOFFSET2XVDD_MASK)
311  >> _DEVINFO_ADC0CAL2_NEGSEOFFSET2XVDD_SHIFT)
312  << _ADC_CAL_SINGLEOFFSETINV_SHIFT;
313 #endif
314  break;
315 
316 #if defined( _ADC_SINGLECTRLX_VREFSEL_VDDXWATT )
317  case adcRefVddxAtt:
318  newCal |= ((DEVINFO->ADC0CAL1 & DEVINFO_ADC0_GAINVDD_MASK)
319  >> DEVINFO_ADC0_GAINVDD_SHIFT)
321  newCal |= ((DEVINFO->ADC0CAL1 & DEVINFO_ADC0_OFFSETVDD_MASK)
322  >> DEVINFO_ADC0_OFFSETVDD_SHIFT)
324  newCal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_NEGSEOFFSETVDD_MASK)
325  >> _DEVINFO_ADC0CAL1_NEGSEOFFSETVDD_SHIFT)
326  << _ADC_CAL_SINGLEOFFSETINV_SHIFT;
327  break;
328 #endif
329 
330  /* For external references, the calibration must be determined for the
331  specific application and set by the user. Calibration data is also not
332  available for the internal references adcRefVBGR, adcRefVEntropy and
333  adcRefVBGRlow. */
334  default:
335  newCal = 0;
336  break;
337  }
338 
339  adc->CAL = calReg | (newCal << shift);
340 }
341 
344 /*******************************************************************************
345  ************************** GLOBAL FUNCTIONS *******************************
346  ******************************************************************************/
347 
348 /***************************************************************************/
371 void ADC_Init(ADC_TypeDef *adc, const ADC_Init_TypeDef *init)
372 {
373  uint32_t tmp;
374  uint8_t presc = init->prescale;
375 
376  EFM_ASSERT(ADC_REF_VALID(adc));
377 
378  if (presc == 0)
379  {
380  /* Assume maximum ADC clock for prescaler 0 */
381  presc = ADC_PrescaleCalc(ADC_MAX_CLOCK, 0);
382  }
383  else
384  {
385  /* Check prescaler bounds against ADC_MAX_CLOCK and ADC_MIN_CLOCK */
386 #if defined(_ADC_CTRL_ADCCLKMODE_MASK)
387  if (ADC0->CTRL & ADC_CTRL_ADCCLKMODE_SYNC)
388 #endif
389  {
390  EFM_ASSERT(presc >= ADC_PrescaleCalc(ADC_MAX_CLOCK, 0));
391  EFM_ASSERT(presc <= ADC_PrescaleCalc(ADC_MIN_CLOCK, 0));
392  }
393  }
394 
395  /* Make sure conversion is not in progress */
397 
398  tmp = ((uint32_t)(init->ovsRateSel) << _ADC_CTRL_OVSRSEL_SHIFT)
399  | (((uint32_t)(init->timebase) << _ADC_CTRL_TIMEBASE_SHIFT)
401  | (((uint32_t)(presc) << _ADC_CTRL_PRESC_SHIFT)
403 #if defined ( _ADC_CTRL_LPFMODE_MASK )
404  | ((uint32_t)(init->lpfMode) << _ADC_CTRL_LPFMODE_SHIFT)
405 #endif
406  | ((uint32_t)(init->warmUpMode) << _ADC_CTRL_WARMUPMODE_SHIFT);
407 
408  if (init->tailgate)
409  {
410  tmp |= ADC_CTRL_TAILGATE;
411  }
412  adc->CTRL = tmp;
413 
414  /* Set ADC EM2 clock configuration */
415 #if defined( _ADC_CTRL_ADCCLKMODE_MASK )
416  BUS_RegMaskedWrite(&ADC0->CTRL,
417  _ADC_CTRL_ADCCLKMODE_MASK | _ADC_CTRL_ASYNCCLKEN_MASK,
418  init->em2ClockConfig);
419 #endif
420 
421 #if defined( _SILICON_LABS_GECKO_INTERNAL_SDID_80 )
422  /* A debugger can trigger the SCANUF interrupt on EFM32xG1 or EFR32xG1 */
423  ADC_IntClear(adc, ADC_IFC_SCANUF);
424 #endif
425 }
426 
427 
428 #if defined( _ADC_SCANINPUTSEL_MASK )
429 /***************************************************************************/
436 void ADC_ScanInputClear(ADC_InitScan_TypeDef *scanInit)
437 {
438  /* Clear input configuration */
439 
440  /* Select none */
441  scanInit->scanInputConfig.scanInputSel = ADC_SCANINPUTSEL_NONE;
442  scanInit->scanInputConfig.scanInputEn = 0;
443 
444  /* Default alternative negative inputs */
445  scanInit->scanInputConfig.scanNegSel = _ADC_SCANNEGSEL_RESETVALUE;
446 }
447 
448 
449 /***************************************************************************/
471 uint32_t ADC_ScanSingleEndedInputAdd(ADC_InitScan_TypeDef *scanInit,
472  ADC_ScanInputGroup_TypeDef inputGroup,
473  ADC_PosSel_TypeDef singleEndedSel)
474 {
475  uint32_t currentSel;
476  uint32_t newSel;
477  uint32_t scanId;
478 
479  scanInit->diff = false;
480 
481  /* Check for unsupported APORTs */
482  EFM_ASSERT((singleEndedSel <= adcPosSelAPORT0YCH0) || (singleEndedSel >= adcPosSelAPORT0YCH15));
483 
484  /* Decode the input group select by shifting right by 3 */
485  newSel = singleEndedSel >> 3;
486 
487  currentSel = (scanInit->scanInputConfig.scanInputSel >> (inputGroup * 8)) & 0xFF;
488 
489  /* If none selected */
490  if (currentSel == ADC_SCANINPUTSEL_GROUP_NONE)
491  {
492  scanInit->scanInputConfig.scanInputSel &= ~(0xFF << (inputGroup * 8));
493  scanInit->scanInputConfig.scanInputSel |= (newSel << (inputGroup * 8));
494  }
495  else if (currentSel == newSel)
496  {
497  /* Ok, but do nothing. */
498  }
499  else
500  {
501  /* Invalid channel range. A range is already selected for this group. */
502  EFM_ASSERT(false);
503  }
504 
505  /* Update and return scan input enable mask (SCANMASK) */
506  scanId = (inputGroup * 8) + (singleEndedSel & 0x7);
507  EFM_ASSERT(scanId < 32);
508  scanInit->scanInputConfig.scanInputEn |= 0x1 << scanId;
509  return scanId;
510 }
511 
512 
513 /***************************************************************************/
543 uint32_t ADC_ScanDifferentialInputAdd(ADC_InitScan_TypeDef *scanInit,
544  ADC_ScanInputGroup_TypeDef inputGroup,
545  ADC_PosSel_TypeDef posSel,
546  ADC_ScanNegInput_TypeDef negInput)
547 {
548  uint32_t negInputRegMask = 0;
549  uint32_t negInputRegShift = 0;
550  uint32_t negInputRegVal = 0;
551  uint32_t scanId = 0;
552 
553  /* Do a single ended init, then update for differential scan. */
554  scanId = ADC_ScanSingleEndedInputAdd(scanInit, inputGroup, posSel);
555 
556  /* Reset to differential mode */
557  scanInit->diff = true;
558 
559  /* Set negative ADC input, unless the default is selected. */
560  if (negInput != adcScanNegInputDefault)
561  {
562  if (scanId == 0)
563  {
564  negInputRegMask = _ADC_SCANNEGSEL_INPUT0NEGSEL_MASK;
565  negInputRegShift = _ADC_SCANNEGSEL_INPUT0NEGSEL_SHIFT;
566  EFM_ASSERT(inputGroup == 0);
567  }
568  else if (scanId == 2)
569  {
570  negInputRegMask = _ADC_SCANNEGSEL_INPUT2NEGSEL_MASK;
571  negInputRegShift = _ADC_SCANNEGSEL_INPUT2NEGSEL_SHIFT;
572  EFM_ASSERT(inputGroup == 0);
573  }
574  else if (scanId == 4)
575  {
576  negInputRegMask = _ADC_SCANNEGSEL_INPUT4NEGSEL_MASK;
577  negInputRegShift = _ADC_SCANNEGSEL_INPUT4NEGSEL_SHIFT;
578  EFM_ASSERT(inputGroup == 0);
579  }
580  else if (scanId == 6)
581  {
582  negInputRegMask = _ADC_SCANNEGSEL_INPUT6NEGSEL_MASK;
583  negInputRegShift = _ADC_SCANNEGSEL_INPUT6NEGSEL_SHIFT;
584  EFM_ASSERT(inputGroup == 0);
585  }
586  else if (scanId == 9)
587  {
588  negInputRegMask = _ADC_SCANNEGSEL_INPUT9NEGSEL_MASK;
589  negInputRegShift = _ADC_SCANNEGSEL_INPUT9NEGSEL_SHIFT;
590  EFM_ASSERT(inputGroup == 1);
591  }
592  else if (scanId == 11)
593  {
594  negInputRegMask = _ADC_SCANNEGSEL_INPUT11NEGSEL_MASK;
595  negInputRegShift = _ADC_SCANNEGSEL_INPUT11NEGSEL_SHIFT;
596  EFM_ASSERT(inputGroup == 1);
597  }
598  else if (scanId == 13)
599  {
600  negInputRegMask = _ADC_SCANNEGSEL_INPUT13NEGSEL_MASK;
601  negInputRegShift = _ADC_SCANNEGSEL_INPUT13NEGSEL_SHIFT;
602  EFM_ASSERT(inputGroup == 1);
603  }
604  else if (scanId == 15)
605  {
606  negInputRegMask = _ADC_SCANNEGSEL_INPUT15NEGSEL_MASK;
607  negInputRegShift = _ADC_SCANNEGSEL_INPUT15NEGSEL_SHIFT;
608  EFM_ASSERT(inputGroup == 1);
609  }
610  else
611  {
612  /* There is not negative input option for this positive input (negInput is posInput + 1). */
613  EFM_ASSERT(false);
614  }
615 
616  /* Find ADC_SCANNEGSEL_CHxNSEL value for positive input 0, 2, 4 and 6 */
617  if (inputGroup == 0)
618  {
619  switch (negInput)
620  {
621  case adcScanNegInput1:
622  negInputRegVal = _ADC_SCANNEGSEL_INPUT0NEGSEL_INPUT1;
623  break;
624 
625  case adcScanNegInput3:
626  negInputRegVal = _ADC_SCANNEGSEL_INPUT0NEGSEL_INPUT3;
627  break;
628 
629  case adcScanNegInput5:
630  negInputRegVal = _ADC_SCANNEGSEL_INPUT0NEGSEL_INPUT5;
631  break;
632 
633  case adcScanNegInput7:
634  negInputRegVal = _ADC_SCANNEGSEL_INPUT0NEGSEL_INPUT7;
635  break;
636 
637  default:
638  /* Invalid selection. Options are input 1, 3, 5 and 7. */
639  EFM_ASSERT(false);
640  break;
641  }
642  }
643  else if (inputGroup == 1)
644  {
645  /* Find ADC_SCANNEGSEL_CHxNSEL value for positive input 9, 11, 13 and 15 */
646  switch (negInput)
647  {
648  case adcScanNegInput8:
649  negInputRegVal = _ADC_SCANNEGSEL_INPUT9NEGSEL_INPUT8;
650  break;
651 
652  case adcScanNegInput10:
653  negInputRegVal = _ADC_SCANNEGSEL_INPUT9NEGSEL_INPUT10;
654  break;
655 
656  case adcScanNegInput12:
657  negInputRegVal = _ADC_SCANNEGSEL_INPUT9NEGSEL_INPUT12;
658  break;
659 
660  case adcScanNegInput14:
661  negInputRegVal = _ADC_SCANNEGSEL_INPUT9NEGSEL_INPUT14;
662  break;
663 
664  default:
665  /* Invalid selection. Options are input 8, 10, 12 and 14. */
666  EFM_ASSERT(false);
667  break;
668  }
669  }
670  else
671  {
672  /* No alternative negative input for input group > 1 */
673  EFM_ASSERT(false);
674  }
675 
676  /* Update config */
677  scanInit->scanInputConfig.scanNegSel &= ~negInputRegMask;
678  scanInit->scanInputConfig.scanNegSel |= negInputRegVal << negInputRegShift;
679  }
680  return scanId;
681 }
682 #endif
683 
684 
685 /***************************************************************************/
711 {
712  uint32_t tmp;
713 
714  EFM_ASSERT(ADC_REF_VALID(adc));
715 
716  /* Make sure scan sequence is not in progress */
717  adc->CMD = ADC_CMD_SCANSTOP;
718 
719  /* Load calibration data for selected reference */
720  ADC_LoadDevinfoCal(adc, init->reference, true);
721 
722  tmp = 0
723 #if defined ( _ADC_SCANCTRL_PRSSEL_MASK )
725 #endif
726  | (init->acqTime << _ADC_SCANCTRL_AT_SHIFT)
727 #if defined ( _ADC_SCANCTRL_INPUTMASK_MASK )
728  | init->input
729 #endif
730  | (init->resolution << _ADC_SCANCTRL_RES_SHIFT);
731 
732  if (init->prsEnable)
733  {
734  tmp |= ADC_SCANCTRL_PRSEN;
735  }
736 
737  if (init->leftAdjust)
738  {
739  tmp |= ADC_SCANCTRL_ADJ_LEFT;
740  }
741 
742 #if defined( _ADC_SCANCTRL_INPUTMASK_MASK )
743  if (init->diff)
744 #elif defined( _ADC_SCANINPUTSEL_MASK )
745  if (init->diff)
746 #endif
747  {
748  tmp |= ADC_SCANCTRL_DIFF;
749  }
750 
751  if (init->rep)
752  {
753 #if defined( _SILICON_LABS_GECKO_INTERNAL_SDID_80 )
754  /* Scan repeat mode does not work on EFM32JG1, EFM32PG1 or EFR32xG1x devices.
755  * The errata is called ADC_E211 in the errata document. */
756  EFM_ASSERT(false);
757 #endif
758  tmp |= ADC_SCANCTRL_REP;
759  }
760 
761  /* Set scan reference. Check if reference configuraion is extended to SCANCTRLX. */
762 #if defined ( _ADC_SCANCTRLX_VREFSEL_MASK )
763  if (init->reference & ADC_CTRLX_VREFSEL_REG)
764  {
765  /* Select extension register */
766  tmp |= ADC_SCANCTRL_REF_CONF;
767  }
768  else
769  {
770  tmp |= init->reference << _ADC_SCANCTRL_REF_SHIFT;
771  }
772 #else
773  tmp |= init->reference << _ADC_SCANCTRL_REF_SHIFT;
774 #endif
775 
776 #if defined( _ADC_SCANCTRL_INPUTMASK_MASK )
777  tmp |= init->input;
778 #endif
779 
780  adc->SCANCTRL = tmp;
781 
782  /* Update SINGLECTRLX for reference select and PRS select */
783 #if defined ( _ADC_SCANCTRLX_MASK )
784  tmp = adc->SCANCTRLX & ~(_ADC_SCANCTRLX_VREFSEL_MASK
785  | _ADC_SCANCTRLX_PRSSEL_MASK
786  | _ADC_SCANCTRLX_FIFOOFACT_MASK);
787  if (init->reference & ADC_CTRLX_VREFSEL_REG)
788  {
789  tmp |= (init->reference & ~ADC_CTRLX_VREFSEL_REG) << _ADC_SCANCTRLX_VREFSEL_SHIFT;
790  }
791 
792  tmp |= init->prsSel << _ADC_SCANCTRLX_PRSSEL_SHIFT;
793 
794  if (init->fifoOverwrite)
795  {
796  tmp |= ADC_SCANCTRLX_FIFOOFACT_OVERWRITE;
797  }
798 
799  adc->SCANCTRLX = tmp;
800 #endif
801 
802 #if defined( _ADC_CTRL_SCANDMAWU_MASK )
803  BUS_RegBitWrite(&adc->CTRL, _ADC_CTRL_SCANDMAWU_SHIFT, init->scanDmaEm2Wu);
804 #endif
805 
806  /* Write scan input configuration */
807 #if defined( _ADC_SCANINPUTSEL_MASK )
808  /* Check for valid scan input configuration. Use @ref ADC_ScanInputClear()
809  @ref ADC_ScanSingleEndedInputAdd() and @ref ADC_ScanDifferentialInputAdd() to set
810  scan input configuration. */
811  EFM_ASSERT(init->scanInputConfig.scanInputSel != ADC_SCANINPUTSEL_NONE);
812  adc->SCANINPUTSEL = init->scanInputConfig.scanInputSel;
813  adc->SCANMASK = init->scanInputConfig.scanInputEn;
814  adc->SCANNEGSEL = init->scanInputConfig.scanNegSel;
815 #endif
816 
817  /* Assert for any APORT bus conflicts programming errors */
818 #if defined( _ADC_BUSCONFLICT_MASK )
819  tmp = adc->BUSREQ;
820  EFM_ASSERT(!(tmp & adc->BUSCONFLICT));
821  EFM_ASSERT(!(adc->STATUS & _ADC_STATUS_PROGERR_MASK));
822 #endif
823 }
824 
825 
826 /***************************************************************************/
855 {
856  uint32_t tmp;
857 
858  EFM_ASSERT(ADC_REF_VALID(adc));
859 
860  /* Make sure single conversion is not in progress */
861  adc->CMD = ADC_CMD_SINGLESTOP;
862 
863  /* Load calibration data for selected reference */
864  ADC_LoadDevinfoCal(adc, init->reference, false);
865 
866  tmp = 0
867 #if defined( _ADC_SINGLECTRL_PRSSEL_MASK )
869 #endif
870  | (init->acqTime << _ADC_SINGLECTRL_AT_SHIFT)
871 #if defined( _ADC_SINGLECTRL_INPUTSEL_MASK )
873 #endif
874 #if defined( _ADC_SINGLECTRL_POSSEL_MASK )
875  | (init->posSel << _ADC_SINGLECTRL_POSSEL_SHIFT)
876 #endif
877 #if defined( _ADC_SINGLECTRL_NEGSEL_MASK )
878  | (init->negSel << _ADC_SINGLECTRL_NEGSEL_SHIFT)
879 #endif
880  | ((uint32_t)(init->resolution) << _ADC_SINGLECTRL_RES_SHIFT);
881 
882  if (init->prsEnable)
883  {
884  tmp |= ADC_SINGLECTRL_PRSEN;
885  }
886 
887  if (init->leftAdjust)
888  {
890  }
891 
892  if (init->diff)
893  {
894  tmp |= ADC_SINGLECTRL_DIFF;
895  }
896 
897  if (init->rep)
898  {
899  tmp |= ADC_SINGLECTRL_REP;
900  }
901 
902 #if defined( _ADC_SINGLECTRL_POSSEL_TEMP )
903  /* Force at least 8 cycle acquisition time when reading internal temperature
904  * sensor with 1.25V reference */
905  if ((init->posSel == adcPosSelTEMP)
906  && (init->reference == adcRef1V25)
907  && (init->acqTime < adcAcqTime8))
908  {
909  tmp = (tmp & ~_ADC_SINGLECTRL_AT_MASK)
911  }
912 #endif
913 
914  /* Set single reference. Check if reference configuraion is extended to SINGLECTRLX. */
915 #if defined ( _ADC_SINGLECTRLX_MASK )
916  if (init->reference & ADC_CTRLX_VREFSEL_REG)
917  {
918  /* Select extension register */
919  tmp |= ADC_SINGLECTRL_REF_CONF;
920  }
921  else
922  {
923  tmp |= (init->reference << _ADC_SINGLECTRL_REF_SHIFT);
924  }
925 #else
926  tmp |= (init->reference << _ADC_SINGLECTRL_REF_SHIFT);
927 #endif
928  adc->SINGLECTRL = tmp;
929 
930  /* Update SINGLECTRLX for reference select and PRS select */
931 #if defined ( _ADC_SINGLECTRLX_VREFSEL_MASK )
932  tmp = adc->SINGLECTRLX & (_ADC_SINGLECTRLX_VREFSEL_MASK
933  | _ADC_SINGLECTRLX_PRSSEL_MASK
934  | _ADC_SINGLECTRLX_FIFOOFACT_MASK);
935  if (init->reference & ADC_CTRLX_VREFSEL_REG)
936  {
937  tmp |= ((init->reference & ~ADC_CTRLX_VREFSEL_REG) << _ADC_SINGLECTRLX_VREFSEL_SHIFT);
938  }
939 
940  tmp |= ((init->prsSel << _ADC_SINGLECTRLX_PRSSEL_SHIFT));
941 
942  if (init->fifoOverwrite)
943  {
944  tmp |= ADC_SINGLECTRLX_FIFOOFACT_OVERWRITE;
945  }
946 
947  adc->SINGLECTRLX = tmp;
948 #endif
949 
950  /* Set DMA availability in EM2 */
951 #if defined( _ADC_CTRL_SINGLEDMAWU_MASK )
952  BUS_RegBitWrite(&adc->CTRL, _ADC_CTRL_SINGLEDMAWU_SHIFT, init->singleDmaEm2Wu);
953 #endif
954 
955 #if defined( _ADC_BIASPROG_GPBIASACC_MASK ) && defined( FIX_ADC_TEMP_BIAS_EN )
956  if (init->posSel == adcPosSelTEMP)
957  {
958  /* ADC should always use low accuracy setting when reading the internal
959  * temperature sensor on platform 2 generation 1 devices. Using high
960  * accuracy setting can introduce a glitch. */
961  BUS_RegBitWrite(&adc->BIASPROG, _ADC_BIASPROG_GPBIASACC_SHIFT, 1);
962  }
963  else
964  {
965  BUS_RegBitWrite(&adc->BIASPROG, _ADC_BIASPROG_GPBIASACC_SHIFT, 0);
966  }
967 #endif
968 
969  /* Assert for any APORT bus conflicts programming errors */
970 #if defined( _ADC_BUSCONFLICT_MASK )
971  tmp = adc->BUSREQ;
972  EFM_ASSERT(!(tmp & adc->BUSCONFLICT));
973  EFM_ASSERT(!(adc->STATUS & _ADC_STATUS_PROGERR_MASK));
974 #endif
975 }
976 
977 
978 #if defined( _ADC_SCANDATAX_MASK )
979 /***************************************************************************/
996 uint32_t ADC_DataIdScanGet(ADC_TypeDef *adc, uint32_t *scanId)
997 {
998  uint32_t scanData;
999 
1000  /* Pop data FIFO with scan ID */
1001  scanData = adc->SCANDATAX;
1002  *scanId = (scanData & _ADC_SCANDATAX_SCANINPUTID_MASK) >> _ADC_SCANDATAX_SCANINPUTID_SHIFT;
1003  return (scanData & _ADC_SCANDATAX_DATA_MASK) >> _ADC_SCANDATAX_DATA_SHIFT;
1004 }
1005 #endif
1006 
1007 
1008 /***************************************************************************/
1025 uint8_t ADC_PrescaleCalc(uint32_t adcFreq, uint32_t hfperFreq)
1026 {
1027  uint32_t ret;
1028 
1029  /* Make sure selected ADC clock is within valid range */
1030  if (adcFreq > ADC_MAX_CLOCK)
1031  {
1032  adcFreq = ADC_MAX_CLOCK;
1033  }
1034  else if (adcFreq < ADC_MIN_CLOCK)
1035  {
1036  adcFreq = ADC_MIN_CLOCK;
1037  }
1038 
1039  /* Use current HFPER frequency? */
1040  if (!hfperFreq)
1041  {
1042  hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER);
1043  }
1044 
1045  ret = (hfperFreq + adcFreq - 1) / adcFreq;
1046  if (ret)
1047  {
1048  ret--;
1049  }
1050 
1051  return (uint8_t)ret;
1052 }
1053 
1054 
1055 /***************************************************************************/
1067 {
1068  /* Stop conversions, before resetting other registers. */
1071 #if defined( _ADC_SINGLECTRLX_MASK )
1072  adc->SINGLECTRLX = _ADC_SINGLECTRLX_RESETVALUE;
1073 #endif
1075 #if defined( _ADC_SCANCTRLX_MASK )
1076  adc->SCANCTRLX = _ADC_SCANCTRLX_RESETVALUE;
1077 #endif
1078  adc->CTRL = _ADC_CTRL_RESETVALUE;
1079  adc->IEN = _ADC_IEN_RESETVALUE;
1080  adc->IFC = _ADC_IFC_MASK;
1082 #if defined( _ADC_SCANMASK_MASK )
1083  adc->SCANMASK = _ADC_SCANMASK_RESETVALUE;
1084 #endif
1085 #if defined( _ADC_SCANINPUTSEL_MASK )
1086  adc->SCANINPUTSEL = _ADC_SCANINPUTSEL_RESETVALUE;
1087 #endif
1088 #if defined( _ADC_SCANNEGSEL_MASK )
1089  adc->SCANNEGSEL = _ADC_SCANNEGSEL_RESETVALUE;
1090 #endif
1091 
1092  /* Clear data FIFOs */
1093 #if defined( _ADC_SINGLEFIFOCLEAR_MASK )
1094  adc->SINGLEFIFOCLEAR |= ADC_SINGLEFIFOCLEAR_SINGLEFIFOCLEAR;
1095  adc->SCANFIFOCLEAR |= ADC_SCANFIFOCLEAR_SCANFIFOCLEAR;
1096 #endif
1097 
1098  /* Load calibration values for the 1V25 internal reference. */
1099  ADC_LoadDevinfoCal(adc, adcRef1V25, false);
1100  ADC_LoadDevinfoCal(adc, adcRef1V25, true);
1101 
1102 #if defined( _ADC_SCANINPUTSEL_MASK )
1103  /* Do not reset route register, setting should be done independently */
1104 #endif
1105 }
1106 
1107 
1108 /***************************************************************************/
1118 uint8_t ADC_TimebaseCalc(uint32_t hfperFreq)
1119 {
1120  if (!hfperFreq)
1121  {
1122  hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER);
1123 
1124  /* Just in case, make sure we get non-zero freq for below calculation */
1125  if (!hfperFreq)
1126  {
1127  hfperFreq = 1;
1128  }
1129  }
1130 #if defined( _EFM32_GIANT_FAMILY ) || defined( _EFM32_WONDER_FAMILY )
1131  /* Handle errata on Giant Gecko, max TIMEBASE is 5 bits wide or max 0x1F */
1132  /* cycles. This will give a warmp up time of e.g. 0.645us, not the */
1133  /* required 1us when operating at 48MHz. One must also increase acqTime */
1134  /* to compensate for the missing clock cycles, adding up to 1us in total.*/
1135  /* See reference manual for details. */
1136  if ( hfperFreq > 32000000 )
1137  {
1138  hfperFreq = 32000000;
1139  }
1140 #endif
1141  /* Determine number of HFPERCLK cycle >= 1us */
1142  hfperFreq += 999999;
1143  hfperFreq /= 1000000;
1144 
1145  /* Return timebase value (N+1 format) */
1146  return (uint8_t)(hfperFreq - 1);
1147 }
1148 
1149 
1152 #endif /* defined(ADC_COUNT) && (ADC_COUNT > 0) */
Clock management unit (CMU) API.
#define _ADC_IFC_MASK
Definition: efm32gg_adc.h:581
#define _ADC_SCANCTRL_RES_SHIFT
Definition: efm32gg_adc.h:393
#define _ADC_CAL_SINGLEGAIN_SHIFT
Definition: efm32gg_adc.h:642
#define _ADC_CAL_SCANOFFSET_SHIFT
Definition: efm32gg_adc.h:646
#define _ADC_BIASPROG_RESETVALUE
Definition: efm32gg_adc.h:656
Emlib peripheral API "assert" implementation.
#define _ADC_CAL_SINGLEOFFSET_MASK
Definition: efm32gg_adc.h:639
uint32_t input
Definition: em_adc.h:909
void ADC_Reset(ADC_TypeDef *adc)
Reset ADC to same state as after a HW reset.
Definition: em_adc.c:1066
uint8_t timebase
Definition: em_adc.h:819
#define _ADC_IEN_RESETVALUE
Definition: efm32gg_adc.h:508
#define _ADC_SINGLECTRL_AT_MASK
Definition: efm32gg_adc.h:316
#define _ADC_SINGLECTRL_RESETVALUE
Definition: efm32gg_adc.h:220
ADC_AcqTime_TypeDef acqTime
Definition: em_adc.h:993
#define _ADC_CTRL_LPFMODE_MASK
Definition: efm32gg_adc.h:88
#define _ADC_SCANCTRL_REF_SHIFT
Definition: efm32gg_adc.h:433
#define _ADC_SINGLECTRL_PRSSEL_SHIFT
Definition: efm32gg_adc.h:342
#define _ADC_SINGLECTRL_AT_SHIFT
Definition: efm32gg_adc.h:315
__STATIC_INLINE void ADC_IntClear(ADC_TypeDef *adc, uint32_t flags)
Clear one or more pending ADC interrupts.
Definition: em_adc.h:1194
#define ADC0
#define _ADC_CTRL_RESETVALUE
Definition: efm32gg_adc.h:68
ADC_SingleInput_TypeDef input
Definition: em_adc.h:1009
#define _ADC_CTRL_TIMEBASE_MASK
Definition: efm32gg_adc.h:104
#define ADC_SINGLECTRL_PRSEN
Definition: efm32gg_adc.h:337
#define _ADC_SCANCTRL_PRSSEL_SHIFT
Definition: efm32gg_adc.h:478
ADC_PRSSEL_TypeDef prsSel
Definition: em_adc.h:990
__IOM uint32_t IFC
Definition: efm32gg_adc.h:51
#define _ADC_CTRL_PRESC_SHIFT
Definition: efm32gg_adc.h:97
#define ADC_SCANCTRL_PRSEN
Definition: efm32gg_adc.h:473
#define _ADC_SCANCTRL_RESETVALUE
Definition: efm32gg_adc.h:372
#define _ADC_CTRL_OVSRSEL_SHIFT
Definition: efm32gg_adc.h:107
void ADC_Init(ADC_TypeDef *adc, const ADC_Init_TypeDef *init)
Initialize ADC.
Definition: em_adc.c:371
__IOM uint32_t SINGLECTRL
Definition: efm32gg_adc.h:46
#define ADC_SINGLECTRL_REP
Definition: efm32gg_adc.h:222
#define _ADC_CAL_SINGLEGAIN_MASK
Definition: efm32gg_adc.h:643
ADC_PRSSEL_TypeDef prsSel
Definition: em_adc.h:888
#define _ADC_CTRL_LPFMODE_SHIFT
Definition: efm32gg_adc.h:87
uint8_t ADC_TimebaseCalc(uint32_t hfperFreq)
Calculate timebase value in order to get a timebase providing at least 1us.
Definition: em_adc.c:1118
#define DEVINFO
__IOM uint32_t IEN
Definition: efm32gg_adc.h:48
ADC_Res_TypeDef resolution
Definition: em_adc.h:1002
#define _ADC_CTRL_WARMUPMODE_SHIFT
Definition: efm32gg_adc.h:70
uint8_t prescale
Definition: em_adc.h:822
__IOM uint32_t BIASPROG
Definition: efm32gg_adc.h:59
#define _ADC_CAL_SINGLEOFFSET_SHIFT
Definition: efm32gg_adc.h:638
#define ADC_CTRL_TAILGATE
Definition: efm32gg_adc.h:82
void ADC_InitSingle(ADC_TypeDef *adc, const ADC_InitSingle_TypeDef *init)
Initialize single ADC sample conversion.
Definition: em_adc.c:854
#define _ADC_SINGLECTRL_REF_SHIFT
Definition: efm32gg_adc.h:297
#define ADC_SCANCTRL_DIFF
Definition: efm32gg_adc.h:379
#define ADC_CMD_SCANSTOP
Definition: efm32gg_adc.h:154
__IOM uint32_t CTRL
Definition: efm32gg_adc.h:43
#define _ADC_CAL_SCANGAIN_MASK
Definition: efm32gg_adc.h:651
#define ADC_CMD_SINGLESTOP
Definition: efm32gg_adc.h:144
__STATIC_INLINE void BUS_RegMaskedWrite(volatile uint32_t *addr, uint32_t mask, uint32_t val)
Perform peripheral register masked clear and value write.
Definition: em_bus.h:288
uint8_t ADC_PrescaleCalc(uint32_t adcFreq, uint32_t hfperFreq)
Calculate prescaler value used to determine ADC clock.
Definition: em_adc.c:1025
#define ADC_SINGLECTRL_DIFF
Definition: efm32gg_adc.h:227
ADC_LPFilter_TypeDef lpfMode
Definition: em_adc.h:806
__IOM uint32_t SCANCTRL
Definition: efm32gg_adc.h:47
__IOM uint32_t CAL
Definition: efm32gg_adc.h:56
#define ADC_SINGLECTRL_ADJ_LEFT
Definition: efm32gg_adc.h:240
void ADC_InitScan(ADC_TypeDef *adc, const ADC_InitScan_TypeDef *init)
Initialize ADC scan sequence.
Definition: em_adc.c:710
#define _ADC_CTRL_PRESC_MASK
Definition: efm32gg_adc.h:98
Analog to Digital Converter (ADC) peripheral API.
__IM uint32_t STATUS
Definition: efm32gg_adc.h:45
#define _ADC_SINGLECTRL_RES_SHIFT
Definition: efm32gg_adc.h:241
#define ADC_SCANCTRL_ADJ_LEFT
Definition: efm32gg_adc.h:392
#define _ADC_CTRL_TIMEBASE_SHIFT
Definition: efm32gg_adc.h:103
__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:148
ADC_Ref_TypeDef reference
Definition: em_adc.h:999
#define _ADC_CAL_SCANOFFSET_MASK
Definition: efm32gg_adc.h:647
ADC_OvsRateSel_TypeDef ovsRateSel
Definition: em_adc.h:802
__IOM uint32_t CMD
Definition: efm32gg_adc.h:44
#define _ADC_SCANCTRL_AT_SHIFT
Definition: efm32gg_adc.h:451
uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)
Get clock frequency for a clock point.
Definition: em_cmu.c:1550
ADC_Ref_TypeDef reference
Definition: em_adc.h:897
ADC_Res_TypeDef resolution
Definition: em_adc.h:900
ADC_Ref_TypeDef
Definition: em_adc.h:189
#define _ADC_SINGLECTRL_INPUTSEL_SHIFT
Definition: efm32gg_adc.h:253
ADC_AcqTime_TypeDef acqTime
Definition: em_adc.h:891
ADC_Warmup_TypeDef warmUpMode
Definition: em_adc.h:810
#define ADC_SCANCTRL_REP
Definition: efm32gg_adc.h:374