1 /*
2  * Copyright (c) 2018 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define ADC_CONTEXT_USES_KERNEL_TIMER
8 #include "adc_context.h"
9 #include <hal/nrf_saadc.h>
10 #include <zephyr/dt-bindings/adc/nrf-adc.h>
11 
12 #define LOG_LEVEL CONFIG_ADC_LOG_LEVEL
13 #include <zephyr/logging/log.h>
14 #include <zephyr/irq.h>
15 LOG_MODULE_REGISTER(adc_nrfx_saadc);
16 
17 #define DT_DRV_COMPAT nordic_nrf_saadc
18 
19 BUILD_ASSERT((NRF_SAADC_AIN0 == NRF_SAADC_INPUT_AIN0) &&
20 	     (NRF_SAADC_AIN1 == NRF_SAADC_INPUT_AIN1) &&
21 	     (NRF_SAADC_AIN2 == NRF_SAADC_INPUT_AIN2) &&
22 	     (NRF_SAADC_AIN3 == NRF_SAADC_INPUT_AIN3) &&
23 	     (NRF_SAADC_AIN4 == NRF_SAADC_INPUT_AIN4) &&
24 	     (NRF_SAADC_AIN5 == NRF_SAADC_INPUT_AIN5) &&
25 	     (NRF_SAADC_AIN6 == NRF_SAADC_INPUT_AIN6) &&
26 	     (NRF_SAADC_AIN7 == NRF_SAADC_INPUT_AIN7) &&
27 	     (NRF_SAADC_AIN7 == NRF_SAADC_INPUT_AIN7) &&
28 #if defined(SAADC_CH_PSELP_PSELP_VDDHDIV5)
29 	     (NRF_SAADC_VDDHDIV5 == NRF_SAADC_INPUT_VDDHDIV5) &&
30 #endif
31 	     (NRF_SAADC_VDD == NRF_SAADC_INPUT_VDD),
32 	     "Definitions from nrf-adc.h do not match those from nrf_saadc.h");
33 
34 struct driver_data {
35 	struct adc_context ctx;
36 
37 	uint8_t positive_inputs[SAADC_CH_NUM];
38 };
39 
40 static struct driver_data m_data = {
41 	ADC_CONTEXT_INIT_TIMER(m_data, ctx),
42 	ADC_CONTEXT_INIT_LOCK(m_data, ctx),
43 	ADC_CONTEXT_INIT_SYNC(m_data, ctx),
44 };
45 
46 
47 /* Implementation of the ADC driver API function: adc_channel_setup. */
adc_nrfx_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)48 static int adc_nrfx_channel_setup(const struct device *dev,
49 				  const struct adc_channel_cfg *channel_cfg)
50 {
51 	nrf_saadc_channel_config_t config = {
52 		.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
53 		.resistor_n = NRF_SAADC_RESISTOR_DISABLED,
54 		.burst      = NRF_SAADC_BURST_DISABLED,
55 	};
56 	uint8_t channel_id = channel_cfg->channel_id;
57 
58 	if (channel_id >= SAADC_CH_NUM) {
59 		return -EINVAL;
60 	}
61 
62 	switch (channel_cfg->gain) {
63 	case ADC_GAIN_1_6:
64 		config.gain = NRF_SAADC_GAIN1_6;
65 		break;
66 	case ADC_GAIN_1_5:
67 		config.gain = NRF_SAADC_GAIN1_5;
68 		break;
69 	case ADC_GAIN_1_4:
70 		config.gain = NRF_SAADC_GAIN1_4;
71 		break;
72 	case ADC_GAIN_1_3:
73 		config.gain = NRF_SAADC_GAIN1_3;
74 		break;
75 	case ADC_GAIN_1_2:
76 		config.gain = NRF_SAADC_GAIN1_2;
77 		break;
78 	case ADC_GAIN_1:
79 		config.gain = NRF_SAADC_GAIN1;
80 		break;
81 	case ADC_GAIN_2:
82 		config.gain = NRF_SAADC_GAIN2;
83 		break;
84 	case ADC_GAIN_4:
85 		config.gain = NRF_SAADC_GAIN4;
86 		break;
87 	default:
88 		LOG_ERR("Selected ADC gain is not valid");
89 		return -EINVAL;
90 	}
91 
92 	switch (channel_cfg->reference) {
93 	case ADC_REF_INTERNAL:
94 		config.reference = NRF_SAADC_REFERENCE_INTERNAL;
95 		break;
96 	case ADC_REF_VDD_1_4:
97 		config.reference = NRF_SAADC_REFERENCE_VDD4;
98 		break;
99 	default:
100 		LOG_ERR("Selected ADC reference is not valid");
101 		return -EINVAL;
102 	}
103 
104 	switch (channel_cfg->acquisition_time) {
105 	case ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 3):
106 		config.acq_time = NRF_SAADC_ACQTIME_3US;
107 		break;
108 	case ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5):
109 		config.acq_time = NRF_SAADC_ACQTIME_5US;
110 		break;
111 	case ADC_ACQ_TIME_DEFAULT:
112 	case ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 10):
113 		config.acq_time = NRF_SAADC_ACQTIME_10US;
114 		break;
115 	case ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 15):
116 		config.acq_time = NRF_SAADC_ACQTIME_15US;
117 		break;
118 	case ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 20):
119 		config.acq_time = NRF_SAADC_ACQTIME_20US;
120 		break;
121 	case ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 40):
122 		config.acq_time = NRF_SAADC_ACQTIME_40US;
123 		break;
124 	default:
125 		LOG_ERR("Selected ADC acquisition time is not valid");
126 		return -EINVAL;
127 	}
128 
129 	config.mode = (channel_cfg->differential ?
130 		NRF_SAADC_MODE_DIFFERENTIAL : NRF_SAADC_MODE_SINGLE_ENDED);
131 
132 	/* Keep the channel disabled in hardware (set positive input to
133 	 * NRF_SAADC_INPUT_DISABLED) until it is selected to be included
134 	 * in a sampling sequence.
135 	 */
136 
137 	nrf_saadc_channel_init(NRF_SAADC, channel_id, &config);
138 	nrf_saadc_channel_input_set(NRF_SAADC,
139 				    channel_id,
140 				    NRF_SAADC_INPUT_DISABLED,
141 				    channel_cfg->input_negative);
142 
143 	/* Store the positive input selection in a dedicated array,
144 	 * to get it later when the channel is selected for a sampling
145 	 * and to mark the channel as configured (ready to be selected).
146 	 */
147 	m_data.positive_inputs[channel_id] = channel_cfg->input_positive;
148 
149 	return 0;
150 }
151 
adc_context_start_sampling(struct adc_context * ctx)152 static void adc_context_start_sampling(struct adc_context *ctx)
153 {
154 	nrf_saadc_enable(NRF_SAADC);
155 
156 	if (ctx->sequence.calibrate) {
157 		nrf_saadc_task_trigger(NRF_SAADC,
158 				       NRF_SAADC_TASK_CALIBRATEOFFSET);
159 	} else {
160 		nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_START);
161 		nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_SAMPLE);
162 	}
163 }
164 
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat)165 static void adc_context_update_buffer_pointer(struct adc_context *ctx,
166 					      bool repeat)
167 {
168 	ARG_UNUSED(ctx);
169 
170 	if (!repeat) {
171 		nrf_saadc_buffer_pointer_set(
172 			NRF_SAADC,
173 			(uint16_t *)nrf_saadc_buffer_pointer_get(NRF_SAADC) +
174 			nrf_saadc_amount_get(NRF_SAADC));
175 	}
176 }
177 
set_resolution(const struct adc_sequence * sequence)178 static int set_resolution(const struct adc_sequence *sequence)
179 {
180 	nrf_saadc_resolution_t nrf_resolution;
181 
182 	switch (sequence->resolution) {
183 	case  8:
184 		nrf_resolution = NRF_SAADC_RESOLUTION_8BIT;
185 		break;
186 	case 10:
187 		nrf_resolution = NRF_SAADC_RESOLUTION_10BIT;
188 		break;
189 	case 12:
190 		nrf_resolution = NRF_SAADC_RESOLUTION_12BIT;
191 		break;
192 	case 14:
193 		nrf_resolution = NRF_SAADC_RESOLUTION_14BIT;
194 		break;
195 	default:
196 		LOG_ERR("ADC resolution value %d is not valid",
197 			    sequence->resolution);
198 		return -EINVAL;
199 	}
200 
201 	nrf_saadc_resolution_set(NRF_SAADC, nrf_resolution);
202 	return 0;
203 }
204 
set_oversampling(const struct adc_sequence * sequence,uint8_t active_channels)205 static int set_oversampling(const struct adc_sequence *sequence,
206 			    uint8_t active_channels)
207 {
208 	nrf_saadc_oversample_t nrf_oversampling;
209 
210 	if ((active_channels > 1) && (sequence->oversampling > 0)) {
211 		LOG_ERR(
212 			"Oversampling is supported for single channel only");
213 		return -EINVAL;
214 	}
215 
216 	switch (sequence->oversampling) {
217 	case 0:
218 		nrf_oversampling = NRF_SAADC_OVERSAMPLE_DISABLED;
219 		break;
220 	case 1:
221 		nrf_oversampling = NRF_SAADC_OVERSAMPLE_2X;
222 		break;
223 	case 2:
224 		nrf_oversampling = NRF_SAADC_OVERSAMPLE_4X;
225 		break;
226 	case 3:
227 		nrf_oversampling = NRF_SAADC_OVERSAMPLE_8X;
228 		break;
229 	case 4:
230 		nrf_oversampling = NRF_SAADC_OVERSAMPLE_16X;
231 		break;
232 	case 5:
233 		nrf_oversampling = NRF_SAADC_OVERSAMPLE_32X;
234 		break;
235 	case 6:
236 		nrf_oversampling = NRF_SAADC_OVERSAMPLE_64X;
237 		break;
238 	case 7:
239 		nrf_oversampling = NRF_SAADC_OVERSAMPLE_128X;
240 		break;
241 	case 8:
242 		nrf_oversampling = NRF_SAADC_OVERSAMPLE_256X;
243 		break;
244 	default:
245 		LOG_ERR("Oversampling value %d is not valid",
246 			    sequence->oversampling);
247 		return -EINVAL;
248 	}
249 
250 	nrf_saadc_oversample_set(NRF_SAADC, nrf_oversampling);
251 	return 0;
252 }
253 
check_buffer_size(const struct adc_sequence * sequence,uint8_t active_channels)254 static int check_buffer_size(const struct adc_sequence *sequence,
255 			     uint8_t active_channels)
256 {
257 	size_t needed_buffer_size;
258 
259 	needed_buffer_size = active_channels * sizeof(uint16_t);
260 	if (sequence->options) {
261 		needed_buffer_size *= (1 + sequence->options->extra_samplings);
262 	}
263 
264 	if (sequence->buffer_size < needed_buffer_size) {
265 		LOG_ERR("Provided buffer is too small (%u/%u)",
266 			    sequence->buffer_size, needed_buffer_size);
267 		return -ENOMEM;
268 	}
269 
270 	return 0;
271 }
272 
start_read(const struct device * dev,const struct adc_sequence * sequence)273 static int start_read(const struct device *dev,
274 		      const struct adc_sequence *sequence)
275 {
276 	int error;
277 	uint32_t selected_channels = sequence->channels;
278 	uint8_t active_channels;
279 	uint8_t channel_id;
280 
281 	/* Signal an error if channel selection is invalid (no channels or
282 	 * a non-existing one is selected).
283 	 */
284 	if (!selected_channels ||
285 	    (selected_channels & ~BIT_MASK(SAADC_CH_NUM))) {
286 		LOG_ERR("Invalid selection of channels");
287 		return -EINVAL;
288 	}
289 
290 	active_channels = 0U;
291 
292 	/* Enable only the channels selected for the pointed sequence.
293 	 * Disable all the rest.
294 	 */
295 	channel_id = 0U;
296 	do {
297 		if (selected_channels & BIT(channel_id)) {
298 			/* Signal an error if a selected channel has not been
299 			 * configured yet.
300 			 */
301 			if (m_data.positive_inputs[channel_id] == 0U) {
302 				LOG_ERR("Channel %u not configured",
303 					    channel_id);
304 				return -EINVAL;
305 			}
306 			/* When oversampling is used, the burst mode needs to
307 			 * be activated. Unfortunately, this mode cannot be
308 			 * activated permanently in the channel setup, because
309 			 * then the multiple channel sampling fails (the END
310 			 * event is not generated) after switching to a single
311 			 * channel sampling and back. Thus, when oversampling
312 			 * is not used (hence, the multiple channel sampling is
313 			 * possible), the burst mode have to be deactivated.
314 			 */
315 			nrf_saadc_burst_set(NRF_SAADC, channel_id,
316 				(sequence->oversampling != 0U ?
317 					NRF_SAADC_BURST_ENABLED :
318 					NRF_SAADC_BURST_DISABLED));
319 			nrf_saadc_channel_pos_input_set(
320 				NRF_SAADC,
321 				channel_id,
322 				m_data.positive_inputs[channel_id]);
323 			++active_channels;
324 		} else {
325 			nrf_saadc_channel_pos_input_set(
326 				NRF_SAADC,
327 				channel_id,
328 				NRF_SAADC_INPUT_DISABLED);
329 		}
330 	} while (++channel_id < SAADC_CH_NUM);
331 
332 	error = set_resolution(sequence);
333 	if (error) {
334 		return error;
335 	}
336 
337 	error = set_oversampling(sequence, active_channels);
338 	if (error) {
339 		return error;
340 	}
341 
342 	error = check_buffer_size(sequence, active_channels);
343 	if (error) {
344 		return error;
345 	}
346 
347 	nrf_saadc_buffer_init(NRF_SAADC,
348 			      (nrf_saadc_value_t *)sequence->buffer,
349 			      active_channels);
350 
351 	adc_context_start_read(&m_data.ctx, sequence);
352 
353 	error = adc_context_wait_for_completion(&m_data.ctx);
354 	return error;
355 }
356 
357 /* Implementation of the ADC driver API function: adc_read. */
adc_nrfx_read(const struct device * dev,const struct adc_sequence * sequence)358 static int adc_nrfx_read(const struct device *dev,
359 			 const struct adc_sequence *sequence)
360 {
361 	int error;
362 
363 	adc_context_lock(&m_data.ctx, false, NULL);
364 	error = start_read(dev, sequence);
365 	adc_context_release(&m_data.ctx, error);
366 
367 	return error;
368 }
369 
370 #ifdef CONFIG_ADC_ASYNC
371 /* Implementation of the ADC driver API function: adc_read_async. */
adc_nrfx_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)372 static int adc_nrfx_read_async(const struct device *dev,
373 			       const struct adc_sequence *sequence,
374 			       struct k_poll_signal *async)
375 {
376 	int error;
377 
378 	adc_context_lock(&m_data.ctx, true, async);
379 	error = start_read(dev, sequence);
380 	adc_context_release(&m_data.ctx, error);
381 
382 	return error;
383 }
384 #endif /* CONFIG_ADC_ASYNC */
385 
saadc_irq_handler(const struct device * dev)386 static void saadc_irq_handler(const struct device *dev)
387 {
388 	if (nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_END)) {
389 		nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
390 
391 		nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_STOP);
392 		nrf_saadc_disable(NRF_SAADC);
393 
394 		adc_context_on_sampling_done(&m_data.ctx, dev);
395 	} else if (nrf_saadc_event_check(NRF_SAADC,
396 					 NRF_SAADC_EVENT_CALIBRATEDONE)) {
397 		nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_CALIBRATEDONE);
398 
399 		/*
400 		 * The workaround for Nordic nRF52832 anomalies 86 and
401 		 * 178 is an explicit STOP after CALIBRATEOFFSET
402 		 * before issuing START.
403 		 */
404 		nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_STOP);
405 		nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_START);
406 		nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_SAMPLE);
407 	}
408 }
409 
init_saadc(const struct device * dev)410 static int init_saadc(const struct device *dev)
411 {
412 	nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
413 	nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_CALIBRATEDONE);
414 	nrf_saadc_int_enable(NRF_SAADC,
415 			     NRF_SAADC_INT_END | NRF_SAADC_INT_CALIBRATEDONE);
416 	NRFX_IRQ_ENABLE(DT_INST_IRQN(0));
417 
418 	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
419 		    saadc_irq_handler, DEVICE_DT_INST_GET(0), 0);
420 
421 	adc_context_unlock_unconditionally(&m_data.ctx);
422 
423 	return 0;
424 }
425 
426 static const struct adc_driver_api adc_nrfx_driver_api = {
427 	.channel_setup = adc_nrfx_channel_setup,
428 	.read          = adc_nrfx_read,
429 #ifdef CONFIG_ADC_ASYNC
430 	.read_async    = adc_nrfx_read_async,
431 #endif
432 	.ref_internal  = 600,
433 };
434 
435 /*
436  * There is only one instance on supported SoCs, so inst is guaranteed
437  * to be 0 if any instance is okay. (We use adc_0 above, so the driver
438  * is relying on the numeric instance value in a way that happens to
439  * be safe.)
440  *
441  * Just in case that assumption becomes invalid in the future, we use
442  * a BUILD_ASSERT().
443  */
444 #define SAADC_INIT(inst)						\
445 	BUILD_ASSERT((inst) == 0,					\
446 		     "multiple instances not supported");		\
447 	DEVICE_DT_INST_DEFINE(0,					\
448 			    init_saadc,					\
449 			    NULL,					\
450 			    NULL,					\
451 			    NULL,					\
452 			    POST_KERNEL,				\
453 			    CONFIG_ADC_INIT_PRIORITY,			\
454 			    &adc_nrfx_driver_api);
455 
456 DT_INST_FOREACH_STATUS_OKAY(SAADC_INIT)
457