1 /* 2 * Copyright (c) 2015 - 2023, Nordic Semiconductor ASA 3 * All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright notice, this 11 * list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the copyright holder nor the names of its 18 * contributors may be used to endorse or promote products derived from this 19 * software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #ifndef NRFX_SAADC_H__ 35 #define NRFX_SAADC_H__ 36 37 #include <nrfx.h> 38 #include <haly/nrfy_saadc.h> 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif 43 44 /** 45 * @defgroup nrfx_saadc SAADC driver 46 * @{ 47 * @ingroup nrf_saadc 48 * @brief Successive Approximation Analog-to-Digital Converter (SAADC) peripheral driver. 49 */ 50 51 #if NRF_SAADC_HAS_ACQTIME_ENUM || defined(__NRFX_DOXYGEN__) 52 /** @brief Auxiliary symbol specifying default value for the SAADC acquisition time. */ 53 #define NRFX_SAADC_DEFAULT_ACQTIME NRF_SAADC_ACQTIME_10US 54 #else 55 #define NRFX_SAADC_DEFAULT_ACQTIME 79 56 #endif 57 58 #if NRF_SAADC_HAS_CONV_TIME || defined(__NRFX_DOXYGEN__) 59 /** @brief Auxiliary symbol specifying default value for the SAADC conversion time. */ 60 #define NRFX_SAADC_DEFAULT_CONV_TIME 7 61 #endif 62 63 /** 64 * @brief SAADC channel default configuration for the single-ended mode. 65 * 66 * This configuration sets up single-ended SAADC channel with the following options: 67 * - resistor ladder disabled 68 * - gain: 1 69 * - reference voltage: internal 70 * - sample acquisition time: 10 us 71 * - burst disabled 72 * 73 * @param[in] _pin_p Positive input analog pin. 74 * @param[in] _index Channel index. 75 * 76 * @sa nrfx_saadc_channel_t 77 */ 78 #define NRFX_SAADC_DEFAULT_CHANNEL_SE(_pin_p, _index) \ 79 { \ 80 .channel_config = \ 81 { \ 82 NRFX_COND_CODE_1(NRF_SAADC_HAS_CH_CONFIG_RES, \ 83 (.resistor_p = NRF_SAADC_RESISTOR_DISABLED, \ 84 .resistor_n = NRF_SAADC_RESISTOR_DISABLED,), \ 85 ()) \ 86 .gain = NRF_SAADC_GAIN1, \ 87 .reference = NRF_SAADC_REFERENCE_INTERNAL, \ 88 .acq_time = NRFX_SAADC_DEFAULT_ACQTIME, \ 89 NRFX_COND_CODE_1(NRF_SAADC_HAS_CONV_TIME, \ 90 (.conv_time = NRFX_SAADC_DEFAULT_CONV_TIME,), \ 91 ()) \ 92 .mode = NRF_SAADC_MODE_SINGLE_ENDED, \ 93 .burst = NRF_SAADC_BURST_DISABLED, \ 94 }, \ 95 .pin_p = (nrf_saadc_input_t)_pin_p, \ 96 .pin_n = NRF_SAADC_INPUT_DISABLED, \ 97 .channel_index = _index, \ 98 } 99 100 /** 101 * @brief SAADC channel default configuration for the differential mode. 102 * 103 * This configuration sets up differential SAADC channel with the following options: 104 * - resistor ladder disabled 105 * - gain: 1/6 106 * - reference voltage: internal 107 * - sample acquisition time: 10 us 108 * - burst disabled 109 * 110 * @param[in] _pin_p Positive input analog pin. 111 * @param[in] _pin_n Negative input analog pin. 112 * @param[in] _index Channel index. 113 * 114 * @sa nrfx_saadc_channel_t 115 */ 116 #define NRFX_SAADC_DEFAULT_CHANNEL_DIFFERENTIAL(_pin_p, _pin_n, _index) \ 117 { \ 118 .channel_config = \ 119 { \ 120 NRFX_COND_CODE_1(NRF_SAADC_HAS_CH_CONFIG_RES, \ 121 (.resistor_p = NRF_SAADC_RESISTOR_DISABLED, \ 122 .resistor_n = NRF_SAADC_RESISTOR_DISABLED,), \ 123 ()) \ 124 .gain = NRF_SAADC_GAIN1, \ 125 .reference = NRF_SAADC_REFERENCE_INTERNAL, \ 126 .acq_time = NRFX_SAADC_DEFAULT_ACQTIME, \ 127 NRFX_COND_CODE_1(NRF_SAADC_HAS_CONV_TIME, \ 128 (.conv_time = NRFX_SAADC_DEFAULT_CONV_TIME,), \ 129 ()) \ 130 .mode = NRF_SAADC_MODE_DIFFERENTIAL, \ 131 .burst = NRF_SAADC_BURST_DISABLED, \ 132 }, \ 133 .pin_p = (nrf_saadc_input_t)_pin_p, \ 134 .pin_n = (nrf_saadc_input_t)_pin_n, \ 135 .channel_index = _index, \ 136 } 137 138 /** 139 * @brief SAADC driver advanced mode default configuration. 140 * 141 * This configuration sets up advanced mode of the SAADC driver with the following options: 142 * - oversampling disabled 143 * - burst disabled 144 * - internal sampling timer disabled 145 * - triggering of the START task on the END event disabled 146 * 147 * @param[in] _pin_p Positive input analog pin. 148 * @param[in] _pin_n Negative input analog pin. 149 * @param[in] _index Channel index. 150 * 151 * @sa nrfx_saadc_adv_config_t 152 */ 153 #define NRFX_SAADC_DEFAULT_ADV_CONFIG \ 154 { \ 155 .oversampling = NRF_SAADC_OVERSAMPLE_DISABLED, \ 156 .burst = NRF_SAADC_BURST_DISABLED, \ 157 .internal_timer_cc = 0, \ 158 .start_on_end = false, \ 159 } 160 161 /** @brief SAADC channel configuration structure. */ 162 typedef struct 163 { 164 nrf_saadc_channel_config_t channel_config; ///< Channel hardware configuration. 165 nrf_saadc_input_t pin_p; ///< Input positive pin selection. 166 nrf_saadc_input_t pin_n; ///< Input negative pin selection. 167 uint8_t channel_index; ///< Channel index. 168 } nrfx_saadc_channel_t; 169 170 /** @brief SAADC driver advanced mode configuration structure. */ 171 typedef struct 172 { 173 nrf_saadc_oversample_t oversampling; ///< Oversampling configuration. 174 nrf_saadc_burst_t burst; ///< Burst configuration. 175 uint16_t internal_timer_cc; ///< Internal timer capture and compare value. 176 bool start_on_end; ///< Flag indicating if the START task is to be triggered on the END event. 177 } nrfx_saadc_adv_config_t; 178 179 /** @brief SAADC driver event types. */ 180 typedef enum 181 { 182 NRFX_SAADC_EVT_DONE, ///< Event generated when the buffer is filled with samples. 183 NRFX_SAADC_EVT_LIMIT, ///< Event generated when one of the limits is reached. 184 NRFX_SAADC_EVT_CALIBRATEDONE, ///< Event generated when the calibration is complete. 185 NRFX_SAADC_EVT_BUF_REQ, ///< Event generated when the next buffer for continuous conversion is requested. 186 NRFX_SAADC_EVT_READY, ///< Event generated when the first buffer is acquired by the peripheral and sampling can be started. 187 NRFX_SAADC_EVT_FINISHED, ///< Event generated when all supplied buffers are filled with results. 188 } nrfx_saadc_evt_type_t; 189 190 /** @brief SAADC driver done event data. */ 191 typedef struct 192 { 193 nrf_saadc_value_t * p_buffer; ///< Pointer to the buffer with converted samples. 194 uint16_t size; ///< Number of samples in the buffer. 195 } nrfx_saadc_done_evt_t; 196 197 /** @brief SAADC driver limit event data. */ 198 typedef struct 199 { 200 uint8_t channel; ///< Channel on which the limit was detected. 201 nrf_saadc_limit_t limit_type; ///< Type of limit detected. 202 } nrfx_saadc_limit_evt_t; 203 204 /** @brief SAADC driver event structure. */ 205 typedef struct 206 { 207 nrfx_saadc_evt_type_t type; ///< Event type. 208 union 209 { 210 nrfx_saadc_done_evt_t done; ///< Data for @ref NRFX_SAADC_EVT_DONE event. 211 nrfx_saadc_limit_evt_t limit; ///< Data for @ref NRFX_SAADC_EVT_LIMIT event. 212 } data; ///< Union to store event data. 213 } nrfx_saadc_evt_t; 214 215 /** 216 * @brief SAADC driver event handler. 217 * 218 * When operating in the advanced mode: 219 * - when the sampling is performed by the external timer, the external timer can be safely started 220 * on @ref NRFX_SAADC_EVT_READY and stopped on @ref NRFX_SAADC_EVT_FINISHED. 221 * - call the @ref nrfx_saadc_buffer_set() on @ref NRFX_SAADC_EVT_BUF_REQ to achieve the continuous conversion. 222 * 223 * @param[in] p_event Pointer to an SAADC driver event. The event structure is allocated on 224 * the stack, so it is valid only within the context of the event handler. 225 */ 226 typedef void (* nrfx_saadc_event_handler_t)(nrfx_saadc_evt_t const * p_event); 227 228 /** 229 * @brief Function for initializing the SAADC driver. 230 * 231 * @param[in] interrupt_priority Interrupt priority. 232 * 233 * @retval NRFX_SUCCESS Initialization was successful. 234 * @retval NRFX_ERROR_INVALID_STATE The driver is already initialized. 235 */ 236 nrfx_err_t nrfx_saadc_init(uint8_t interrupt_priority); 237 238 /** 239 * @brief Function for uninitializing the SAADC driver. 240 * 241 * This function stops all ongoing conversions and disables all channels. 242 */ 243 void nrfx_saadc_uninit(void); 244 245 /** 246 * @brief Function for configuring multiple SAADC channels. 247 * 248 * @note The values of the @ref nrf_saadc_channel_config_t.burst fields in channel configurations 249 * are ignored. They will be overridden with the value suitable for the selected driver 250 * operation mode. 251 * @note The desired mode (simple or advanced) must be set after the channels are configured. 252 * 253 * @warning This function overrides previous configuration done on any channel by 254 * @ref nrfx_saadc_channels_config or @ref nrfx_saadc_channel_config. 255 * 256 * @param[in] p_channels Pointer to the array of channel configuration structures. 257 * @param[in] channel_count Number of channels to be configured. 258 * 259 * @retval NRFX_SUCCESS Configuration was successful. 260 * @retval NRFX_ERROR_BUSY There is a conversion or calibration ongoing. 261 * @retval NRFX_ERROR_INVALID_PARAM Attempt to configure the same channel more than once. 262 */ 263 nrfx_err_t nrfx_saadc_channels_config(nrfx_saadc_channel_t const * p_channels, 264 uint32_t channel_count); 265 266 /** 267 * @brief Function for configuring single SAADC channel. 268 * 269 * @note The values of the @ref nrf_saadc_channel_config_t.burst fields in channel configurations 270 * are ignored. They will be overridden with the value suitable for the selected driver 271 * operation mode. 272 * 273 * @warning This function overrides previous configuration done on specified channel by 274 * @ref nrfx_saadc_channels_config or @ref nrfx_saadc_channel_config. 275 * 276 * @param[in] p_channel Pointer to the channel configuration structure. 277 * 278 * @retval NRFX_SUCCESS Configuration was successful. 279 * @retval NRFX_ERROR_BUSY There is a conversion or calibration ongoing. 280 */ 281 nrfx_err_t nrfx_saadc_channel_config(nrfx_saadc_channel_t const * p_channel); 282 283 /** 284 * @brief Function for getting the currently configured SAADC channels. 285 * 286 * @return Bitmask of configured channels. 287 */ 288 uint32_t nrfx_saadc_channels_configured_get(void); 289 290 /** 291 * @brief Function for deconfiguring the specified SAADC channels. 292 * 293 * @warning Pins associated with the deconfigured channels will be released after 294 * next @ref nrfx_saadc_simple_mode_set() or @ref nrfx_saadc_advanced_mode_set() call. 295 * 296 * @param[in] channel_mask Bitmask of channels to be deconfigured. 297 * 298 * @retval NRFX_SUCCESS Deconfiguration was successful. 299 * @retval NRFX_ERROR_BUSY There is a conversion or calibration ongoing. 300 */ 301 nrfx_err_t nrfx_saadc_channels_deconfig(uint32_t channel_mask); 302 303 /** 304 * @brief Function for setting the SAADC driver in the simple mode. 305 * 306 * The simple mode allows obtaining a single sample from each requested channel. 307 * The conversion can be done in a blocking or non-blocking manner. 308 * Sampling is initiated by calling @ref nrfx_saadc_mode_trigger() once. 309 * 310 * @param[in] channel_mask Bitmask of channels to be used in the simple mode. 311 * @param[in] resolution Resolution configuration. 312 * @param[in] oversampling Oversampling configuration. 313 * @param[in] event_handler Event handler provided by the user. In case of providing NULL, 314 * the conversion will be performed in the blocking manner. 315 * 316 * @retval NRFX_SUCCESS Initialization was successful. 317 * @retval NRFX_ERROR_BUSY There is a conversion or calibration ongoing. 318 * @retval NRFX_ERROR_INVALID_PARAM Attempt to activate channel that is not configured. 319 */ 320 nrfx_err_t nrfx_saadc_simple_mode_set(uint32_t channel_mask, 321 nrf_saadc_resolution_t resolution, 322 nrf_saadc_oversample_t oversampling, 323 nrfx_saadc_event_handler_t event_handler); 324 325 /** 326 * @brief Function for setting the SAADC driver in the advanced mode. 327 * 328 * The advanced mode allows performing double-buffered conversions of arbitrary length. 329 * The conversions can be done in a blocking or non-blocking manner. When performing conversions 330 * in the non-blocking manner and @ref nrfx_saadc_adv_config_t.internal_timer_cc is set to 0, 331 * sampling needs to be done by triggering @ref NRF_SAADC_TASK_SAMPLE externally 332 * (for example by using the TIMER and/or the PPI/DPPI). 333 * When performing conversions in the non-blocking manner and @ref nrfx_saadc_adv_config_t.start_on_end 334 * is false, the @ref NRF_SAADC_TASK_START needs to be triggered on @ref NRF_SAADC_EVENT_END 335 * externally (for example by using the PPI/DPPI). 336 * Sampling is initiated by calling @ref nrfx_saadc_mode_trigger(). In case of performing 337 * conversions in the blocking manner, @ref nrfx_saadc_mode_trigger() may need to be called several 338 * times as each call sample each requested channel once. 339 * 340 * @note The internal timer can only be used when a single input channel is enabled. 341 * @note The internal timer can only be used in the non-blocking mode. 342 * 343 * @param[in] channel_mask Bitmask of channels to be used in the advanced mode. 344 * @param[in] resolution Resolution configuration. 345 * @param[in] p_config Pointer to the structure with the advanced mode configuration. 346 * @param[in] event_handler Event handler provided by the user. In case of providing NULL, 347 * the conversion will be performed in the blocking manner. 348 * 349 * @retval NRFX_SUCCESS Initialization was successful. 350 * @retval NRFX_ERROR_BUSY There is a conversion or calibration ongoing. 351 * @retval NRFX_ERROR_INVALID_PARAM Attempt to activate channel that is not configured. 352 * @retval NRFX_ERROR_NOT_SUPPORTED Attempt to activate either of the following: 353 * * internal timer in the blocking mode, 354 * * internal timer with multiple channels enabled, 355 * * oversampling without burst with multiple channels enabled. 356 */ 357 nrfx_err_t nrfx_saadc_advanced_mode_set(uint32_t channel_mask, 358 nrf_saadc_resolution_t resolution, 359 nrfx_saadc_adv_config_t const * p_config, 360 nrfx_saadc_event_handler_t event_handler); 361 362 /** 363 * @brief Function for supplying the buffer to be used in the next part of 364 * the conversion. 365 * 366 * @param[in] p_buffer Pointer to the buffer to be filled with conversion results. 367 * @param[in] size Number of @ref nrf_saadc_value_t samples in buffer. 368 * 369 * @retval NRFX_SUCCESS Buffer was supplied successfully. 370 * @retval NRFX_ERROR_INVALID_ADDR The provided buffer is not in the Data RAM region. 371 * @retval NRFX_ERROR_INVALID_LENGTH The provided buffer is not aligned to the number of activated channels 372 * or is too long for the EasyDMA to handle. 373 * @retval NRFX_ERROR_INVALID_STATE The driver is in the idle mode. 374 * @retval NRFX_ERROR_ALREADY_INITIALIZED Both buffers for double-buffered conversions are already set. 375 */ 376 nrfx_err_t nrfx_saadc_buffer_set(nrf_saadc_value_t * p_buffer, uint16_t size); 377 378 /** 379 * @brief Function for triggering the conversion in the configured mode. 380 * 381 * @retval NRFX_SUCCESS Operation finished successfully in the blocking manner or started 382 * successfully in the non-blocking manner. 383 * @retval NRFX_ERROR_BUSY The driver is performing the conversion in the advanced blocking mode. 384 * Call the function again to continue the conversion. 385 * @retval NRFX_ERROR_NO_MEM There is no buffer provided. 386 * Supply the buffer using @ref nrfx_saadc_buffer_set() and try again. 387 * @retval NRFX_ERROR_INVALID_STATE There is an ongoing conversion or calibration being performed 388 * in the non-blocking manner or the driver is in the idle mode. 389 */ 390 nrfx_err_t nrfx_saadc_mode_trigger(void); 391 392 /** 393 * @brief Function for aborting the ongoing and buffered conversions. 394 * 395 * @warning Aborting blocking conversion or calibration from different context is not supported. 396 * Perform the operation in non-blocking manner instead. 397 * 398 * @note @ref NRFX_SAADC_EVT_DONE event will be generated if there is a conversion in progress. 399 * Event will contain number of words in the sample buffer. 400 */ 401 void nrfx_saadc_abort(void); 402 403 /** 404 * @brief Function for setting the SAADC channel limits. 405 * 406 * When limits are enabled and the conversion result exceeds the defined bounds, 407 * the handler function is called with the corresponding event as parameter. 408 * 409 * @note Before the limits are set, the driver operation mode (simple or advanced) has 410 * to be configured. Only non-blocking conversions can be monitored. 411 * 412 * @note Changing of the driver operation mode disables all configured limits. 413 * 414 * @param[in] channel Channel index. 415 * @param[in] limit_low Limit low value to generate interrupt. Use @c INT16_MIN 416 * to disable interrupt generation. 417 * @param[in] limit_high Limit high value to generate interrupt. Use @c INT16_MAX 418 * to disable interrupt generation. 419 * 420 * @retval NRFX_SUCCESS Requested channel limits were set. 421 * @retval NRFX_ERROR_INVALID_PARAM Attempt to activate the limits on disabled channel. 422 * @retval NRFX_ERROR_FORBIDDEN Attempt to activate the limits for blocking conversions. 423 * @retval NRFX_ERROR_INVALID_STATE Attempt to activate the limits without configured mode. 424 */ 425 nrfx_err_t nrfx_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t limit_high); 426 427 /** 428 * @brief Function for starting the SAADC offset calibration. 429 * 430 * @param[in] calib_event_handler Calibration event handler provided by the user. In case of providing NULL, 431 * the calibration will be performed in the blocking manner. 432 * 433 * @retval NRFX_SUCCESS Calibration finished successfully in the blocking manner 434 * or started successfully in the non-blocking manner. 435 * @retval NRFX_ERROR_BUSY There is a conversion or calibration ongoing. 436 */ 437 nrfx_err_t nrfx_saadc_offset_calibrate(nrfx_saadc_event_handler_t calib_event_handler); 438 439 /** @} */ 440 441 void nrfx_saadc_irq_handler(void); 442 443 #ifdef __cplusplus 444 } 445 #endif 446 447 #endif // NRFX_SAADC_H__ 448 449