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