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