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