1 /*
2  * Copyright 2017-2020 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef FSL_ADC_H_
9 #define FSL_ADC_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  *  @addtogroup adc_12b1msps_sar
15  *  @{
16  */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 /*! @brief ADC driver version */
22 #define FSL_ADC_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*!< Version 2.1.0. */
23 
24 /*!
25  * @brief Reference voltage source.
26  */
27 typedef enum _adc_reference_voltage_source
28 {
29     kADC_ReferenceVoltageSourceAlt0 = 0U, /*!< Default voltage reference pin pair (VREFH/VREFL). >*/
30     kADC_ReferenceVoltageSourceAlt1 = 1U, /*!< Analog supply pin pair (VDDA/VSSA). >*/
31 } adc_reference_voltage_source_t;
32 
33 /*!
34  * @brief Clock divider for the converter.
35  */
36 typedef enum _adc_clock_divider
37 {
38     kADC_ClockDivider1 = 0U, /*!< Divide ration = 1, and clock rate = Input clock. >*/
39     kADC_ClockDivider2 = 1U, /*!< Divide ration = 2, and clock rate = Input clock / 2. >*/
40     kADC_ClockDivider4 = 2U, /*!< Divide ration = 3, and clock rate = Input clock / 4. >*/
41     kADC_ClockDivider8 = 3U, /*!< Divide ration = 4, and clock rate = Input clock / 8. >*/
42 } adc_clock_divider_t;
43 
44 /*!
45  * @brief ADC converter resolution mode.
46  */
47 typedef enum _adc_resolution_mode
48 {
49     kADC_Resolution8BitMode  = 0U, /*!< 8-bit conversion (N = 8). >*/
50     kADC_Resolution10BitMode = 1U, /*!< 10-bit conversion (N = 10) >*/
51     kADC_Resolution12BitMode = 2U, /*!< 12-bit conversion (N = 12) >*/
52 } adc_resolution_mode_t;
53 
54 /*!
55  * @brief ADC input Clock source.
56  */
57 typedef enum _adc_clock_source
58 {
59     kADC_ClockSourceAlt0 = 0U, /*!< Bus clock. >*/
60     kADC_ClockSourceAlt1 = 1U, /*!< Bus clock divided by 2. >*/
61     kADC_ClockSourceAlt2 = 2U, /*!< Alternate clock (ALTCLK). >*/
62     kADC_ClockSourceAlt3 = 3U, /*!< Asynchronous clock (ADACK). >*/
63 } adc_clock_source_t;
64 
65 /*!
66  * @brief Compare function mode.
67  */
68 typedef enum _adc_compare_mode
69 {
70     kADC_CompareDisableMode        = 0U, /*!< Compare function disabled. >*/
71     kADC_CompareLessMode           = 2U, /*!< Compare triggers when input is less than compare level. >*/
72     kADC_CompareGreaterOrEqualMode = 3U, /*!< Compare triggers when input is greater than or equal to compare level. >*/
73 } adc_compare_mode_t;
74 
75 /*!
76  * @brief ADC status flags mask.
77  */
78 enum _adc_status_flags
79 {
80     kADC_ActiveFlag    = ADC_SC2_ADACT_MASK,  /*!< Indicates that a conversion is in progress. >*/
81     kADC_FifoEmptyFlag = ADC_SC2_FEMPTY_MASK, /*!< Indicates that ADC result FIFO have no valid new data. >*/
82     kADC_FifoFullFlag  = ADC_SC2_FFULL_MASK,  /*!< Indicates that ADC result FIFO is full. >*/
83 };
84 
85 #if defined(FSL_FEATURE_ADC_HAS_SC5_REG) && FSL_FEATURE_ADC_HAS_SC5_REG
86 /*!
87  * @brief Hardware tigger mask mode.
88  */
89 typedef enum _adc_hardware_trigger_mask_mode
90 {
91     kADC_HWTriggerMaskDisableMode =
92         0U, /*!< Hardware trigger mask disable and hardware trigger can trigger ADC conversion. >*/
93     kADC_HWTriggerMaskAutoMode = 1U, /*!< Hardware trigger mask automatically when data fifo is not empty. >*/
94     kADC_HWTriggerMaskEnableMode =
95         2U, /*!< Hardware trigger mask enable and hardware trigger cannot trigger ADC conversion. >*/
96 } adc_hardware_trigger_mask_mode_t;
97 #endif /* FSL_FEATURE_ADC_HAS_SC5_REG */
98 
99 /*!
100  * @brief ADC converter configuration.
101  */
102 typedef struct _adc_config
103 {
104     adc_reference_voltage_source_t
105         referenceVoltageSource; /*!< Selects the voltage reference source used for conversions. >*/
106     bool enableLowPower; /*!< Enable low power mode. The power is reduced at the expense of maximum clock speed. >*/
107     bool enableLongSampleTime;            /*!< Enable long sample time mode. >*/
108     adc_clock_divider_t clockDivider;     /*!< Select the divider of input clock source. >*/
109     adc_resolution_mode_t ResolutionMode; /*!< Select the sample resolution mode. >*/
110     adc_clock_source_t clockSource;       /*!< Select the input Clock source. >*/
111 } adc_config_t;
112 
113 /*!
114  * @brief ADC hardware comparison configuration.
115  */
116 typedef struct _adc_hardware_compare_config
117 {
118     uint32_t compareValue;          /*!< Setting the compare value. The value are compared to the conversion result. >*/
119     adc_compare_mode_t compareMode; /*!< Setting the compare mode. Refer to "adc_compare_mode_t". >*/
120 } adc_hardware_compare_config_t;
121 
122 /*!
123  * @brief ADC FIFO configuration.
124  */
125 typedef struct _adc_fifo_config
126 {
127 #if defined(FSL_FEATURE_ADC_HAS_SC4_HTRGME) && FSL_FEATURE_ADC_HAS_SC4_HTRGME
128     bool enableHWTriggerMultConv; /*!< The field is valid when FIFO is enabled.Enable hardware trigger
129                                        multiple conversion. One hardware trigger pulse triggers multiple
130                                        conversions in fifo mode. >*/
131 #endif                            /* FSL_FEATURE_ADC_HAS_SC4_HTRGME */
132     bool enableFifoScanMode;      /*!< The field is valid when FIFO is enabled. Enable the FIFO scan mode.
133                                      If enable, ADC will repeat using the first FIFO channel as the conversion
134                                      channel until the result FIFO is fulfilled. >*/
135     bool enableCompareAndMode;    /*!< The field is valid when FIFO is enabled. If enable, ADC will AND all of compare
136                                        triggers and set COCO after all of compare triggers occur. If disable, ADC will
137                                        OR all of compare triggers and set COCO after at least one of compare trigger
138                                      occurs. >*/
139     uint32_t FifoDepth;           /*!< Setting the depth of FIFO. Depth of fifo is FifoDepth + 1. When FifoDepth = 0U,
140                                        the FIFO is DISABLED. When FifoDepth is set to nonzero, the FIFO function is ENABLED
141                                        and the depth is indicated by the FifoDepth field. >*/
142 } adc_fifo_config_t;
143 
144 /*!
145  * @brief ADC channel conversion configuration
146  */
147 typedef struct _adc_channel_config
148 {
149     uint32_t channelNumber;                    /*!< Setting the conversion channel number. The available range is 0-31.
150                                                     See channel connection information for each chip in Reference
151                                                     Manual document. */
152     bool enableContinuousConversion;           /*!< enables continuous conversions. >*/
153     bool enableInterruptOnConversionCompleted; /*!< Generate an interrupt request once the conversion is completed. */
154 } adc_channel_config_t;
155 
156 #if defined(__cplusplus)
157 extern "C" {
158 #endif
159 
160 /*******************************************************************************
161  * API
162  ******************************************************************************/
163 
164 /*!
165  * @name Initialization
166  * @{
167  */
168 
169 /*!
170  * @brief Initializes the ADC module.
171  *
172  * @param base   ADC peripheral base address.
173  * @param config Pointer to configuration structure. See "adc_config_t".
174  */
175 void ADC_Init(ADC_Type *base, const adc_config_t *config);
176 
177 /*!
178  * @brief De-initialize the ADC module.
179  *
180  * @param base ADC peripheral base address.
181  */
182 void ADC_Deinit(ADC_Type *base);
183 
184 /*!
185  * @brief Gets an available pre-defined settings for the converter's configuration.
186  *
187  * This function initializes the converter configuration structure with available settings. The default values are as
188  * follows.
189  * @code
190  *   config->referenceVoltageSource = kADC_ReferenceVoltageSourceAlt0;
191  *   config->enableLowPower = false;
192  *   config->enableLongSampleTime = false;
193  *   config->clockDivider = kADC_ClockDivider1;
194  *   config->ResolutionMode = kADC_Resolution8BitMode;
195  *   config->clockSource = kADC_ClockSourceAlt0;
196  * @endcode
197  * @param config Pointer to the configuration structure.
198  */
199 void ADC_GetDefaultConfig(adc_config_t *config);
200 
201 /*!
202  * @brief Enable the hardware trigger mode.
203  *
204  * @param base ADC peripheral base address.
205  * @param enable Switcher of the hardware trigger feature. "true" means enabled, "false" means not enabled.
206  */
ADC_EnableHardwareTrigger(ADC_Type * base,bool enable)207 static inline void ADC_EnableHardwareTrigger(ADC_Type *base, bool enable)
208 {
209     if (enable)
210     {
211         base->SC2 |= ADC_SC2_ADTRG_MASK;
212     }
213     else
214     {
215         base->SC2 &= ~ADC_SC2_ADTRG_MASK;
216     }
217 }
218 
219 /*!
220  * @brief Configure the hardware compare mode.
221  *
222  * The compare function can be configured to check for an upper or lower limit. After the
223  * input is sampled and converted, the result is added to the complement of the compare
224  * value (ADC_CV).
225  *
226  * @param base ADC peripheral base address.
227  * @param config Pointer to "adc_hardware_compare_config_t" structure.
228  */
229 void ADC_SetHardwareCompare(ADC_Type *base, const adc_hardware_compare_config_t *config);
230 
231 /*!
232  * @brief Configure the Fifo mode.
233  *
234  * The ADC module supports FIFO operation to minimize the interrupts to CPU in order to
235  * reduce CPU loading in ADC interrupt service routines. This module contains two FIFOs
236  * to buffer analog input channels and analog results respectively.
237  *
238  * @param base ADC peripheral base address.
239  * @param config Pointer to "adc_fifo_config_t" structure.
240  */
241 void ADC_SetFifoConfig(ADC_Type *base, const adc_fifo_config_t *config);
242 
243 /*!
244  * @brief Gets an available pre-defined settings for the FIFO's configuration.
245  *
246  * @param config Pointer to the FIFO configuration structure, please refer to @ref adc_fifo_config_t for details.
247  */
248 void ADC_GetDefaultFIFOConfig(adc_fifo_config_t *config);
249 
250 /*!
251  * @brief Configures the conversion channel.
252  *
253  * This operation triggers the conversion when in software trigger mode. When in hardware trigger mode, this API
254  * configures the channel while the external trigger source helps to trigger the conversion.
255  *
256  * @param base ADC peripheral base address.
257  * @param config Pointer to "adc_channel_config_t" structure.
258  */
259 void ADC_SetChannelConfig(ADC_Type *base, const adc_channel_config_t *config);
260 
261 /*!
262  * @brief Get the status flags of channel.
263  *
264  * @param  base ADC peripheral base address.
265  * @return "True" means conversion has completed and "false" means conversion has not completed.
266  */
267 bool ADC_GetChannelStatusFlags(ADC_Type *base);
268 
269 /*!
270  * @brief Get the ADC status flags.
271  *
272  * @param base ADC peripheral base address.
273  * @return Flags' mask if indicated flags are asserted. See "_adc_status_flags".
274  */
275 uint32_t ADC_GetStatusFlags(ADC_Type *base);
276 
277 /*!
278  * @brief Disables the I/O port control of the pins used as analog inputs.
279  *
280  * When a pin control register bit is set, the following conditions are forced for the associated MCU pin:
281  *  -The output buffer is forced to its high impedance state.
282  *  -The input buffer is disabled. A read of the I/O port returns a zero for any pin with its input buffer disabled.
283  *  -The pullup is disabled.
284  *
285  * @param base ADC peripheral base address.
286  * @param mask The mask of the pin associated with channel ADx. Valid range is AD0:0x1U ~ AD15:0x8000U.
287  *             For example: If enable AD0, AD1 and AD2 pins, mask should be set to 0x7U.
288  * @param enable The "true" means enabled, "false" means not enabled.
289  */
ADC_EnableAnalogInput(ADC_Type * base,uint32_t mask,bool enable)290 static inline void ADC_EnableAnalogInput(ADC_Type *base, uint32_t mask, bool enable)
291 {
292     if (enable)
293     {
294         base->APCTL1 |= ADC_APCTL1_ADPC(mask);
295     }
296     else
297     {
298         base->APCTL1 &= ~ADC_APCTL1_ADPC(mask);
299     }
300 }
301 
302 /*!
303  * @brief  Gets the conversion value.
304  *
305  * @param base ADC peripheral base address.
306  * @return Conversion value.
307  */
ADC_GetChannelConversionValue(ADC_Type * base)308 static inline uint32_t ADC_GetChannelConversionValue(ADC_Type *base)
309 {
310     return (((base->R) & ADC_R_ADR_MASK) >> ADC_R_ADR_SHIFT);
311 }
312 
313 #if defined(FSL_FEATURE_ADC_HAS_SC5_REG) && FSL_FEATURE_ADC_HAS_SC5_REG
ADC_SetHardwareTriggerMaskMode(ADC_Type * base,adc_hardware_trigger_mask_mode_t mode)314 static inline void ADC_SetHardwareTriggerMaskMode(ADC_Type *base, adc_hardware_trigger_mask_mode_t mode)
315 {
316     base->SC5 = (uint32_t)mode << ADC_SC5_HTRGMASKSEL_SHIFT;
317 }
318 #endif /* FSL_FEATURE_ADC_HAS_SC5_REG */
319 
320 /*! @} */
321 
322 #if defined(__cplusplus)
323 }
324 #endif
325 
326 /*! @} */
327 
328 #endif /* FSL_ADC_H_ */
329