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