1 /*
2 * Copyright 2018-2020 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #ifndef FSL_CMP_H_
9 #define FSL_CMP_H_
10
11 #include "fsl_common.h"
12
13 /*!
14 * @addtogroup cmp_1
15 * @{
16 */
17
18 /******************************************************************************
19 * Definitions.
20 *****************************************************************************/
21 /*! @name Driver version */
22 /*! @{ */
23 /*! @brief Driver version 2.2.1. */
24 #define FSL_CMP_DRIVER_VERSION (MAKE_VERSION(2U, 2U, 1U))
25 /*! @} */
26
27 /*! @brief CMP input mux for positive and negative sides. */
28 enum _cmp_input_mux
29 {
30 kCMP_InputVREF = 0U, /*!< Cmp input from VREF. */
31 kCMP_Input1 = 1U, /*!< Cmp input source 1. */
32 kCMP_Input2 = 2U, /*!< Cmp input source 2. */
33 kCMP_Input3 = 3U, /*!< Cmp input source 3. */
34 kCMP_Input4 = 4U, /*!< Cmp input source 4. */
35 kCMP_Input5 = 5U, /*!< Cmp input source 5. */
36 };
37
38 /*! @brief CMP interrupt type. */
39 enum _cmp_interrupt_type
40 {
41 kCMP_EdgeDisable = 0U, /*!< Disable edge interupt. */
42 kCMP_EdgeRising = 2U, /*!< Interrupt on falling edge. */
43 kCMP_EdgeFalling = 4U, /*!< Interrupt on rising edge. */
44 kCMP_EdgeRisingFalling = 6U, /*!< Interrupt on both rising and falling edges. */
45
46 kCMP_LevelDisable = 1U, /*!< Disable level interupt. */
47 kCMP_LevelHigh = 3U, /*!< Interrupt on high level. */
48 kCMP_LevelLow = 5U, /*!< Interrupt on low level. */
49 };
50
51 /*! @brief CMP Voltage Reference source. */
52 typedef enum _cmp_vref_source
53 {
54 KCMP_VREFSourceVDDA = 1U, /*!< Select VDDA as VREF. */
55 KCMP_VREFSourceInternalVREF = 0U, /*!< Select internal VREF as VREF. */
56 } cmp_vref_source_t;
57
58 typedef struct _cmp_vref_config
59 {
60 cmp_vref_source_t vrefSource; /*!< Reference voltage source. */
61 uint8_t vrefValue; /*!< Reference voltage step. Available range is 0-31. Per step equals to VREFINPUT/31. */
62 } cmp_vref_config_t;
63
64 /*! @brief CMP Filter sample mode. */
65 typedef enum _cmp_filtercgf_samplemode
66 {
67 kCMP_FilterSampleMode0 = 0U, /*!< Bypass mode. Filtering is disabled. */
68 kCMP_FilterSampleMode1 = 1U, /*!< Filter 1 clock period. */
69 kCMP_FilterSampleMode2 = 2U, /*!< Filter 2 clock period. */
70 kCMP_FilterSampleMode3 = 3U /*!< Filter 3 clock period. */
71 } cmp_filtercgf_samplemode_t;
72
73 /*! @brief CMP Filter clock divider. */
74 typedef enum _cmp_filtercgf_clkdiv
75 {
76 kCMP_FilterClockDivide1 = 0U, /*!< Filter clock period duration equals 1 analog comparator clock period. */
77 kCMP_FilterClockDivide2 = 1U, /*!< Filter clock period duration equals 2 analog comparator clock period. */
78 kCMP_FilterClockDivide4 = 2U, /*!< Filter clock period duration equals 4 analog comparator clock period. */
79 kCMP_FilterClockDivide8 = 3U, /*!< Filter clock period duration equals 8 analog comparator clock period. */
80 kCMP_FilterClockDivide16 = 4U, /*!< Filter clock period duration equals 16 analog comparator clock period. */
81 kCMP_FilterClockDivide32 = 5U, /*!< Filter clock period duration equals 32 analog comparator clock period. */
82 kCMP_FilterClockDivide64 = 6U /*!< Filter clock period duration equals 64 analog comparator clock period. */
83 } cmp_filtercgf_clkdiv_t;
84
85 /*! @brief CMP configuration structure. */
86 typedef struct _cmp_config
87 {
88 bool enableHysteresis; /*!< Enable hysteresis. */
89 bool enableLowPower; /*!< Enable low power mode. */
90 cmp_filtercgf_clkdiv_t filterClockDivider; /* Filter clock divider. Filter clock equals the Analog Comparator clock
91 divided by 2^FILTERCGF_CLKDIV. */
92 cmp_filtercgf_samplemode_t
93 filterSampleMode; /* Filter sample mode. Control the filtering of the Analog Comparator output. */
94 } cmp_config_t;
95
96 /*************************************************************************************************
97 * API
98 ************************************************************************************************/
99 #if defined(__cplusplus)
100 extern "C" {
101 #endif
102
103 /*!
104 * @name Initialization and deinitialization
105 * @{
106 */
107
108 /*!
109 * @brief CMP initialization.
110 *
111 * This function enables the CMP module and do necessary settings.
112 *
113 * @param config Pointer to the configuration structure.
114 */
115 void CMP_Init(const cmp_config_t *config);
116
117 /*!
118 * @brief CMP deinitialization.
119 *
120 * This function gates the clock for CMP module.
121 */
122 void CMP_Deinit(void);
123
124 /*!
125 * @brief Initializes the CMP user configuration structure.
126 *
127 * This function initializes the user configuration structure to these default values.
128 * @code
129 * config->enableHysteresis = true;
130 * config->enableLowPower = true;
131 * config->filterClockDivider = kCMP_FilterClockDivide1;
132 * config->filterSampleMode = kCMP_FilterSampleMode0;
133 * @endcode
134 * @param config Pointer to the configuration structure.
135 */
136 void CMP_GetDefaultConfig(cmp_config_t *config);
137
138 /*! @} */
139
140 /*!
141 * @name Compare Interface
142 * @{
143 */
144
145 /*
146 * @brief Set the input channels for the comparator.
147 *
148 * @param positiveChannel Positive side input channel number. See "_cmp_input_mux".
149 * @param negativeChannel Negative side input channel number. See "_cmp_input_mux".
150 */
CMP_SetInputChannels(uint8_t positiveChannel,uint8_t negativeChannel)151 static inline void CMP_SetInputChannels(uint8_t positiveChannel, uint8_t negativeChannel)
152 {
153 PMC->COMP &= ~(PMC_COMP_PMUX_MASK | PMC_COMP_NMUX_MASK);
154 PMC->COMP |= (PMC_COMP_PMUX(positiveChannel) | PMC_COMP_NMUX(negativeChannel));
155 }
156
157 /*!
158 * @brief Configures the VREFINPUT.
159 *
160 * @param config Pointer to the configuration structure.
161 */
162 void CMP_SetVREF(const cmp_vref_config_t *config);
163
164 /*!
165 * @brief Get CMP compare output.
166 *
167 * @return The output result. true: voltage on positive side is greater than negative side.
168 * false: voltage on positive side is lower than negative side.
169 */
CMP_GetOutput(void)170 static inline bool CMP_GetOutput(void)
171 {
172 return SYSCON_COMP_INT_STATUS_VAL_MASK == (SYSCON->COMP_INT_STATUS & SYSCON_COMP_INT_STATUS_VAL_MASK);
173 }
174
175 /*! @} */
176
177 /*!
178 * @name Interrupt Interface
179 * @{
180 */
181
182 /*!
183 * @brief CMP enable interrupt.
184 *
185 * @param type CMP interrupt type. See "_cmp_interrupt_type".
186 */
CMP_EnableInterrupt(uint32_t type)187 static inline void CMP_EnableInterrupt(uint32_t type)
188 {
189 SYSCON->COMP_INT_CTRL |= (SYSCON_COMP_INT_CTRL_INT_CTRL(type) | SYSCON_COMP_INT_CTRL_INT_ENABLE_MASK);
190 }
191
192 /*!
193 * @brief CMP disable interrupt.
194 *
195 */
CMP_DisableInterrupt(void)196 static inline void CMP_DisableInterrupt(void)
197 {
198 SYSCON->COMP_INT_CTRL &= ~SYSCON_COMP_INT_CTRL_INT_ENABLE_MASK;
199 }
200
201 /*!
202 * @brief CMP clear interrupt.
203 *
204 */
CMP_ClearInterrupt(void)205 static inline void CMP_ClearInterrupt(void)
206 {
207 SYSCON->COMP_INT_CTRL |= SYSCON_COMP_INT_CTRL_INT_CLEAR_MASK;
208 }
209
210 /*!
211 * @brief Select which Analog comparator output (filtered or un-filtered) is used for interrupt detection.
212 *
213 * @param enable false: Select Analog Comparator raw output (unfiltered) as input for interrupt detection.
214 * true: Select Analog Comparator filtered output as input for interrupt detection.
215 *
216 * @note: When CMP is configured as the wakeup source in power down mode, this function must use the raw output as the
217 * interupt source, that is, call this function and set parameter enable to false.
218 */
CMP_EnableFilteredInterruptSource(bool enable)219 static inline void CMP_EnableFilteredInterruptSource(bool enable)
220 {
221 if (enable)
222 {
223 SYSCON->COMP_INT_CTRL &= ~SYSCON_COMP_INT_CTRL_INT_SOURCE_MASK;
224 }
225 else
226 {
227 SYSCON->COMP_INT_CTRL |= SYSCON_COMP_INT_CTRL_INT_SOURCE_MASK;
228 }
229 }
230 /*! @} */
231
232 /*!
233 * @name Status Interface
234 * @{
235 */
236
237 /*!
238 * @brief Get CMP interrupt status before interupt enable.
239 *
240 * @return Interrupt status. true: interrupt pending,
241 * false: no interrupt pending.
242 */
CMP_GetPreviousInterruptStatus(void)243 static inline bool CMP_GetPreviousInterruptStatus(void)
244 {
245 return SYSCON_COMP_INT_STATUS_STATUS_MASK == (SYSCON->COMP_INT_STATUS & SYSCON_COMP_INT_STATUS_STATUS_MASK);
246 }
247
248 /*!
249 * @brief Get CMP interrupt status after interupt enable.
250 *
251 * @return Interrupt status. true: interrupt pending,
252 * false: no interrupt pending.
253 */
CMP_GetInterruptStatus(void)254 static inline bool CMP_GetInterruptStatus(void)
255 {
256 return SYSCON_COMP_INT_STATUS_INT_STATUS_MASK == (SYSCON->COMP_INT_STATUS & SYSCON_COMP_INT_STATUS_INT_STATUS_MASK);
257 }
258 /*! @} */
259
260 /*!
261 * @name Filter Interface
262 * @{
263 */
264
265 /*!
266 * @brief CMP Filter Sample Config.
267 *
268 * This function allows the users to configure the sampling mode and clock divider of the CMP Filter.
269 *
270 * @param filterSampleMode CMP Select filter sample mode
271 * @param filterClockDivider CMP Set fileter clock divider
272 */
CMP_FilterSampleConfig(cmp_filtercgf_samplemode_t filterSampleMode,cmp_filtercgf_clkdiv_t filterClockDivider)273 static inline void CMP_FilterSampleConfig(cmp_filtercgf_samplemode_t filterSampleMode,
274 cmp_filtercgf_clkdiv_t filterClockDivider)
275 {
276 uint32_t comp = PMC->COMP;
277
278 comp &= ~(PMC_COMP_FILTERCGF_CLKDIV_MASK | PMC_COMP_FILTERCGF_SAMPLEMODE_MASK);
279 comp |= (((uint32_t)filterClockDivider << PMC_COMP_FILTERCGF_CLKDIV_SHIFT) |
280 ((uint32_t)filterSampleMode << PMC_COMP_FILTERCGF_SAMPLEMODE_SHIFT));
281
282 PMC->COMP = comp;
283 }
284 /*! @} */
285
286 #if defined(__cplusplus)
287 }
288 #endif
289
290 /*! @} */
291 #endif /* FSL_CMP_H_ */
292