1 /**
2  * @file    adc.h
3  * @brief   Analog to Digital Converter(ADC) function prototypes and data types.
4  */
5 
6 /******************************************************************************
7  *
8  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
9  * Analog Devices, Inc.),
10  * Copyright (C) 2023-2024 Analog Devices, Inc.
11  *
12  * Licensed under the Apache License, Version 2.0 (the "License");
13  * you may not use this file except in compliance with the License.
14  * You may obtain a copy of the License at
15  *
16  *     http://www.apache.org/licenses/LICENSE-2.0
17  *
18  * Unless required by applicable law or agreed to in writing, software
19  * distributed under the License is distributed on an "AS IS" BASIS,
20  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  * See the License for the specific language governing permissions and
22  * limitations under the License.
23  *
24  ******************************************************************************/
25 
26 /* Define to prevent redundant inclusion */
27 #ifndef LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32572_ADC_H_
28 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32572_ADC_H_
29 
30 /* **** Includes **** */
31 #include <stdint.h>
32 #include "adc_regs.h"
33 #include "mcr_regs.h"
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 /**
40  * @defgroup adc Analog to Digital Converter (ADC)
41  * @ingroup periphlibs
42  * @{
43  */
44 
45 ///< Macros to select ADC channels
46 #define MXC_V_ADC_CTRL_ADC_CHSEL_AIN0 ((uint32_t)(0x00000000UL))
47 #define MXC_V_ADC_CTRL_ADC_CHSEL_AIN1 ((uint32_t)(0x00000001UL))
48 #define MXC_V_ADC_CTRL_ADC_CHSEL_AIN2 ((uint32_t)(0x00000002UL))
49 #define MXC_V_ADC_CTRL_ADC_CHSEL_AIN3 ((uint32_t)(0x00000003UL))
50 #define MXC_V_ADC_CTRL_ADC_CHSEL_AIN4 ((uint32_t)(0x00000004UL))
51 #define MXC_V_ADC_CTRL_ADC_CHSEL_AIN5 ((uint32_t)(0x00000005UL))
52 #define MXC_V_ADC_CTRL_ADC_CHSEL_AIN6 ((uint32_t)(0x00000006UL))
53 #define MXC_V_ADC_CTRL_ADC_CHSEL_AIN7 ((uint32_t)(0x00000007UL))
54 #define MXC_V_ADC_CTRL_ADC_CHSEL_VCOREA ((uint32_t)(0x00000008UL))
55 #define MXC_V_ADC_CTRL_ADC_CHSEL_VCOREB ((uint32_t)(0x00000009UL))
56 #define MXC_V_ADC_CTRL_ADC_CHSEL_VRXOUT ((uint32_t)(0x0000000AUL))
57 #define MXC_V_ADC_CTRL_ADC_CHSEL_VTXOUT ((uint32_t)(0x0000000BUL))
58 #define MXC_V_ADC_CTRL_ADC_CHSEL_VDDA ((uint32_t)(0x0000000CUL))
59 #define MXC_V_ADC_CTRL_ADC_CHSEL_VDDB ((uint32_t)(0x0000000DUL))
60 #define MXC_V_ADC_CTRL_ADC_CHSEL_VDDI0 ((uint32_t)(0x0000000EUL))
61 #define MXC_V_ADC_CTRL_ADC_CHSEL_VDDI0H ((uint32_t)(0x0000000FUL))
62 #define MXC_V_ADC_CTRL_ADC_CHSEL_VREGI ((uint32_t)(0x00000010UL))
63 
64 /***************************************************************************************************************
65                                     DATA STRUCTURES FOR ADC INITIALIZATION
66 ***************************************************************************************************************/
67 /**
68   * @brief  Enumeration type for the ADC Input Channels
69   *
70   */
71 typedef enum {
72     MXC_ADC_CH_0 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN0, ///< Select Channel 0
73     MXC_ADC_CH_1 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN1, ///< Select Channel 1
74     MXC_ADC_CH_2 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN2, ///< Select Channel 2
75     MXC_ADC_CH_3 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN3, ///< Select Channel 3
76     MXC_ADC_CH_4 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN4, ///< Channel 0 divided by 5
77     MXC_ADC_CH_5 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN5, ///< Channel 1 divided by 5
78     MXC_ADC_CH_6 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN6, ///< VDDB divided by 4
79     MXC_ADC_CH_7 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN7, ///< VDD18 input select
80     MXC_ADC_CH_VCOREA = MXC_V_ADC_CTRL_ADC_CHSEL_VCOREA, ///< VDD12 input select
81     MXC_ADC_CH_VCOREB = MXC_V_ADC_CTRL_ADC_CHSEL_VCOREB,
82     MXC_ADC_CH_VRXOUT = MXC_V_ADC_CTRL_ADC_CHSEL_VRXOUT, ///< VRTC divided by 2
83     MXC_ADC_CH_VTXOUT = MXC_V_ADC_CTRL_ADC_CHSEL_VTXOUT, ///< TMON input select
84     MXC_ADC_CH_VDDA = MXC_V_ADC_CTRL_ADC_CHSEL_VDDA,
85     MXC_ADC_CH_VDDB = MXC_V_ADC_CTRL_ADC_CHSEL_VDDB,
86     MXC_ADC_CH_VDDIO = MXC_V_ADC_CTRL_ADC_CHSEL_VDDI0,
87     MXC_ADC_CH_VDDIOH = MXC_V_ADC_CTRL_ADC_CHSEL_VDDI0H,
88     MXC_ADC_CH_VREGI = MXC_V_ADC_CTRL_ADC_CHSEL_VREGI,
89 } mxc_adc_chsel_t;
90 
91 /**
92  * @brief   Enumeration type for the ADC Monitors
93  *          4 Monitors exist and can be mapped to any ADC channels
94  *
95  */
96 typedef enum {
97     MXC_ADC_MONITOR_0,
98     MXC_ADC_MONITOR_1,
99     MXC_ADC_MONITOR_2,
100     MXC_ADC_MONITOR_3,
101 } mxc_adc_monitor_t;
102 
103 /**
104  * @brief   Enumeration type for ADC Scale values
105  *          Internal ADC channels automatically use the most appropriate scale
106  *
107  */
108 typedef enum {
109     MXC_ADC_SCALE_2X, ///< ADC Scale by 2x (this scales ADC Reference by 1/2)
110     MXC_ADC_SCALE_1, ///< ADC Scale by 1x (no scaling)
111     MXC_ADC_SCALE_2, ///< ADC Scale by 1/2
112     MXC_ADC_SCALE_3, ///< ADC Scale by 1/3
113     MXC_ADC_SCALE_4, ///< ADC Scale by 1/4
114     MXC_ADC_SCALE_6, ///< ADC Scale by 1/6 (this uses 1/3 and an additional 1/2 scaling)
115     MXC_ADC_SCALE_8, ///< ADC Scale by 1/8 (this uses 1/4 and an additional 1/2 scaling)
116 } mxc_adc_scale_t;
117 
118 /**
119  * @brief   Callback used when a conversion event is complete
120  *
121  */
122 typedef void (*mxc_adc_complete_cb_t)(void *req, int error);
123 
124 /**
125  * @brief   Callback used when a monitor detects that a channel has reached a limit
126  *
127  */
128 typedef void (*mxc_adc_monitor_cb_t)(void *req, int error);
129 
130 /**
131  * @brief   Used to set up a monitor to watch a channel
132  *
133  */
134 typedef struct {
135     mxc_adc_monitor_t monitor; ///< Monitor to use
136     mxc_adc_scale_t scale; ///< Channel scale to use (if external channel)
137     mxc_adc_chsel_t channel; ///< Channel to use
138     int lowThreshold; ///< Low Threshold for monitor (RAW ADC counts)
139     int highThreshold; ///< High Threshold for monitor (RAW ADC counts)
140     mxc_adc_monitor_cb_t callback; ///< Function to call when the channel crosses threshold
141 } mxc_adc_monitor_req_t;
142 
143 /**
144  * @brief   Used to set up channel for conversion
145  *
146  */
147 typedef struct {
148     mxc_adc_chsel_t channel; ///< Channel to use
149     mxc_adc_scale_t scale; ///< Channel scale to use (if external channel)
150     int rawADCValue; ///< Result of the conversion
151     mxc_adc_complete_cb_t callback; ///< Function to call when callback is complete
152 } mxc_adc_conversion_req_t;
153 
154 /**
155  * Enumeration type for ADC reference sources
156  */
157 typedef enum {
158     MXC_ADC_REF_INT, // Selects internal bandgap reference
159     MXC_ADC_REF_EXT, // Selects external reference pins
160 } mxc_adc_ref_t;
161 
162 /**
163  * @brief   Performs the ADC startup procedure
164  *
165  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
166  */
167 int MXC_ADC_Init(void);
168 
169 /**
170  * @brief   Shuts down the ADC
171  *
172  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
173  */
174 int MXC_ADC_Shutdown(void);
175 
176 /**
177  * @brief   Checks if the ADC is busy (performing a conversion)
178  *
179  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
180  */
181 int MXC_ADC_Busy(void);
182 
183 /**
184  * @brief   Enable specific ADC interrupts
185  *
186  * @param   flags mask of interrupt flags to enables
187  */
188 void MXC_ADC_EnableInt(uint32_t flags);
189 
190 /**
191  * @brief   Disable specific ADC interrupts
192  *
193  * @param   flags mask of interrupt flags to enables
194  */
195 void MXC_ADC_DisableInt(uint32_t flags);
196 
197 /**
198  * @brief   Performs the ADC startup procedure
199  *
200  * @return  active flags
201  */
202 int MXC_ADC_GetFlags(void);
203 
204 /**
205  * @brief   Performs the ADC startup procedure
206  *
207  * @param   flags mask of flags to clear
208  */
209 void MXC_ADC_ClearFlags(uint32_t flags);
210 
211 /**
212  * @brief   Sets the ADC conversion speed
213  *
214  * @param   hz conversion frequency
215  *
216  * @return  Actual conversion speed, or \ref MXC_Error_Codes for Error.
217  */
218 int MXC_ADC_SetConversionSpeed(uint32_t hz);
219 
220 /**
221  * @brief   Gets the current ADC conversion speed
222  *
223  * @return  Actual conversion speed, or \ref MXC_Error_Codes for Error.
224  */
225 int MXC_ADC_GetConversionSpeed(void);
226 
227 /**
228  * @brief   Set the data alignment
229  *
230  * @param   msbJustify set this bit to fill the 12 most significant bits of the data registers
231  */
232 void MXC_ADC_SetDataAlignment(int msbJustify);
233 
234 /**
235  * @brief   Sets the scaling used for conversions on external channels
236  * @note    Internal channels are approx. known and have fixed scaling
237  *          Externals channels can be scaled with standard scaling (1-4x)
238  *          Or by using a separate 1/2 input scale, or a 1/2 ref scale (total range 0.5-8x)
239  * @param   scale requested scale or \ref mxc_adc_scale_t
240  */
241 void MXC_ADC_SetExtScale(mxc_adc_scale_t scale);
242 
243 /**
244  * @brief   Enable channel high/low monitor
245  * @note    This function only enables an already configured monitor
246  *
247  * @param   monitor The monitor to enable or \ref mxc_adc_monitor_t
248  */
249 void MXC_ADC_EnableMonitor(mxc_adc_monitor_t monitor);
250 
251 /**
252  * @brief   Disable channel high/low monitor
253  * @note    This function only disables an already configured monitor
254  *
255  * @param   monitor The monitor to disable or \ref mxc_adc_monitor_t
256  */
257 void MXC_ADC_DisableMonitor(mxc_adc_monitor_t monitor);
258 
259 /**
260  * @brief   Set the high limit for a specific monitor
261  * @note    setting a value of 0 disables this limit
262  *
263  * @param   monitor the monitor to set the limit on or \ref mxc_adc_monitor_t
264  * @param   threshold the limit to set
265  */
266 void MXC_ADC_SetMonitorHighThreshold(mxc_adc_monitor_t monitor, uint32_t threshold);
267 
268 /**
269  * @brief   Set the high limit for a specific monitor
270  *
271  * @param   monitor the monitor to set the limit on or \ref mxc_adc_monitor_t
272  *
273  * @return  the monitor's high threshold
274  */
275 int MXC_ADC_GetMonitorHighThreshold(mxc_adc_monitor_t monitor);
276 
277 /**
278  * @brief   Set the low limit for a specific monitor
279  * @note    setting a value of 0 disables this limit
280  *
281  * @param   monitor the monitor to set the limit on or \ref mxc_adc_monitor_t
282  * @param   threshold the limit to set
283  */
284 void MXC_ADC_SetMonitorLowThreshold(mxc_adc_monitor_t monitor, uint32_t threshold);
285 
286 /**
287  * @brief   Set the low limit for a specific monitor
288  *
289  * @param   monitor the monitor to set the limit on or \ref mxc_adc_monitor_t
290  *
291  * @return  the monitor's low threshold
292  */
293 int MXC_ADC_GetMonitorLowThreshold(mxc_adc_monitor_t monitor);
294 
295 /**
296  * @brief   Set a monitor to use a specific channel
297  * @note    The monitor must be enabled separately
298  *
299  * @param   monitor the monitor to set the limit on or \ref mxc_adc_monitor_t
300  * @param   channel the channel to monitor or \ref mxc_adc_chsel_t
301  */
302 void MXC_ADC_SetMonitorChannel(mxc_adc_monitor_t monitor, mxc_adc_chsel_t channel);
303 
304 /**
305  * @brief   Get the channel used by a monitor
306  *
307  * @param   monitor the monitor to set the limit on or \ref mxc_adc_monitor_t
308  *
309  * @return  the channel being monitored
310  */
311 int MXC_ADC_GetMonitorChannel(mxc_adc_monitor_t monitor);
312 
313 /**
314  * @brief   Set a callback to be called when a monitor goes out of range
315  * @note    The ADC interrupt must be enabled and MXC_ADC_Handler() called in the ISR
316  *
317  * @param   monitor the monitor to register callback for or \ref mxc_adc_monitor_t
318  * @param   callback the function called when the limit is hit or \ref mxc_adc_monitor_cb_t
319  */
320 void MXC_ADC_EnableMonitorAsync(mxc_adc_monitor_t monitor, mxc_adc_monitor_cb_t callback);
321 
322 /**
323  * @brief   Disable a callback for a monitor
324  *
325  * @param   monitor the monitor to unregister callback for or \ref mxc_adc_monitor_t
326  */
327 void MXC_ADC_DisableMonitorAsync(mxc_adc_monitor_t monitor);
328 
329 /**
330  * @brief   Perform a conversion on a specific channel
331  * @note    The channel must be configured separately
332  *
333  * @param   channel the channel to perform the conversion on or \ref mxc_adc_chsel_t
334  *
335  * @return  Raw conversion value, or \ref MXC_Error_Codes for error.
336  */
337 int MXC_ADC_StartConversion(mxc_adc_chsel_t channel);
338 
339 /**
340  * @brief   Perform a conversion on a specific channel
341  * @note    The channel must be configured separately
342  *          The ADC interrupt must be enabled and MXC_ADC_Handler() called in the ISR
343  *          places data in the error parameter of the callback function
344  *
345  * @param   channel the channel to perform the conversion on or \ref mxc_adc_chsel_t
346  * @param   callback the function to call when the conversion is complete
347  *
348  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
349  */
350 int MXC_ADC_StartConversionAsync(mxc_adc_chsel_t channel, mxc_adc_complete_cb_t callback);
351 
352 /**
353  * @brief   Perform a conversion on a specific channel
354  * @note    The channel must be configured separately
355  *
356  * @param   channel  the channel to perform the conversion on or \ref mxc_adc_chsel_t
357  * @param   data     return rax adc data
358  * @param   callback DMA complete callback
359  *
360  * @return  Raw conversion value, or \ref MXC_Error_Codes for error.
361  */
362 int MXC_ADC_StartConversionDMA(mxc_adc_chsel_t channel, uint16_t *data, void (*callback)(int, int));
363 
364 /**
365  * @brief      Call this function from the ADC ISR when using Async API
366  *             functions
367  *
368  * @return     Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
369  */
370 int MXC_ADC_Handler(void);
371 
372 /**
373  * @brief      Perform a conversion on a specific channel
374  * @note       The result will be placed back in the request structure
375  *
376  * @param      req   The structure containing all information for the conversion
377  *
378  * @return     \ref MXC_Error_Codes for error.
379  */
380 int MXC_ADC_Convert(mxc_adc_conversion_req_t *req);
381 
382 /**
383  * @brief      Perform a conversion on a specific channel
384  * @note       The result will be placed back in the request structure The ADC
385  *             interrupt must be enabled and MXC_ADC_Handler() called in the ISR
386  *
387  * @param      req   The structure containing all information for the conversion
388  *
389  * @return     return E_NO_ERROR OR E_BUSY
390  */
391 int MXC_ADC_ConvertAsync(mxc_adc_conversion_req_t *req);
392 
393 /**
394  * @brief   Monitor a specific channel for an out of range event
395  * @note    synchronously waits for an out of range event to occur on the monitor
396  * @param   req The structure containing all information for monitoring
397  */
398 void MXC_ADC_Monitor(mxc_adc_monitor_req_t req);
399 
400 /**
401  * @brief   Monitor a specific channel for an out of range event
402  * @note    If a callback is included, the ADC interrupt must be enabled
403  *          and MXC_ADC_Handler() called in the ISR
404  *
405  * @param   req The structure containing all information for monitoring
406  */
407 void MXC_ADC_MonitorAsync(mxc_adc_monitor_req_t req);
408 
409 /**
410  * @brief Gets the result from the previous ADC conversion
411  * @param      outdata Pointer to store the ADC data conversion result
412  * @return     #E_OVERFLOW   ADC overflow error
413  * @return     #E_NO_ERROR   Data returned in \p outdata parameter
414  */
415 int MXC_ADC_GetData(uint16_t *outdata);
416 /**@} end of group adc */
417 
418 #ifdef __cplusplus
419 }
420 #endif
421 
422 #endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32572_ADC_H_
423