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_MAX32650_ADC_H_ 28 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32650_ADC_H_ 29 30 /* **** Includes **** */ 31 #include <stdint.h> 32 #include "adc_regs.h" 33 #include "mxc_sys.h" 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 /** 40 * @defgroup adc Analog Digital Converter (ADC) 41 * @ingroup periphlibs 42 * @{ 43 */ 44 // Macros to select ADC channels 45 #define MXC_V_ADC_CTRL_ADC_CHSEL_AIN0 ((uint32_t)(0x00000000UL)) 46 #define MXC_V_ADC_CTRL_ADC_CHSEL_AIN1 ((uint32_t)(0x00000001UL)) 47 #define MXC_V_ADC_CTRL_ADC_CHSEL_AIN2 ((uint32_t)(0x00000002UL)) 48 #define MXC_V_ADC_CTRL_ADC_CHSEL_AIN3 ((uint32_t)(0x00000003UL)) 49 #define MXC_V_ADC_CTRL_ADC_CHSEL_AIN0_DIV_5 ((uint32_t)(0x00000004UL)) 50 #define MXC_V_ADC_CTRL_ADC_CHSEL_AIN1_DIV_5 ((uint32_t)(0x00000005UL)) 51 #define MXC_V_ADC_CTRL_ADC_CHSEL_VDDB_DIV_4 ((uint32_t)(0x00000006UL)) 52 #define MXC_V_ADC_CTRL_ADC_CHSEL_VDDA ((uint32_t)(0x00000007UL)) 53 #define MXC_V_ADC_CTRL_ADC_CHSEL_VCORE ((uint32_t)(0x00000008UL)) 54 #define MXC_V_ADC_CTRL_ADC_CHSEL_VRTC_DIV_2 ((uint32_t)(0x00000009UL)) 55 #define MXC_V_ADC_CTRL_ADC_CHSEL_VDDIO_DIV4 ((uint32_t)(0x0000000BUL)) 56 #define MXC_V_ADC_CTRL_ADC_CHSEL_VDDIOH_DIV4 ((uint32_t)(0x0000000CUL)) 57 58 /*************************************************************************************************************** 59 DATA STRUCTURES FOR ADC INITIALIZATION 60 ***************************************************************************************************************/ 61 /** 62 * Enumeration type for the ADC Input Channels 63 */ 64 typedef enum { 65 MXC_ADC_CH_0 = MXC_V_ADC_CTRL_CH_SEL_AIN0, // Select Channel 0 66 MXC_ADC_CH_1 = MXC_V_ADC_CTRL_CH_SEL_AIN1, // Select Channel 1 67 MXC_ADC_CH_2 = MXC_V_ADC_CTRL_CH_SEL_AIN2, // Select Channel 2 68 MXC_ADC_CH_3 = MXC_V_ADC_CTRL_CH_SEL_AIN3, // Select Channel 3 69 MXC_ADC_CH_0_DIV_5 = MXC_V_ADC_CTRL_CH_SEL_AIN0_DIV5, // Channel 0 divided by 5 70 MXC_ADC_CH_1_DIV_5 = MXC_V_ADC_CTRL_CH_SEL_AIN1_DIV5, // Channel 1 divided by 5 71 MXC_ADC_CH_VDDB_DIV_4 = MXC_V_ADC_CTRL_CH_SEL_VDDB_DIV4, // VDDB divided by 4 72 MXC_ADC_CH_VDDA = MXC_V_ADC_CTRL_CH_SEL_VDDA, // VDDA input select 73 MXC_ADC_CH_VCORE = MXC_V_ADC_CTRL_CH_SEL_VCORE, // VCORE input select 74 MXC_ADC_CH_VRTC_DIV_2 = MXC_V_ADC_CTRL_CH_SEL_VRTC_DIV2, // VRTC divided by 2 75 MXC_ADC_CH_VDDIO_DIV4 = MXC_V_ADC_CTRL_CH_SEL_VDDIO_DIV4, // VDDIO divided by 4 76 MXC_ADC_CH_VDDIOH_DIV4 = MXC_V_ADC_CTRL_CH_SEL_VDDIOH_DIV4, // VDDIOH divided by 4 77 } mxc_adc_chsel_t; 78 79 /** 80 * @brief Enumeration type for the ADC Monitors 81 * 4 Monitors exist and can be mapped to any ADC channels 82 * 83 */ 84 typedef enum { 85 MXC_ADC_MONITOR_0, 86 MXC_ADC_MONITOR_1, 87 MXC_ADC_MONITOR_2, 88 MXC_ADC_MONITOR_3, 89 } mxc_adc_monitor_t; 90 91 /** 92 * @brief Enumeration type for ADC Scale values 93 * Internal ADC channels automatically use the most appropriate scale 94 * 95 */ 96 typedef enum { 97 MXC_ADC_SCALE_2X, ///< ADC Scale by 2x 98 MXC_ADC_SCALE_1, ///< ADC Scale by 1x (no scaling) 99 MXC_ADC_SCALE_2, ///< ADC Scale by 1/2 100 } mxc_adc_scale_t; 101 102 /** 103 * @brief Callback used when a conversion event is complete 104 * 105 */ 106 typedef void (*mxc_adc_complete_cb_t)(void *req, int error); 107 108 /** 109 * @brief Callback used when a monitor detects that a channel has reached a limit 110 * 111 */ 112 typedef void (*mxc_adc_monitor_cb_t)(void *req, int error); 113 114 /** 115 * @brief Used to set up a monitor to watch a channel 116 * 117 */ 118 typedef struct { 119 mxc_adc_monitor_t monitor; ///< Monitor to use 120 mxc_adc_scale_t scale; ///< Channel scale to use (if external channel) 121 mxc_adc_chsel_t channel; ///< Channel to use 122 int lowThreshold; ///< Low Threshold for monitor (RAW ADC counts) 123 int highThreshold; ///< High Threshold for monitor (RAW ADC counts) 124 mxc_adc_monitor_cb_t callback; ///< Function to call when the channel crosses threshold 125 } mxc_adc_monitor_req_t; 126 127 /** 128 * @brief Used to set up channel for conversion 129 * 130 */ 131 typedef struct { 132 mxc_adc_chsel_t channel; ///< Channel to use 133 mxc_adc_scale_t scale; ///< Channel scale to use (if external channel) 134 int rawADCValue; ///< Result of the conversion 135 mxc_adc_complete_cb_t callback; ///< Function to call when callback is complete 136 } mxc_adc_conversion_req_t; 137 138 /*************************************************************************************************************** 139 DRIVER EXPOSED API's 140 ***************************************************************************************************************/ 141 /** 142 * @brief Initialize the ADC hardware 143 * 144 * @return #E_NO_ERROR if successful 145 */ 146 int MXC_ADC_Init(void); 147 148 /** 149 * @brief Shuts down the ADC 150 * 151 * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. 152 */ 153 int MXC_ADC_Shutdown(void); 154 155 /** 156 * @brief Checks if the ADC is busy (performing a conversion) 157 * 158 * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. 159 */ 160 int MXC_ADC_Busy(void); 161 162 /** 163 * @brief Enables the ADC interrupts specified by the mask parameter 164 * @param flags ADC interrupts to enable. See @ref ADC_INTR 165 * "ADC_INTR Register" for the interrupt enable bit masks. 166 */ 167 void MXC_ADC_EnableInt(uint32_t flags); 168 169 /** 170 * @brief Disable ADC interrupts based on mask 171 * @param flags ADC interrupts to disable. See @ref ADC_INTR 172 * "ADC_INTR Register" for the interrupt enable bit masks. 173 */ 174 void MXC_ADC_DisableInt(uint32_t flags); 175 176 /** 177 * @brief Get interrupt flags 178 * @return ADC Interrupt flags bit mask. See the @ref ADC_INTR 179 * "ADC_INTR Register" for the interrupt flag masks. 180 */ 181 uint32_t MXC_ADC_GetFlags(void); 182 183 /** 184 * @brief Clear interrupt flag(s) using the mask parameter. All bits set in 185 * the parameter will be cleared 186 * @param flags Interrupt flags to clear. See the @ref ADC_INTR 187 * "ADC_INTR Register" for the interrupt flag masks 188 */ 189 void MXC_ADC_ClearFlags(uint32_t flags); 190 191 /** 192 * @brief Sets the ADC conversion speed 193 * 194 * @param hz conversion frequency 195 * 196 * @return Actual conversion speed, or \ref MXC_Error_Codes for Error. 197 */ 198 int MXC_ADC_SetConversionSpeed(uint32_t hz); 199 200 /** 201 * @brief Gets the current ADC conversion speed 202 * 203 * @return Actual conversion speed, or \ref MXC_Error_Codes for Error. 204 */ 205 int MXC_ADC_GetConversionSpeed(void); 206 207 /** 208 * @brief Set the data alignment 209 * 210 * @param msbJustify Setting this to a non-zero number will fill the 211 * 12 most significant bits of the data registers. 212 * Otherwise, the 12 Least significant bits will be filled. 213 */ 214 void MXC_ADC_SetDataAlignment(int msbJustify); 215 216 /** 217 * @brief Sets the scaling used for conversions on external channels 218 * @note Internal channels are approx. known and have fixed scaling 219 * Externals channels can be scaled with standard scaling (1-4x) 220 * Or by using a separate 1/2 input scale, or a 1/2 ref scale (total range 0.5-8x) 221 * @param scale requested scale or \ref mxc_adc_scale_t 222 */ 223 void MXC_ADC_SetExtScale(mxc_adc_scale_t scale); 224 225 /** 226 * @brief Enable channel high/low monitor 227 * @note This function only enables an already configured monitor 228 * 229 * @param monitor The monitor to enable or \ref mxc_adc_monitor_t 230 */ 231 void MXC_ADC_EnableMonitor(mxc_adc_monitor_t monitor); 232 233 /** 234 * @brief Disable channel high/low monitor 235 * @note This function only disables an already configured monitor 236 * 237 * @param monitor The monitor to disable or \ref mxc_adc_monitor_t 238 */ 239 void MXC_ADC_DisableMonitor(mxc_adc_monitor_t monitor); 240 241 /** 242 * @brief Set the high limit for a specific monitor 243 * @note setting a value of 0 disables this limit 244 * 245 * @param monitor the monitor to set the limit on or \ref mxc_adc_monitor_t 246 * @param threshold the limit to set 247 */ 248 void MXC_ADC_SetMonitorHighThreshold(mxc_adc_monitor_t monitor, uint32_t threshold); 249 250 /** 251 * @brief Set the high limit for a specific monitor 252 * 253 * @param monitor the monitor to set the limit on or \ref mxc_adc_monitor_t 254 * 255 * @return the monitor's high threshold 256 */ 257 int MXC_ADC_GetMonitorHighThreshold(mxc_adc_monitor_t monitor); 258 259 /** 260 * @brief Set the low limit for a specific monitor 261 * @note setting a value of 0 disables this limit 262 * 263 * @param monitor the monitor to set the limit on or \ref mxc_adc_monitor_t 264 * @param threshold the limit to set 265 */ 266 void MXC_ADC_SetMonitorLowThreshold(mxc_adc_monitor_t monitor, uint32_t threshold); 267 268 /** 269 * @brief Set the low limit for a specific monitor 270 * 271 * @param monitor the monitor to set the limit on or \ref mxc_adc_monitor_t 272 * 273 * @return the monitor's low threshold 274 */ 275 int MXC_ADC_GetMonitorLowThreshold(mxc_adc_monitor_t monitor); 276 277 /** 278 * @brief Set a monitor to use a specific channel 279 * @note The monitor must be enabled separately 280 * 281 * @param monitor the monitor to set the limit on or \ref mxc_adc_monitor_t 282 * @param channel the channel to monitor or \ref mxc_adc_chsel_t 283 */ 284 void MXC_ADC_SetMonitorChannel(mxc_adc_monitor_t monitor, mxc_adc_chsel_t channel); 285 286 /** 287 * @brief Get the channel used by a monitor 288 * 289 * @param monitor the monitor to set the limit on or \ref mxc_adc_monitor_t 290 * 291 * @return the channel being monitored 292 */ 293 int MXC_ADC_GetMonitorChannel(mxc_adc_monitor_t monitor); 294 295 /** 296 * @brief Set a callback to be called when a monitor goes out of range 297 * @note The ADC interrupt must be enabled and MXC_ADC_Handler() called in the ISR 298 * 299 * @param monitor the monitor to register callback for or \ref mxc_adc_monitor_t 300 * @param callback the function called when the limit is hit or \ref mxc_adc_monitor_cb_t 301 */ 302 void MXC_ADC_EnableMonitorAsync(mxc_adc_monitor_t monitor, mxc_adc_monitor_cb_t callback); 303 304 /** 305 * @brief Disable a callback for a monitor 306 * 307 * @param monitor the monitor to unregister callback for or \ref mxc_adc_monitor_t 308 */ 309 void MXC_ADC_DisableMonitorAsync(mxc_adc_monitor_t monitor); 310 311 /** 312 * @brief Start ADC conversion on the selected channel 313 * @param channel Channel select from #mxc_adc_chsel_t 314 * @return Data read in the conversion if successful, an error code otherwise 315 */ 316 int MXC_ADC_StartConversion(mxc_adc_chsel_t channel); 317 318 /** 319 * @brief Perform a conversion on a specific channel 320 * @note The channel must be configured separately 321 * The ADC interrupt must be enabled and MXC_ADC_Handler() called in the ISR 322 * places data in the error parameter of the callback function 323 * 324 * @param channel the channel to perform the conversion on or \ref mxc_adc_chsel_t 325 * @param callback the function to call when the conversion is complete 326 * 327 * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. 328 */ 329 int MXC_ADC_StartConversionAsync(mxc_adc_chsel_t channel, mxc_adc_complete_cb_t callback); 330 331 /** 332 * @brief Perform a conversion on a specific channel 333 * @note The channel must be configured separately 334 * 335 * @param channel the channel to perform the conversion on or \ref mxc_adc_chsel_t 336 * @param data return rax adc data 337 * @param callback DMA complete callback 338 * 339 * @return Raw conversion value, or \ref MXC_Error_Codes for error. 340 */ 341 int MXC_ADC_StartConversionDMA(mxc_adc_chsel_t channel, uint16_t *data, void (*callback)(int, int)); 342 343 /** 344 * @brief Call this function from the ADC ISR when using Async API 345 * functions 346 * 347 * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. 348 */ 349 int MXC_ADC_Handler(void); 350 351 /** 352 * @brief Perform a conversion on a specific channel 353 * @note The result will be placed back in the request structure 354 * 355 * @param req The structure containing all information for the conversion 356 * 357 * @return \ref MXC_Error_Codes for error. 358 */ 359 int MXC_ADC_Convert(mxc_adc_conversion_req_t *req); 360 361 /** 362 * @brief Perform a conversion on a specific channel 363 * @note The result will be placed back in the request structure The ADC 364 * interrupt must be enabled and MXC_ADC_Handler() called in the ISR 365 * 366 * @param req The structure containing all information for the conversion 367 * 368 * @return return E_NO_ERROR OR E_BUSY 369 */ 370 int MXC_ADC_ConvertAsync(mxc_adc_conversion_req_t *req); 371 372 /** 373 * @brief Monitor a specific channel for an out of range event 374 * @note synchronously waits for an out of range event to occur on the monitor 375 * @param req The structure containing all information for monitoring 376 */ 377 void MXC_ADC_Monitor(mxc_adc_monitor_req_t req); 378 379 /** 380 * @brief Monitor a specific channel for an out of range event 381 * @note If a callback is included, the ADC interrupt must be enabled 382 * and MXC_ADC_Handler() called in the ISR 383 * 384 * @param req The structure containing all information for monitoring 385 */ 386 void MXC_ADC_MonitorAsync(mxc_adc_monitor_req_t req); 387 388 /** 389 * @brief Gets the result from the previous ADC conversion 390 * @param outdata Pointer to store the ADC data conversion result 391 * @return #E_OVERFLOW ADC overflow error 392 * @return #E_NO_ERROR Data returned in \p outdata parameter 393 */ 394 int MXC_ADC_GetData(uint16_t *outdata); 395 396 /**@} end of group adc */ 397 398 #ifdef __cplusplus 399 } 400 #endif 401 402 #endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32650_ADC_H_ 403