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