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_MAX32672_ADC_H_
28 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32672_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 ADC
41  * @ingroup periphlibs
42  * @details API for Analog to Digital Converter (ADC).
43  * @{
44  */
45 
46 /* MAX32672 Specific */
47 #define MAX_ADC_SLOT_NUM 16
48 #define MAX_ADC_FIFO_LEN 16
49 #define MAX_ADC_RES_DIV_CH 12
50 
51 /***************************************************************************************************************
52                                     DATA STRUCTURES FOR ADC INITIALIZATION
53 ***************************************************************************************************************/
54 
55 /**
56   * @brief  Enumeration type for the ADC Input Channels
57   *
58   */
59 typedef enum {
60     MXC_ADC_CH_0, ///< Select Channel 0
61     MXC_ADC_CH_1, ///< Select Channel 1
62     MXC_ADC_CH_2, ///< Select Channel 2
63     MXC_ADC_CH_3, ///< Select Channel 3
64     MXC_ADC_CH_4, ///< Select Channel 4
65     MXC_ADC_CH_5, ///< Select Channel 5
66     MXC_ADC_CH_6, ///< Select Channel 6
67     MXC_ADC_CH_7, ///< Select Channel 7
68     MXC_ADC_CH_8, ///< Select Channel 8
69     MXC_ADC_CH_9, ///< Select Channel 9
70     MXC_ADC_CH_10, ///< Select Channel 10
71     MXC_ADC_CH_11, ///< Select Channel 11
72     MXC_ADC_CH_12, ///< Select Channel 12
73     MXC_ADC_CH_13, ///< Select Channel 13
74     MXC_ADC_CH_14, ///< Select Channel 14
75     MXC_ADC_CH_15 ///< Select Channel 15
76 } mxc_adc_chsel_t;
77 
78 /**
79   * @brief  Enumeration type for the number of samples to average
80   *
81   */
82 typedef enum {
83     MXC_ADC_AVG_1 = MXC_S_ADC_CTRL1_AVG_AVG1, ///< Select Channel 0
84     MXC_ADC_AVG_2 = MXC_S_ADC_CTRL1_AVG_AVG2, ///< Select Channel 1
85     MXC_ADC_AVG_4 = MXC_S_ADC_CTRL1_AVG_AVG4, ///< Select Channel 2
86     MXC_ADC_AVG_8 = MXC_S_ADC_CTRL1_AVG_AVG8, ///< Select Channel 3
87     MXC_ADC_AVG_16 = MXC_S_ADC_CTRL1_AVG_AVG16, ///< Select Channel 4
88     MXC_ADC_AVG_32 = MXC_S_ADC_CTRL1_AVG_AVG32, ///< Select Channel 5
89 } mxc_adc_avg_t;
90 
91 /**
92   * Enumeration type for the ADC Compartors
93   */
94 typedef enum {
95     MXC_ADC_COMP_0 = 1,
96     MXC_ADC_COMP_1 = 2,
97     // MXC_ADC_COMP_HYST_0  = 1 << MXC_F_MCR_AINCOMP_AINCOMPHYST_POS,    //Refer to the V HYST specification in the data sheet electrical characteristics
98     // // for the values corresponding to this field value.
99     // MXC_ADC_COMP_HYST_1     = 2 << 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_t;
102 
103 /**
104  * @brief       Enumeration type for ADC clock divider
105  */
106 typedef enum {
107     MXC_ADC_CLKDIV_2, ///< ADC Scale by 1/2
108     MXC_ADC_CLKDIV_4, ///< ADC Scale by 1/4
109     MXC_ADC_CLKDIV_8, ///< ADC Scale by 1/8
110     MXC_ADC_CLKDIV_16, ///< ADC Scale by 1/16
111     MXC_ADC_CLKDIV_1, ///< ADC Scale by 1x (no scaling)
112 } mxc_adc_clkdiv_t;
113 
114 /**
115  * @brief       Clock settings
116  */
117 typedef enum {
118     MXC_ADC_CLK_HCLK, ///< HCLK CLock
119     MXC_ADC_CLK_EXT, ///< External Clock
120     MXC_ADC_CLK_IBRO, ///< IBRO Clock
121     MXC_ADC_CLK_ERFO, ///< ERFO Clock
122 } mxc_adc_clock_t;
123 
124 /**
125  * @brief       Calibration settings
126  */
127 typedef enum {
128     MXC_ADC_SKIP_CAL, ///< Skip calibration on power-up
129     MXC_ADC_EN_CAL, ///< Calibrate on power-up
130 } mxc_adc_calibration_t;
131 
132 /**
133  * @brief       trigger mode settings
134  */
135 typedef enum {
136     MXC_ADC_TRIG_SOFTWARE, ///< Software Trigger
137     MXC_ADC_TRIG_HARDWARE, ///< Hardware Trigger
138 } mxc_adc_trig_mode_t;
139 
140 /**
141  * @brief       Hardware trigger select options
142  */
143 typedef enum {
144     MXC_ADC_TRIG_SEL_TMR0, ///< Timer 0 Out Rising edge
145     MXC_ADC_TRIG_SEL_TMR1, ///< Timer 1 Out Rising Edge
146     MXC_ADC_TRIG_SEL_TMR2, ///< Timer 2 Out Rising Edge
147     MXC_ADC_TRIG_SEL_TMR3, ///< Timer 3 Out Rising Edge
148     MXC_ADC_TRIG_SEL_P0_29, ///< GPIO Port 0, Pin 29
149     MXC_ADC_TRIG_SEL_P0_22, ///< GPIO Port 0, Pin 22
150     MXC_ADC_TRIG_SEL_P1_4, ///< GPIO Port 1, Pin 4
151     MXC_ADC_TRIG_SEL_TEMP_SENS, ///< Temperature Sensor Ready
152 } mxc_adc_trig_sel_t;
153 
154 /**
155  * @brief       trigger mode settings
156  */
157 typedef enum {
158     MXC_ADC_ATOMIC_CONV, ///< Software Trigger
159     MXC_ADC_CONTINUOUS_CONV, ///< Hardware Trigger
160 } mxc_adc_conversion_mode_t;
161 
162 /**
163  * @brief  Analog input divider select.
164  */
165 typedef enum {
166     MXC_ADC_DIV1 = MXC_V_MCR_ADC_CFG2_CH0_DIV1, ///< No input divider
167     MXC_ADC_DIV2_5K =
168         MXC_V_MCR_ADC_CFG2_CH0_DIV2_5K, ///< Divide analog input by two with 5K resistor
169     MXC_ADC_DIV2_50K =
170         MXC_V_MCR_ADC_CFG2_CH0_DIV2_50K, ///< Divide analog input by two with 50K resistor
171 } mxc_adc_divsel_t;
172 
173 /**
174  * @brief  Reference voltage select type.
175  */
176 typedef enum {
177     MXC_ADC_REF_EXT, ///< Use external reference voltage source
178     MXC_ADC_REF_INT_1V25, ///< Use internal 1.25V source
179     MXC_ADC_REF_INT_2V048, ///< Use internal 2.048V souce
180 } mxc_adc_refsel_t;
181 
182 /**
183  * @brief  Divide by 2 control in low power mode
184  */
185 
186 typedef enum {
187     MXC_ADC_DIV_2_5K_50K_ENABLE, ///< 2.5K and 50K divide by 2 enable in lpmode
188     MXC_ADC_DIV_2_5K_DISABLE, ///< 2.5K disable and 50K divide  by 2 enable in lpmode
189     MXC_ADC_DIV_50K_DISABLE, ///< 2.5K enable and 50K divide  by 2 disable in lpmode
190     MXC_ADC_DIV_2_5K_50K_DISABLE, ///< 2.5K and 50K divide by 2 disable in lpmode
191 } mxc_adc_div_lpmode_t;
192 
193 /** TODO
194  * @brief  Data FIFO data format
195  */
196 typedef enum {
197     MXC_ADC_DATA_STATUS, ///< Data(12-bit) plus Status
198     MXC_ADC_DATA, ///< Data(12-bit) only
199     MXC_ADC_RAW_DATA, ///< 18-bit raw data
200 } mxc_adc_fifodataformat_t;
201 
202 /** TODO
203  * @brief  Dynamic Divider pullup control
204  */
205 typedef enum {
206     MXC_ADC_PY_DN_DISABLE, ///< Disable Dynamic Divider Pullup
207     MXC_ADC_PY_DN_ENABLE, ///< Enable Dynamic Divider Pullup
208 } mxc_adc_dynamic_pullup_t;
209 
210 ///< Callback used when a conversion event is complete
211 typedef void (*mxc_adc_complete_cb_t)(void *req, int error);
212 
213 /**
214  * @brief  ADC Settings
215  */
216 typedef struct {
217     mxc_adc_clock_t clock; ///< clock to use
218     mxc_adc_clkdiv_t clkdiv; ///< clock divider
219     mxc_adc_calibration_t cal; ///< skip calibration
220     mxc_adc_refsel_t ref; ///< ADC reference voltage
221     uint32_t trackCount; ///< Sample Clock High time
222     uint32_t idleCount; ///< Sample Clock Low time
223 } mxc_adc_req_t;
224 
225 /**
226  * @brief  ADC Slot Settings
227  */
228 typedef struct {
229     mxc_adc_chsel_t channel; ///< channel select
230     mxc_adc_divsel_t div; ///< Analog input divider
231     mxc_adc_dynamic_pullup_t pullup_dyn; ///< Dynamic Pullup
232 } mxc_adc_slot_req_t;
233 
234 /**
235  * @brief  ADC Conversion Settings
236  */
237 typedef struct {
238     mxc_adc_conversion_mode_t mode; ///< conversion mode
239     mxc_adc_trig_mode_t trig; ///< trigger mode
240     mxc_adc_trig_sel_t hwTrig; ///< HW Trigger Source
241     mxc_adc_fifodataformat_t fifo_format; ///< FIFO Data Format
242     uint8_t fifo_threshold; ///< FIFO Threshold Configuration
243     mxc_adc_avg_t avg_number; ///< no of samples to average
244     mxc_adc_div_lpmode_t lpmode_divder; ///< Divide by 2 control in lpmode
245     uint8_t num_slots; ///< num of slots in the sequence
246     int8_t dma_channel; ///<The channel to use for DMA-enabled transactions
247 } mxc_adc_conversion_req_t;
248 
249 /**
250  * @brief   Performs the ADC startup procedure
251  *
252  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
253  */
254 int MXC_ADC_Init(mxc_adc_req_t *req);
255 
256 /**
257  * @brief   Shuts down the ADC
258  *
259  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
260  */
261 int MXC_ADC_Shutdown(void);
262 
263 /**
264  * @brief   Enable specific ADC interrupts
265  *
266  * @param   flags mask of interrupt flags to enables
267  */
268 void MXC_ADC_EnableInt(uint32_t flags);
269 
270 /**
271  * @brief   Disable specific ADC interrupts
272  *
273  * @param   flags mask of interrupt flags to enables
274  */
275 void MXC_ADC_DisableInt(uint32_t flags);
276 
277 /**
278  * @brief   Get adc interrupt flags
279  *
280  * @return  active flags
281  */
282 int MXC_ADC_GetFlags(void);
283 
284 /**
285  * @brief   Clear adc interrupt flags
286  *
287  * @param   flags mask of flags to clear
288  */
289 void MXC_ADC_ClearFlags(uint32_t flags);
290 
291 /**
292  * @brief   Initiate configured ADC conversion
293  * @note    The channel must be configured separately
294  *
295  * @return  Raw conversion value, or \ref MXC_Error_Codes for error.
296  */
297 int MXC_ADC_StartConversion(void);
298 
299 /**
300  * @brief   Perform a conversion on a specific channel
301  * @note    The channel must be configured separately
302  *          The ADC interrupt must be enabled and MXC_ADC_Handler() called in the ISR
303  *          places data in the error parameter of the callback function
304  *
305  * @param   callback the function to call when the conversion is complete
306  *
307  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
308  */
309 int MXC_ADC_StartConversionAsync(mxc_adc_complete_cb_t callback);
310 
311 /**
312  * @brief   Perform a conversion on a specific channel using a DMA transfer.
313  *          DMA channel must be acquired using \ref MXC_DMA_AcquireChannel and should
314  *          be passed to this function via "dma_channel" member of "req" input struct.
315  *          DMA IRQ corresponding to that channel must be enabled using \ref MXC_NVIC_SetVector,
316  *          and the \ref MXC_DMA_Handler should be called from the respective ISR.
317  *
318  * @param   req \ref mxc_adc_conversion_req_t
319  * @param   pointer to the variable to hold the conversion result
320  * @param   callback the function to call when the conversion is complete
321  *
322  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
323  */
324 int MXC_ADC_StartConversionDMA(mxc_adc_conversion_req_t *req, int *data,
325                                void (*callback)(int, int));
326 
327 /**
328  * @brief      Call this function from the ADC ISR when using Async API
329  *             functions
330  *
331  * @return     Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
332  */
333 
334 int MXC_ADC_Handler(void);
335 
336 /**
337  * @brief   Enable the Comparator
338  *
339  * @param   comp    Selects the comparator to enable
340  * @param   negCh   Channel to use for the negative input of the comparator, valid channels AIN0-AIN3
341  * @param   posCh   Channel to use for the positive input of the comparator, valid channels AIN4-AIN7
342  *
343  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
344  */
345 int MXC_ADC_EnableComparator(mxc_adc_comp_t comp, mxc_adc_chsel_t negCh, mxc_adc_chsel_t posCh);
346 
347 /**
348  * @brief   Disable the Comparators
349  *
350  * @param   comp    Selects the comparator to disable
351  *
352  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
353  */
354 int MXC_ADC_DisableComparator(mxc_adc_comp_t comp);
355 
356 /**
357  * @brief   Enable comparator hysteresis.
358  *
359  * @param   comp    Selects the comparator to enable hysteresis for.
360  *
361  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
362  */
363 int MXC_ADC_ComparatorHysteresisEn(mxc_adc_comp_t comp);
364 
365 /**
366  * @brief   Disable comparator hysteresis.
367  *
368  * @param   comp    Selects the comparator to disable hysteresis for.
369  *
370  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
371  */
372 int MXC_ADC_ComparatorHysteresisDis(mxc_adc_comp_t comp);
373 
374 /**
375  * @brief   Selects the analog input divider.
376  *
377  * @param   ch     Channel to set divider for
378  * @param   div    The analog input divider to select
379  * @param   lpEn   If Divide by 2, non-zero values will enable divide by 2 in low-power modes.
380  *
381  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
382  */
383 int MXC_ADC_InputDividerSelect(mxc_adc_chsel_t ch, mxc_adc_divsel_t div,
384                                mxc_adc_dynamic_pullup_t lpEn);
385 
386 /**
387  * @brief Selects the desired reference voltage for the ADC.
388  *
389  * @param ref   Desired reference voltage source.
390  *
391  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
392  */
393 int MXC_ADC_ReferenceSelect(mxc_adc_refsel_t ref);
394 
395 /**
396  * @brief  Enables the ADC Dynamic Power-Up Mode.
397  *
398  * @param  Channel to enable dynamic mode for.
399  *
400  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
401  */
402 int MXC_ADC_DynamicModeEn(mxc_adc_chsel_t ch);
403 
404 /**
405  * @brief  Disables the ADC Dynamic Power-Up Mode.
406  *
407  * @param  Channel to disable dynamic mode for.
408  *
409  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
410  */
411 int MXC_ADC_DynamicModeDis(mxc_adc_chsel_t ch);
412 
413 /**
414  * @brief      Gets the ADC readout after the ADC conversion
415  *
416  * @param      Pointer to store the ADC data conversion result
417  *
418  * @return     see \ref MXC_Error_Codes for a list of return codes.
419  */
420 int MXC_ADC_GetData(int *outdata);
421 
422 /**
423  * @brief      Configures the ADC.
424  *
425  * @param      pointer to the variable having ADC configuration.
426  *
427  * @return     see \ref MXC_Error_Codes for a list of return codes.
428  */
429 int MXC_ADC_Configuration(mxc_adc_conversion_req_t *req);
430 
431 /**
432  * @brief      Configures ADC slot and channel registers.
433  *
434  * @param      Pointer of a variable having channel parameter configuration.
435  * @param      Number of slots for ADC sequence.
436  *
437  * @return     see \ref MXC_Error_Codes for a list of return codes.
438  */
439 int MXC_ADC_SlotConfiguration(mxc_adc_slot_req_t *req, uint32_t slot_length);
440 
441 /**
442  * @brief   Enables the temperature sensor
443  *
444  * @param   None
445  */
446 void MXC_ADC_TS_SelectEnable(void);
447 
448 /**
449  * @brief   Disables the temperature sensor
450  *
451  * @param   None
452  */
453 void MXC_ADC_TS_SelectDisable(void);
454 
455 /**
456  * @brief   Enables the ADC converter
457  *
458  * @param   None
459  */
460 void MXC_ADC_EnableConversion(void);
461 
462 /**
463  * @brief   Disables the ADC converter
464  *
465  * @param   None
466  */
467 void MXC_ADC_DisableConversion(void);
468 
469 /**
470  * @brief   Provides the ADC FIFO level.
471  *
472  * @return  return the ADC FIFO level counts.
473  */
474 uint16_t MXC_ADC_FIFO_Level(void);
475 
476 /**
477  * @brief   Flushes the ADC FIFO.
478  *
479  * @param   None
480  */
481 void MAX_ADC_Flush_FIFO(void);
482 
483 /**
484  * @brief   Configures the ADC FIFO threshold register.
485  *
486  * @param   FIFO threshold.
487  *
488  * @return  see \ref MXC_Error_Codes for a list of return codes.
489  */
490 int MXC_ADC_FIFO_Threshold_Config(uint32_t fifo_threshold);
491 
492 /**
493  * @brief   Configures number of sample average in the sequence for each channel.
494  *
495  * @param   Average number
496  *
497  * @return  see \ref MXC_Error_Codes for a list of return codes.
498  */
499 int MXC_ADC_AverageConfig(mxc_adc_avg_t avg_number);
500 
501 /**
502  * @brief   Clear all channel select registers.
503  *
504  * @return  None.
505  */
506 void MXC_ADC_Clear_ChannelSelect(void);
507 
508 /**
509  * @brief   Configures ADC Trigger to initiate ADC conversion
510  *
511  * @param   pointer to ADC configure data structure.
512  *
513  * @return  None.
514  */
515 void MXC_ADC_TriggerConfig(mxc_adc_conversion_req_t *req);
516 
517 /**
518  * @brief   Configures ADC Conversion Mode: Single vs Continuous Conversion.
519  *
520  * @param   pointer to ADC configure data structure.
521  *
522  * @return  None.
523  */
524 void MXC_ADC_ConversionModeConfig(mxc_adc_conversion_req_t *req);
525 
526 /**
527  * @brief   Set Sample Delay before Continuous Mode Conversion Restart.
528  *
529  * @param   number of sample clock periods to delay in between conversions.
530  *
531  * @return  None.
532  */
533 void MXC_ADC_SetConversionDelay(int delay);
534 
535 /**
536  * @brief   Configures number of slots for ADC sequence.
537  *
538  * @param   pointer to ADC configure data structure.
539  *
540  * @return  see \ref MXC_Error_Codes for a list of return codes.
541  */
542 int MXC_ADC_SlotsConfig(mxc_adc_conversion_req_t *req);
543 
544 /**
545  * @brief   Calculates temperature (in K) from ADC readout.
546  *
547  * @param   Temperature readout from ADC.
548  * @param   ADC refereence (internal 1.25V, 2.048V and external reference).
549  * @param   external reference value for ADC if used.
550  * @param   pointer to temperature value.
551  *
552  * @return  see \ref MXC_Error_Codes for a list of return codes.
553  */
554 int MXC_ConvertTemperature_ToK(uint16_t tempSensor_Readout, mxc_adc_refsel_t ref, float ext_ref,
555                                float *temp_k);
556 
557 /**
558  * @brief   Calculates temperature (in C) from ADC readout.
559  *
560  * @param   Temperature readout from ADC.
561  * @param   ADC refereence (internal 1.25V, 2.048V and external reference).
562  * @param   external reference value for ADC if used.
563  * @param   pointer to temperature value.
564  *
565  * @return  see \ref MXC_Error_Codes for a list of return codes.
566  */
567 int MXC_ConvertTemperature_ToC(uint16_t tempSensor_Readout, mxc_adc_refsel_t ref, float ext_ref,
568                                float *temp);
569 
570 /**
571  * @brief   Calculates temperature (in F) from ADC readout.
572  *
573  * @param   Temperature readout from ADC.
574  * @param   ADC refereence (internal 1.25V, 2.048V and external reference).
575  * @param   external reference value for ADC if used.
576  * @param   pointer to temperature value.
577  *
578  * @return  see \ref MXC_Error_Codes for a list of return codes.
579  */
580 int MXC_ConvertTemperature_ToF(uint16_t tempSensor_Readout, mxc_adc_refsel_t ref, float ext_ref,
581                                float *temp);
582 
583 /**
584  * @brief   Configures Divider (0-12 channel) in the low power mode.
585  *
586  * @param   Channel specific low power divider control in the lp mode.
587  *
588  * @return  see \ref MXC_Error_Codes for a list of return codes.
589  */
590 int MXC_ADC_LowPowerModeDividerSelect(mxc_adc_div_lpmode_t div_lpmode);
591 
592 /**@} end of group adc */
593 #ifdef __cplusplus
594 }
595 #endif
596 
597 #endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32672_ADC_H_
598