1 /*
2 * Copyright 2021 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_hscmp.h"
9
10 /*******************************************************************************
11 * Definitions
12 ******************************************************************************/
13 /* Component ID definition, used by tools. */
14 #ifndef FSL_COMPONENT_ID
15 #define FSL_COMPONENT_ID "platform.drivers.hscmp"
16 #endif
17
18 #if defined(HSCMP_RSTS)
19 #define HSCMP_RESETS_ARRAY HSCMP_RSTS
20 #endif
21
22 /*******************************************************************************
23 * Prototypes
24 ******************************************************************************/
25 #if defined(HSCMP_CLOCKS)
26 /*!
27 * @brief Get instance number for HSCMP module.
28 *
29 * @param base HSCMP peripheral base address
30 */
31 static uint32_t HSCMP_GetInstance(HSCMP_Type *base);
32 #endif /* HSCMP_CLOCKS */
33
34 /*******************************************************************************
35 * Variables
36 ******************************************************************************/
37 #if defined(HSCMP_CLOCKS)
38 /*! @brief Pointers to HSCMP bases for each instance. */
39 static HSCMP_Type *const s_hscmpBases[] = HSCMP_BASE_PTRS;
40
41 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
42 /*! @brief Pointers to HSCMP clocks for each instance. */
43 static const clock_ip_name_t s_hscmpClocks[] = HSCMP_CLOCKS;
44 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
45 #endif /* HSCMP_CLOCKS */
46
47 #if defined(HSCMP_RESETS_ARRAY)
48 /* Reset array */
49 static const reset_ip_name_t s_hscmpResets[] = HSCMP_RESETS_ARRAY;
50 #endif
51
52 /*******************************************************************************
53 * Codes
54 ******************************************************************************/
55 #if defined(HSCMP_CLOCKS) || defined(HSCMP_RESETS_ARRAY)
HSCMP_GetInstance(HSCMP_Type * base)56 static uint32_t HSCMP_GetInstance(HSCMP_Type *base)
57 {
58 uint32_t instance;
59
60 /* Find the instance index from base address mappings. */
61 for (instance = 0; instance < ARRAY_SIZE(s_hscmpBases); instance++)
62 {
63 if (s_hscmpBases[instance] == base)
64 {
65 break;
66 }
67 }
68
69 assert(instance < ARRAY_SIZE(s_hscmpBases));
70
71 return instance;
72 }
73 #endif /* HSCMP_CLOCKS */
74
75 /*!
76 * brief Initialize the HSCMP
77 *
78 * This function initializes the HSCMP module. The operations included are:
79 * - Enabling the clock for HSCMP module.
80 * - Configuring the comparator.
81 * - Enabling the HSCMP module.
82 * Note: For some devices, multiple HSCMP instance share the same clock gate. In this case, to enable the clock for
83 * any instance enables all the HSCMPs. Check the chip reference manual for the clock assignment of the HSCMP.
84 *
85 * param base HSCMP peripheral base address.
86 * param config Pointer to "hscmp_config_t" structure.
87 */
HSCMP_Init(HSCMP_Type * base,const hscmp_config_t * config)88 void HSCMP_Init(HSCMP_Type *base, const hscmp_config_t *config)
89 {
90 assert(config != NULL);
91
92 uint32_t tmp32;
93
94 #if defined(HSCMP_CLOCKS)
95 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
96 /* Enable the clock. */
97 CLOCK_EnableClock(s_hscmpClocks[HSCMP_GetInstance(base)]);
98 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
99 #endif /* HSCMP_CLOCKS */
100
101 #if defined(HSCMP_RESETS_ARRAY)
102 RESET_ReleasePeripheralReset(s_hscmpResets[HSCMP_GetInstance(base)]);
103 #endif
104
105 /* Configure. */
106 HSCMP_Enable(base, false);
107 /* CCR0 register. */
108 if (config->enableStopMode)
109 {
110 base->CCR0 |= HSCMP_CCR0_CMP_STOP_EN_MASK;
111 }
112 else
113 {
114 base->CCR0 &= ~HSCMP_CCR0_CMP_STOP_EN_MASK;
115 }
116 /* CCR1 register. */
117 tmp32 = base->CCR1 & ~(HSCMP_CCR1_COUT_PEN_MASK | HSCMP_CCR1_COUT_SEL_MASK | HSCMP_CCR1_COUT_INV_MASK);
118 if (config->enableOutputPin)
119 {
120 tmp32 |= HSCMP_CCR1_COUT_PEN_MASK;
121 }
122 if (config->useUnfilteredOutput)
123 {
124 tmp32 |= HSCMP_CCR1_COUT_SEL_MASK;
125 }
126 if (config->enableInvertOutput)
127 {
128 tmp32 |= HSCMP_CCR1_COUT_INV_MASK;
129 }
130 base->CCR1 = tmp32;
131 /* CCR2 register. */
132 tmp32 = base->CCR2 & ~(HSCMP_CCR2_HYSTCTR_MASK | HSCMP_CCR2_CMP_NPMD_MASK | HSCMP_CCR2_CMP_HPMD_MASK);
133 tmp32 |= HSCMP_CCR2_HYSTCTR(config->hysteresisMode);
134 tmp32 |= ((uint32_t)(config->powerMode) << HSCMP_CCR2_CMP_HPMD_SHIFT);
135 base->CCR2 = tmp32;
136
137 HSCMP_Enable(base, true); /* Enable the HSCMP module. */
138 }
139
140 /*!
141 * brief De-initializes the HSCMP module.
142 *
143 * This function de-initializes the HSCMP module. The operations included are:
144 * - Disabling the HSCMP module.
145 * - Disabling the clock for HSCMP module.
146 *
147 * This function disables the clock for the HSCMP.
148 * Note: For some devices, multiple HSCMP instance shares the same clock gate. In this case, before disabling the
149 * clock for the HSCMP, ensure that all the HSCMP instances are not used.
150 *
151 * param base HSCMP peripheral base address.
152 */
HSCMP_Deinit(HSCMP_Type * base)153 void HSCMP_Deinit(HSCMP_Type *base)
154 {
155 /* Disable the HSCMP module. */
156 HSCMP_Enable(base, false);
157 #if defined(HSCMP_CLOCKS)
158 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
159 /* Disable the clock. */
160 CLOCK_DisableClock(s_hscmpClocks[HSCMP_GetInstance(base)]);
161 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
162 #endif /* HSCMP_CLOCKS */
163 }
164
165 /*!
166 * brief Gets an available pre-defined settings for the comparator's configuration.
167 *
168 * This function initializes the comparator configuration structure to these default values:
169 * code
170 * config->enableStopMode = false;
171 * config->enableOutputPin = false;
172 * config->useUnfilteredOutput = false;
173 * config->enableInvertOutput = false;
174 * config->hysteresisMode = kHSCMP_HysteresisLevel0;
175 * config->powerMode = kHSCMP_LowSpeedPowerMode;
176 * endcode
177 * param config Pointer to "hscmp_config_t" structure.
178 */
HSCMP_GetDefaultConfig(hscmp_config_t * config)179 void HSCMP_GetDefaultConfig(hscmp_config_t *config)
180 {
181 /* Initializes the configure structure to zero. */
182 (void)memset(config, 0, sizeof(*config));
183
184 config->enableStopMode = false;
185 config->enableOutputPin = false;
186 config->useUnfilteredOutput = false;
187 config->enableInvertOutput = false;
188 config->hysteresisMode = kHSCMP_HysteresisLevel0;
189 config->powerMode = kHSCMP_LowSpeedPowerMode;
190 }
191
192 /*!
193 * brief Select the input channels for HSCMP. This function determines which input
194 * is selected for the negative and positive mux.
195 *
196 * param base HSCMP peripheral base address.
197 * param positiveChannel Positive side input channel number. Available range is 0-7.
198 * param negativeChannel Negative side input channel number. Available range is 0-7.
199 */
HSCMP_SetInputChannels(HSCMP_Type * base,uint32_t positiveChannel,uint32_t negativeChannel)200 void HSCMP_SetInputChannels(HSCMP_Type *base, uint32_t positiveChannel, uint32_t negativeChannel)
201 {
202 uint32_t tmp32;
203
204 tmp32 = base->CCR2 & ~(HSCMP_CCR2_PSEL_MASK | HSCMP_CCR2_MSEL_MASK);
205 tmp32 |= HSCMP_CCR2_PSEL(positiveChannel) | HSCMP_CCR2_MSEL(negativeChannel);
206 base->CCR2 = tmp32;
207 }
208
209 /*!
210 * brief Configures the filter.
211 *
212 * param base HSCMP peripheral base address.
213 * param config Pointer to "hscmp_filter_config_t" structure.
214 */
HSCMP_SetFilterConfig(HSCMP_Type * base,const hscmp_filter_config_t * config)215 void HSCMP_SetFilterConfig(HSCMP_Type *base, const hscmp_filter_config_t *config)
216 {
217 assert(config != NULL);
218
219 uint32_t tmp32;
220
221 tmp32 = base->CCR1 & ~(HSCMP_CCR1_FILT_PER_MASK | HSCMP_CCR1_FILT_CNT_MASK | HSCMP_CCR1_SAMPLE_EN_MASK);
222 if (config->enableSample)
223 {
224 tmp32 |= HSCMP_CCR1_SAMPLE_EN_MASK;
225 }
226 tmp32 |= HSCMP_CCR1_FILT_PER(config->filterSamplePeriod) | HSCMP_CCR1_FILT_CNT(config->filterSampleCount);
227 base->CCR1 = tmp32;
228 }
229
230 /*!
231 * brief Configure the internal DAC module.
232 *
233 * param base HSCMP peripheral base address.
234 * param config Pointer to "hscmp_dac_config_t" structure. If config is "NULL", disable internal DAC.
235 */
HSCMP_SetDACConfig(HSCMP_Type * base,const hscmp_dac_config_t * config)236 void HSCMP_SetDACConfig(HSCMP_Type *base, const hscmp_dac_config_t *config)
237 {
238 uint32_t tmp32;
239 if (config == NULL)
240 {
241 tmp32 = 0U; /* Disable internal DAC. */
242 }
243 else
244 {
245 tmp32 = HSCMP_DCR_VRSEL(config->referenceVoltageSource) | HSCMP_DCR_DAC_DATA(config->DACValue);
246 if (config->enableLowPowerMode)
247 {
248 tmp32 |= HSCMP_DCR_DAC_HPMD_MASK;
249 }
250 tmp32 |= HSCMP_DCR_DAC_EN_MASK;
251 }
252 base->DCR = tmp32;
253 }
254