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_MAX32570_ADC_H_
28 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32570_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  * @brief   Performs the ADC startup procedure
156  *
157  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
158  */
159 int MXC_ADC_Init(void);
160 
161 /**
162  * @brief   Shuts down the ADC
163  *
164  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
165  */
166 int MXC_ADC_Shutdown(void);
167 
168 /**
169  * @brief   Checks if the ADC is busy (performing a conversion)
170  *
171  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
172  */
173 int MXC_ADC_Busy(void);
174 
175 /**
176  * @brief   Enable specific ADC interrupts
177  *
178  * @param   flags mask of interrupt flags to enables
179  */
180 void MXC_ADC_EnableInt(uint32_t flags);
181 
182 /**
183  * @brief   Disable specific ADC interrupts
184  *
185  * @param   flags mask of interrupt flags to enables
186  */
187 void MXC_ADC_DisableInt(uint32_t flags);
188 
189 /**
190  * @brief   Performs the ADC startup procedure
191  *
192  * @return  active flags
193  */
194 int MXC_ADC_GetFlags(void);
195 
196 /**
197  * @brief   Performs the ADC startup procedure
198  *
199  * @param   flags mask of flags to clear
200  */
201 void MXC_ADC_ClearFlags(uint32_t flags);
202 
203 /**
204  * @brief   Sets the ADC conversion speed
205  *
206  * @param   hz conversion frequency
207  *
208  * @return  Actual conversion speed, or \ref MXC_Error_Codes for Error.
209  */
210 int MXC_ADC_SetConversionSpeed(uint32_t hz);
211 
212 /**
213  * @brief   Gets the current ADC conversion speed
214  *
215  * @return  Actual conversion speed, or \ref MXC_Error_Codes for Error.
216  */
217 int MXC_ADC_GetConversionSpeed(void);
218 
219 /**
220  * @brief   Set the data alignment
221  *
222  * @param   msbJustify set this bit to fill the 12 most significant bits of the data registers
223  */
224 void MXC_ADC_SetDataAlignment(int msbJustify);
225 
226 /**
227  * @brief   Sets the scaling used for conversions on external channels
228  * @note    Internal channels are approx. known and have fixed scaling
229  *          Externals channels can be scaled with standard scaling (1-4x)
230  *          Or by using a separate 1/2 input scale, or a 1/2 ref scale (total range 0.5-8x)
231  * @param   scale requested scale or \ref mxc_adc_scale_t
232  */
233 void MXC_ADC_SetExtScale(mxc_adc_scale_t scale);
234 
235 /**
236  * @brief   Enable channel high/low monitor
237  * @note    This function only enables an already configured monitor
238  *
239  * @param   monitor The monitor to enable or \ref mxc_adc_monitor_t
240  */
241 void MXC_ADC_EnableMonitor(mxc_adc_monitor_t monitor);
242 
243 /**
244  * @brief   Disable channel high/low monitor
245  * @note    This function only disables an already configured monitor
246  *
247  * @param   monitor The monitor to disable or \ref mxc_adc_monitor_t
248  */
249 void MXC_ADC_DisableMonitor(mxc_adc_monitor_t monitor);
250 
251 /**
252  * @brief   Set the high limit for a specific monitor
253  * @note    setting a value of 0 disables this limit
254  *
255  * @param   monitor the monitor to set the limit on or \ref mxc_adc_monitor_t
256  * @param   threshold the limit to set
257  */
258 void MXC_ADC_SetMonitorHighThreshold(mxc_adc_monitor_t monitor, uint32_t threshold);
259 
260 /**
261  * @brief   Set the high limit for a specific monitor
262  *
263  * @param   monitor the monitor to set the limit on or \ref mxc_adc_monitor_t
264  *
265  * @return  the monitor's high threshold
266  */
267 int MXC_ADC_GetMonitorHighThreshold(mxc_adc_monitor_t monitor);
268 
269 /**
270  * @brief   Set the low limit for a specific monitor
271  * @note    setting a value of 0 disables this limit
272  *
273  * @param   monitor the monitor to set the limit on or \ref mxc_adc_monitor_t
274  * @param   threshold the limit to set
275  */
276 void MXC_ADC_SetMonitorLowThreshold(mxc_adc_monitor_t monitor, uint32_t threshold);
277 
278 /**
279  * @brief   Set the low limit for a specific monitor
280  *
281  * @param   monitor the monitor to set the limit on or \ref mxc_adc_monitor_t
282  *
283  * @return  the monitor's low threshold
284  */
285 int MXC_ADC_GetMonitorLowThreshold(mxc_adc_monitor_t monitor);
286 
287 /**
288  * @brief   Set a monitor to use a specific channel
289  * @note    The monitor must be enabled separately
290  *
291  * @param   monitor the monitor to set the limit on or \ref mxc_adc_monitor_t
292  * @param   channel the channel to monitor or \ref mxc_adc_chsel_t
293  */
294 void MXC_ADC_SetMonitorChannel(mxc_adc_monitor_t monitor, mxc_adc_chsel_t channel);
295 
296 /**
297  * @brief   Get the channel used by a monitor
298  *
299  * @param   monitor the monitor to set the limit on or \ref mxc_adc_monitor_t
300  *
301  * @return  the channel being monitored
302  */
303 int MXC_ADC_GetMonitorChannel(mxc_adc_monitor_t monitor);
304 
305 /**
306  * @brief   Set a callback to be called when a monitor goes out of range
307  * @note    The ADC interrupt must be enabled and MXC_ADC_Handler() called in the ISR
308  *
309  * @param   monitor the monitor to register callback for or \ref mxc_adc_monitor_t
310  * @param   callback the function called when the limit is hit or \ref mxc_adc_monitor_cb_t
311  */
312 void MXC_ADC_EnableMonitorAsync(mxc_adc_monitor_t monitor, mxc_adc_monitor_cb_t callback);
313 
314 /**
315  * @brief   Disable a callback for a monitor
316  *
317  * @param   monitor the monitor to unregister callback for or \ref mxc_adc_monitor_t
318  */
319 void MXC_ADC_DisableMonitorAsync(mxc_adc_monitor_t monitor);
320 
321 /**
322  * @brief   Perform a conversion on a specific channel
323  * @note    The channel must be configured separately
324  *
325  * @param   channel the channel to perform the conversion on or \ref mxc_adc_chsel_t
326  *
327  * @return  Raw conversion value, or \ref MXC_Error_Codes for error.
328  */
329 int MXC_ADC_StartConversion(mxc_adc_chsel_t channel);
330 
331 /**
332  * @brief   Perform a conversion on a specific channel
333  * @note    The channel must be configured separately
334  *          The ADC interrupt must be enabled and MXC_ADC_Handler() called in the ISR
335  *          places data in the error parameter of the callback function
336  *
337  * @param   channel the channel to perform the conversion on or \ref mxc_adc_chsel_t
338  * @param   callback the function to call when the conversion is complete
339  *
340  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
341  */
342 int MXC_ADC_StartConversionAsync(mxc_adc_chsel_t channel, mxc_adc_complete_cb_t callback);
343 
344 /**
345  * @brief   Perform a conversion on a specific channel
346  * @note    The channel must be configured separately
347  *
348  * @param   channel  the channel to perform the conversion on or \ref mxc_adc_chsel_t
349  * @param   data     return rax adc data
350  * @param   callback DMA complete callback
351  *
352  * @return  Raw conversion value, or \ref MXC_Error_Codes for error.
353  */
354 int MXC_ADC_StartConversionDMA(mxc_adc_chsel_t channel, uint16_t *data, void (*callback)(int, int));
355 
356 /**
357  * @brief      Call this function from the ADC ISR when using Async API
358  *             functions
359  *
360  * @return     Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
361  */
362 int MXC_ADC_Handler(void);
363 
364 /**
365  * @brief      Perform a conversion on a specific channel
366  * @note       The result will be placed back in the request structure
367  *
368  * @param      req   The structure containing all information for the conversion
369  *
370  * @return     \ref MXC_Error_Codes for error.
371  */
372 int MXC_ADC_Convert(mxc_adc_conversion_req_t *req);
373 
374 /**
375  * @brief      Perform a conversion on a specific channel
376  * @note       The result will be placed back in the request structure The ADC
377  *             interrupt must be enabled and MXC_ADC_Handler() called in the ISR
378  *
379  * @param      req   The structure containing all information for the conversion
380  *
381  * @return     return E_NO_ERROR OR E_BUSY
382  */
383 int MXC_ADC_ConvertAsync(mxc_adc_conversion_req_t *req);
384 
385 /**
386  * @brief   Monitor a specific channel for an out of range event
387  * @note    synchronously waits for an out of range event to occur on the monitor
388  * @param   req The structure containing all information for monitoring
389  */
390 void MXC_ADC_Monitor(mxc_adc_monitor_req_t req);
391 
392 /**
393  * @brief   Monitor a specific channel for an out of range event
394  * @note    If a callback is included, the ADC interrupt must be enabled
395  *          and MXC_ADC_Handler() called in the ISR
396  *
397  * @param   req The structure containing all information for monitoring
398  */
399 void MXC_ADC_MonitorAsync(mxc_adc_monitor_req_t req);
400 
401 /**
402  * @brief Gets the result from the previous ADC conversion
403  * @param      outdata Pointer to store the ADC data conversion result
404  * @return     #E_OVERFLOW   ADC overflow error
405  * @return     #E_NO_ERROR   Data returned in \p outdata parameter
406  */
407 int MXC_ADC_GetData(uint16_t *outdata);
408 /**@} end of group adc */
409 
410 #ifdef __cplusplus
411 }
412 #endif
413 
414 #endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32570_ADC_H_
415