xref: /nrf52832-nimble/nordic/nrfx/hal/nrf_saadc.h (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
1 /*
2  * Copyright (c) 2015 - 2018, 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 NRF_SAADC_H_
33 #define NRF_SAADC_H_
34 
35 #include <nrfx.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /**
42  * @defgroup nrf_saadc_hal SAADC HAL
43  * @{
44  * @ingroup nrf_saadc
45  * @brief   Hardware access layer for managing the SAADC peripheral.
46  */
47 
48 #define NRF_SAADC_CHANNEL_COUNT 8
49 
50 /**
51  * @brief Resolution of the analog-to-digital converter.
52  */
53 typedef enum
54 {
55     NRF_SAADC_RESOLUTION_8BIT  = SAADC_RESOLUTION_VAL_8bit,  ///< 8 bit resolution.
56     NRF_SAADC_RESOLUTION_10BIT = SAADC_RESOLUTION_VAL_10bit, ///< 10 bit resolution.
57     NRF_SAADC_RESOLUTION_12BIT = SAADC_RESOLUTION_VAL_12bit, ///< 12 bit resolution.
58     NRF_SAADC_RESOLUTION_14BIT = SAADC_RESOLUTION_VAL_14bit  ///< 14 bit resolution.
59 } nrf_saadc_resolution_t;
60 
61 
62 /**
63  * @brief Input selection for the analog-to-digital converter.
64  */
65 typedef enum
66 {
67     NRF_SAADC_INPUT_DISABLED = SAADC_CH_PSELP_PSELP_NC,           ///< Not connected.
68     NRF_SAADC_INPUT_AIN0     = SAADC_CH_PSELP_PSELP_AnalogInput0, ///< Analog input 0 (AIN0).
69     NRF_SAADC_INPUT_AIN1     = SAADC_CH_PSELP_PSELP_AnalogInput1, ///< Analog input 1 (AIN1).
70     NRF_SAADC_INPUT_AIN2     = SAADC_CH_PSELP_PSELP_AnalogInput2, ///< Analog input 2 (AIN2).
71     NRF_SAADC_INPUT_AIN3     = SAADC_CH_PSELP_PSELP_AnalogInput3, ///< Analog input 3 (AIN3).
72     NRF_SAADC_INPUT_AIN4     = SAADC_CH_PSELP_PSELP_AnalogInput4, ///< Analog input 4 (AIN4).
73     NRF_SAADC_INPUT_AIN5     = SAADC_CH_PSELP_PSELP_AnalogInput5, ///< Analog input 5 (AIN5).
74     NRF_SAADC_INPUT_AIN6     = SAADC_CH_PSELP_PSELP_AnalogInput6, ///< Analog input 6 (AIN6).
75     NRF_SAADC_INPUT_AIN7     = SAADC_CH_PSELP_PSELP_AnalogInput7, ///< Analog input 7 (AIN7).
76     NRF_SAADC_INPUT_VDD      = SAADC_CH_PSELP_PSELP_VDD           ///< VDD as input.
77 } nrf_saadc_input_t;
78 
79 
80 /**
81  * @brief Analog-to-digital converter oversampling mode.
82  */
83 typedef enum
84 {
85     NRF_SAADC_OVERSAMPLE_DISABLED = SAADC_OVERSAMPLE_OVERSAMPLE_Bypass,   ///< No oversampling.
86     NRF_SAADC_OVERSAMPLE_2X       = SAADC_OVERSAMPLE_OVERSAMPLE_Over2x,   ///< Oversample 2x.
87     NRF_SAADC_OVERSAMPLE_4X       = SAADC_OVERSAMPLE_OVERSAMPLE_Over4x,   ///< Oversample 4x.
88     NRF_SAADC_OVERSAMPLE_8X       = SAADC_OVERSAMPLE_OVERSAMPLE_Over8x,   ///< Oversample 8x.
89     NRF_SAADC_OVERSAMPLE_16X      = SAADC_OVERSAMPLE_OVERSAMPLE_Over16x,  ///< Oversample 16x.
90     NRF_SAADC_OVERSAMPLE_32X      = SAADC_OVERSAMPLE_OVERSAMPLE_Over32x,  ///< Oversample 32x.
91     NRF_SAADC_OVERSAMPLE_64X      = SAADC_OVERSAMPLE_OVERSAMPLE_Over64x,  ///< Oversample 64x.
92     NRF_SAADC_OVERSAMPLE_128X     = SAADC_OVERSAMPLE_OVERSAMPLE_Over128x, ///< Oversample 128x.
93     NRF_SAADC_OVERSAMPLE_256X     = SAADC_OVERSAMPLE_OVERSAMPLE_Over256x  ///< Oversample 256x.
94 } nrf_saadc_oversample_t;
95 
96 
97 /**
98  * @brief Analog-to-digital converter channel resistor control.
99  */
100 typedef enum
101 {
102     NRF_SAADC_RESISTOR_DISABLED = SAADC_CH_CONFIG_RESP_Bypass,   ///< Bypass resistor ladder.
103     NRF_SAADC_RESISTOR_PULLDOWN = SAADC_CH_CONFIG_RESP_Pulldown, ///< Pull-down to GND.
104     NRF_SAADC_RESISTOR_PULLUP   = SAADC_CH_CONFIG_RESP_Pullup,   ///< Pull-up to VDD.
105     NRF_SAADC_RESISTOR_VDD1_2   = SAADC_CH_CONFIG_RESP_VDD1_2    ///< Set input at VDD/2.
106 } nrf_saadc_resistor_t;
107 
108 
109 /**
110  * @brief Gain factor of the analog-to-digital converter input.
111  */
112 typedef enum
113 {
114     NRF_SAADC_GAIN1_6 = SAADC_CH_CONFIG_GAIN_Gain1_6, ///< Gain factor 1/6.
115     NRF_SAADC_GAIN1_5 = SAADC_CH_CONFIG_GAIN_Gain1_5, ///< Gain factor 1/5.
116     NRF_SAADC_GAIN1_4 = SAADC_CH_CONFIG_GAIN_Gain1_4, ///< Gain factor 1/4.
117     NRF_SAADC_GAIN1_3 = SAADC_CH_CONFIG_GAIN_Gain1_3, ///< Gain factor 1/3.
118     NRF_SAADC_GAIN1_2 = SAADC_CH_CONFIG_GAIN_Gain1_2, ///< Gain factor 1/2.
119     NRF_SAADC_GAIN1   = SAADC_CH_CONFIG_GAIN_Gain1,   ///< Gain factor 1.
120     NRF_SAADC_GAIN2   = SAADC_CH_CONFIG_GAIN_Gain2,   ///< Gain factor 2.
121     NRF_SAADC_GAIN4   = SAADC_CH_CONFIG_GAIN_Gain4,   ///< Gain factor 4.
122 } nrf_saadc_gain_t;
123 
124 
125 /**
126  * @brief Reference selection for the analog-to-digital converter.
127  */
128 typedef enum
129 {
130     NRF_SAADC_REFERENCE_INTERNAL = SAADC_CH_CONFIG_REFSEL_Internal, ///< Internal reference (0.6 V).
131     NRF_SAADC_REFERENCE_VDD4     = SAADC_CH_CONFIG_REFSEL_VDD1_4    ///< VDD/4 as reference.
132 } nrf_saadc_reference_t;
133 
134 
135 /**
136  * @brief Analog-to-digital converter acquisition time.
137  */
138 typedef enum
139 {
140     NRF_SAADC_ACQTIME_3US  = SAADC_CH_CONFIG_TACQ_3us,  ///< 3 us.
141     NRF_SAADC_ACQTIME_5US  = SAADC_CH_CONFIG_TACQ_5us,  ///< 5 us.
142     NRF_SAADC_ACQTIME_10US = SAADC_CH_CONFIG_TACQ_10us, ///< 10 us.
143     NRF_SAADC_ACQTIME_15US = SAADC_CH_CONFIG_TACQ_15us, ///< 15 us.
144     NRF_SAADC_ACQTIME_20US = SAADC_CH_CONFIG_TACQ_20us, ///< 20 us.
145     NRF_SAADC_ACQTIME_40US = SAADC_CH_CONFIG_TACQ_40us  ///< 40 us.
146 } nrf_saadc_acqtime_t;
147 
148 
149 /**
150  * @brief Analog-to-digital converter channel mode.
151  */
152 typedef enum
153 {
154     NRF_SAADC_MODE_SINGLE_ENDED = SAADC_CH_CONFIG_MODE_SE,  ///< Single ended, PSELN will be ignored, negative input to ADC shorted to GND.
155     NRF_SAADC_MODE_DIFFERENTIAL = SAADC_CH_CONFIG_MODE_Diff ///< Differential mode.
156 } nrf_saadc_mode_t;
157 
158 
159 /**
160  * @brief Analog-to-digital converter channel burst mode.
161  */
162 typedef enum
163 {
164     NRF_SAADC_BURST_DISABLED = SAADC_CH_CONFIG_BURST_Disabled, ///< Burst mode is disabled (normal operation).
165     NRF_SAADC_BURST_ENABLED  = SAADC_CH_CONFIG_BURST_Enabled   ///< Burst mode is enabled. SAADC takes 2^OVERSAMPLE number of samples as fast as it can, and sends the average to Data RAM.
166 } nrf_saadc_burst_t;
167 
168 
169 /**
170  * @brief Analog-to-digital converter tasks.
171  */
172 typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
173 {
174     NRF_SAADC_TASK_START           = offsetof(NRF_SAADC_Type, TASKS_START),           ///< Start the ADC and prepare the result buffer in RAM.
175     NRF_SAADC_TASK_SAMPLE          = offsetof(NRF_SAADC_Type, TASKS_SAMPLE),          ///< Take one ADC sample. If scan is enabled, all channels are sampled.
176     NRF_SAADC_TASK_STOP            = offsetof(NRF_SAADC_Type, TASKS_STOP),            ///< Stop the ADC and terminate any on-going conversion.
177     NRF_SAADC_TASK_CALIBRATEOFFSET = offsetof(NRF_SAADC_Type, TASKS_CALIBRATEOFFSET), ///< Starts offset auto-calibration.
178 } nrf_saadc_task_t;
179 
180 
181 /**
182  * @brief Analog-to-digital converter events.
183  */
184 typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
185 {
186     NRF_SAADC_EVENT_STARTED       = offsetof(NRF_SAADC_Type, EVENTS_STARTED),       ///< The ADC has started.
187     NRF_SAADC_EVENT_END           = offsetof(NRF_SAADC_Type, EVENTS_END),           ///< The ADC has filled up the result buffer.
188     NRF_SAADC_EVENT_DONE          = offsetof(NRF_SAADC_Type, EVENTS_DONE),          ///< A conversion task has been completed.
189     NRF_SAADC_EVENT_RESULTDONE    = offsetof(NRF_SAADC_Type, EVENTS_RESULTDONE),    ///< A result is ready to get transferred to RAM.
190     NRF_SAADC_EVENT_CALIBRATEDONE = offsetof(NRF_SAADC_Type, EVENTS_CALIBRATEDONE), ///< Calibration is complete.
191     NRF_SAADC_EVENT_STOPPED       = offsetof(NRF_SAADC_Type, EVENTS_STOPPED),       ///< The ADC has stopped.
192     NRF_SAADC_EVENT_CH0_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[0].LIMITH),  ///< Last result is equal or above CH[0].LIMIT.HIGH.
193     NRF_SAADC_EVENT_CH0_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[0].LIMITL),  ///< Last result is equal or below CH[0].LIMIT.LOW.
194     NRF_SAADC_EVENT_CH1_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[1].LIMITH),  ///< Last result is equal or above CH[1].LIMIT.HIGH.
195     NRF_SAADC_EVENT_CH1_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[1].LIMITL),  ///< Last result is equal or below CH[1].LIMIT.LOW.
196     NRF_SAADC_EVENT_CH2_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[2].LIMITH),  ///< Last result is equal or above CH[2].LIMIT.HIGH.
197     NRF_SAADC_EVENT_CH2_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[2].LIMITL),  ///< Last result is equal or below CH[2].LIMIT.LOW.
198     NRF_SAADC_EVENT_CH3_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[3].LIMITH),  ///< Last result is equal or above CH[3].LIMIT.HIGH.
199     NRF_SAADC_EVENT_CH3_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[3].LIMITL),  ///< Last result is equal or below CH[3].LIMIT.LOW.
200     NRF_SAADC_EVENT_CH4_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[4].LIMITH),  ///< Last result is equal or above CH[4].LIMIT.HIGH.
201     NRF_SAADC_EVENT_CH4_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[4].LIMITL),  ///< Last result is equal or below CH[4].LIMIT.LOW.
202     NRF_SAADC_EVENT_CH5_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[5].LIMITH),  ///< Last result is equal or above CH[5].LIMIT.HIGH.
203     NRF_SAADC_EVENT_CH5_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[5].LIMITL),  ///< Last result is equal or below CH[5].LIMIT.LOW.
204     NRF_SAADC_EVENT_CH6_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[6].LIMITH),  ///< Last result is equal or above CH[6].LIMIT.HIGH.
205     NRF_SAADC_EVENT_CH6_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[6].LIMITL),  ///< Last result is equal or below CH[6].LIMIT.LOW.
206     NRF_SAADC_EVENT_CH7_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[7].LIMITH),  ///< Last result is equal or above CH[7].LIMIT.HIGH.
207     NRF_SAADC_EVENT_CH7_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[7].LIMITL)   ///< Last result is equal or below CH[7].LIMIT.LOW.
208 } nrf_saadc_event_t;
209 
210 
211 /**
212  * @brief Analog-to-digital converter interrupt masks.
213  */
214 typedef enum
215 {
216     NRF_SAADC_INT_STARTED       = SAADC_INTENSET_STARTED_Msk,       ///< Interrupt on EVENTS_STARTED event.
217     NRF_SAADC_INT_END           = SAADC_INTENSET_END_Msk,           ///< Interrupt on EVENTS_END event.
218     NRF_SAADC_INT_DONE          = SAADC_INTENSET_DONE_Msk,          ///< Interrupt on EVENTS_DONE event.
219     NRF_SAADC_INT_RESULTDONE    = SAADC_INTENSET_RESULTDONE_Msk,    ///< Interrupt on EVENTS_RESULTDONE event.
220     NRF_SAADC_INT_CALIBRATEDONE = SAADC_INTENSET_CALIBRATEDONE_Msk, ///< Interrupt on EVENTS_CALIBRATEDONE event.
221     NRF_SAADC_INT_STOPPED       = SAADC_INTENSET_STOPPED_Msk,       ///< Interrupt on EVENTS_STOPPED event.
222     NRF_SAADC_INT_CH0LIMITH     = SAADC_INTENSET_CH0LIMITH_Msk,     ///< Interrupt on EVENTS_CH[0].LIMITH event.
223     NRF_SAADC_INT_CH0LIMITL     = SAADC_INTENSET_CH0LIMITL_Msk,     ///< Interrupt on EVENTS_CH[0].LIMITL event.
224     NRF_SAADC_INT_CH1LIMITH     = SAADC_INTENSET_CH1LIMITH_Msk,     ///< Interrupt on EVENTS_CH[1].LIMITH event.
225     NRF_SAADC_INT_CH1LIMITL     = SAADC_INTENSET_CH1LIMITL_Msk,     ///< Interrupt on EVENTS_CH[1].LIMITL event.
226     NRF_SAADC_INT_CH2LIMITH     = SAADC_INTENSET_CH2LIMITH_Msk,     ///< Interrupt on EVENTS_CH[2].LIMITH event.
227     NRF_SAADC_INT_CH2LIMITL     = SAADC_INTENSET_CH2LIMITL_Msk,     ///< Interrupt on EVENTS_CH[2].LIMITL event.
228     NRF_SAADC_INT_CH3LIMITH     = SAADC_INTENSET_CH3LIMITH_Msk,     ///< Interrupt on EVENTS_CH[3].LIMITH event.
229     NRF_SAADC_INT_CH3LIMITL     = SAADC_INTENSET_CH3LIMITL_Msk,     ///< Interrupt on EVENTS_CH[3].LIMITL event.
230     NRF_SAADC_INT_CH4LIMITH     = SAADC_INTENSET_CH4LIMITH_Msk,     ///< Interrupt on EVENTS_CH[4].LIMITH event.
231     NRF_SAADC_INT_CH4LIMITL     = SAADC_INTENSET_CH4LIMITL_Msk,     ///< Interrupt on EVENTS_CH[4].LIMITL event.
232     NRF_SAADC_INT_CH5LIMITH     = SAADC_INTENSET_CH5LIMITH_Msk,     ///< Interrupt on EVENTS_CH[5].LIMITH event.
233     NRF_SAADC_INT_CH5LIMITL     = SAADC_INTENSET_CH5LIMITL_Msk,     ///< Interrupt on EVENTS_CH[5].LIMITL event.
234     NRF_SAADC_INT_CH6LIMITH     = SAADC_INTENSET_CH6LIMITH_Msk,     ///< Interrupt on EVENTS_CH[6].LIMITH event.
235     NRF_SAADC_INT_CH6LIMITL     = SAADC_INTENSET_CH6LIMITL_Msk,     ///< Interrupt on EVENTS_CH[6].LIMITL event.
236     NRF_SAADC_INT_CH7LIMITH     = SAADC_INTENSET_CH7LIMITH_Msk,     ///< Interrupt on EVENTS_CH[7].LIMITH event.
237     NRF_SAADC_INT_CH7LIMITL     = SAADC_INTENSET_CH7LIMITL_Msk,     ///< Interrupt on EVENTS_CH[7].LIMITL event.
238     NRF_SAADC_INT_ALL           = 0x7FFFFFFFUL                      ///< Mask of all interrupts.
239 } nrf_saadc_int_mask_t;
240 
241 
242 /**
243  * @brief Analog-to-digital converter value limit type.
244  */
245 typedef enum
246 {
247     NRF_SAADC_LIMIT_LOW  = 0,
248     NRF_SAADC_LIMIT_HIGH = 1
249 } nrf_saadc_limit_t;
250 
251 
252 typedef int16_t nrf_saadc_value_t;  ///< Type of a single ADC conversion result.
253 
254 
255 /**
256  * @brief Analog-to-digital converter configuration structure.
257  */
258 typedef struct
259 {
260     nrf_saadc_resolution_t resolution;
261     nrf_saadc_oversample_t oversample;
262     nrf_saadc_value_t *    buffer;
263     uint32_t               buffer_size;
264 } nrf_saadc_config_t;
265 
266 
267 /**
268  * @brief Analog-to-digital converter channel configuration structure.
269  */
270 typedef struct
271 {
272     nrf_saadc_resistor_t  resistor_p;
273     nrf_saadc_resistor_t  resistor_n;
274     nrf_saadc_gain_t      gain;
275     nrf_saadc_reference_t reference;
276     nrf_saadc_acqtime_t   acq_time;
277     nrf_saadc_mode_t      mode;
278     nrf_saadc_burst_t     burst;
279     nrf_saadc_input_t     pin_p;
280     nrf_saadc_input_t     pin_n;
281 } nrf_saadc_channel_config_t;
282 
283 /**
284  * @brief Function for triggering a specific SAADC task.
285  *
286  * @param[in] saadc_task SAADC task.
287  */
288 __STATIC_INLINE void nrf_saadc_task_trigger(nrf_saadc_task_t saadc_task);
289 
290 /**
291  * @brief Function for getting the address of a specific SAADC task register.
292  *
293  * @param[in] saadc_task SAADC task.
294  *
295  * @return Address of the specified SAADC task.
296  */
297 __STATIC_INLINE uint32_t nrf_saadc_task_address_get(nrf_saadc_task_t saadc_task);
298 
299 /**
300  * @brief Function for getting the state of a specific SAADC event.
301  *
302  * @param[in] saadc_event SAADC event.
303  *
304  * @return State of the specified SAADC event.
305  */
306 __STATIC_INLINE bool nrf_saadc_event_check(nrf_saadc_event_t saadc_event);
307 
308 /**
309  * @brief Function for clearing the specific SAADC event.
310  *
311  * @param[in] saadc_event SAADC event.
312  */
313 __STATIC_INLINE void nrf_saadc_event_clear(nrf_saadc_event_t saadc_event);
314 
315 /**
316  * @brief Function for getting the address of a specific SAADC event register.
317  *
318  * @param[in] saadc_event SAADC event.
319  *
320  * @return Address of the specified SAADC event.
321  */
322 __STATIC_INLINE uint32_t  nrf_saadc_event_address_get(nrf_saadc_event_t saadc_event);
323 
324 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
325 /**
326  * @brief Function for setting the subscribe configuration for a given
327  *        SAADC task.
328  *
329  * @param[in] task    Task for which to set the configuration.
330  * @param[in] channel Channel through which to subscribe events.
331  */
332 __STATIC_INLINE void nrf_saadc_subscribe_set(nrf_saadc_task_t task,
333                                              uint8_t          channel);
334 
335 /**
336  * @brief Function for clearing the subscribe configuration for a given
337  *        SAADC task.
338  *
339  * @param[in] task Task for which to clear the configuration.
340  */
341 __STATIC_INLINE void nrf_saadc_subscribe_clear(nrf_saadc_task_t task);
342 
343 /**
344  * @brief Function for setting the publish configuration for a given
345  *        SAADC event.
346  *
347  * @param[in] event   Event for which to set the configuration.
348  * @param[in] channel Channel through which to publish the event.
349  */
350 __STATIC_INLINE void nrf_saadc_publish_set(nrf_saadc_event_t event,
351                                            uint8_t           channel);
352 
353 /**
354  * @brief Function for clearing the publish configuration for a given
355  *        SAADC event.
356  *
357  * @param[in] event Event for which to clear the configuration.
358  */
359 __STATIC_INLINE void nrf_saadc_publish_clear(nrf_saadc_event_t event);
360 #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
361 
362 /**
363  * @brief Function for getting the address of a specific SAADC limit event register.
364  *
365  * @param[in] channel Channel number.
366  * @param[in] limit_type Low limit or high limit.
367  *
368  * @return Address of the specified SAADC limit event.
369  */
370 __STATIC_INLINE volatile uint32_t * nrf_saadc_event_limit_address_get(uint8_t channel, nrf_saadc_limit_t limit_type);
371 
372 /**
373  * @brief Function for getting the SAADC channel monitoring limit events.
374  *
375  * @param[in] channel    Channel number.
376  * @param[in] limit_type Low limit or high limit.
377  */
378 __STATIC_INLINE nrf_saadc_event_t nrf_saadc_event_limit_get(uint8_t channel, nrf_saadc_limit_t limit_type);
379 
380 /**
381  * @brief Function for configuring the input pins for a specific SAADC channel.
382  *
383  * @param[in] channel Channel number.
384  * @param[in] pselp   Positive input.
385  * @param[in] pseln   Negative input. Set to NRF_SAADC_INPUT_DISABLED in single ended mode.
386  */
387 __STATIC_INLINE void nrf_saadc_channel_input_set(uint8_t channel,
388                                                  nrf_saadc_input_t pselp,
389                                                  nrf_saadc_input_t pseln);
390 
391 /**
392  * @brief Function for configuring the positive input pin for a specific SAADC channel.
393  *
394  * @param[in] channel Channel number.
395  * @param[in] pselp   Positive input.
396  */
397 __STATIC_INLINE void nrf_saadc_channel_pos_input_set(uint8_t channel,
398                                                      nrf_saadc_input_t pselp);
399 
400 /**
401  * @brief Function for setting the SAADC channel monitoring limits.
402  *
403  * @param[in] channel Channel number.
404  * @param[in] low     Low limit.
405  * @param[in] high    High limit.
406  */
407 __STATIC_INLINE void nrf_saadc_channel_limits_set(uint8_t channel, int16_t low, int16_t high);
408 
409 /**
410  * @brief Function for enabling specified SAADC interrupts.
411  *
412  * @param[in] saadc_int_mask Interrupt(s) to enable.
413  */
414 __STATIC_INLINE void nrf_saadc_int_enable(uint32_t saadc_int_mask);
415 
416 /**
417  * @brief Function for retrieving the state of specified SAADC interrupts.
418  *
419  * @param[in] saadc_int_mask Interrupt(s) to check.
420  *
421  * @retval true  If all specified interrupts are enabled.
422  * @retval false If at least one of the given interrupts is not enabled.
423  */
424 __STATIC_INLINE bool nrf_saadc_int_enable_check(uint32_t saadc_int_mask);
425 
426 /**
427  * @brief Function for disabling specified interrupts.
428  *
429  * @param saadc_int_mask Interrupt(s) to disable.
430  */
431 __STATIC_INLINE void nrf_saadc_int_disable(uint32_t saadc_int_mask);
432 
433 /**
434  * @brief Function for generating masks for SAADC channel limit interrupts.
435  *
436  * @param[in] channel    SAADC channel number.
437  * @param[in] limit_type Limit type.
438  *
439  * @returns Interrupt mask.
440  */
441 __STATIC_INLINE uint32_t nrf_saadc_limit_int_get(uint8_t channel, nrf_saadc_limit_t limit_type);
442 
443 /**
444  * @brief Function for checking whether the SAADC is busy.
445  *
446  * This function checks whether the analog-to-digital converter is busy with a conversion.
447  *
448  * @retval true  If the SAADC is busy.
449  * @retval false If the SAADC is not busy.
450  */
451 __STATIC_INLINE bool nrf_saadc_busy_check(void);
452 
453 /**
454  * @brief Function for enabling the SAADC.
455  *
456  * The analog-to-digital converter must be enabled before use.
457  */
458 __STATIC_INLINE void nrf_saadc_enable(void);
459 
460 /**
461  * @brief Function for disabling the SAADC.
462  */
463 __STATIC_INLINE void nrf_saadc_disable(void);
464 
465 /**
466  * @brief Function for checking if the SAADC is enabled.
467  *
468  * @retval true  If the SAADC is enabled.
469  * @retval false If the SAADC is not enabled.
470  */
471 __STATIC_INLINE bool nrf_saadc_enable_check(void);
472 
473 /**
474  * @brief Function for initializing the SAADC result buffer.
475  *
476  * @param[in] p_buffer Pointer to the result buffer.
477  * @param[in] size     Size of the buffer (in 16-bit samples).
478  */
479 __STATIC_INLINE void nrf_saadc_buffer_init(nrf_saadc_value_t * p_buffer,
480                                            uint32_t            size);
481 
482 /**
483  * @brief Function for setting the SAADC result buffer pointer.
484  *
485  * @param[in] p_buffer Pointer to the result buffer.
486  */
487 __STATIC_INLINE void nrf_saadc_buffer_pointer_set(nrf_saadc_value_t * p_buffer);
488 
489 /**
490  * @brief Function for getting the SAADC result buffer pointer.
491  *
492  * @return Pointer to the result buffer.
493  */
494 __STATIC_INLINE nrf_saadc_value_t * nrf_saadc_buffer_pointer_get(void);
495 
496 /**
497  * @brief Function for getting the number of samples written to the result
498  *        buffer since the previous START task.
499  *
500  * @returns Number of 16-bit samples written to the buffer.
501  */
502 __STATIC_INLINE uint16_t nrf_saadc_amount_get(void);
503 
504 /**
505  * @brief Function for setting the SAADC sample resolution.
506  *
507  * @param[in] resolution Bit resolution.
508  */
509 __STATIC_INLINE void nrf_saadc_resolution_set(nrf_saadc_resolution_t resolution);
510 
511 /**
512  * @brief Function for configuring the oversampling feature.
513  *
514  * @param[in] oversample Oversampling mode.
515  */
516 __STATIC_INLINE void nrf_saadc_oversample_set(nrf_saadc_oversample_t oversample);
517 
518 /**
519  * @brief Function for getting the oversampling feature configuration.
520  *
521  * @return Oversampling configuration.
522  */
523 __STATIC_INLINE nrf_saadc_oversample_t nrf_saadc_oversample_get(void);
524 
525 /**
526  * @brief Function for initializing the SAADC channel.
527  *
528  * @param[in] channel Channel number.
529  * @param[in] config  Pointer to the channel configuration structure.
530  */
531 __STATIC_INLINE void nrf_saadc_channel_init(uint8_t                                  channel,
532                                             nrf_saadc_channel_config_t const * const config);
533 
534 /**
535  * @brief Function for configuring the burst mode for the specified channel.
536  *
537  * @param[in] channel Channel number.
538  * @param[in] burst   Burst mode setting.
539  */
540 __STATIC_INLINE void nrf_saadc_burst_set(uint8_t           channel,
541                                          nrf_saadc_burst_t burst);
542 
543 #ifndef SUPPRESS_INLINE_IMPLEMENTATION
544 
nrf_saadc_task_trigger(nrf_saadc_task_t saadc_task)545 __STATIC_INLINE void nrf_saadc_task_trigger(nrf_saadc_task_t saadc_task)
546 {
547     *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_task)) = 0x1UL;
548 }
549 
nrf_saadc_task_address_get(nrf_saadc_task_t saadc_task)550 __STATIC_INLINE uint32_t nrf_saadc_task_address_get(nrf_saadc_task_t saadc_task)
551 {
552     return (uint32_t)((uint8_t *)NRF_SAADC + (uint32_t)saadc_task);
553 }
554 
nrf_saadc_event_check(nrf_saadc_event_t saadc_event)555 __STATIC_INLINE bool nrf_saadc_event_check(nrf_saadc_event_t saadc_event)
556 {
557     return (bool)*(volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event);
558 }
559 
nrf_saadc_event_clear(nrf_saadc_event_t saadc_event)560 __STATIC_INLINE void nrf_saadc_event_clear(nrf_saadc_event_t saadc_event)
561 {
562     *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event)) = 0x0UL;
563 #if __CORTEX_M == 0x04
564     volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event));
565     (void)dummy;
566 #endif
567 }
568 
nrf_saadc_event_address_get(nrf_saadc_event_t saadc_event)569 __STATIC_INLINE uint32_t  nrf_saadc_event_address_get(nrf_saadc_event_t saadc_event)
570 {
571     return (uint32_t )((uint8_t *)NRF_SAADC + (uint32_t)saadc_event);
572 }
573 
574 #if defined(DPPI_PRESENT)
nrf_saadc_subscribe_set(nrf_saadc_task_t task,uint8_t channel)575 __STATIC_INLINE void nrf_saadc_subscribe_set(nrf_saadc_task_t task,
576                                              uint8_t          channel)
577 {
578     *((volatile uint32_t *) ((uint8_t *) NRF_SAADC + (uint32_t) task + 0x80uL)) =
579             ((uint32_t)channel | SAADC_SUBSCRIBE_START_EN_Msk);
580 }
581 
nrf_saadc_subscribe_clear(nrf_saadc_task_t task)582 __STATIC_INLINE void nrf_saadc_subscribe_clear(nrf_saadc_task_t task)
583 {
584     *((volatile uint32_t *) ((uint8_t *) NRF_SAADC + (uint32_t) task + 0x80uL)) = 0;
585 }
586 
nrf_saadc_publish_set(nrf_saadc_event_t event,uint8_t channel)587 __STATIC_INLINE void nrf_saadc_publish_set(nrf_saadc_event_t event,
588                                            uint8_t           channel)
589 {
590     *((volatile uint32_t *) ((uint8_t *) NRF_SAADC + (uint32_t) event + 0x80uL)) =
591             ((uint32_t)channel | SAADC_PUBLISH_STARTED_EN_Msk);
592 }
593 
nrf_saadc_publish_clear(nrf_saadc_event_t event)594 __STATIC_INLINE void nrf_saadc_publish_clear(nrf_saadc_event_t event)
595 {
596     *((volatile uint32_t *) ((uint8_t *) NRF_SAADC + (uint32_t) event + 0x80uL)) = 0;
597 }
598 #endif // defined(DPPI_PRESENT)
599 
nrf_saadc_event_limit_address_get(uint8_t channel,nrf_saadc_limit_t limit_type)600 __STATIC_INLINE volatile uint32_t * nrf_saadc_event_limit_address_get(uint8_t channel, nrf_saadc_limit_t limit_type)
601 {
602     NRFX_ASSERT(channel < NRF_SAADC_CHANNEL_COUNT);
603     if (limit_type == NRF_SAADC_LIMIT_HIGH)
604     {
605         return &NRF_SAADC->EVENTS_CH[channel].LIMITH;
606     }
607     else
608     {
609         return &NRF_SAADC->EVENTS_CH[channel].LIMITL;
610     }
611 }
612 
nrf_saadc_event_limit_get(uint8_t channel,nrf_saadc_limit_t limit_type)613 __STATIC_INLINE nrf_saadc_event_t nrf_saadc_event_limit_get(uint8_t channel, nrf_saadc_limit_t limit_type)
614 {
615     if (limit_type == NRF_SAADC_LIMIT_HIGH)
616     {
617         return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITH +
618                         (uint32_t) (NRF_SAADC_EVENT_CH1_LIMITH - NRF_SAADC_EVENT_CH0_LIMITH)
619                         * (uint32_t) channel );
620     }
621     else
622     {
623         return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITL +
624                         (uint32_t) (NRF_SAADC_EVENT_CH1_LIMITL - NRF_SAADC_EVENT_CH0_LIMITL)
625                         * (uint32_t) channel );
626     }
627 }
628 
nrf_saadc_channel_input_set(uint8_t channel,nrf_saadc_input_t pselp,nrf_saadc_input_t pseln)629 __STATIC_INLINE void nrf_saadc_channel_input_set(uint8_t channel,
630                                                  nrf_saadc_input_t pselp,
631                                                  nrf_saadc_input_t pseln)
632 {
633     NRF_SAADC->CH[channel].PSELN = pseln;
634     NRF_SAADC->CH[channel].PSELP = pselp;
635 }
636 
nrf_saadc_channel_pos_input_set(uint8_t channel,nrf_saadc_input_t pselp)637 __STATIC_INLINE void nrf_saadc_channel_pos_input_set(uint8_t channel,
638                                                      nrf_saadc_input_t pselp)
639 {
640     NRF_SAADC->CH[channel].PSELP = pselp;
641 }
642 
nrf_saadc_channel_limits_set(uint8_t channel,int16_t low,int16_t high)643 __STATIC_INLINE void nrf_saadc_channel_limits_set(uint8_t channel, int16_t low, int16_t high)
644 {
645     NRF_SAADC->CH[channel].LIMIT = (
646             (((uint32_t) low << SAADC_CH_LIMIT_LOW_Pos) & SAADC_CH_LIMIT_LOW_Msk)
647           | (((uint32_t) high << SAADC_CH_LIMIT_HIGH_Pos) & SAADC_CH_LIMIT_HIGH_Msk));
648 }
649 
nrf_saadc_int_enable(uint32_t saadc_int_mask)650 __STATIC_INLINE void nrf_saadc_int_enable(uint32_t saadc_int_mask)
651 {
652     NRF_SAADC->INTENSET = saadc_int_mask;
653 }
654 
nrf_saadc_int_enable_check(uint32_t saadc_int_mask)655 __STATIC_INLINE bool nrf_saadc_int_enable_check(uint32_t saadc_int_mask)
656 {
657     return (bool)(NRF_SAADC->INTENSET & saadc_int_mask);
658 }
659 
nrf_saadc_int_disable(uint32_t saadc_int_mask)660 __STATIC_INLINE void nrf_saadc_int_disable(uint32_t saadc_int_mask)
661 {
662     NRF_SAADC->INTENCLR = saadc_int_mask;
663 }
664 
nrf_saadc_limit_int_get(uint8_t channel,nrf_saadc_limit_t limit_type)665 __STATIC_INLINE uint32_t nrf_saadc_limit_int_get(uint8_t channel, nrf_saadc_limit_t limit_type)
666 {
667     NRFX_ASSERT(channel < NRF_SAADC_CHANNEL_COUNT);
668     uint32_t mask = (limit_type == NRF_SAADC_LIMIT_LOW) ? NRF_SAADC_INT_CH0LIMITL : NRF_SAADC_INT_CH0LIMITH;
669     return mask << (channel * 2);
670 }
671 
nrf_saadc_busy_check(void)672 __STATIC_INLINE bool nrf_saadc_busy_check(void)
673 {
674     //return ((NRF_SAADC->STATUS & SAADC_STATUS_STATUS_Msk) == SAADC_STATUS_STATUS_Msk);
675     //simplified for performance
676     return NRF_SAADC->STATUS;
677 }
678 
nrf_saadc_enable(void)679 __STATIC_INLINE void nrf_saadc_enable(void)
680 {
681     NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos);
682 }
683 
nrf_saadc_disable(void)684 __STATIC_INLINE void nrf_saadc_disable(void)
685 {
686     NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Disabled << SAADC_ENABLE_ENABLE_Pos);
687 }
688 
nrf_saadc_enable_check(void)689 __STATIC_INLINE bool nrf_saadc_enable_check(void)
690 {
691     //simplified for performance
692     return NRF_SAADC->ENABLE;
693 }
694 
nrf_saadc_buffer_init(nrf_saadc_value_t * p_buffer,uint32_t size)695 __STATIC_INLINE void nrf_saadc_buffer_init(nrf_saadc_value_t * p_buffer,
696                                            uint32_t            size)
697 {
698     NRF_SAADC->RESULT.PTR = (uint32_t)p_buffer;
699     NRF_SAADC->RESULT.MAXCNT = size;
700 }
701 
nrf_saadc_buffer_pointer_set(nrf_saadc_value_t * p_buffer)702 __STATIC_INLINE void nrf_saadc_buffer_pointer_set(nrf_saadc_value_t * p_buffer)
703 {
704     NRF_SAADC->RESULT.PTR = (uint32_t)p_buffer;
705 }
706 
nrf_saadc_buffer_pointer_get(void)707 __STATIC_INLINE nrf_saadc_value_t * nrf_saadc_buffer_pointer_get(void)
708 {
709     return (nrf_saadc_value_t *)NRF_SAADC->RESULT.PTR;
710 }
711 
nrf_saadc_amount_get(void)712 __STATIC_INLINE uint16_t nrf_saadc_amount_get(void)
713 {
714     return NRF_SAADC->RESULT.AMOUNT;
715 }
716 
nrf_saadc_resolution_set(nrf_saadc_resolution_t resolution)717 __STATIC_INLINE void nrf_saadc_resolution_set(nrf_saadc_resolution_t resolution)
718 {
719     NRF_SAADC->RESOLUTION = resolution;
720 }
721 
nrf_saadc_oversample_set(nrf_saadc_oversample_t oversample)722 __STATIC_INLINE void nrf_saadc_oversample_set(nrf_saadc_oversample_t oversample)
723 {
724     NRF_SAADC->OVERSAMPLE = oversample;
725 }
726 
nrf_saadc_oversample_get(void)727 __STATIC_INLINE nrf_saadc_oversample_t nrf_saadc_oversample_get(void)
728 {
729     return (nrf_saadc_oversample_t)NRF_SAADC->OVERSAMPLE;
730 }
731 
nrf_saadc_channel_init(uint8_t channel,nrf_saadc_channel_config_t const * const config)732 __STATIC_INLINE void nrf_saadc_channel_init(uint8_t                                  channel,
733                                             nrf_saadc_channel_config_t const * const config)
734 {
735     NRF_SAADC->CH[channel].CONFIG =
736             ((config->resistor_p   << SAADC_CH_CONFIG_RESP_Pos)   & SAADC_CH_CONFIG_RESP_Msk)
737             | ((config->resistor_n << SAADC_CH_CONFIG_RESN_Pos)   & SAADC_CH_CONFIG_RESN_Msk)
738             | ((config->gain       << SAADC_CH_CONFIG_GAIN_Pos)   & SAADC_CH_CONFIG_GAIN_Msk)
739             | ((config->reference  << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_Msk)
740             | ((config->acq_time   << SAADC_CH_CONFIG_TACQ_Pos)   & SAADC_CH_CONFIG_TACQ_Msk)
741             | ((config->mode       << SAADC_CH_CONFIG_MODE_Pos)   & SAADC_CH_CONFIG_MODE_Msk)
742             | ((config->burst      << SAADC_CH_CONFIG_BURST_Pos)  & SAADC_CH_CONFIG_BURST_Msk);
743     nrf_saadc_channel_input_set(channel, config->pin_p, config->pin_n);
744 }
745 
nrf_saadc_burst_set(uint8_t channel,nrf_saadc_burst_t burst)746 __STATIC_INLINE void nrf_saadc_burst_set(uint8_t channel,
747                                          nrf_saadc_burst_t burst)
748 {
749     NRF_SAADC->CH[channel].CONFIG =
750         (NRF_SAADC->CH[channel].CONFIG & ~SAADC_CH_CONFIG_BURST_Msk) |
751         (burst << SAADC_CH_CONFIG_BURST_Pos);
752 }
753 
754 #endif // SUPPRESS_INLINE_IMPLEMENTATION
755 
756 /** @} */
757 
758 #ifdef __cplusplus
759 }
760 #endif
761 
762 #endif // NRF_SAADC_H_
763