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