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