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_MAX32662_ADC_H_
28 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32662_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 /* MAX32662 Specific */
47 #define MAX_ADC_SLOT_NUM 29
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_VDDA_DIV2 = 12, ///< Select Channel 12
65     MXC_ADC_CH_VCOREA = 14, ///< Select Channel 14
66     MXC_ADC_CH_VSS = 15, ///< Select Channel 15
67 } mxc_adc_chsel_t;
68 
69 /**
70   * @brief  Enumeration type for the number of samples to average
71   *
72   */
73 typedef enum {
74     MXC_ADC_AVG_1 = MXC_S_ADC_CTRL1_AVG_AVG1, ///< Select Channel 0
75     MXC_ADC_AVG_2 = MXC_S_ADC_CTRL1_AVG_AVG2, ///< Select Channel 1
76     MXC_ADC_AVG_4 = MXC_S_ADC_CTRL1_AVG_AVG4, ///< Select Channel 2
77     MXC_ADC_AVG_8 = MXC_S_ADC_CTRL1_AVG_AVG8, ///< Select Channel 3
78     MXC_ADC_AVG_16 = MXC_S_ADC_CTRL1_AVG_AVG16, ///< Select Channel 4
79     MXC_ADC_AVG_32 = MXC_S_ADC_CTRL1_AVG_AVG32, ///< Select Channel 5
80 } mxc_adc_avg_t;
81 
82 /**
83  * @brief       Enumeration type for ADC clock divider
84  */
85 typedef enum {
86     MXC_ADC_CLKDIV_2, ///< ADC Scale by 1/2
87     MXC_ADC_CLKDIV_4, ///< ADC Scale by 1/4
88     MXC_ADC_CLKDIV_8, ///< ADC Scale by 1/8
89     MXC_ADC_CLKDIV_16, ///< ADC Scale by 1/16
90     MXC_ADC_CLKDIV_1, ///< ADC Scale by 1x (no scaling)
91 } mxc_adc_clkdiv_t;
92 
93 /**
94  * @brief       Clock settings
95  */
96 typedef enum {
97     MXC_ADC_HCLK, ///< HCLK CLock
98     MXC_ADC_CLK_ADC0, ///< HF EXT Clock
99     MXC_ADC_CLK_ADC1, ///< IBRO Clock
100     MXC_ADC_CLK_ADC2, ///< ERFO Clock
101 } mxc_adc_clock_t;
102 
103 /**
104  * @brief       Calibration settings
105  */
106 typedef enum {
107     MXC_ADC_SKIP_CAL, ///< HCLK CLock
108     MXC_ADC_EN_CAL, ///< ADC0 Clock
109 } mxc_adc_calibration_t;
110 
111 /**
112  * @brief       trigger mode settings
113  */
114 typedef enum {
115     MXC_ADC_TRIG_SOFTWARE, ///< Software Trigger
116     MXC_ADC_TRIG_HARDWARE, ///< Hardware Trigger
117 } mxc_adc_trig_mode_t;
118 
119 /**
120  * @brief       Hardware trigger select options
121  */
122 typedef enum {
123     MXC_ADC_TRIG_SEL_TMR0, ///< Timer 0 Out Rising edge
124     MXC_ADC_TRIG_SEL_TMR1, ///< Timer 1 Out Rising Edge
125     MXC_ADC_TRIG_SEL_TMR2, ///< Timer 2 Out Rising Edge
126     MXC_ADC_TRIG_SEL_TMR3, ///< Timer 3 Out Rising Edge
127     MXC_ADC_TRIG_SEL_P0_9, ///< GPIO P0.9, AF4
128     MXC_ADC_TRIG_SEL_P0_0, ///< GPIO P0.0, AF5
129 } mxc_adc_trig_sel_t;
130 
131 /**
132  * @brief       trigger mode settings
133  */
134 typedef enum {
135     MXC_ADC_ATOMIC_CONV, ///< Software Trigger
136     MXC_ADC_CONTINUOUS_CONV, ///< Hardware Trigger
137 } mxc_adc_conversion_mode_t;
138 
139 /**
140  * @brief  Reference voltage select type.
141  */
142 typedef enum {
143     MXC_ADC_REF_EXT, ///< Use external reference voltage source
144     MXC_ADC_REF_INT_1V25, ///< Use internal 1.25V source
145     MXC_ADC_REF_INT_2V048, ///< Use internal 2.048V souce
146 } mxc_adc_refsel_t;
147 
148 /**
149  * @brief  Divide by 2 control in low power mode
150  */
151 
152 typedef enum {
153     MXC_ADC_DIV_2_5K_50K_ENABLE, ///< 2.5K and 50K divide by 2 enable in lpmode
154     MXC_ADC_DIV_2_5K_DISABLE, ///< 2.5K disable and 50K divide  by 2 enable in lpmode
155     MXC_ADC_DIV_50K_DISABLE, ///< 2.5K enable and 50K divide  by 2 disable in lpmode
156     MXC_ADC_DIV_2_5K_50K_DISABLE, ///< 2.5K and 50K divide by 2 disable in lpmode
157 } mxc_adc_div_lpmode_t;
158 
159 /** TODO
160  * @brief  Data FIFO data format
161  */
162 typedef enum {
163     MXC_ADC_DATA_STATUS, ///< Data(12-bit) plus Status
164     MXC_ADC_DATA, ///< Data(12-bit) only
165     MXC_ADC_RAW_DATA, ///< 18-bit raw data
166 } mxc_adc_fifodataformat_t;
167 
168 ///< Callback used when a conversion event is complete
169 typedef void (*mxc_adc_complete_cb_t)(void *req, int error);
170 
171 /**
172  * @brief  ADC Settings
173  */
174 typedef struct {
175     mxc_adc_clock_t clock; ///< clock to use
176     mxc_adc_clkdiv_t clkdiv; ///< clock divider
177     mxc_adc_calibration_t cal; ///< skip calibration
178     mxc_adc_refsel_t ref; ///< ADC reference voltage
179     uint32_t trackCount; ///< Sample Clock High time
180     uint32_t idleCount; ///< Sample Clock Low time
181 } mxc_adc_req_t;
182 
183 /**
184  * @brief  ADC Slot Settings
185  */
186 typedef struct {
187     mxc_adc_chsel_t channel; ///< channel select
188 } mxc_adc_slot_req_t;
189 
190 /**
191  * @brief  ADC Conversion Settings
192  */
193 typedef struct {
194     mxc_adc_conversion_mode_t mode; ///< conversion mode
195     mxc_adc_trig_mode_t trig; ///< trigger mode
196     mxc_adc_trig_sel_t hwTrig; ///< HW Trigger Source
197     mxc_adc_fifodataformat_t fifo_format; ///< FIFO Data Format
198     uint8_t fifo_threshold; ///< FIFO Threshold Configuration
199     mxc_adc_avg_t avg_number; ///< no of samples to average
200     mxc_adc_div_lpmode_t lpmode_divder; ///< Divide by 2 control in lpmode
201     uint8_t num_slots; ///< num of slots in the sequence
202     int8_t dma_channel; ///<The channel to use for DMA-enabled transactions
203 } mxc_adc_conversion_req_t;
204 
205 /**
206  * @brief   Performs the ADC startup procedure
207  *
208  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
209  */
210 int MXC_ADC_Init(mxc_adc_req_t *req);
211 
212 /**
213  * @brief   Shuts down the ADC
214  *
215  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
216  */
217 int MXC_ADC_Shutdown(void);
218 
219 /**
220  * @brief   Enable specific ADC interrupts
221  *
222  * @param   flags mask of interrupt flags to enables
223  */
224 void MXC_ADC_EnableInt(uint32_t flags);
225 
226 /**
227  * @brief   Disable specific ADC interrupts
228  *
229  * @param   flags mask of interrupt flags to enables
230  */
231 void MXC_ADC_DisableInt(uint32_t flags);
232 
233 /**
234  * @brief   Performs the ADC startup procedure
235  *
236  * @return  active flags
237  */
238 int MXC_ADC_GetFlags(void);
239 
240 /**
241  * @brief   Performs the ADC startup procedure
242  *
243  * @param   flags mask of flags to clear
244  */
245 void MXC_ADC_ClearFlags(uint32_t flags);
246 
247 /**
248  * @brief   Initiate configured ADC conversion
249  * @note    The channel must be configured separately
250  *
251  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
252  */
253 int MXC_ADC_StartConversion(void);
254 
255 /**
256  * @brief   Perform a conversion on a specific channel
257  * @note    The channel must be configured separately
258  *          The ADC interrupt must be enabled and MXC_ADC_Handler() called in the ISR
259  *          places data in the error parameter of the callback function
260  *
261  * @param   callback the function to call when the conversion is complete
262  *
263  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
264  */
265 int MXC_ADC_StartConversionAsync(mxc_adc_complete_cb_t callback);
266 
267 /**
268  * @brief   Perform a conversion on a specific channel using a DMA transfer.
269  *          DMA channel must be acquired using \ref MXC_DMA_AcquireChannel and should
270  *          be passed to this function via "dma_channel" member of "req" input struct.
271  *          DMA IRQ corresponding to that channel must be enabled using \ref MXC_NVIC_SetVector,
272  *          and the \ref MXC_DMA_Handler should be called from the respective ISR.
273  *
274  * @param   req \ref mxc_adc_conversion_req_t
275  * @param   pointer to the variable to hold the conversion result
276  * @param   callback the function to call when the conversion is complete
277  *
278  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
279  */
280 int MXC_ADC_StartConversionDMA(mxc_adc_conversion_req_t *req, int *data,
281                                void (*callback)(int, int));
282 
283 /**
284  * @brief      Call this function from the ADC ISR when using Async API
285  *             functions
286  *
287  * @return     Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
288  */
289 int MXC_ADC_Handler(void);
290 
291 /**
292  * @brief   Selects the analog input divider.
293  *
294  * @param   ch     Channel to set divider for
295  * @param   div    The analog input divider to select
296  * @param   lpEn   If Divide by 2, non-zero values will enable divide by 2 in low-power modes.
297  *
298  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
299  */
300 int MXC_ADC_InputDividerSelect(mxc_adc_chsel_t ch);
301 
302 /**
303  * @brief Selects the desired reference voltage for the ADC.
304  *
305  * @param ref   Desired reference voltage source.
306  *
307  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
308  */
309 int MXC_ADC_ReferenceSelect(mxc_adc_refsel_t ref);
310 
311 /**
312  * @brief  Enables the ADC Dynamic Power-Up Mode.
313  *
314  * @param  Channel to enable dynamic mode for.
315  *
316  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
317  */
318 int MXC_ADC_DynamicModeEn(mxc_adc_chsel_t ch);
319 
320 /**
321  * @brief  Disables the ADC Dynamic Power-Up Mode.
322  *
323  * @param  Channel to disable dynamic mode for.
324  *
325  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
326  */
327 int MXC_ADC_DynamicModeDis(mxc_adc_chsel_t ch);
328 
329 /**
330  * @brief      Gets the ADC readout after the ADC conversion
331  *
332  * @param      Pointer to store the ADC data conversion result
333  *
334  * @return     see \ref MXC_Error_Codes for a list of return codes.
335  */
336 int MXC_ADC_GetData(int *outdata);
337 
338 /**
339  * @brief      Configures the ADC.
340  *
341  * @param      pointer to the variable having ADC configuration.
342  *
343  * @return     see \ref MXC_Error_Codes for a list of return codes.
344  */
345 int MXC_ADC_Configuration(mxc_adc_conversion_req_t *req);
346 
347 /**
348  * @brief      Configures ADC slot and channel registers.
349  *
350  * @param      Pointer of a variable having channel parameter configuration.
351  * @param      Number of slots for ADC sequence.
352  *
353  * @return     see \ref MXC_Error_Codes for a list of return codes.
354  */
355 int MXC_ADC_SlotConfiguration(mxc_adc_slot_req_t *req, uint32_t slot_length);
356 
357 /**
358  * @brief   Enables the ADC converter
359  *
360  * @param   None
361  */
362 void MXC_ADC_EnableConversion(void);
363 
364 /**
365  * @brief   Disables the ADC converter
366  *
367  * @param   None
368  */
369 void MXC_ADC_DisableConversion(void);
370 
371 /**
372  * @brief   Provides the ADC FIFO level.
373  *
374  * @return  return the ADC FIFO level counts.
375  */
376 uint16_t MXC_ADC_FIFO_Level(void);
377 
378 /**
379  * @brief   Flushes the ADC FIFO.
380  *
381  * @param   None
382  */
383 void MAX_ADC_Flush_FIFO(void);
384 
385 /**
386  * @brief   Configures the ADC FIFO threshold register.
387  *
388  * @param   FIFO threshold.
389  *
390  * @return  see \ref MXC_Error_Codes for a list of return codes.
391  */
392 int MXC_ADC_FIFO_Threshold_Config(uint32_t fifo_threshold);
393 
394 /**
395  * @brief   Configures number of sample average in the sequence for each channel.
396  *
397  * @param   Average number
398  *
399  * @return  see \ref MXC_Error_Codes for a list of return codes.
400  */
401 int MXC_ADC_AverageConfig(mxc_adc_avg_t avg_number);
402 
403 /**
404  * @brief   Clear all channel select registers.
405  *
406  * @return  None.
407  */
408 void MXC_ADC_Clear_ChannelSelect(void);
409 
410 /**
411  * @brief   Configures ADC Trigger to initiate ADC conversion
412  *
413  * @param   pointer to ADC configure data structure.
414  *
415  * @return  None.
416  */
417 void MXC_ADC_TriggerConfig(mxc_adc_conversion_req_t *req);
418 
419 /**
420  * @brief   Configures ADC Conversion Mode: Single vs Continuous Conversion.
421  *
422  * @param   pointer to ADC configure data structure.
423  *
424  * @return  None.
425  */
426 void MXC_ADC_ConversionModeConfig(mxc_adc_conversion_req_t *req);
427 
428 /**
429  * @brief   Set Sample Delay before Continuous Mode Conversion Restart.
430  *
431  * @param   number of sample clock periods to delay in between conversions.
432  *
433  * @return  None.
434  */
435 void MXC_ADC_SetConversionDelay(int delay);
436 
437 /**
438  * @brief   Configures number of slots for ADC sequence.
439  *
440  * @param   pointer to ADC configure data structure.
441  *
442  * @return  see \ref MXC_Error_Codes for a list of return codes.
443  */
444 int MXC_ADC_SlotsConfig(mxc_adc_conversion_req_t *req);
445 
446 /**
447  * @brief   Calculates temperature (in K) from ADC readout.
448  *
449  * @param   Temperature readout from ADC.
450  * @param   ADC refereence (internal 1.25V, 2.048V and external reference).
451  * @param   external reference value for ADC if used.
452  * @param   pointer to temperature value.
453  *
454  * @return  see \ref MXC_Error_Codes for a list of return codes.
455  */
456 int MXC_ConvertTemperature_ToK(uint16_t tempSensor_Readout, mxc_adc_refsel_t ref, float ext_ref,
457                                float *temp_k);
458 
459 /**
460  * @brief   Calculates temperature (in C) from ADC readout.
461  *
462  * @param   Temperature readout from ADC.
463  * @param   ADC refereence (internal 1.25V, 2.048V and external reference).
464  * @param   external reference value for ADC if used.
465  * @param   pointer to temperature value.
466  *
467  * @return  see \ref MXC_Error_Codes for a list of return codes.
468  */
469 int MXC_ConvertTemperature_ToC(uint16_t tempSensor_Readout, mxc_adc_refsel_t ref, float ext_ref,
470                                float *temp);
471 
472 /**
473  * @brief   Calculates temperature (in F) from ADC readout.
474  *
475  * @param   Temperature readout from ADC.
476  * @param   ADC refereence (internal 1.25V, 2.048V and external reference).
477  * @param   external reference value for ADC if used.
478  * @param   pointer to temperature value.
479  *
480  * @return  see \ref MXC_Error_Codes for a list of return codes.
481  */
482 int MXC_ConvertTemperature_ToF(uint16_t tempSensor_Readout, mxc_adc_refsel_t ref, float ext_ref,
483                                float *temp);
484 
485 /**@} end of group adc */
486 
487 #ifdef __cplusplus
488 }
489 #endif
490 
491 #endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32662_ADC_H_
492