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