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_MAX32680_ADC_H_ 28 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32680_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 freuquency for ADC conversion. 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_MAX32680_ADC_H_ 434