1*150812a8SEvalZero /* 2*150812a8SEvalZero * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA 3*150812a8SEvalZero * All rights reserved. 4*150812a8SEvalZero * 5*150812a8SEvalZero * Redistribution and use in source and binary forms, with or without 6*150812a8SEvalZero * modification, are permitted provided that the following conditions are met: 7*150812a8SEvalZero * 8*150812a8SEvalZero * 1. Redistributions of source code must retain the above copyright notice, this 9*150812a8SEvalZero * list of conditions and the following disclaimer. 10*150812a8SEvalZero * 11*150812a8SEvalZero * 2. Redistributions in binary form must reproduce the above copyright 12*150812a8SEvalZero * notice, this list of conditions and the following disclaimer in the 13*150812a8SEvalZero * documentation and/or other materials provided with the distribution. 14*150812a8SEvalZero * 15*150812a8SEvalZero * 3. Neither the name of the copyright holder nor the names of its 16*150812a8SEvalZero * contributors may be used to endorse or promote products derived from this 17*150812a8SEvalZero * software without specific prior written permission. 18*150812a8SEvalZero * 19*150812a8SEvalZero * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20*150812a8SEvalZero * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21*150812a8SEvalZero * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22*150812a8SEvalZero * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23*150812a8SEvalZero * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24*150812a8SEvalZero * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25*150812a8SEvalZero * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26*150812a8SEvalZero * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27*150812a8SEvalZero * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28*150812a8SEvalZero * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29*150812a8SEvalZero * POSSIBILITY OF SUCH DAMAGE. 30*150812a8SEvalZero */ 31*150812a8SEvalZero 32*150812a8SEvalZero #ifndef NRFX_SAADC_H__ 33*150812a8SEvalZero #define NRFX_SAADC_H__ 34*150812a8SEvalZero 35*150812a8SEvalZero #include <nrfx.h> 36*150812a8SEvalZero #include <hal/nrf_saadc.h> 37*150812a8SEvalZero 38*150812a8SEvalZero #ifdef __cplusplus 39*150812a8SEvalZero extern "C" { 40*150812a8SEvalZero #endif 41*150812a8SEvalZero 42*150812a8SEvalZero /** 43*150812a8SEvalZero * @defgroup nrfx_saadc SAADC driver 44*150812a8SEvalZero * @{ 45*150812a8SEvalZero * @ingroup nrf_saadc 46*150812a8SEvalZero * @brief Successive Approximation Analog-to-Digital Converter (SAADC) peripheral driver. 47*150812a8SEvalZero */ 48*150812a8SEvalZero 49*150812a8SEvalZero /** 50*150812a8SEvalZero * @brief Value that should be set as high limit to disable limit detection. 51*150812a8SEvalZero */ 52*150812a8SEvalZero #define NRFX_SAADC_LIMITH_DISABLED (2047) 53*150812a8SEvalZero /** 54*150812a8SEvalZero * @brief Value that should be set as low limit to disable limit detection. 55*150812a8SEvalZero */ 56*150812a8SEvalZero #define NRFX_SAADC_LIMITL_DISABLED (-2048) 57*150812a8SEvalZero 58*150812a8SEvalZero /** 59*150812a8SEvalZero * @brief Macro for setting @ref nrfx_saadc_config_t to default settings. 60*150812a8SEvalZero */ 61*150812a8SEvalZero #define NRFX_SAADC_DEFAULT_CONFIG \ 62*150812a8SEvalZero { \ 63*150812a8SEvalZero .resolution = (nrf_saadc_resolution_t)NRFX_SAADC_CONFIG_RESOLUTION, \ 64*150812a8SEvalZero .oversample = (nrf_saadc_oversample_t)NRFX_SAADC_CONFIG_OVERSAMPLE, \ 65*150812a8SEvalZero .interrupt_priority = NRFX_SAADC_CONFIG_IRQ_PRIORITY, \ 66*150812a8SEvalZero .low_power_mode = NRFX_SAADC_CONFIG_LP_MODE \ 67*150812a8SEvalZero } 68*150812a8SEvalZero 69*150812a8SEvalZero /** 70*150812a8SEvalZero * @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings 71*150812a8SEvalZero * in single ended mode. 72*150812a8SEvalZero * 73*150812a8SEvalZero * @param PIN_P Analog input. 74*150812a8SEvalZero */ 75*150812a8SEvalZero #define NRFX_SAADC_DEFAULT_CHANNEL_CONFIG_SE(PIN_P) \ 76*150812a8SEvalZero { \ 77*150812a8SEvalZero .resistor_p = NRF_SAADC_RESISTOR_DISABLED, \ 78*150812a8SEvalZero .resistor_n = NRF_SAADC_RESISTOR_DISABLED, \ 79*150812a8SEvalZero .gain = NRF_SAADC_GAIN1_6, \ 80*150812a8SEvalZero .reference = NRF_SAADC_REFERENCE_INTERNAL, \ 81*150812a8SEvalZero .acq_time = NRF_SAADC_ACQTIME_10US, \ 82*150812a8SEvalZero .mode = NRF_SAADC_MODE_SINGLE_ENDED, \ 83*150812a8SEvalZero .burst = NRF_SAADC_BURST_DISABLED, \ 84*150812a8SEvalZero .pin_p = (nrf_saadc_input_t)(PIN_P), \ 85*150812a8SEvalZero .pin_n = NRF_SAADC_INPUT_DISABLED \ 86*150812a8SEvalZero } 87*150812a8SEvalZero 88*150812a8SEvalZero /** 89*150812a8SEvalZero * @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings 90*150812a8SEvalZero * in differential mode. 91*150812a8SEvalZero * 92*150812a8SEvalZero * @param PIN_P Positive analog input. 93*150812a8SEvalZero * @param PIN_N Negative analog input. 94*150812a8SEvalZero */ 95*150812a8SEvalZero #define NRFX_SAADC_DEFAULT_CHANNEL_CONFIG_DIFFERENTIAL(PIN_P, PIN_N) \ 96*150812a8SEvalZero { \ 97*150812a8SEvalZero .resistor_p = NRF_SAADC_RESISTOR_DISABLED, \ 98*150812a8SEvalZero .resistor_n = NRF_SAADC_RESISTOR_DISABLED, \ 99*150812a8SEvalZero .gain = NRF_SAADC_GAIN1_6, \ 100*150812a8SEvalZero .reference = NRF_SAADC_REFERENCE_INTERNAL, \ 101*150812a8SEvalZero .acq_time = NRF_SAADC_ACQTIME_10US, \ 102*150812a8SEvalZero .mode = NRF_SAADC_MODE_DIFFERENTIAL, \ 103*150812a8SEvalZero .pin_p = (nrf_saadc_input_t)(PIN_P), \ 104*150812a8SEvalZero .pin_n = (nrf_saadc_input_t)(PIN_N) \ 105*150812a8SEvalZero } 106*150812a8SEvalZero 107*150812a8SEvalZero /** 108*150812a8SEvalZero * @brief Analog-to-digital converter driver configuration structure. 109*150812a8SEvalZero */ 110*150812a8SEvalZero typedef struct 111*150812a8SEvalZero { 112*150812a8SEvalZero nrf_saadc_resolution_t resolution; ///< Resolution configuration. 113*150812a8SEvalZero nrf_saadc_oversample_t oversample; ///< Oversampling configuration. 114*150812a8SEvalZero uint8_t interrupt_priority; ///< Interrupt priority. 115*150812a8SEvalZero bool low_power_mode; ///< Indicates if low power mode is active. 116*150812a8SEvalZero } nrfx_saadc_config_t; 117*150812a8SEvalZero 118*150812a8SEvalZero /** 119*150812a8SEvalZero * @brief Driver event types. 120*150812a8SEvalZero */ 121*150812a8SEvalZero typedef enum 122*150812a8SEvalZero { 123*150812a8SEvalZero NRFX_SAADC_EVT_DONE, ///< Event generated when the buffer is filled with samples. 124*150812a8SEvalZero NRFX_SAADC_EVT_LIMIT, ///< Event generated after one of the limits is reached. 125*150812a8SEvalZero NRFX_SAADC_EVT_CALIBRATEDONE ///< Event generated when the calibration is complete. 126*150812a8SEvalZero } nrfx_saadc_evt_type_t; 127*150812a8SEvalZero 128*150812a8SEvalZero /** 129*150812a8SEvalZero * @brief Analog-to-digital converter driver done event data. 130*150812a8SEvalZero */ 131*150812a8SEvalZero typedef struct 132*150812a8SEvalZero { 133*150812a8SEvalZero nrf_saadc_value_t * p_buffer; ///< Pointer to buffer with converted samples. 134*150812a8SEvalZero uint16_t size; ///< Number of samples in the buffer. 135*150812a8SEvalZero } nrfx_saadc_done_evt_t; 136*150812a8SEvalZero 137*150812a8SEvalZero /** 138*150812a8SEvalZero * @brief Analog-to-digital converter driver limit event data. 139*150812a8SEvalZero */ 140*150812a8SEvalZero typedef struct 141*150812a8SEvalZero { 142*150812a8SEvalZero uint8_t channel; ///< Channel on which the limit was detected. 143*150812a8SEvalZero nrf_saadc_limit_t limit_type; ///< Type of limit detected. 144*150812a8SEvalZero } nrfx_saadc_limit_evt_t; 145*150812a8SEvalZero 146*150812a8SEvalZero /** 147*150812a8SEvalZero * @brief Analog-to-digital converter driver event structure. 148*150812a8SEvalZero */ 149*150812a8SEvalZero typedef struct 150*150812a8SEvalZero { 151*150812a8SEvalZero nrfx_saadc_evt_type_t type; ///< Event type. 152*150812a8SEvalZero union 153*150812a8SEvalZero { 154*150812a8SEvalZero nrfx_saadc_done_evt_t done; ///< Data for @ref NRFX_SAADC_EVT_DONE event. 155*150812a8SEvalZero nrfx_saadc_limit_evt_t limit; ///< Data for @ref NRFX_SAADC_EVT_LIMIT event. 156*150812a8SEvalZero } data; 157*150812a8SEvalZero } nrfx_saadc_evt_t; 158*150812a8SEvalZero 159*150812a8SEvalZero /** 160*150812a8SEvalZero * @brief ADC event handler. 161*150812a8SEvalZero * 162*150812a8SEvalZero * @param[in] p_event Pointer to an ADC event. The event structure is allocated on 163*150812a8SEvalZero * the stack, so it is valid only within the context of 164*150812a8SEvalZero * the event handler. 165*150812a8SEvalZero */ 166*150812a8SEvalZero typedef void (* nrfx_saadc_event_handler_t)(nrfx_saadc_evt_t const * p_event); 167*150812a8SEvalZero 168*150812a8SEvalZero /** 169*150812a8SEvalZero * @brief Function for initializing the SAADC. 170*150812a8SEvalZero * 171*150812a8SEvalZero * @param[in] p_config Pointer to the structure with initial configuration. 172*150812a8SEvalZero * @param[in] event_handler Event handler provided by the user. 173*150812a8SEvalZero * Must not be NULL. 174*150812a8SEvalZero * 175*150812a8SEvalZero * @retval NRFX_SUCCESS If initialization was successful. 176*150812a8SEvalZero * @retval NRFX_ERROR_INVALID_STATE If the driver is already initialized. 177*150812a8SEvalZero */ 178*150812a8SEvalZero nrfx_err_t nrfx_saadc_init(nrfx_saadc_config_t const * p_config, 179*150812a8SEvalZero nrfx_saadc_event_handler_t event_handler); 180*150812a8SEvalZero 181*150812a8SEvalZero /** 182*150812a8SEvalZero * @brief Function for uninitializing the SAADC. 183*150812a8SEvalZero * 184*150812a8SEvalZero * This function stops all ongoing conversions and disables all channels. 185*150812a8SEvalZero */ 186*150812a8SEvalZero void nrfx_saadc_uninit(void); 187*150812a8SEvalZero 188*150812a8SEvalZero 189*150812a8SEvalZero /** 190*150812a8SEvalZero * @brief Function for getting the address of a SAMPLE SAADC task. 191*150812a8SEvalZero * 192*150812a8SEvalZero * @return Task address. 193*150812a8SEvalZero */ 194*150812a8SEvalZero uint32_t nrfx_saadc_sample_task_get(void); 195*150812a8SEvalZero 196*150812a8SEvalZero /** 197*150812a8SEvalZero * @brief Function for initializing an SAADC channel. 198*150812a8SEvalZero * 199*150812a8SEvalZero * This function configures and enables the channel. 200*150812a8SEvalZero * 201*150812a8SEvalZero * @retval NRFX_SUCCESS If initialization was successful. 202*150812a8SEvalZero * @retval NRFX_ERROR_INVALID_STATE If the ADC was not initialized. 203*150812a8SEvalZero * @retval NRFX_ERROR_NO_MEM If the specified channel was already allocated. 204*150812a8SEvalZero */ 205*150812a8SEvalZero nrfx_err_t nrfx_saadc_channel_init(uint8_t channel, 206*150812a8SEvalZero nrf_saadc_channel_config_t const * const p_config); 207*150812a8SEvalZero 208*150812a8SEvalZero 209*150812a8SEvalZero /** 210*150812a8SEvalZero * @brief Function for uninitializing an SAADC channel. 211*150812a8SEvalZero * 212*150812a8SEvalZero * @retval NRFX_SUCCESS If uninitialization was successful. 213*150812a8SEvalZero * @retval NRFX_ERROR_BUSY If the ADC is busy. 214*150812a8SEvalZero */ 215*150812a8SEvalZero nrfx_err_t nrfx_saadc_channel_uninit(uint8_t channel); 216*150812a8SEvalZero 217*150812a8SEvalZero /** 218*150812a8SEvalZero * @brief Function for starting SAADC sampling. 219*150812a8SEvalZero * 220*150812a8SEvalZero * @retval NRFX_SUCCESS If ADC sampling was triggered. 221*150812a8SEvalZero * @retval NRFX_ERROR_INVALID_STATE If ADC is in idle state. 222*150812a8SEvalZero */ 223*150812a8SEvalZero nrfx_err_t nrfx_saadc_sample(void); 224*150812a8SEvalZero 225*150812a8SEvalZero /** 226*150812a8SEvalZero * @brief Blocking function for executing a single ADC conversion. 227*150812a8SEvalZero * 228*150812a8SEvalZero * This function selects the desired input, starts a single conversion, 229*150812a8SEvalZero * waits for it to finish, and returns the result. 230*150812a8SEvalZero * 231*150812a8SEvalZero * The function will fail if ADC is busy. 232*150812a8SEvalZero * 233*150812a8SEvalZero * @param[in] channel Channel. 234*150812a8SEvalZero * @param[out] p_value Pointer to the location where the result should be placed. 235*150812a8SEvalZero * 236*150812a8SEvalZero * @retval NRFX_SUCCESS If conversion was successful. 237*150812a8SEvalZero * @retval NRFX_ERROR_BUSY If the ADC driver is busy. 238*150812a8SEvalZero */ 239*150812a8SEvalZero nrfx_err_t nrfx_saadc_sample_convert(uint8_t channel, nrf_saadc_value_t * p_value); 240*150812a8SEvalZero 241*150812a8SEvalZero /** 242*150812a8SEvalZero * @brief Function for issuing conversion of data to the buffer. 243*150812a8SEvalZero * 244*150812a8SEvalZero * This function is non-blocking. The application is notified about filling the buffer by the event 245*150812a8SEvalZero * handler. Conversion will be done on all enabled channels. If the ADC is in idle state, the 246*150812a8SEvalZero * function will set up Easy DMA for the conversion. The ADC will be ready for sampling and wait for 247*150812a8SEvalZero * the SAMPLE task. It can be triggered manually by the @ref nrfx_saadc_sample function or by PPI 248*150812a8SEvalZero * using the @ref NRF_SAADC_TASK_SAMPLE task. If one buffer is already set and the conversion is 249*150812a8SEvalZero * ongoing, calling this function will result in queuing the given buffer. The driver will start 250*150812a8SEvalZero * filling the issued buffer when the first one is completed. If the function is called again before 251*150812a8SEvalZero * the first buffer is filled or calibration is in progress, it will return with error. 252*150812a8SEvalZero * 253*150812a8SEvalZero * @param[in] buffer Result buffer. 254*150812a8SEvalZero * @param[in] size Buffer size in words. 255*150812a8SEvalZero * 256*150812a8SEvalZero * @retval NRFX_SUCCESS If conversion was successful. 257*150812a8SEvalZero * @retval NRFX_ERROR_BUSY If the driver already has two buffers set or calibration is in progress. 258*150812a8SEvalZero */ 259*150812a8SEvalZero nrfx_err_t nrfx_saadc_buffer_convert(nrf_saadc_value_t * buffer, uint16_t size); 260*150812a8SEvalZero 261*150812a8SEvalZero /** 262*150812a8SEvalZero * @brief Function for triggering the ADC offset calibration. 263*150812a8SEvalZero * 264*150812a8SEvalZero * This function is non-blocking. The application is notified about completion by the event handler. 265*150812a8SEvalZero * Calibration will also trigger DONE and RESULTDONE events. 266*150812a8SEvalZero * 267*150812a8SEvalZero * The function will fail if ADC is busy or calibration is already in progress. 268*150812a8SEvalZero * 269*150812a8SEvalZero * @retval NRFX_SUCCESS If calibration was started successfully. 270*150812a8SEvalZero * @retval NRFX_ERROR_BUSY If the ADC driver is busy. 271*150812a8SEvalZero */ 272*150812a8SEvalZero nrfx_err_t nrfx_saadc_calibrate_offset(void); 273*150812a8SEvalZero 274*150812a8SEvalZero /** 275*150812a8SEvalZero * @brief Function for retrieving the SAADC state. 276*150812a8SEvalZero * 277*150812a8SEvalZero * @retval true If the ADC is busy. 278*150812a8SEvalZero * @retval false If the ADC is ready. 279*150812a8SEvalZero */ 280*150812a8SEvalZero bool nrfx_saadc_is_busy(void); 281*150812a8SEvalZero 282*150812a8SEvalZero /** 283*150812a8SEvalZero * @brief Function for aborting ongoing and buffered conversions. 284*150812a8SEvalZero * @note @ref NRFX_SAADC_EVT_DONE event will be generated if there is a conversion in progress. 285*150812a8SEvalZero * Event will contain number of words in the sample buffer. 286*150812a8SEvalZero */ 287*150812a8SEvalZero void nrfx_saadc_abort(void); 288*150812a8SEvalZero 289*150812a8SEvalZero /** 290*150812a8SEvalZero * @brief Function for setting the SAADC channel limits. 291*150812a8SEvalZero * When limits are enabled and the result exceeds the defined bounds, the limit handler 292*150812a8SEvalZero * function is called. 293*150812a8SEvalZero * 294*150812a8SEvalZero * @param[in] channel SAADC channel number. 295*150812a8SEvalZero * @param[in] limit_low Lower limit (valid values from @ref NRFX_SAADC_LIMITL_DISABLED to 296*150812a8SEvalZero * @ref NRFX_SAADC_LIMITH_DISABLED). Conversion results below this value will 297*150812a8SEvalZero * trigger the handler function. Set to @ref NRFX_SAADC_LIMITL_DISABLED 298*150812a8SEvalZero * to disable this limit. 299*150812a8SEvalZero * @param[in] limit_high Upper limit (valid values from @ref NRFX_SAADC_LIMITL_DISABLED to 300*150812a8SEvalZero * @ref NRFX_SAADC_LIMITH_DISABLED). Conversion results above this value will 301*150812a8SEvalZero * trigger the handler function. Set to @ref NRFX_SAADC_LIMITH_DISABLED 302*150812a8SEvalZero * to disable this limit. 303*150812a8SEvalZero */ 304*150812a8SEvalZero void nrfx_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t limit_high); 305*150812a8SEvalZero 306*150812a8SEvalZero 307*150812a8SEvalZero void nrfx_saadc_irq_handler(void); 308*150812a8SEvalZero 309*150812a8SEvalZero 310*150812a8SEvalZero /** @} */ 311*150812a8SEvalZero 312*150812a8SEvalZero #ifdef __cplusplus 313*150812a8SEvalZero } 314*150812a8SEvalZero #endif 315*150812a8SEvalZero 316*150812a8SEvalZero #endif // NRFX_SAADC_H__ 317*150812a8SEvalZero 318