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