EFM32 Giant Gecko Software Documentation  efm32gg-doc-5.1.2
em_acmp.c
Go to the documentation of this file.
1 /***************************************************************************/
34 #include "em_acmp.h"
35 #if defined(ACMP_COUNT) && (ACMP_COUNT > 0)
36 
37 #include <stdbool.h>
38 #include "em_bus.h"
39 #include "em_assert.h"
40 
41 /***************************************************************************/
46 /***************************************************************************/
51 /*******************************************************************************
52  ******************************* DEFINES ***********************************
53  ******************************************************************************/
54 
60 #if (ACMP_COUNT == 1)
61 #define ACMP_REF_VALID(ref) ((ref) == ACMP0)
62 #elif (ACMP_COUNT == 2)
63 #define ACMP_REF_VALID(ref) (((ref) == ACMP0) || ((ref) == ACMP1))
64 #else
65 #error Undefined number of analog comparators (ACMP).
66 #endif
67 
70 #if defined(_ACMP_ROUTE_LOCATION_LOC3)
71 #define _ACMP_ROUTE_LOCATION_MAX _ACMP_ROUTE_LOCATION_LOC3
72 #elif defined(_ACMP_ROUTE_LOCATION_LOC2)
73 #define _ACMP_ROUTE_LOCATION_MAX _ACMP_ROUTE_LOCATION_LOC2
74 #elif defined(_ACMP_ROUTE_LOCATION_LOC1)
75 #define _ACMP_ROUTE_LOCATION_MAX _ACMP_ROUTE_LOCATION_LOC1
76 #elif defined(_ACMP_ROUTELOC0_OUTLOC_LOC31)
77 #define _ACMP_ROUTE_LOCATION_MAX _ACMP_ROUTELOC0_OUTLOC_LOC31
78 #else
79 #error Undefined max route locations
80 #endif
81 
84 /*******************************************************************************
85  ************************** GLOBAL FUNCTIONS *******************************
86  ******************************************************************************/
87 
88 /***************************************************************************/
110 {
111  /* Make sure the module exists on the selected chip */
112  EFM_ASSERT(ACMP_REF_VALID(acmp));
113 
114  /* Make sure that vddLevel is within bounds */
115 #if defined(_ACMP_INPUTSEL_VDDLEVEL_MASK)
116  EFM_ASSERT(init->vddLevel < 64);
117 #else
118  EFM_ASSERT(init->vddLevelLow < 64);
119  EFM_ASSERT(init->vddLevelHigh < 64);
120 #endif
121 
122  /* Make sure biasprog is within bounds */
123  EFM_ASSERT(init->biasProg <=
125 
126  /* Set control register. No need to set interrupt modes */
127  acmp->CTRL = (init->fullBias << _ACMP_CTRL_FULLBIAS_SHIFT)
128 #if defined(_ACMP_CTRL_HALFBIAS_MASK)
130 #endif
132 #if defined(_ACMP_CTRL_WARMTIME_MASK)
134 #endif
135 #if defined(_ACMP_CTRL_HYSTSEL_MASK)
137 #endif
138 #if defined(_ACMP_CTRL_ACCURACY_MASK)
139  | ACMP_CTRL_ACCURACY_HIGH
140 #endif
141  ;
142 
143 #if defined(_ACMP_HYSTERESIS0_MASK)
144  acmp->HYSTERESIS0 = (init->vddLevelHigh << _ACMP_HYSTERESIS0_DIVVA_SHIFT)
145  | (init->hysteresisLevel_0 << _ACMP_HYSTERESIS0_HYST_SHIFT);
146  acmp->HYSTERESIS1 = (init->vddLevelLow << _ACMP_HYSTERESIS1_DIVVA_SHIFT)
147  | (init->hysteresisLevel_1 << _ACMP_HYSTERESIS1_HYST_SHIFT);
148 #endif
149 
150  /* Select capacative sensing mode by selecting a resistor and enabling it */
153 #if defined(_ACMP_INPUTSEL_LPREF_MASK)
155 #endif
156 #if defined(_ACMP_INPUTSEL_VDDLEVEL_MASK)
158 #endif
161 #else
162  | ACMP_INPUTSEL_VASEL_VDD
163  | ACMP_INPUTSEL_NEGSEL_VADIV
164 #endif
165  ;
166 
167  /* Enable ACMP if requested. */
169 }
170 
171 /***************************************************************************/
186 {
187  /* Make sure the module exists on the selected chip */
188  EFM_ASSERT(ACMP_REF_VALID(acmp));
189 
190 #if defined(_ACMP_INPUTSEL_POSSEL_CH7)
191  /* Make sure that only external channels are used */
192  EFM_ASSERT(channel <= _ACMP_INPUTSEL_POSSEL_CH7);
193 #elif defined(_ACMP_INPUTSEL_POSSEL_BUS4XCH31)
194  /* Make sure that only external channels are used */
195  EFM_ASSERT(channel <= _ACMP_INPUTSEL_POSSEL_BUS4XCH31);
196 #endif
197 
198  /* Set channel as positive channel in ACMP */
200  channel << _ACMP_INPUTSEL_POSSEL_SHIFT);
201 }
202 
203 /***************************************************************************/
211 {
212  /* Make sure the module exists on the selected chip */
213  EFM_ASSERT(ACMP_REF_VALID(acmp));
214 
215  acmp->CTRL &= ~ACMP_CTRL_EN;
216 }
217 
218 /***************************************************************************/
226 {
227  /* Make sure the module exists on the selected chip */
228  EFM_ASSERT(ACMP_REF_VALID(acmp));
229 
230  acmp->CTRL |= ACMP_CTRL_EN;
231 }
232 
233 #if defined(_ACMP_EXTIFCTRL_MASK)
234 /***************************************************************************/
250 void ACMP_ExternalInputSelect(ACMP_TypeDef *acmp, ACMP_ExternalInput_Typedef aport)
251 {
252  acmp->EXTIFCTRL = (aport << _ACMP_EXTIFCTRL_APORTSEL_SHIFT)
253  | ACMP_EXTIFCTRL_EN;
254  while (!(acmp->STATUS & ACMP_STATUS_EXTIFACT))
255  ;
256 }
257 #endif
258 
259 /***************************************************************************/
271 {
272  /* Make sure the module exists on the selected chip */
273  EFM_ASSERT(ACMP_REF_VALID(acmp));
274 
275  acmp->CTRL = _ACMP_CTRL_RESETVALUE;
277 #if defined(_ACMP_HYSTERESIS0_HYST_MASK)
278  acmp->HYSTERESIS0 = _ACMP_HYSTERESIS0_RESETVALUE;
279  acmp->HYSTERESIS1 = _ACMP_HYSTERESIS1_RESETVALUE;
280 #endif
281  acmp->IEN = _ACMP_IEN_RESETVALUE;
282  acmp->IFC = _ACMP_IF_MASK;
283 }
284 
285 /***************************************************************************/
305 void ACMP_GPIOSetup(ACMP_TypeDef *acmp, uint32_t location, bool enable, bool invert)
306 {
307  /* Make sure the module exists on the selected chip */
308  EFM_ASSERT(ACMP_REF_VALID(acmp));
309 
310  /* Sanity checking of location */
311  EFM_ASSERT(location <= _ACMP_ROUTE_LOCATION_MAX);
312 
313  /* Set GPIO inversion */
315  invert << _ACMP_CTRL_GPIOINV_SHIFT);
316 
317 #if defined(_ACMP_ROUTE_MASK)
318  acmp->ROUTE = (location << _ACMP_ROUTE_LOCATION_SHIFT)
319  | (enable << _ACMP_ROUTE_ACMPPEN_SHIFT);
320 #endif
321 #if defined(_ACMP_ROUTELOC0_MASK)
322  acmp->ROUTELOC0 = location << _ACMP_ROUTELOC0_OUTLOC_SHIFT;
323  acmp->ROUTEPEN = enable ? ACMP_ROUTEPEN_OUTPEN : 0;
324 #endif
325 }
326 
327 /***************************************************************************/
341  ACMP_Channel_TypeDef posSel)
342 {
343  /* Make sure the module exists on the selected chip */
344  EFM_ASSERT(ACMP_REF_VALID(acmp));
345 
346  /* Make sure that posSel and negSel channel selectors are valid. */
347 #if defined(_ACMP_INPUTSEL_NEGSEL_DAC0CH1)
348  EFM_ASSERT(negSel <= _ACMP_INPUTSEL_NEGSEL_DAC0CH1);
349 #elif defined(_ACMP_INPUTSEL_NEGSEL_CAPSENSE)
350  EFM_ASSERT(negSel <= _ACMP_INPUTSEL_NEGSEL_CAPSENSE);
351 #endif
352 
353 #if defined(_ACMP_INPUTSEL_POSSEL_CH7)
354  EFM_ASSERT(posSel <= _ACMP_INPUTSEL_POSSEL_CH7);
355 #endif
356 
357  acmp->INPUTSEL = (acmp->INPUTSEL & ~(_ACMP_INPUTSEL_POSSEL_MASK
359  | (negSel << _ACMP_INPUTSEL_NEGSEL_SHIFT)
360  | (posSel << _ACMP_INPUTSEL_POSSEL_SHIFT);
361 }
362 
363 /***************************************************************************/
374 void ACMP_Init(ACMP_TypeDef *acmp, const ACMP_Init_TypeDef *init)
375 {
376  /* Make sure the module exists on the selected chip */
377  EFM_ASSERT(ACMP_REF_VALID(acmp));
378 
379  /* Make sure biasprog is within bounds */
380  EFM_ASSERT(init->biasProg <=
382 
383  /* Make sure the ACMP is disable since we might be changing the
384  * ACMP power source */
386 
387  /* Set control register. No need to set interrupt modes */
388  acmp->CTRL = (init->fullBias << _ACMP_CTRL_FULLBIAS_SHIFT)
389 #if defined(_ACMP_CTRL_HALFBIAS_MASK)
391 #endif
395 #if defined(_ACMP_CTRL_INPUTRANGE_MASK)
396  | (init->inputRange << _ACMP_CTRL_INPUTRANGE_SHIFT)
397 #endif
398 #if defined(_ACMP_CTRL_ACCURACY_MASK)
399  | (init->accuracy << _ACMP_CTRL_ACCURACY_SHIFT)
400 #endif
401 #if defined(_ACMP_CTRL_PWRSEL_MASK)
402  | (init->powerSource << _ACMP_CTRL_PWRSEL_SHIFT)
403 #endif
404 #if defined(_ACMP_CTRL_WARMTIME_MASK)
406 #endif
407 #if defined(_ACMP_CTRL_HYSTSEL_MASK)
409 #endif
411 
412  acmp->INPUTSEL = (0)
413 #if defined(_ACMP_INPUTSEL_VLPSEL_MASK)
414  | (init->vlpInput << _ACMP_INPUTSEL_VLPSEL_SHIFT)
415 #endif
416 #if defined(_ACMP_INPUTSEL_LPREF_MASK)
418 #endif
419 #if defined(_ACMP_INPUTSEL_VDDLEVEL_MASK)
421 #endif
422  ;
423 
424  /* Enable ACMP if requested. */
426 }
427 
428 #if defined(_ACMP_INPUTSEL_VASEL_MASK)
429 /***************************************************************************/
440 void ACMP_VASetup(ACMP_TypeDef *acmp, const ACMP_VAConfig_TypeDef *vaconfig)
441 {
442  EFM_ASSERT(vaconfig->div0 < 64);
443  EFM_ASSERT(vaconfig->div1 < 64);
444 
445  BUS_RegMaskedWrite(&acmp->INPUTSEL, _ACMP_INPUTSEL_VASEL_MASK,
446  vaconfig->input << _ACMP_INPUTSEL_VASEL_SHIFT);
447  BUS_RegMaskedWrite(&acmp->HYSTERESIS0, _ACMP_HYSTERESIS0_DIVVA_MASK,
448  vaconfig->div0 << _ACMP_HYSTERESIS0_DIVVA_SHIFT);
449  BUS_RegMaskedWrite(&acmp->HYSTERESIS1, _ACMP_HYSTERESIS1_DIVVA_MASK,
450  vaconfig->div1 << _ACMP_HYSTERESIS1_DIVVA_SHIFT);
451 }
452 #endif
453 
454 #if defined(_ACMP_INPUTSEL_VBSEL_MASK)
455 /***************************************************************************/
466 void ACMP_VBSetup(ACMP_TypeDef *acmp, const ACMP_VBConfig_TypeDef *vbconfig)
467 {
468  EFM_ASSERT(vbconfig->div0 < 64);
469  EFM_ASSERT(vbconfig->div1 < 64);
470 
471  BUS_RegMaskedWrite(&acmp->INPUTSEL, _ACMP_INPUTSEL_VBSEL_MASK,
472  vbconfig->input << _ACMP_INPUTSEL_VBSEL_SHIFT);
473  BUS_RegMaskedWrite(&acmp->HYSTERESIS0, _ACMP_HYSTERESIS0_DIVVB_MASK,
474  vbconfig->div0 << _ACMP_HYSTERESIS0_DIVVB_SHIFT);
475  BUS_RegMaskedWrite(&acmp->HYSTERESIS1, _ACMP_HYSTERESIS1_DIVVB_MASK,
476  vbconfig->div1 << _ACMP_HYSTERESIS1_DIVVB_SHIFT);
477 }
478 #endif
479 
482 #endif /* defined(ACMP_COUNT) && (ACMP_COUNT > 0) */
ACMP_CapsenseResistor_TypeDef resistor
Definition: em_acmp.h:572
void ACMP_Disable(ACMP_TypeDef *acmp)
Disables the ACMP.
Definition: em_acmp.c:210
ACMP_HysteresisLevel_TypeDef hysteresisLevel
Definition: em_acmp.h:561
ACMP_Channel_TypeDef
Definition: em_acmp.h:465
Emlib peripheral API "assert" implementation.
__IOM uint32_t IFC
Definition: efm32gg_acmp.h:49
#define _ACMP_INPUTSEL_NEGSEL_DAC0CH1
Definition: efm32gg_acmp.h:201
#define _ACMP_CTRL_HALFBIAS_SHIFT
Definition: efm32gg_acmp.h:152
#define _ACMP_CTRL_IFALL_SHIFT
Definition: efm32gg_acmp.h:139
#define _ACMP_CTRL_WARMTIME_MASK
Definition: efm32gg_acmp.h:110
RAM and peripheral bit-field set and clear API.
#define ACMP_CTRL_EN
Definition: efm32gg_acmp.h:61
#define _ACMP_INPUTSEL_LPREF_SHIFT
Definition: efm32gg_acmp.h:222
uint32_t biasProg
Definition: em_acmp.h:663
#define _ACMP_INPUTSEL_POSSEL_SHIFT
Definition: efm32gg_acmp.h:165
void ACMP_CapsenseChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef channel)
Sets the ACMP channel used for capacative sensing.
Definition: em_acmp.c:185
#define _ACMP_INPUTSEL_NEGSEL_SHIFT
Definition: efm32gg_acmp.h:185
bool interruptOnRisingEdge
Definition: em_acmp.h:669
#define _ACMP_INPUTSEL_LPREF_MASK
Definition: efm32gg_acmp.h:223
__IM uint32_t STATUS
Definition: efm32gg_acmp.h:45
#define _ACMP_CTRL_WARMTIME_SHIFT
Definition: efm32gg_acmp.h:109
__IOM uint32_t IEN
Definition: efm32gg_acmp.h:46
void ACMP_Enable(ACMP_TypeDef *acmp)
Enables the ACMP.
Definition: em_acmp.c:225
uint32_t vddLevel
Definition: em_acmp.h:724
#define _ACMP_INPUTSEL_NEGSEL_CAPSENSE
Definition: efm32gg_acmp.h:199
__IOM uint32_t INPUTSEL
Definition: efm32gg_acmp.h:44
#define _ACMP_ROUTE_LOCATION_SHIFT
Definition: efm32gg_acmp.h:322
#define _ACMP_INPUTSEL_CSRESSEL_SHIFT
Definition: efm32gg_acmp.h:231
#define _ACMP_CTRL_BIASPROG_MASK
Definition: efm32gg_acmp.h:148
#define _ACMP_CTRL_GPIOINV_SHIFT
Definition: efm32gg_acmp.h:81
bool lowPowerReferenceEnabled
Definition: em_acmp.h:718
ACMP_WarmTime_TypeDef warmTime
Definition: em_acmp.h:556
void ACMP_ChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef negSel, ACMP_Channel_TypeDef posSel)
Sets which channels should be used in ACMP comparisons.
Definition: em_acmp.c:340
#define ACMP_INPUTSEL_CSRESEN
Definition: efm32gg_acmp.h:226
__IOM uint32_t CTRL
Definition: efm32gg_acmp.h:43
void ACMP_CapsenseInit(ACMP_TypeDef *acmp, const ACMP_CapsenseInit_TypeDef *init)
Sets up the ACMP for use in capacative sense applications.
Definition: em_acmp.c:109
void ACMP_Reset(ACMP_TypeDef *acmp)
Reset ACMP to same state as after a HW reset.
Definition: em_acmp.c:270
#define _ACMP_INPUTSEL_NEGSEL_MASK
Definition: efm32gg_acmp.h:186
#define _ACMP_INPUTSEL_POSSEL_MASK
Definition: efm32gg_acmp.h:166
ACMP_WarmTime_TypeDef warmTime
Definition: em_acmp.h:692
#define _ACMP_CTRL_HYSTSEL_MASK
Definition: efm32gg_acmp.h:90
#define _ACMP_CTRL_BIASPROG_SHIFT
Definition: efm32gg_acmp.h:147
#define _ACMP_CTRL_IRISE_SHIFT
Definition: efm32gg_acmp.h:130
#define _ACMP_IF_MASK
Definition: efm32gg_acmp.h:274
#define _ACMP_CTRL_GPIOINV_MASK
Definition: efm32gg_acmp.h:82
#define _ACMP_CTRL_RESETVALUE
Definition: efm32gg_acmp.h:59
#define _ACMP_INPUTSEL_RESETVALUE
Definition: efm32gg_acmp.h:163
Analog Comparator (ACMP) peripheral API.
#define _ACMP_CTRL_HALFBIAS_MASK
Definition: efm32gg_acmp.h:153
__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
bool interruptOnFallingEdge
Definition: em_acmp.h:666
#define ACMP_INPUTSEL_NEGSEL_CAPSENSE
Definition: efm32gg_acmp.h:214
#define _ACMP_INPUTSEL_VDDLEVEL_MASK
Definition: efm32gg_acmp.h:218
#define _ACMP_CTRL_HYSTSEL_SHIFT
Definition: efm32gg_acmp.h:89
#define _ACMP_CTRL_INACTVAL_SHIFT
Definition: efm32gg_acmp.h:72
#define _ACMP_CTRL_EN_SHIFT
Definition: efm32gg_acmp.h:62
__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
#define _ACMP_INPUTSEL_POSSEL_CH7
Definition: efm32gg_acmp.h:175
void ACMP_Init(ACMP_TypeDef *acmp, const ACMP_Init_TypeDef *init)
Initialize ACMP.
Definition: em_acmp.c:374
#define _ACMP_ROUTE_ACMPPEN_SHIFT
Definition: efm32gg_acmp.h:318
__IOM uint32_t ROUTE
Definition: efm32gg_acmp.h:50
void ACMP_GPIOSetup(ACMP_TypeDef *acmp, uint32_t location, bool enable, bool invert)
Sets up GPIO output from the ACMP.
Definition: em_acmp.c:305
#define _ACMP_IEN_RESETVALUE
Definition: efm32gg_acmp.h:259
#define _ACMP_INPUTSEL_VDDLEVEL_SHIFT
Definition: efm32gg_acmp.h:217
#define _ACMP_CTRL_FULLBIAS_SHIFT
Definition: efm32gg_acmp.h:157
ACMP_HysteresisLevel_TypeDef hysteresisLevel
Definition: em_acmp.h:697
bool inactiveValue
Definition: em_acmp.h:713