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_MAX78000_ADC_H_
28 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX78000_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   * Enumeration type for the ADC Input Channels
69   */
70 typedef enum {
71     MXC_ADC_CH_0 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN0, // Select Channel 0
72     MXC_ADC_CH_1 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN1, // Select Channel 1
73     MXC_ADC_CH_2 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN2, // Select Channel 2
74     MXC_ADC_CH_3 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN3, // Select Channel 3
75     MXC_ADC_CH_4 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN4, // Channel 0 divided by 5
76     MXC_ADC_CH_5 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN5, // Channel 1 divided by 5
77     MXC_ADC_CH_6 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN6, // VDDB divided by 4
78     MXC_ADC_CH_7 = MXC_V_ADC_CTRL_ADC_CHSEL_AIN7, // VDD18 input select
79     MXC_ADC_CH_VCOREA = MXC_V_ADC_CTRL_ADC_CHSEL_VCOREA, // VDD12 input select
80     MXC_ADC_CH_VCOREB = MXC_V_ADC_CTRL_ADC_CHSEL_VCOREB,
81     MXC_ADC_CH_VRXOUT = MXC_V_ADC_CTRL_ADC_CHSEL_VRXOUT, // VRTC divided by 2
82     MXC_ADC_CH_VTXOUT = MXC_V_ADC_CTRL_ADC_CHSEL_VTXOUT, // TMON input select
83     MXC_ADC_CH_VDDA = MXC_V_ADC_CTRL_ADC_CHSEL_VDDA,
84     MXC_ADC_CH_VDDB = MXC_V_ADC_CTRL_ADC_CHSEL_VDDB,
85     MXC_ADC_CH_VDDIO = MXC_V_ADC_CTRL_ADC_CHSEL_VDDI0,
86     MXC_ADC_CH_VDDIOH = MXC_V_ADC_CTRL_ADC_CHSEL_VDDI0H,
87     MXC_ADC_CH_VREGI = MXC_V_ADC_CTRL_ADC_CHSEL_VREGI,
88 } mxc_adc_chsel_t;
89 
90 #if 0
91 /**
92   * Enumeration type for the ADC Compartors
93   */
94 typedef enum {
95     MXC_ADC_COMP_0          = MXC_F_MCR_AINCOMP_AINCOMP0PD,
96     MXC_ADC_COMP_1          = MXC_F_MCR_AINCOMP_AINCOMP1PD,
97     MXC_ADC_COMP_2          = MXC_F_MCR_AINCOMP_AINCOMP2PD,
98     MXC_ADC_COMP_3          = MXC_F_MCR_AINCOMP_AINCOMP3PD,
99     MXC_ADC_COMP_HYST_0     = 1 << MXC_F_MCR_AINCOMP_AINCOMPHYST_POS,    //Refer to the V HYST specification in the data sheet electrical characteristics
100     // for the values corresponding to this field value.
101     MXC_ADC_COMP_HYST_1     = 2 << MXC_F_MCR_AINCOMP_AINCOMPHYST_POS,   //Refer to the V HYST specification in the data sheet electrical characteristics
102     // for the values corresponding to this field value.
103 } mxc_adc_comp_t;
104 #endif
105 
106 /**
107  * Enumeration type for the ADC Monitors
108  * 4 Monitors exist and can be mapped to any ADC channels
109  */
110 typedef enum {
111     MXC_ADC_MONITOR_0,
112     MXC_ADC_MONITOR_1,
113     MXC_ADC_MONITOR_2,
114     MXC_ADC_MONITOR_3,
115 } mxc_adc_monitor_t;
116 
117 /**
118  * Enumeration type for ADC Scale values
119  * Internal ADC channels automatically use the most appropriate scale
120  */
121 typedef enum {
122     MXC_ADC_SCALE_2X, // ADC Scale by 2x (this scales ADC Reference by 1/2)
123     MXC_ADC_SCALE_1, // ADC Scale by 1x (no scaling)
124     MXC_ADC_SCALE_2, // ADC Scale by 1/2
125     MXC_ADC_SCALE_3, // ADC Scale by 1/3
126     MXC_ADC_SCALE_4, // ADC Scale by 1/4
127     MXC_ADC_SCALE_6, // ADC Scale by 1/6 (this uses 1/3 and an additional 1/2 scaling)
128     MXC_ADC_SCALE_8, // ADC Scale by 1/8 (this uses 1/4 and an additional 1/2 scaling)
129 } mxc_adc_scale_t;
130 
131 /**
132  * Enumeration type for ADC reference sources
133  */
134 typedef enum {
135     MXC_ADC_REF_INT, // Selects internal bandgap reference
136     MXC_ADC_REF_EXT, // Selects external reference pins
137 } mxc_adc_ref_t;
138 
139 // Callback used when a conversion event is complete
140 typedef void (*mxc_adc_complete_cb_t)(void *req, int error);
141 
142 // Callback used when a monitor detects that a channel has reached a limit
143 typedef void (*mxc_adc_monitor_cb_t)(void *req, int error);
144 
145 // Used to set up a monitor to watch a channel
146 typedef struct {
147     mxc_adc_monitor_t monitor; // Monitor to use
148     mxc_adc_scale_t scale; // Channel scale to use (if external channel)
149     mxc_adc_chsel_t channel; // Channel to use
150     int lowThreshold; // Low Threshold for monitor (RAW ADC counts)
151     int highThreshold; // High Threshold for monitor (RAW ADC counts)
152     mxc_adc_monitor_cb_t callback; // Function to call when the channel crosses threshold
153 } mxc_adc_monitor_req_t;
154 
155 typedef struct {
156     mxc_adc_chsel_t channel; // Channel to use
157     mxc_adc_scale_t scale; // Channel scale to use (if external channel)
158     int rawADCValue; // Result of the conversion
159     mxc_adc_complete_cb_t callback; // Function to call when callback is complete
160 } mxc_adc_conversion_req_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   Desired clock speed for ADC conversions.
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   Gets the current ADC conversion speed
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 // Internal channels are approx. known and have fixed scaling
235 // Externals channels can be scaled with standard scaling (1-4x)
236 // Or by using a separate 1/2 input scale, or a 1/2 ref scale (total range 0.5-8x)
237 /**
238  * @brief   Sets the scaling used for conversions on external channels
239  *
240  * @param   scale requested scale
241  */
242 void MXC_ADC_SetExtScale(mxc_adc_scale_t scale);
243 
244 /**
245  * @brief   Select the ADC reference source
246  *
247  * @param   ref The ADC reference to use
248  */
249 void MXC_ADC_RefSelect(mxc_adc_ref_t ref);
250 
251 /**
252  * @brief   Enable channel high/low monitor
253  * @note    This function only enables an already configured monitor
254  *
255  * @param   monitors The monitor(s) to enable
256  */
257 void MXC_ADC_EnableMonitor(mxc_adc_monitor_t monitors);
258 
259 /**
260  * @brief   Disable channel high/low monitor
261  * @note    This function only disables an already configured monitor
262  *
263  * @param   monitors The monitor(s) to disable
264  */
265 void MXC_ADC_DisableMonitor(mxc_adc_monitor_t monitors);
266 
267 /**
268  * @brief   Set the high limit for a specific monitor
269  * @note    setting a value of 0 disables this limit
270  *
271  * @param   monitor the monitor to set the limit on
272  * @param   threshold the limit to set
273  */
274 void MXC_ADC_SetMonitorHighThreshold(mxc_adc_monitor_t monitor, uint32_t threshold);
275 
276 /**
277  * @brief   Set the high limit for a specific monitor
278  *
279  * @param   monitor the monitor to set the limit on
280  *
281  * @return  the monitor's high threshold
282  */
283 int MXC_ADC_GetMonitorHighThreshold(mxc_adc_monitor_t monitor);
284 
285 /**
286  * @brief   Set the low limit for a specific monitor
287  * @note    setting a value of 0 disables this limit
288  *
289  * @param   monitor the monitor to set the limit on
290  * @param   threshold the limit to set
291  */
292 void MXC_ADC_SetMonitorLowThreshold(mxc_adc_monitor_t monitor, uint32_t threshold);
293 
294 /**
295  * @brief   Set the low limit for a specific monitor
296  *
297  * @param   monitor the monitor to set the limit on
298  *
299  * @return  the monitor's low threshold
300  */
301 int MXC_ADC_GetMonitorLowThreshold(mxc_adc_monitor_t monitor);
302 
303 /**
304  * @brief   Set a monitor to use a specific channel
305  * @note    The monitor must be enabled separately
306  *
307  * @param   monitor the monitor to set the limit on
308  * @param   channel the channel to monitor
309  */
310 void MXC_ADC_SetMonitorChannel(mxc_adc_monitor_t monitor, mxc_adc_chsel_t channel);
311 
312 /**
313  * @brief   Get the channel used by a monitor
314  *
315  * @param   monitor the monitor to set the limit on
316  *
317  * @return  the channel being monitored
318  */
319 int MXC_ADC_GetMonitorChannel(mxc_adc_monitor_t monitor);
320 
321 // Monitor a channel and call the callback if it hits a limit
322 /**
323  * @brief   Set a callback to be called when a monitor goes out of range
324  * @note    The ADC interrupt must be enabled and MXC_ADC_Handler() called in the ISR
325  *
326  * @param   monitor the monitor to register callback for
327  * @param   callback the function called when the limit is hit
328  */
329 void MXC_ADC_EnableMonitorAsync(mxc_adc_monitor_t monitor, mxc_adc_monitor_cb_t callback);
330 
331 /**
332  * @brief   Disable a callback for a monitor
333  *
334  * @param   monitor the monitor to unregister callback for
335  */
336 void MXC_ADC_DisableMonitorAsync(mxc_adc_monitor_t monitor);
337 
338 /**
339  * @brief   Perform a conversion on a specific channel
340  * @note    The channel must be configured separately
341  *
342  * @param   channel the channel to perform the conversion on
343  *
344  * @return  Raw conversion value, or \ref MXC_Error_Codes for error.
345  */
346 int MXC_ADC_StartConversion(mxc_adc_chsel_t channel);
347 
348 /**
349  * @brief   Perform a conversion on a specific channel
350  * @note    The channel must be configured separately
351  *          The ADC interrupt must be enabled and MXC_ADC_Handler() called in the ISR
352  *          places data in the error parameter of the callback function
353  *
354  * @param   channel the channel to perform the conversion on
355  * @param   callback the function to call when the conversion is complete
356  *
357  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
358  */
359 int MXC_ADC_StartConversionAsync(mxc_adc_chsel_t channel, mxc_adc_complete_cb_t callback);
360 
361 /**
362  * @brief      Call this function from the ADC ISR when using Async API
363  *             functions
364  *
365  * @return     Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
366  */
367 int MXC_ADC_Handler(void);
368 
369 /**
370  * @brief      Perform a conversion on a specific channel
371  * @note       The result will be placed back in the request structure
372  *
373  * @param      req   The structure containing all information for the conversion
374  *
375  * @return     \ref MXC_Error_Codes for error.
376  */
377 int MXC_ADC_Convert(mxc_adc_conversion_req_t *req);
378 
379 /**
380  * @brief      Perform a conversion on a specific channel
381  * @note       The result will be placed back in the request structure The ADC
382  *             interrupt must be enabled and MXC_ADC_Handler() called in the ISR
383  *
384  * @param      req   The structure containing all information for the conversion
385  *
386  * @return     return E_NO_ERROR OR E_BUSY
387  */
388 int MXC_ADC_ConvertAsync(mxc_adc_conversion_req_t *req);
389 
390 /**
391  * @brief   Monitor a specific channel for an out of range event
392  * @note    synchronously waits for an out of range event to occur on the monitor
393  * @param   req The structure containing all information for monitoring
394  */
395 void MXC_ADC_Monitor(mxc_adc_monitor_req_t req);
396 
397 /**
398  * @brief   Monitor a specific channel for an out of range event
399  * @note    If a callback is included, the ADC interrupt must be enabled
400  *          and MXC_ADC_Handler() called in the ISR
401  *
402  * @param   req The structure containing all information for monitoring
403  */
404 void MXC_ADC_MonitorAsync(mxc_adc_monitor_req_t req);
405 
406 /**
407  * @brief   Enable the Comparators
408  *
409  * @param   mask using mxc_adc_comp_t enum to create the mask of comparators to enable
410  */
411 void MXC_ADC_EnableComparators(uint32_t mask);
412 
413 /**
414  * @brief   Disable the Comparators
415  *
416  * @param   mask using mxc_adc_comp_t enum to create the mask of comparators to enable
417  */
418 void MXC_ADC_DisableComparators(uint32_t mask);
419 
420 /**
421  * @brief Gets the result from the previous ADC conversion
422  * @param      outdata Pointer to store the ADC data conversion result
423  * @return     #E_OVERFLOW   ADC overflow error
424  * @return     #E_NO_ERROR   Data returned in \p outdata parameter
425  */
426 int MXC_ADC_GetData(uint16_t *outdata);
427 /**@} end of group adc */
428 
429 #ifdef __cplusplus
430 }
431 #endif
432 
433 #endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX78000_ADC_H_
434