1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2020, 2023-2024 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_acmp.h"
10
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.acmp"
18 #endif
19
20 /*******************************************************************************
21 * Prototypes
22 ******************************************************************************/
23 /*!
24 * @brief Get the ACMP instance from the peripheral base address.
25 *
26 * @param base ACMP peripheral base address.
27 * @return ACMP instance.
28 */
29 static uint32_t ACMP_GetInstance(CMP_Type *base);
30
31 /*******************************************************************************
32 * Variables
33 ******************************************************************************/
34 /* Array of ACMP peripheral base address. */
35 static CMP_Type *const s_acmpBases[] = CMP_BASE_PTRS;
36 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
37 /* Clock name of ACMP. */
38 static const clock_ip_name_t s_acmpClock[] = CMP_CLOCKS;
39 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
40
41 /*******************************************************************************
42 * Codes
43 ******************************************************************************/
ACMP_GetInstance(CMP_Type * base)44 static uint32_t ACMP_GetInstance(CMP_Type *base)
45 {
46 uint32_t instance = 0U;
47
48 /* Find the instance index from base address mappings. */
49 for (instance = 0; instance < ARRAY_SIZE(s_acmpBases); instance++)
50 {
51 if (MSDK_REG_SECURE_ADDR(s_acmpBases[instance]) == MSDK_REG_SECURE_ADDR(base))
52 {
53 break;
54 }
55 }
56
57 assert(instance < ARRAY_SIZE(s_acmpBases));
58
59 return instance;
60 }
61
62 /*!
63 * brief Initializes the ACMP.
64 *
65 * The default configuration can be got by calling ACMP_GetDefaultConfig().
66 *
67 * param base ACMP peripheral base address.
68 * param config Pointer to ACMP configuration structure.
69 */
ACMP_Init(CMP_Type * base,const acmp_config_t * config)70 void ACMP_Init(CMP_Type *base, const acmp_config_t *config)
71 {
72 assert(NULL != config);
73
74 uint32_t tmp32;
75
76 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
77 /* Open clock gate. */
78 CLOCK_EnableClock(s_acmpClock[ACMP_GetInstance(base)]);
79 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
80
81 /* Disable the module before configuring it. */
82 ACMP_Enable(base, false);
83
84 /* CMPx_C0
85 * Set control bit. Avoid clearing status flags at the same time.
86 */
87 tmp32 = (base->C0 & (~(CMP_C0_PMODE_MASK | CMP_C0_INVT_MASK | CMP_C0_COS_MASK | CMP_C0_OPE_MASK |
88 #if defined(FSL_FEATURE_ACMP_HAS_C0_HYSTCTR_BIT) && (FSL_FEATURE_ACMP_HAS_C0_HYSTCTR_BIT == 1U)
89 CMP_C0_HYSTCTR_MASK |
90 #endif /* FSL_FEATURE_ACMP_HAS_C0_HYSTCTR_BIT */
91 CMP_C0_CFx_MASK)));
92 #if defined(FSL_FEATURE_ACMP_HAS_C0_OFFSET_BIT) && (FSL_FEATURE_ACMP_HAS_C0_OFFSET_BIT == 1U)
93 tmp32 &= ~CMP_C0_OFFSET_MASK;
94 #endif /* FSL_FEATURE_ACMP_HAS_C0_OFFSET_BIT */
95 if (config->enableHighSpeed)
96 {
97 tmp32 |= CMP_C0_PMODE_MASK;
98 }
99 if (config->enableInvertOutput)
100 {
101 tmp32 |= CMP_C0_INVT_MASK;
102 }
103 if (config->useUnfilteredOutput)
104 {
105 tmp32 |= CMP_C0_COS_MASK;
106 }
107 if (config->enablePinOut)
108 {
109 tmp32 |= CMP_C0_OPE_MASK;
110 }
111 #if defined(FSL_FEATURE_ACMP_HAS_C0_HYSTCTR_BIT) && (FSL_FEATURE_ACMP_HAS_C0_HYSTCTR_BIT == 1U)
112 tmp32 |= CMP_C0_HYSTCTR(config->hysteresisMode);
113 #endif /* FSL_FEATURE_ACMP_HAS_C0_HYSTCTR_BIT */
114 #if defined(FSL_FEATURE_ACMP_HAS_C0_OFFSET_BIT) && (FSL_FEATURE_ACMP_HAS_C0_OFFSET_BIT == 1U)
115 tmp32 |= CMP_C0_OFFSET(config->offsetMode);
116 #endif /* FSL_FEATURE_ACMP_HAS_C0_OFFSET_BIT */
117 base->C0 = tmp32;
118 }
119
120 /*!
121 * brief Deinitializes the ACMP.
122 *
123 * param base ACMP peripheral base address.
124 */
ACMP_Deinit(CMP_Type * base)125 void ACMP_Deinit(CMP_Type *base)
126 {
127 /* Disable the module. */
128 ACMP_Enable(base, false);
129
130 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
131 /* Disable clock gate. */
132 CLOCK_DisableClock(s_acmpClock[ACMP_GetInstance(base)]);
133 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
134 }
135
136 /*!
137 * brief Gets the default configuration for ACMP.
138 *
139 * This function initializes the user configuration structure to default value. The default value are:
140 *
141 * Example:
142 code
143 config->enableHighSpeed = false;
144 config->enableInvertOutput = false;
145 config->useUnfilteredOutput = false;
146 config->enablePinOut = false;
147 config->enableHysteresisBothDirections = false;
148 config->hysteresisMode = kACMP_hysteresisMode0;
149 endcode
150 *
151 * param config Pointer to ACMP configuration structure.
152 */
ACMP_GetDefaultConfig(acmp_config_t * config)153 void ACMP_GetDefaultConfig(acmp_config_t *config)
154 {
155 assert(NULL != config);
156
157 /* Initializes the configure structure to zero. */
158 (void)memset(config, 0, sizeof(*config));
159
160 /* Fill default configuration */
161 config->enableHighSpeed = false;
162 config->enableInvertOutput = false;
163 config->useUnfilteredOutput = false;
164 config->enablePinOut = false;
165 #if defined(FSL_FEATURE_ACMP_HAS_C0_OFFSET_BIT) && (FSL_FEATURE_ACMP_HAS_C0_OFFSET_BIT == 1U)
166 config->offsetMode = kACMP_OffsetLevel0;
167 #endif /* FSL_FEATURE_ACMP_HAS_C0_OFFSET_BIT */
168 #if defined(FSL_FEATURE_ACMP_HAS_C0_HYSTCTR_BIT) && (FSL_FEATURE_ACMP_HAS_C0_HYSTCTR_BIT == 1U)
169 config->hysteresisMode = kACMP_HysteresisLevel0;
170 #endif /* FSL_FEATURE_ACMP_HAS_C0_HYSTCTR_BIT */
171 }
172
173 /*!
174 * brief Enables or disables the ACMP.
175 *
176 * param base ACMP peripheral base address.
177 * param enable True to enable the ACMP.
178 */
ACMP_Enable(CMP_Type * base,bool enable)179 void ACMP_Enable(CMP_Type *base, bool enable)
180 {
181 /* CMPx_C0
182 * Set control bit. Avoid clearing status flags at the same time.
183 */
184 if (enable)
185 {
186 base->C0 = ((base->C0 | CMP_C0_EN_MASK) & ~CMP_C0_CFx_MASK);
187 }
188 else
189 {
190 base->C0 &= ~(CMP_C0_EN_MASK | CMP_C0_CFx_MASK);
191 }
192 }
193
194 #if defined(FSL_FEATURE_ACMP_HAS_C0_LINKEN_BIT) && (FSL_FEATURE_ACMP_HAS_C0_LINKEN_BIT == 1U)
195 /*!
196 * brief Enables the link from CMP to DAC enable.
197 *
198 * When this bit is set, the DAC enable/disable is controlled by the bit CMP_C0[EN] instead of CMP_C1[DACEN].
199 *
200 * param base ACMP peripheral base address.
201 * param enable Enable the feature or not.
202 */
ACMP_EnableLinkToDAC(CMP_Type * base,bool enable)203 void ACMP_EnableLinkToDAC(CMP_Type *base, bool enable)
204 {
205 /* CMPx_C0_LINKEN
206 * Set control bit. Avoid clearing status flags at the same time.
207 */
208 if (enable)
209 {
210 base->C0 = ((base->C0 | CMP_C0_LINKEN_MASK) & ~CMP_C0_CFx_MASK);
211 }
212 else
213 {
214 base->C0 &= ~(CMP_C0_LINKEN_MASK | CMP_C0_CFx_MASK);
215 }
216 }
217 #endif /* FSL_FEATURE_ACMP_HAS_C0_LINKEN_BIT */
218
219 /*!
220 * brief Sets the channel configuration.
221 *
222 * Note that the plus/minus mux's setting is only valid when the positive/negative port's input isn't from DAC but
223 * from channel mux.
224 *
225 * Example:
226 code
227 acmp_channel_config_t configStruct = {0};
228 configStruct.positivePortInput = kACMP_PortInputFromDAC;
229 configStruct.negativePortInput = kACMP_PortInputFromMux;
230 configStruct.minusMuxInput = 1U;
231 ACMP_SetChannelConfig(CMP0, &configStruct);
232 endcode
233 *
234 * param base ACMP peripheral base address.
235 * param config Pointer to channel configuration structure.
236 */
ACMP_SetChannelConfig(CMP_Type * base,const acmp_channel_config_t * config)237 void ACMP_SetChannelConfig(CMP_Type *base, const acmp_channel_config_t *config)
238 {
239 assert(NULL != config);
240
241 uint32_t tmp32 = (base->C1 & (~(CMP_C1_PSEL_MASK | CMP_C1_MSEL_MASK)));
242
243 /* CMPx_C1
244 * Set the input of CMP's positive port.
245 */
246 #if (defined(FSL_FEATURE_ACMP_HAS_C1_INPSEL_BIT) && (FSL_FEATURE_ACMP_HAS_C1_INPSEL_BIT == 1U))
247 tmp32 &= ~CMP_C1_INPSEL_MASK;
248 tmp32 |= CMP_C1_INPSEL(config->positivePortInput);
249 #endif /* FSL_FEATURE_ACMP_HAS_C1_INPSEL_BIT */
250
251 #if (defined(FSL_FEATURE_ACMP_HAS_C1_INNSEL_BIT) && (FSL_FEATURE_ACMP_HAS_C1_INNSEL_BIT == 1U))
252 tmp32 &= ~CMP_C1_INNSEL_MASK;
253 tmp32 |= CMP_C1_INNSEL(config->negativePortInput);
254 #endif /* FSL_FEATURE_ACMP_HAS_C1_INPSEL_BIT */
255
256 tmp32 |= CMP_C1_PSEL(config->plusMuxInput) | CMP_C1_MSEL(config->minusMuxInput);
257
258 base->C1 = tmp32;
259 }
260
261 /*!
262 * brief Enables or disables DMA.
263 *
264 * param base ACMP peripheral base address.
265 * param enable True to enable DMA.
266 */
ACMP_EnableDMA(CMP_Type * base,bool enable)267 void ACMP_EnableDMA(CMP_Type *base, bool enable)
268 {
269 /* CMPx_C0
270 * Set control bit. Avoid clearing status flags at the same time.
271 */
272 if (enable)
273 {
274 base->C0 = ((base->C0 | CMP_C0_DMAEN_MASK) & ~CMP_C0_CFx_MASK);
275 }
276 else
277 {
278 base->C0 &= ~(CMP_C0_DMAEN_MASK | CMP_C0_CFx_MASK);
279 }
280 }
281
282 #if !(defined(FSL_FEATURE_ACMP_HAS_NO_WINDOW_MODE) && (FSL_FEATURE_ACMP_HAS_NO_WINDOW_MODE == 1U))
283 /*!
284 * brief Enables or disables window mode.
285 *
286 * param base ACMP peripheral base address.
287 * param enable True to enable window mode.
288 */
ACMP_EnableWindowMode(CMP_Type * base,bool enable)289 void ACMP_EnableWindowMode(CMP_Type *base, bool enable)
290 {
291 /* CMPx_C0
292 * Set control bit. Avoid clearing status flags at the same time.
293 */
294 if (enable)
295 {
296 base->C0 = ((base->C0 | CMP_C0_WE_MASK) & ~CMP_C0_CFx_MASK);
297 }
298 else
299 {
300 base->C0 &= ~(CMP_C0_WE_MASK | CMP_C0_CFx_MASK);
301 }
302 }
303 #endif /* !(defined(FSL_FEATURE_ACMP_HAS_NO_WINDOW_MODE) && (FSL_FEATURE_ACMP_HAS_NO_WINDOW_MODE == 1U)) */
304
305 /*!
306 * brief Configures the filter.
307 *
308 * The filter can be enabled when the filter count is bigger than 1, the filter period is greater than 0 and the sample
309 * clock is from divided bus clock or the filter is bigger than 1 and the sample clock is from external clock. Detailed
310 * usage can be got from the reference manual.
311 *
312 * Example:
313 code
314 acmp_filter_config_t configStruct = {0};
315 configStruct.filterCount = 5U;
316 configStruct.filterPeriod = 200U;
317 configStruct.enableSample = false;
318 ACMP_SetFilterConfig(CMP0, &configStruct);
319 endcode
320 *
321 * param base ACMP peripheral base address.
322 * param config Pointer to filter configuration structure.
323 */
ACMP_SetFilterConfig(CMP_Type * base,const acmp_filter_config_t * config)324 void ACMP_SetFilterConfig(CMP_Type *base, const acmp_filter_config_t *config)
325 {
326 assert(NULL != config);
327
328 /* CMPx_C0
329 * Set control bit. Avoid clearing status flags at the same time.
330 */
331 uint32_t tmp32 = (base->C0 & (~(CMP_C0_FILTER_CNT_MASK | CMP_C0_FPR_MASK |
332 #if !(defined(FSL_FEATURE_ACMP_HAS_NO_C0_SE_BIT) && (FSL_FEATURE_ACMP_HAS_NO_C0_SE_BIT == 1U))
333 CMP_C0_SE_MASK |
334 #endif /* FSL_FEATURE_ACMP_HAS_NO_C0_SE_BIT */
335 CMP_C0_CFx_MASK)));
336
337 #if !(defined(FSL_FEATURE_ACMP_HAS_NO_C0_SE_BIT) && (FSL_FEATURE_ACMP_HAS_NO_C0_SE_BIT == 1U))
338 if (config->enableSample)
339 {
340 tmp32 |= CMP_C0_SE_MASK;
341 }
342 #endif /* FSL_FEATURE_ACMP_HAS_NO_C0_SE_BIT */
343 tmp32 |= (CMP_C0_FILTER_CNT(config->filterCount) | CMP_C0_FPR(config->filterPeriod));
344 base->C0 = tmp32;
345 }
346
347 /*!
348 * brief Configures the internal DAC.
349 *
350 * Example:
351 code
352 acmp_dac_config_t configStruct = {0};
353 configStruct.referenceVoltageSource = kACMP_VrefSourceVin1;
354 configStruct.DACValue = 20U;
355 configStruct.enableOutput = false;
356 configStruct.workMode = kACMP_DACWorkLowSpeedMode;
357 ACMP_SetDACConfig(CMP0, &configStruct);
358 endcode
359 *
360 * param base ACMP peripheral base address.
361 * param config Pointer to DAC configuration structure. "NULL" is for disabling the feature.
362 */
ACMP_SetDACConfig(CMP_Type * base,const acmp_dac_config_t * config)363 void ACMP_SetDACConfig(CMP_Type *base, const acmp_dac_config_t *config)
364 {
365 uint32_t tmp32;
366
367 /* CMPx_C1
368 * NULL configuration means to disable the feature.
369 */
370 if (NULL == config)
371 {
372 base->C1 &= ~CMP_C1_DACEN_MASK;
373 return;
374 }
375
376 tmp32 = (base->C1 & (~(CMP_C1_VRSEL_MASK | CMP_C1_VOSEL_MASK)));
377 /* Set configuration and enable the feature. */
378 tmp32 |= (CMP_C1_VRSEL(config->referenceVoltageSource) | CMP_C1_VOSEL(config->DACValue) | CMP_C1_DACEN_MASK);
379
380 #if defined(FSL_FEATURE_ACMP_HAS_C1_DACOE_BIT) && (FSL_FEATURE_ACMP_HAS_C1_DACOE_BIT == 1U)
381 tmp32 &= ~CMP_C1_DACOE_MASK;
382 if (config->enableOutput)
383 {
384 tmp32 |= CMP_C1_DACOE_MASK;
385 }
386 #endif /* FSL_FEATURE_ACMP_HAS_C1_DACOE_BIT */
387
388 #if defined(FSL_FEATURE_ACMP_HAS_C1_DMODE_BIT) && (FSL_FEATURE_ACMP_HAS_C1_DMODE_BIT == 1U)
389 switch (config->workMode)
390 {
391 case kACMP_DACWorkLowSpeedMode:
392 tmp32 &= ~CMP_C1_DMODE_MASK;
393 break;
394 case kACMP_DACWorkHighSpeedMode:
395 tmp32 |= CMP_C1_DMODE_MASK;
396 break;
397 default:
398 assert(false);
399 break;
400 }
401 #endif /* FSL_FEATURE_ACMP_HAS_C1_DMODE_BIT */
402
403 base->C1 = tmp32;
404 }
405
406 #if !(defined(FSL_FEATURE_ACMP_HAS_NO_ROUNDROBIN_MODE) && (FSL_FEATURE_ACMP_HAS_NO_ROUNDROBIN_MODE == 1U))
407 /*!
408 * brief Configures the round robin mode.
409 *
410 * Example:
411 code
412 acmp_round_robin_config_t configStruct = {0};
413 configStruct.fixedPort = kACMP_FixedPlusPort;
414 configStruct.fixedChannelNumber = 3U;
415 configStruct.checkerChannelMask = 0xF7U;
416 configStruct.sampleClockCount = 0U;
417 configStruct.delayModulus = 0U;
418 ACMP_SetRoundRobinConfig(CMP0, &configStruct);
419 endcode
420 * param base ACMP peripheral base address.
421 * param config Pointer to round robin mode configuration structure. "NULL" is for disabling the feature.
422 */
ACMP_SetRoundRobinConfig(CMP_Type * base,const acmp_round_robin_config_t * config)423 void ACMP_SetRoundRobinConfig(CMP_Type *base, const acmp_round_robin_config_t *config)
424 {
425 uint32_t tmp32;
426
427 /* CMPx_C2
428 * Set control bit. Avoid clearing status flags at the same time.
429 * NULL configuration means to disable the feature.
430 */
431 if (NULL == config)
432 {
433 tmp32 = CMP_C2_CHnF_MASK;
434 #if defined(FSL_FEATURE_ACMP_HAS_C2_RRE_BIT) && (FSL_FEATURE_ACMP_HAS_C2_RRE_BIT == 1U)
435 tmp32 |= CMP_C2_RRE_MASK;
436 #endif /* FSL_FEATURE_ACMP_HAS_C2_RRE_BIT */
437 base->C2 &= ~(tmp32);
438 return;
439 }
440
441 /* CMPx_C1
442 * Set all channel's round robin checker enable mask.
443 */
444 tmp32 = (base->C1 & ~(CMP_C1_CHNn_MASK));
445 tmp32 |= ((config->checkerChannelMask) << CMP_C1_CHN0_SHIFT);
446 base->C1 = tmp32;
447
448 /* CMPx_C2
449 * Set configuration and enable the feature.
450 */
451 tmp32 = (base->C2 &
452 (~(CMP_C2_FXMP_MASK | CMP_C2_FXMXCH_MASK | CMP_C2_NSAM_MASK | CMP_C2_INITMOD_MASK | CMP_C2_CHnF_MASK)));
453 tmp32 |= (CMP_C2_FXMP(config->fixedPort) | CMP_C2_FXMXCH(config->fixedChannelNumber) |
454 CMP_C2_NSAM(config->sampleClockCount) | CMP_C2_INITMOD(config->delayModulus));
455 #if defined(FSL_FEATURE_ACMP_HAS_C2_RRE_BIT) && (FSL_FEATURE_ACMP_HAS_C2_RRE_BIT == 1U)
456 tmp32 |= CMP_C2_RRE_MASK;
457 #endif /* FSL_FEATURE_ACMP_HAS_C2_RRE_BIT */
458 base->C2 = tmp32;
459 }
460
461 /*!
462 * brief Defines the pre-set state of channels in round robin mode.
463 *
464 * Note: The pre-state has different circuit with get-round-robin-result in the SOC even though they are same bits.
465 * So get-round-robin-result can't return the same value as the value are set by pre-state.
466 *
467 * param base ACMP peripheral base address.
468 * param mask Mask of round robin channel index. Available range is channel0:0x01 to channel7:0x80.
469 */
ACMP_SetRoundRobinPreState(CMP_Type * base,uint32_t mask)470 void ACMP_SetRoundRobinPreState(CMP_Type *base, uint32_t mask)
471 {
472 /* CMPx_C2
473 * Set control bit. Avoid clearing status flags at the same time.
474 */
475 uint32_t tmp32 = (base->C2 & ~(CMP_C2_ACOn_MASK | CMP_C2_CHnF_MASK));
476
477 tmp32 |= (mask << CMP_C2_ACOn_SHIFT);
478 base->C2 = tmp32;
479 }
480
481 /*!
482 * brief Clears the channel input changed flags in round robin mode.
483 *
484 * param base ACMP peripheral base address.
485 * param mask Mask of channel index. Available range is channel0:0x01 to channel7:0x80.
486 */
ACMP_ClearRoundRobinStatusFlags(CMP_Type * base,uint32_t mask)487 void ACMP_ClearRoundRobinStatusFlags(CMP_Type *base, uint32_t mask)
488 {
489 /* CMPx_C2 */
490 uint32_t tmp32 = (base->C2 & (~CMP_C2_CHnF_MASK));
491
492 tmp32 |= (mask << CMP_C2_CH0F_SHIFT);
493 base->C2 = tmp32;
494 }
495 #endif /* !(defined(FSL_FEATURE_ACMP_HAS_NO_ROUNDROBIN_MODE) && (FSL_FEATURE_ACMP_HAS_NO_ROUNDROBIN_MODE == 1U)) */
496
497 /*!
498 * brief Enables interrupts.
499 *
500 * param base ACMP peripheral base address.
501 * param mask Interrupts mask. See "_acmp_interrupt_enable".
502 */
ACMP_EnableInterrupts(CMP_Type * base,uint32_t mask)503 void ACMP_EnableInterrupts(CMP_Type *base, uint32_t mask)
504 {
505 uint32_t tmp32;
506
507 /* CMPx_C0
508 * Set control bit. Avoid clearing status flags at the same time.
509 * Set CMP interrupt enable flag.
510 */
511 tmp32 = base->C0 & ~CMP_C0_CFx_MASK; /* To protect the W1C flags. */
512 if ((uint32_t)kACMP_OutputRisingInterruptEnable == (mask & (uint32_t)kACMP_OutputRisingInterruptEnable))
513 {
514 tmp32 = ((tmp32 | CMP_C0_IER_MASK) & ~CMP_C0_CFx_MASK);
515 }
516 if ((uint32_t)kACMP_OutputFallingInterruptEnable == (mask & (uint32_t)kACMP_OutputFallingInterruptEnable))
517 {
518 tmp32 = ((tmp32 | CMP_C0_IEF_MASK) & ~CMP_C0_CFx_MASK);
519 }
520 base->C0 = tmp32;
521
522 #if !(defined(FSL_FEATURE_ACMP_HAS_NO_ROUNDROBIN_MODE) && (FSL_FEATURE_ACMP_HAS_NO_ROUNDROBIN_MODE == 1U))
523 /* CMPx_C2
524 * Set round robin interrupt enable flag.
525 */
526 if ((uint32_t)kACMP_RoundRobinInterruptEnable == (mask & (uint32_t)kACMP_RoundRobinInterruptEnable))
527 {
528 tmp32 = base->C2;
529 /* Set control bit. Avoid clearing status flags at the same time. */
530 tmp32 = ((tmp32 | CMP_C2_RRIE_MASK) & ~CMP_C2_CHnF_MASK);
531 base->C2 = tmp32;
532 }
533 #endif /* !(defined(FSL_FEATURE_ACMP_HAS_NO_ROUNDROBIN_MODE) && (FSL_FEATURE_ACMP_HAS_NO_ROUNDROBIN_MODE == 1U)) */
534 }
535
536 /*!
537 * brief Disables interrupts.
538 *
539 * param base ACMP peripheral base address.
540 * param mask Interrupts mask. See "_acmp_interrupt_enable".
541 */
ACMP_DisableInterrupts(CMP_Type * base,uint32_t mask)542 void ACMP_DisableInterrupts(CMP_Type *base, uint32_t mask)
543 {
544 uint32_t tmp32;
545
546 /* CMPx_C0
547 * Set control bit. Avoid clearing status flags at the same time.
548 * Clear CMP interrupt enable flag.
549 */
550 tmp32 = base->C0;
551 if ((uint32_t)kACMP_OutputRisingInterruptEnable == (mask & (uint32_t)kACMP_OutputRisingInterruptEnable))
552 {
553 tmp32 &= ~(CMP_C0_IER_MASK | CMP_C0_CFx_MASK);
554 }
555 if ((uint32_t)kACMP_OutputFallingInterruptEnable == (mask & (uint32_t)kACMP_OutputFallingInterruptEnable))
556 {
557 tmp32 &= ~(CMP_C0_IEF_MASK | CMP_C0_CFx_MASK);
558 }
559 base->C0 = tmp32;
560
561 #if !(defined(FSL_FEATURE_ACMP_HAS_NO_ROUNDROBIN_MODE) && (FSL_FEATURE_ACMP_HAS_NO_ROUNDROBIN_MODE == 1U))
562 /* CMPx_C2
563 * Clear round robin interrupt enable flag.
564 */
565 if ((uint32_t)kACMP_RoundRobinInterruptEnable == (mask & (uint32_t)kACMP_RoundRobinInterruptEnable))
566 {
567 tmp32 = base->C2;
568 /* Set control bit. Avoid clearing status flags at the same time. */
569 tmp32 &= ~(CMP_C2_RRIE_MASK | CMP_C2_CHnF_MASK);
570 base->C2 = tmp32;
571 }
572 #endif /* !(defined(FSL_FEATURE_ACMP_HAS_NO_ROUNDROBIN_MODE) && (FSL_FEATURE_ACMP_HAS_NO_ROUNDROBIN_MODE == 1U)) */
573 }
574
575 /*!
576 * brief Gets status flags.
577 *
578 * param base ACMP peripheral base address.
579 * return Status flags asserted mask. See "_acmp_status_flags".
580 */
ACMP_GetStatusFlags(CMP_Type * base)581 uint32_t ACMP_GetStatusFlags(CMP_Type *base)
582 {
583 uint32_t status = 0U;
584 uint32_t tmp32 = base->C0;
585
586 /* CMPx_C0
587 * Check if each flag is set.
588 */
589 if (CMP_C0_CFR_MASK == (tmp32 & CMP_C0_CFR_MASK))
590 {
591 status |= (uint32_t)kACMP_OutputRisingEventFlag;
592 }
593 if (CMP_C0_CFF_MASK == (tmp32 & CMP_C0_CFF_MASK))
594 {
595 status |= (uint32_t)kACMP_OutputFallingEventFlag;
596 }
597 if (CMP_C0_COUT_MASK == (tmp32 & CMP_C0_COUT_MASK))
598 {
599 status |= (uint32_t)kACMP_OutputAssertEventFlag;
600 }
601
602 return status;
603 }
604
605 /*!
606 * brief Clears status flags.
607 *
608 * param base ACMP peripheral base address.
609 * param mask Status flags mask. See "_acmp_status_flags".
610 */
ACMP_ClearStatusFlags(CMP_Type * base,uint32_t mask)611 void ACMP_ClearStatusFlags(CMP_Type *base, uint32_t mask)
612 {
613 /* CMPx_C0 */
614 uint32_t tmp32 = (base->C0 & (~(CMP_C0_CFR_MASK | CMP_C0_CFF_MASK)));
615
616 /* Clear flag according to mask. */
617 if ((uint32_t)kACMP_OutputRisingEventFlag == (mask & (uint32_t)kACMP_OutputRisingEventFlag))
618 {
619 tmp32 |= CMP_C0_CFR_MASK;
620 }
621 if ((uint32_t)kACMP_OutputFallingEventFlag == (mask & (uint32_t)kACMP_OutputFallingEventFlag))
622 {
623 tmp32 |= CMP_C0_CFF_MASK;
624 }
625 base->C0 = tmp32;
626 }
627
628 #if defined(FSL_FEATURE_ACMP_HAS_C3_REG) && (FSL_FEATURE_ACMP_HAS_C3_REG == 1U)
629 /*!
630 * brief Configure the discrete mode.
631 *
632 * Configure the discrete mode when supporting 3V domain with 1.8V core.
633 *
634 * param base ACMP peripheral base address.
635 * param config Pointer to configuration structure. See "acmp_discrete_mode_config_t".
636 */
ACMP_SetDiscreteModeConfig(CMP_Type * base,const acmp_discrete_mode_config_t * config)637 void ACMP_SetDiscreteModeConfig(CMP_Type *base, const acmp_discrete_mode_config_t *config)
638 {
639 uint32_t tmp32 = 0U;
640
641 if (!config->enablePositiveChannelDiscreteMode)
642 {
643 tmp32 |= CMP_C3_PCHCTEN_MASK;
644 }
645 if (!config->enableNegativeChannelDiscreteMode)
646 {
647 tmp32 |= CMP_C3_NCHCTEN_MASK;
648 }
649 #if !(defined(FSL_FEATURE_ACMP_HAS_NO_3V_DOMAIN) && (FSL_FEATURE_ACMP_HAS_NO_3V_DOMAIN == 1U))
650 if (config->enableResistorDivider)
651 {
652 tmp32 |= CMP_C3_RDIVE_MASK;
653 }
654
655 tmp32 |= CMP_C3_DMCS(config->clockSource) /* Select the clock. */
656 | CMP_C3_ACSAT(config->sampleTime) /* Sample time period. */
657 | CMP_C3_ACPH1TC(config->phase1Time) /* Phase 1 sample time. */
658 | CMP_C3_ACPH2TC(config->phase2Time); /* Phase 2 sample time. */
659 #endif /* !(defined(FSL_FEATURE_ACMP_HAS_NO_3V_DOMAIN) && (FSL_FEATURE_ACMP_HAS_NO_3V_DOMAIN == 1U)) */
660
661 base->C3 = tmp32;
662 }
663
664 /*!
665 * brief Get the default configuration for discrete mode setting.
666 *
667 * param config Pointer to configuration structure to be restored with the setting values.
668 */
ACMP_GetDefaultDiscreteModeConfig(acmp_discrete_mode_config_t * config)669 void ACMP_GetDefaultDiscreteModeConfig(acmp_discrete_mode_config_t *config)
670 {
671 assert(NULL != config);
672
673 /* Initializes the configure structure to zero. */
674 (void)memset(config, 0, sizeof(*config));
675
676 config->enablePositiveChannelDiscreteMode = false;
677 config->enableNegativeChannelDiscreteMode = false;
678
679 #if !(defined(FSL_FEATURE_ACMP_HAS_NO_3V_DOMAIN) && (FSL_FEATURE_ACMP_HAS_NO_3V_DOMAIN == 1U))
680 config->enableResistorDivider = false;
681 config->clockSource = kACMP_DiscreteClockSlow;
682 config->sampleTime = kACMP_DiscreteSampleTimeAs1T;
683 config->phase1Time = kACMP_DiscretePhaseTimeAlt0;
684 config->phase2Time = kACMP_DiscretePhaseTimeAlt0;
685 #endif /* !(defined(FSL_FEATURE_ACMP_HAS_NO_3V_DOMAIN) && (FSL_FEATURE_ACMP_HAS_NO_3V_DOMAIN == 1U)) */
686 }
687
688 #endif /* FSL_FEATURE_ACMP_HAS_C3_REG */
689