1 /*
2 * Copyright (c) 2015 - 2025, 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_ADC_H__
35 #define NRFX_ADC_H__
36
37 #include <nrfx.h>
38 #include <hal/nrf_adc.h>
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 /**
45 * @defgroup nrfx_adc ADC driver
46 * @{
47 * @ingroup nrf_adc
48 * @brief Analog-to-Digital Converter (ADC) peripheral driver.
49 */
50
51 /** @brief Driver event types. */
52 typedef enum
53 {
54 NRFX_ADC_EVT_DONE, ///< Event generated when the buffer is filled with samples.
55 NRFX_ADC_EVT_SAMPLE, ///< Event generated when the requested channel is sampled.
56 } nrfx_adc_evt_type_t;
57
58 /** @brief ADC driver DONE event structure. */
59 typedef struct
60 {
61 nrf_adc_value_t * p_buffer; ///< Pointer to the buffer with converted samples.
62 uint16_t size; ///< Number of samples in the buffer.
63 } nrfx_adc_done_evt_t;
64
65 /** @brief SAMPLE event structure. */
66 typedef struct
67 {
68 nrf_adc_value_t sample; ///< Converted sample.
69 } nrfx_adc_sample_evt_t;
70
71 /** @brief ADC driver event. */
72 typedef struct
73 {
74 nrfx_adc_evt_type_t type; ///< Event type.
75 union
76 {
77 nrfx_adc_done_evt_t done; ///< Data for DONE event.
78 nrfx_adc_sample_evt_t sample; ///< Data for SAMPLE event.
79 } data; ///< Union to store event data.
80 } nrfx_adc_evt_t;
81
82 /**
83 * @brief ADC channel default configuration.
84 *
85 * This configuration sets up ADC channel with the following options:
86 * - 10 bits resolution
87 * - full scale input
88 * - reference voltage: 1.2 V
89 * - external reference input disabled
90 *
91 * @param[in] analog_input Analog input.
92 */
93 #define NRFX_ADC_DEFAULT_CHANNEL(analog_input) \
94 { \
95 NULL, \
96 { \
97 .resolution = NRF_ADC_CONFIG_RES_10BIT, \
98 .scaling = NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE, \
99 .reference = NRF_ADC_CONFIG_REF_VBG, \
100 .input = (nrf_adc_config_input_t)analog_input, \
101 .extref = NRF_ADC_CONFIG_EXTREFSEL_NONE \
102 } \
103 }
104
105 /** @brief Forward declaration of the nrfx_adc_channel_t type. */
106 typedef struct nrfx_adc_channel_s nrfx_adc_channel_t;
107
108 /**
109 * @brief ADC channel.
110 *
111 * This structure is defined by the user and used by the driver. Therefore, it should
112 * not be defined on the stack as a local variable.
113 */
114 struct nrfx_adc_channel_s
115 {
116 nrfx_adc_channel_t * p_next; ///< Pointer to the next enabled channel (for internal use).
117 nrf_adc_config_t config; ///< ADC configuration for the current channel.
118 };
119
120 /** @brief ADC configuration. */
121 typedef struct
122 {
123 uint8_t interrupt_priority; ///< Priority of ADC interrupt.
124 } nrfx_adc_config_t;
125
126 /** @brief ADC default configuration. */
127 #define NRFX_ADC_DEFAULT_CONFIG \
128 { \
129 .interrupt_priority = NRFX_ADC_DEFAULT_CONFIG_IRQ_PRIORITY \
130 }
131
132 /**
133 * @brief User event handler prototype.
134 *
135 * This function is called when the requested number of samples has been processed.
136 *
137 * @param p_event Event.
138 */
139 typedef void (*nrfx_adc_event_handler_t)(nrfx_adc_evt_t const * p_event);
140
141 /**
142 * @brief Function for initializing the ADC.
143 *
144 * If a valid event handler is provided, the driver is initialized in non-blocking mode.
145 * If event_handler is NULL, the driver works in blocking mode.
146 *
147 * @param[in] p_config Pointer to the structure with the initial configuration.
148 * @param[in] event_handler Event handler provided by the user.
149 *
150 * @retval NRFX_SUCCESS Initialization was successful.
151 * @retval NRFX_ERROR_ALREADY The driver is already initialized.
152 * @retval NRFX_ERROR_INVALID_STATE The driver is already initialized.
153 * Deprecated - use @ref NRFX_ERROR_ALREADY instead.
154 */
155 nrfx_err_t nrfx_adc_init(nrfx_adc_config_t const * p_config,
156 nrfx_adc_event_handler_t event_handler);
157
158 /**
159 * @brief Function for uninitializing the ADC.
160 *
161 * This function stops all ongoing conversions and disables all channels.
162 */
163 void nrfx_adc_uninit(void);
164
165 /**
166 * @brief Function for checking if the ADC driver is initialized.
167 *
168 * @retval true Driver is already initialized.
169 * @retval false Driver is not initialized.
170 */
171 bool nrfx_adc_init_check(void);
172
173 /**
174 * @brief Function for enabling an ADC channel.
175 *
176 * This function configures and enables the channel. When @ref nrfx_adc_buffer_convert is
177 * called, all channels that have been enabled with this function are sampled.
178 *
179 * This function can be called only when there is no conversion in progress
180 * (the ADC is not busy).
181 *
182 * @note The channel instance variable @p p_channel is used by the driver as an item
183 * in a list. Therefore, it cannot be an automatic variable that is located on the stack.
184 *
185 * @param[in] p_channel Pointer to the channel instance.
186 */
187 void nrfx_adc_channel_enable(nrfx_adc_channel_t * const p_channel);
188
189 /**
190 * @brief Function for disabling an ADC channel.
191 *
192 * This function can be called only when there is no conversion in progress
193 * (the ADC is not busy).
194 *
195 * @param p_channel Pointer to the channel instance.
196 */
197 void nrfx_adc_channel_disable(nrfx_adc_channel_t * const p_channel);
198
199 /**
200 * @brief Function for disabling all ADC channels.
201 *
202 * This function can be called only when there is no conversion in progress
203 * (the ADC is not busy).
204 */
205 void nrfx_adc_all_channels_disable(void);
206
207 /**
208 * @brief Function for starting ADC sampling.
209 *
210 * This function triggers single ADC sampling. If more than one channel is enabled, the driver
211 * emulates scanning and all channels are sampled in the order they were enabled.
212 */
213 void nrfx_adc_sample(void);
214
215 /**
216 * @brief Function for executing a single ADC conversion.
217 *
218 * This function selects the desired input and starts a single conversion. If a valid pointer
219 * is provided for the result, the function blocks until the conversion is completed. Otherwise, the
220 * function returns when the conversion is started, and the result is provided in an event (driver
221 * must be initialized in non-blocking mode, otherwise an assertion will fail). The function will
222 * fail if ADC is busy. The channel does not need to be enabled to perform a single conversion.
223 *
224 * @param[in] p_channel Channel.
225 * @param[out] p_value Pointer to the location where the result is to be placed. Unless NULL is
226 * provided, the function is blocking.
227 *
228 * @retval NRFX_SUCCESS Conversion was successful.
229 * @retval NRFX_ERROR_BUSY The ADC driver is busy.
230 */
231 nrfx_err_t nrfx_adc_sample_convert(nrfx_adc_channel_t const * p_channel,
232 nrf_adc_value_t * p_value);
233
234 /**
235 * @brief Function for converting data to the buffer.
236 *
237 * If the driver is initialized in non-blocking mode, this function returns when the first
238 * conversion is set up. When the buffer is filled, the application is notified by the event
239 * handler. If the driver is initialized in blocking mode, the function returns when the buffer is
240 * filled.
241 *
242 * Conversion is done on all enabled channels, but it is not triggered by this
243 * function. This function will prepare the ADC for sampling and then
244 * wait for the SAMPLE task. Sampling can be triggered manually by the @ref
245 * nrfx_adc_sample function or by PPI using the @ref NRF_ADC_TASK_START task.
246 *
247 * @note If more than one channel is enabled, the function emulates scanning, and
248 * a single START task will trigger conversion on all enabled channels. For example:
249 * If 3 channels are enabled and the user requests 6 samples, the completion event
250 * handler will be called after 2 START tasks.
251 *
252 * @note The application must adjust the sampling frequency. The maximum frequency
253 * depends on the sampling timer and the maximum latency of the ADC interrupt. If
254 * an interrupt is not handled before the next sampling is triggered, the sample
255 * will be lost.
256 *
257 * @param[in] buffer Result buffer.
258 * @param[in] size Buffer size in samples.
259 *
260 * @retval NRFX_SUCCESS Conversion was successful.
261 * @retval NRFX_ERROR_BUSY The driver is busy.
262 */
263 nrfx_err_t nrfx_adc_buffer_convert(nrf_adc_value_t * buffer, uint16_t size);
264
265 /**
266 * @brief Function for retrieving the ADC state.
267 *
268 * @retval true The ADC is busy.
269 * @retval false The ADC is ready.
270 */
271 bool nrfx_adc_is_busy(void);
272
273 /**
274 * @brief Function for getting the address of the ADC START task.
275 *
276 * This function is used to get the address of the START task, which can be used to trigger ADC
277 * conversion.
278 *
279 * @return Start task address.
280 */
281 NRFX_STATIC_INLINE uint32_t nrfx_adc_start_task_get(void);
282
283 #ifndef NRFX_DECLARE_ONLY
nrfx_adc_start_task_get(void)284 NRFX_STATIC_INLINE uint32_t nrfx_adc_start_task_get(void)
285 {
286 return nrf_adc_task_address_get(NRF_ADC, NRF_ADC_TASK_START);
287 }
288 #endif // NRFX_DECLARE_ONLY
289
290 /** @} */
291
292
293 void nrfx_adc_irq_handler(void);
294
295
296 #ifdef __cplusplus
297 }
298 #endif
299
300 #endif // NRFX_ADC_H__
301