1 /***************************************************************************//**
2 * @file
3 * @brief Voltage Comparator (VCMP) peripheral API
4 *******************************************************************************
5 * # License
6 * <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
7 *******************************************************************************
8 *
9 * SPDX-License-Identifier: Zlib
10 *
11 * The licensor of this software is Silicon Laboratories Inc.
12 *
13 * This software is provided 'as-is', without any express or implied
14 * warranty. In no event will the authors be held liable for any damages
15 * arising from the use of this software.
16 *
17 * Permission is granted to anyone to use this software for any purpose,
18 * including commercial applications, and to alter it and redistribute it
19 * freely, subject to the following restrictions:
20 *
21 * 1. The origin of this software must not be misrepresented; you must not
22 * claim that you wrote the original software. If you use this software
23 * in a product, an acknowledgment in the product documentation would be
24 * appreciated but is not required.
25 * 2. Altered source versions must be plainly marked as such, and must not be
26 * misrepresented as being the original software.
27 * 3. This notice may not be removed or altered from any source distribution.
28 *
29 ******************************************************************************/
30
31 #include "em_vcmp.h"
32 #if defined(VCMP_COUNT) && (VCMP_COUNT > 0)
33
34 #include "sl_assert.h"
35
36 /***************************************************************************//**
37 * @addtogroup vcmp VCMP - Voltage Comparator
38 * @brief Supply Voltage Comparator (VCMP) Peripheral API
39 * @details
40 * This module contains functions to control the VCMP peripheral of Silicon
41 * Labs 32-bit MCUs and SoCs. The VCMP monitors the input voltage supply and
42 * generates interrupts on events using as little as 100 nA.
43 * @{
44 ******************************************************************************/
45
46 /***************************************************************************//**
47 * @brief
48 * Configure and enable Voltage Comparator.
49 *
50 * @param[in] vcmpInit
51 * The VCMP Initialization structure.
52 ******************************************************************************/
VCMP_Init(const VCMP_Init_TypeDef * vcmpInit)53 void VCMP_Init(const VCMP_Init_TypeDef *vcmpInit)
54 {
55 /* Verify input. */
56 EFM_ASSERT((vcmpInit->inactive == 0) || (vcmpInit->inactive == 1));
57 EFM_ASSERT((vcmpInit->biasProg >= 0) && (vcmpInit->biasProg < 16));
58
59 /* Configure the Half Bias setting. */
60 if (vcmpInit->halfBias) {
61 VCMP->CTRL |= VCMP_CTRL_HALFBIAS;
62 } else {
63 VCMP->CTRL &= ~(VCMP_CTRL_HALFBIAS);
64 }
65
66 /* Configure the bias prog. */
67 VCMP->CTRL &= ~(_VCMP_CTRL_BIASPROG_MASK);
68 VCMP->CTRL |= (vcmpInit->biasProg << _VCMP_CTRL_BIASPROG_SHIFT);
69
70 /* Configure sense for the falling edge. */
71 if (vcmpInit->irqFalling) {
72 VCMP->CTRL |= VCMP_CTRL_IFALL;
73 } else {
74 VCMP->CTRL &= ~(VCMP_CTRL_IFALL);
75 }
76
77 /* Configure sense for the rising edge. */
78 if (vcmpInit->irqRising) {
79 VCMP->CTRL |= VCMP_CTRL_IRISE;
80 } else {
81 VCMP->CTRL &= ~(VCMP_CTRL_IRISE);
82 }
83
84 /* Configure the warm-up time. */
85 VCMP->CTRL &= ~(_VCMP_CTRL_WARMTIME_MASK);
86 VCMP->CTRL |= (vcmpInit->warmup << _VCMP_CTRL_WARMTIME_SHIFT);
87
88 /* Configure hysteresis. */
89 switch (vcmpInit->hyst) {
90 case vcmpHyst20mV:
91 VCMP->CTRL |= VCMP_CTRL_HYSTEN;
92 break;
93 case vcmpHystNone:
94 VCMP->CTRL &= ~(VCMP_CTRL_HYSTEN);
95 break;
96 default:
97 break;
98 }
99
100 /* Configure the inactive output value. */
101 VCMP->CTRL |= (vcmpInit->inactive << _VCMP_CTRL_INACTVAL_SHIFT);
102
103 /* Configure the trigger level. */
104 VCMP_TriggerSet(vcmpInit->triggerLevel);
105
106 /* Enable or disable VCMP. */
107 if (vcmpInit->enable) {
108 VCMP->CTRL |= VCMP_CTRL_EN;
109 } else {
110 VCMP->CTRL &= ~(VCMP_CTRL_EN);
111 }
112
113 /* If Low Power Reference is enabled, wait until VCMP is ready */
114 /* before enabling it. See the reference manual for deatils. */
115 /* Configuring Low Power Ref without enable has no effect. */
116 if (vcmpInit->lowPowerRef && vcmpInit->enable) {
117 /* Poll for VCMP ready. */
118 while (!VCMP_Ready()) ;
119 VCMP_LowPowerRefSet(vcmpInit->lowPowerRef);
120 }
121
122 /* Clear the edge interrupt. */
123 VCMP_IntClear(VCMP_IF_EDGE);
124 }
125
126 /***************************************************************************//**
127 * @brief
128 * Enable or disable Low Power Reference setting.
129 *
130 * @param[in] enable
131 * If true, enables low power reference. If false, disable low power reference.
132 ******************************************************************************/
VCMP_LowPowerRefSet(bool enable)133 void VCMP_LowPowerRefSet(bool enable)
134 {
135 if (enable) {
136 VCMP->INPUTSEL |= VCMP_INPUTSEL_LPREF;
137 } else {
138 VCMP->INPUTSEL &= ~VCMP_INPUTSEL_LPREF;
139 }
140 }
141
142 /***************************************************************************//**
143 * @brief
144 * Configure the trigger level of the voltage comparator.
145 *
146 * @param[in] level
147 * A trigger value, in range 0-63.
148 ******************************************************************************/
VCMP_TriggerSet(int level)149 void VCMP_TriggerSet(int level)
150 {
151 /* Trigger range is 6 bits, value from 0-63. */
152 EFM_ASSERT((level > 0) && (level < 64));
153
154 /* Set the trigger level. */
155 VCMP->INPUTSEL = (VCMP->INPUTSEL & ~(_VCMP_INPUTSEL_TRIGLEVEL_MASK))
156 | (level << _VCMP_INPUTSEL_TRIGLEVEL_SHIFT);
157 }
158
159 /** @} (end addtogroup vcmp) */
160 #endif /* defined(VCMP_COUNT) && (VCMP_COUNT > 0) */
161