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 #ifndef EM_VCMP_H
32 #define EM_VCMP_H
33
34 #include "em_device.h"
35 #if defined(VCMP_COUNT) && (VCMP_COUNT > 0)
36
37 #include <stdint.h>
38 #include <stdbool.h>
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 /***************************************************************************//**
45 * @addtogroup vcmp
46 * @{
47 ******************************************************************************/
48
49 /*******************************************************************************
50 ******************************** ENUMS ************************************
51 ******************************************************************************/
52
53 /** Warm-up Time in High Frequency Peripheral Clock cycles. */
54 typedef enum {
55 /** 4 cycles */
56 vcmpWarmTime4Cycles = _VCMP_CTRL_WARMTIME_4CYCLES,
57 /** 8 cycles */
58 vcmpWarmTime8Cycles = _VCMP_CTRL_WARMTIME_8CYCLES,
59 /** 16 cycles */
60 vcmpWarmTime16Cycles = _VCMP_CTRL_WARMTIME_16CYCLES,
61 /** 32 cycles */
62 vcmpWarmTime32Cycles = _VCMP_CTRL_WARMTIME_32CYCLES,
63 /** 64 cycles */
64 vcmpWarmTime64Cycles = _VCMP_CTRL_WARMTIME_64CYCLES,
65 /** 128 cycles */
66 vcmpWarmTime128Cycles = _VCMP_CTRL_WARMTIME_128CYCLES,
67 /** 256 cycles */
68 vcmpWarmTime256Cycles = _VCMP_CTRL_WARMTIME_256CYCLES,
69 /** 512 cycles */
70 vcmpWarmTime512Cycles = _VCMP_CTRL_WARMTIME_512CYCLES
71 } VCMP_WarmTime_TypeDef;
72
73 /** Hysteresis configuration. */
74 typedef enum {
75 /** Normal operation, no hysteresis. */
76 vcmpHystNone,
77 /** Digital output will not toggle until positive edge is at least
78 * 20 mV above or below negative input voltage. */
79 vcmpHyst20mV
80 } VCMP_Hysteresis_TypeDef;
81
82 /*******************************************************************************
83 ******************************* STRUCTS ***********************************
84 ******************************************************************************/
85
86 /** VCMP Initialization structure. */
87 typedef struct {
88 /** If set to true, reduces the bias current by half. */
89 bool halfBias;
90 /** BIAS current configuration, depends on Half Bias setting above,
91 * see reference manual for more information. */
92 int biasProg;
93 /** Enable interrupt for falling edge. */
94 bool irqFalling;
95 /** Enable interrupt for rising edge. */
96 bool irqRising;
97 /** Warm-up time in clock cycles. */
98 VCMP_WarmTime_TypeDef warmup;
99 /** Hysteresis configuration */
100 VCMP_Hysteresis_TypeDef hyst;
101 /** Output value when comparator is inactive, should be 0 or 1. */
102 int inactive;
103 /** Enable low power mode for VDD and band gap reference. */
104 bool lowPowerRef;
105 /** Trigger level, according to formula:
106 * VDD Trigger Level = 1.667V + 0.034V x triggerLevel */
107 int triggerLevel;
108 /** Enable VCMP after configuration. */
109 bool enable;
110 } VCMP_Init_TypeDef;
111
112 /** Default VCMP initialization structure. */
113 #define VCMP_INIT_DEFAULT \
114 { \
115 true, /** Half Bias enabled. */ \
116 0x7, /** Bias current 0.7 uA when half bias is enabled. */ \
117 false, /** Falling edge sense not enabled. */ \
118 false, /** Rising edge sense not enabled. */ \
119 vcmpWarmTime4Cycles, /** 4 clock cycles warm-up time. */ \
120 vcmpHystNone, /** No hysteresis. */ \
121 0, /** 0 in digital output when inactive. */ \
122 true, /** Do not use low power reference. */ \
123 39, /** Trigger level just below 3V. */ \
124 true, /** Enable after initialization. */ \
125 }
126
127 /*******************************************************************************
128 ***************************** PROTOTYPES **********************************
129 ******************************************************************************/
130
131 void VCMP_Init(const VCMP_Init_TypeDef *vcmpInit);
132 void VCMP_LowPowerRefSet(bool enable);
133 void VCMP_TriggerSet(int level);
134
135 /***************************************************************************//**
136 * @brief
137 * Enable Voltage Comparator.
138 ******************************************************************************/
VCMP_Enable(void)139 __STATIC_INLINE void VCMP_Enable(void)
140 {
141 VCMP->CTRL |= VCMP_CTRL_EN;
142 }
143
144 /***************************************************************************//**
145 * @brief
146 * Disable Voltage Comparator.
147 ******************************************************************************/
VCMP_Disable(void)148 __STATIC_INLINE void VCMP_Disable(void)
149 {
150 VCMP->CTRL &= ~VCMP_CTRL_EN;
151 }
152
153 /***************************************************************************//**
154 * @brief
155 * Calculate voltage to trigger level.
156 *
157 * @note
158 * Soft float support is needed for this function to work.
159 *
160 * @param[in] v
161 * Voltage Level for trigger.
162 *
163 * @return
164 * Trigger level.
165 ******************************************************************************/
VCMP_VoltageToLevel(float v)166 __STATIC_INLINE uint32_t VCMP_VoltageToLevel(float v)
167 {
168 return (uint32_t)((v - (float)1.667) / (float)0.034);
169 }
170
171 /***************************************************************************//**
172 * @brief
173 * Check whether VDD is lower than the trigger level.
174 *
175 * @return
176 * True if Voltage Comparator indicated VDD < trigger level, else
177 * returns false.
178 ******************************************************************************/
VCMP_VDDLower(void)179 __STATIC_INLINE bool VCMP_VDDLower(void)
180 {
181 if (VCMP->STATUS & VCMP_STATUS_VCMPOUT) {
182 return false;
183 } else {
184 return true;
185 }
186 }
187
188 /***************************************************************************//**
189 * @brief
190 * Check whether VDD is higher than the trigger level.
191 *
192 * @return
193 * True if Voltage Comparator indicated VDD > trigger level, else
194 * returns false.
195 ******************************************************************************/
VCMP_VDDHigher(void)196 __STATIC_INLINE bool VCMP_VDDHigher(void)
197 {
198 if (VCMP->STATUS & VCMP_STATUS_VCMPOUT) {
199 return true;
200 } else {
201 return false;
202 }
203 }
204
205 /***************************************************************************//**
206 * @brief
207 * Check whether the VCMP output is ready.
208 *
209 * @return
210 * True if VCMP output is ready.
211 ******************************************************************************/
VCMP_Ready(void)212 __STATIC_INLINE bool VCMP_Ready(void)
213 {
214 if (VCMP->STATUS & VCMP_STATUS_VCMPACT) {
215 return true;
216 } else {
217 return false;
218 }
219 }
220
221 /***************************************************************************//**
222 * @brief
223 * Clear one or more pending VCMP interrupts.
224 *
225 * @param[in] flags
226 * VCMP interrupt sources to clear. Use a set of interrupt flags OR-ed
227 * together to clear multiple interrupt sources for the VCMP module
228 * (VCMP_IFS_nnn).
229 ******************************************************************************/
VCMP_IntClear(uint32_t flags)230 __STATIC_INLINE void VCMP_IntClear(uint32_t flags)
231 {
232 VCMP->IFC = flags;
233 }
234
235 /***************************************************************************//**
236 * @brief
237 * Set one or more pending VCMP interrupts from SW.
238 *
239 * @param[in] flags
240 * VCMP interrupt sources to set to pending. Use a set of interrupt flags
241 * OR-ed together to set multiple interrupt sources for the VCMP module
242 * (VCMP_IFS_nnn).
243 ******************************************************************************/
VCMP_IntSet(uint32_t flags)244 __STATIC_INLINE void VCMP_IntSet(uint32_t flags)
245 {
246 VCMP->IFS = flags;
247 }
248
249 /***************************************************************************//**
250 * @brief
251 * Disable one or more VCMP interrupts.
252 *
253 * @param[in] flags
254 * VCMP interrupt sources to enable. Use a set of interrupt flags OR-ed
255 * together to set multiple interrupt sources for the VCMP module
256 * (VCMP_IFS_nnn).
257 ******************************************************************************/
VCMP_IntDisable(uint32_t flags)258 __STATIC_INLINE void VCMP_IntDisable(uint32_t flags)
259 {
260 VCMP->IEN &= ~flags;
261 }
262
263 /***************************************************************************//**
264 * @brief
265 * Enable one or more VCMP interrupts.
266 *
267 * @param[in] flags
268 * VCMP interrupt sources to enable. Use a set of interrupt flags OR-ed
269 * together to set multiple interrupt sources for the VCMP module
270 * (VCMP_IFS_nnn).
271 ******************************************************************************/
VCMP_IntEnable(uint32_t flags)272 __STATIC_INLINE void VCMP_IntEnable(uint32_t flags)
273 {
274 VCMP->IEN |= flags;
275 }
276
277 /***************************************************************************//**
278 * @brief
279 * Get pending VCMP interrupt flags.
280 *
281 * @note
282 * The event bits are not cleared by the use of this function.
283 *
284 * @return
285 * Pending VCMP interrupt sources. Returns a set of interrupt flags OR-ed
286 * together for multiple interrupt sources in the VCMP module (VCMP_IFS_nnn).
287 ******************************************************************************/
VCMP_IntGet(void)288 __STATIC_INLINE uint32_t VCMP_IntGet(void)
289 {
290 return VCMP->IF;
291 }
292
293 /***************************************************************************//**
294 * @brief
295 * Get enabled and pending VCMP interrupt flags.
296 *
297 * @details
298 * Useful for handling more interrupt sources in the same interrupt handler.
299 *
300 * @note
301 * The event bits are not cleared by the use of this function.
302 *
303 * @return
304 * Pending and enabled VCMP interrupt sources.
305 * The return value is the bitwise AND combination of
306 * - the OR combination of enabled interrupt sources in VCMP_IEN_nnn
307 * register (VCMP_IEN_nnn) and
308 * - the OR combination of valid interrupt flags of the VCMP module
309 * (VCMP_IF_nnn).
310 ******************************************************************************/
VCMP_IntGetEnabled(void)311 __STATIC_INLINE uint32_t VCMP_IntGetEnabled(void)
312 {
313 uint32_t tmp = 0U;
314
315 /* Store VCMP->IEN in a temporary variable to define explicit order
316 * of volatile accesses. */
317 tmp = VCMP->IEN;
318
319 /* Bitwise AND of pending and enabled interrupts */
320 return VCMP->IF & tmp;
321 }
322
323 /** @} (end addtogroup vcmp) */
324
325 #ifdef __cplusplus
326 }
327 #endif
328
329 #endif /* defined(VCMP_COUNT) && (VCMP_COUNT > 0) */
330 #endif /* EM_VCMP_H */
331