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