1 /*
2  * Copyright 2021 Google LLC
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/adc.h>
8 #include <zephyr/drivers/adc/adc_emul.h>
9 #include <zephyr/kernel.h>
10 #include <zephyr/ztest.h>
11 
12 #define ADC_DEVICE_NODE		DT_INST(0, zephyr_adc_emul)
13 #define ADC_REF_INTERNAL_MV	DT_PROP(DT_INST(0, zephyr_adc_emul), ref_internal_mv)
14 #define ADC_REF_EXTERNAL1_MV	DT_PROP(DT_INST(0, zephyr_adc_emul), ref_external1_mv)
15 #define ADC_RESOLUTION		14
16 #define ADC_ACQUISITION_TIME	ADC_ACQ_TIME_DEFAULT
17 #define ADC_1ST_CHANNEL_ID	0
18 #define ADC_2ND_CHANNEL_ID	1
19 
20 #define INVALID_ADC_VALUE	SHRT_MIN
21 /* Raw to millivolt conversion doesn't handle rounding */
22 #define MV_OUTPUT_EPS		2
23 #define SEQUENCE_STEP		100
24 
25 #define BUFFER_SIZE  6
26 static ZTEST_BMEM int16_t m_sample_buffer[BUFFER_SIZE];
27 
28 /**
29  * @brief Get ADC emulated device
30  *
31  * @return pointer to ADC device
32  */
get_adc_device(void)33 const struct device *get_adc_device(void)
34 {
35 	const struct device *const adc_dev = DEVICE_DT_GET(ADC_DEVICE_NODE);
36 
37 	zassert_true(device_is_ready(adc_dev), "ADC device is not ready");
38 
39 	return adc_dev;
40 }
41 
42 /**
43  * @brief Setup channel with specific reference and gain
44  *
45  * @param adc_dev Pointer to ADC device
46  * @param ref ADC reference voltage source
47  * @param gain Gain applied to ADC @p channel
48  * @param channel ADC channel which is being setup
49  *
50  * @return none
51  */
channel_setup(const struct device * adc_dev,enum adc_reference ref,enum adc_gain gain,int channel)52 static void channel_setup(const struct device *adc_dev, enum adc_reference ref,
53 			  enum adc_gain gain, int channel)
54 {
55 	int ret;
56 	struct adc_channel_cfg channel_cfg = {
57 		.gain             = gain,
58 		.reference        = ref,
59 		.acquisition_time = ADC_ACQUISITION_TIME,
60 		.channel_id       = channel,
61 	};
62 
63 	ret = adc_channel_setup(adc_dev, &channel_cfg);
64 	zassert_ok(ret, "Setting up of the %d channel failed with code %d",
65 		   channel, ret);
66 }
67 
68 /**
69  * @brief Check if samples for specific channel are correct. It can check
70  *        samples with arithmetic sequence with common difference.
71  *
72  * @param expected_count Number of samples that are expected to be set
73  * @param start_mv_value Voltage in mV that was set on input at the beginning
74  *                       of sampling
75  * @param step Common difference in arithmetic sequence which describes how
76  *             samples were generated
77  * @param num_channels Number of channels that were sampled
78  * @param channel_id ADC channel from which samples are checked
79  * @param ref_mv Reference voltage in mV
80  * @param gain Gain applied to ADC @p channel_id
81  *
82  * @return none
83  */
check_samples(int expected_count,int32_t start_mv_value,int step,int num_channels,int channel_id,int32_t ref_mv,enum adc_gain gain)84 static void check_samples(int expected_count, int32_t start_mv_value, int step,
85 			  int num_channels, int channel_id, int32_t ref_mv,
86 			  enum adc_gain gain)
87 {
88 	int32_t output, expected;
89 	int i, ret;
90 
91 	for (i = channel_id; i < expected_count; i += num_channels) {
92 		expected = start_mv_value + i / num_channels * step;
93 		output = m_sample_buffer[i];
94 		ret = adc_raw_to_millivolts(ref_mv, gain, ADC_RESOLUTION,
95 					    &output);
96 		zassert_ok(ret, "adc_raw_to_millivolts() failed with code %d",
97 			   ret);
98 		zassert_within(expected, output, MV_OUTPUT_EPS,
99 			       "%u != %u [%u] should has set value",
100 			       expected, output, i);
101 	}
102 
103 }
104 
105 /**
106  * @brief Check if any values in buffer were set after expected samples.
107  *
108  * @param expected_count Number of samples that are expected to be set
109  *
110  * @return none
111  */
check_empty_samples(int expected_count)112 static void check_empty_samples(int expected_count)
113 {
114 	int i;
115 
116 	for (i = expected_count; i < BUFFER_SIZE; i++) {
117 		zassert_equal(INVALID_ADC_VALUE, m_sample_buffer[i],
118 			      "[%u] should be empty", i);
119 	}
120 }
121 
122 /**
123  * @brief Run adc_read for given channels and collect specified number of
124  *        samples.
125  *
126  * @param adc_dev Pointer to ADC device
127  * @param channel_mask Mask of channels that will be sampled
128  * @param samples Number of requested samples for each channel
129  *
130  * @return none
131  */
start_adc_read(const struct device * adc_dev,uint32_t channel_mask,int samples)132 static void start_adc_read(const struct device *adc_dev, uint32_t channel_mask,
133 			   int samples)
134 {
135 	int ret;
136 	const struct adc_sequence_options *options_ptr;
137 
138 	const struct adc_sequence_options options = {
139 		.extra_samplings = samples - 1,
140 	};
141 
142 	if (samples > 1) {
143 		options_ptr = &options;
144 	} else {
145 		options_ptr = NULL;
146 	}
147 
148 	const struct adc_sequence sequence = {
149 		.options     = options_ptr,
150 		.channels    = channel_mask,
151 		.buffer      = m_sample_buffer,
152 		.buffer_size = sizeof(m_sample_buffer),
153 		.resolution  = ADC_RESOLUTION,
154 	};
155 
156 	ret = adc_read(adc_dev, &sequence);
157 	zassert_ok(ret, "adc_read() failed with code %d", ret);
158 }
159 
160 /** @brief Data for handle_seq function */
161 struct handle_seq_params {
162 	/** Current input value in mV */
163 	unsigned int value;
164 };
165 
166 /**
167  * @brief Simple custom function to set as value input function for emulated
168  *        ADC channel. It returns arithmetic sequence with SEQUENCE_STEP
169  *        as common difference, starting from param value.
170  *
171  * @param dev Pointer to ADC device
172  * @param channel ADC channel for which input value is requested
173  * @param data Pointer to function parameters. It has to be
174  *             struct handle_seq_params type
175  * @param result Pointer where input value should be stored
176  *
177  * @return 0 on success
178  * @return -EINVAL when current input value equals 0
179  */
handle_seq(const struct device * dev,unsigned int channel,void * data,uint32_t * result)180 static int handle_seq(const struct device *dev, unsigned int channel,
181 		      void *data, uint32_t *result)
182 {
183 	struct handle_seq_params *param = data;
184 
185 	if (param->value == 0) {
186 		return -EINVAL;
187 	}
188 
189 	*result = param->value;
190 	param->value += SEQUENCE_STEP;
191 
192 	return 0;
193 }
194 
195 /** @brief Test setting one channel with constant output. */
ZTEST_USER(adc_emul,test_adc_emul_single_value)196 ZTEST_USER(adc_emul, test_adc_emul_single_value)
197 {
198 	const uint16_t input_mv = 1500;
199 	const int samples = 4;
200 	int ret, i;
201 
202 	for (i = 0; i < BUFFER_SIZE; ++i) {
203 		m_sample_buffer[i] = INVALID_ADC_VALUE;
204 	}
205 
206 	/* Generic ADC setup */
207 	const struct device *adc_dev = get_adc_device();
208 
209 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
210 		      ADC_1ST_CHANNEL_ID);
211 
212 	/* ADC emulator-specific setup */
213 	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input_mv);
214 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
215 
216 	/* Test sampling */
217 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID), samples);
218 
219 	/* Check samples */
220 	check_samples(samples, input_mv, 0 /* step */, 1 /* channels */, 0 /* first channel data */,
221 		      ADC_REF_INTERNAL_MV, ADC_GAIN_1);
222 
223 	check_empty_samples(samples);
224 }
225 
226 /** @brief Test setting one channel with constant raw output. */
ZTEST_USER(adc_emul,test_adc_emul_single_raw_value_half_reference)227 ZTEST_USER(adc_emul, test_adc_emul_single_raw_value_half_reference)
228 {
229 	const uint16_t input_raw_value = (1 << ADC_RESOLUTION) / 2;
230 	const uint16_t input_mv = ADC_REF_INTERNAL_MV / 2;
231 	const int samples = 4;
232 	int ret, i;
233 
234 	for (i = 0; i < BUFFER_SIZE; ++i) {
235 		m_sample_buffer[i] = INVALID_ADC_VALUE;
236 	}
237 
238 	/* Generic ADC setup */
239 	const struct device *adc_dev = get_adc_device();
240 
241 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1, ADC_1ST_CHANNEL_ID);
242 
243 	/* ADC emulator-specific setup */
244 	ret = adc_emul_const_raw_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input_raw_value);
245 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
246 
247 	/* Test sampling */
248 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID), samples);
249 
250 	/* Check samples */
251 	check_samples(samples, input_mv, 0 /* step */, 1 /* channels */, 0 /* first channel data */,
252 		      ADC_REF_INTERNAL_MV, ADC_GAIN_1);
253 
254 	check_empty_samples(samples);
255 }
256 
257 /** @brief Test setting one channel with constant raw output. */
ZTEST_USER(adc_emul,test_adc_emul_single_raw_value_quarter_reference)258 ZTEST_USER(adc_emul, test_adc_emul_single_raw_value_quarter_reference)
259 {
260 	const uint16_t input_raw_value = (1 << ADC_RESOLUTION) / 4;
261 	const uint16_t input_mv = ADC_REF_INTERNAL_MV / 4;
262 	const int samples = 4;
263 	int ret, i;
264 
265 	for (i = 0; i < BUFFER_SIZE; ++i) {
266 		m_sample_buffer[i] = INVALID_ADC_VALUE;
267 	}
268 
269 	/* Generic ADC setup */
270 	const struct device *adc_dev = get_adc_device();
271 
272 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1, ADC_1ST_CHANNEL_ID);
273 
274 	/* ADC emulator-specific setup */
275 	ret = adc_emul_const_raw_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input_raw_value);
276 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
277 
278 	/* Test sampling */
279 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID), samples);
280 
281 	/* Check samples */
282 	check_samples(samples, input_mv, 0 /* step */, 1 /* channels */,
283 		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
284 		      ADC_GAIN_1);
285 
286 	check_empty_samples(samples);
287 }
288 
289 /** @brief Test setting two channels with different constant output */
ZTEST_USER(adc_emul,test_adc_emul_single_value_2ch)290 ZTEST_USER(adc_emul, test_adc_emul_single_value_2ch)
291 {
292 	const uint16_t input1_mv = 3000;
293 	const uint16_t input2_mv = 2000;
294 	const int samples = 3;
295 	int ret, i;
296 
297 	for (i = 0; i < BUFFER_SIZE; ++i) {
298 		m_sample_buffer[i] = INVALID_ADC_VALUE;
299 	}
300 
301 	/* Generic ADC setup */
302 	const struct device *adc_dev = get_adc_device();
303 
304 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
305 		      ADC_1ST_CHANNEL_ID);
306 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
307 		      ADC_2ND_CHANNEL_ID);
308 
309 	/* ADC emulator-specific setup */
310 	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input1_mv);
311 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
312 
313 	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input2_mv);
314 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
315 
316 	/* Test sampling */
317 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
318 			BIT(ADC_2ND_CHANNEL_ID), samples);
319 
320 	/* Check samples */
321 	check_samples(samples * 2, input1_mv, 0 /* step */, 2 /* channels */,
322 		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
323 		      ADC_GAIN_1);
324 	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
325 		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
326 		      ADC_GAIN_1);
327 
328 	check_empty_samples(samples * 2);
329 }
330 
331 /** @brief Test setting one channel with custom function. */
ZTEST_USER(adc_emul,test_adc_emul_custom_function)332 ZTEST_USER(adc_emul, test_adc_emul_custom_function)
333 {
334 	struct handle_seq_params channel1_param;
335 	const uint16_t input_mv = 1500;
336 	const int samples = 4;
337 	int ret, i;
338 
339 	for (i = 0; i < BUFFER_SIZE; ++i) {
340 		m_sample_buffer[i] = INVALID_ADC_VALUE;
341 	}
342 
343 	/* Generic ADC setup */
344 	const struct device *adc_dev = get_adc_device();
345 
346 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
347 		      ADC_1ST_CHANNEL_ID);
348 
349 	/* ADC emulator-specific setup */
350 	channel1_param.value = input_mv;
351 
352 	ret = adc_emul_value_func_set(adc_dev, ADC_1ST_CHANNEL_ID,
353 				      handle_seq, &channel1_param);
354 	zassert_ok(ret, "adc_emul_value_func_set() failed with code %d", ret);
355 
356 	/* Test sampling */
357 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID), samples);
358 
359 	/* Check samples */
360 	check_samples(samples, input_mv, SEQUENCE_STEP, 1 /* channels */,
361 		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
362 		      ADC_GAIN_1);
363 
364 	check_empty_samples(samples);
365 }
366 
367 /** @brief Test setting one channel with custom function raw value. */
ZTEST_USER(adc_emul,test_adc_emul_custom_function_raw_value)368 ZTEST_USER(adc_emul, test_adc_emul_custom_function_raw_value)
369 {
370 	struct handle_seq_params channel1_param;
371 	const uint16_t raw_value = 1000;
372 	const uint16_t input_mV = (raw_value * ADC_REF_INTERNAL_MV / BIT(ADC_RESOLUTION));
373 	const int samples = 4;
374 	int ret, i;
375 
376 	for (i = 0; i < BUFFER_SIZE; ++i) {
377 		m_sample_buffer[i] = INVALID_ADC_VALUE;
378 	}
379 
380 	/* Generic ADC setup */
381 	const struct device *adc_dev = get_adc_device();
382 
383 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1, ADC_1ST_CHANNEL_ID);
384 
385 	/* ADC emulator-specific setup */
386 	channel1_param.value = raw_value;
387 
388 	ret = adc_emul_raw_value_func_set(adc_dev, ADC_1ST_CHANNEL_ID, handle_seq, &channel1_param);
389 	zassert_ok(ret, "adc_emul_value_func_set() failed with code %d", ret);
390 
391 	/* Test sampling */
392 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID), samples);
393 
394 	/* Check samples */
395 	check_samples(samples, input_mV,
396 		      (SEQUENCE_STEP * ADC_REF_INTERNAL_MV / BIT(ADC_RESOLUTION)), 1 /* channels */,
397 		      0 /* first channel data */, ADC_REF_INTERNAL_MV, ADC_GAIN_1);
398 
399 	check_empty_samples(samples);
400 }
401 
402 /**
403  * @brief Test setting two channels with custom function and different
404  *        params.
405  */
ZTEST_USER(adc_emul,test_adc_emul_custom_function_2ch)406 ZTEST_USER(adc_emul, test_adc_emul_custom_function_2ch)
407 {
408 	struct handle_seq_params channel1_param;
409 	struct handle_seq_params channel2_param;
410 	const uint16_t input1_mv = 1500;
411 	const uint16_t input2_mv = 1000;
412 	const int samples = 3;
413 	int ret, i;
414 
415 	for (i = 0; i < BUFFER_SIZE; ++i) {
416 		m_sample_buffer[i] = INVALID_ADC_VALUE;
417 	}
418 
419 	/* Generic ADC setup */
420 	const struct device *adc_dev = get_adc_device();
421 
422 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
423 		      ADC_1ST_CHANNEL_ID);
424 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
425 		      ADC_2ND_CHANNEL_ID);
426 
427 	/* ADC emulator-specific setup */
428 	channel1_param.value = input1_mv;
429 	channel2_param.value = input2_mv;
430 
431 	ret = adc_emul_value_func_set(adc_dev, ADC_1ST_CHANNEL_ID,
432 				      handle_seq, &channel1_param);
433 	zassert_ok(ret, "adc_emul_value_func_set() failed with code %d", ret);
434 
435 	ret = adc_emul_value_func_set(adc_dev, ADC_2ND_CHANNEL_ID,
436 				      handle_seq, &channel2_param);
437 	zassert_ok(ret, "adc_emul_value_func_set() failed with code %d", ret);
438 
439 	/* Test sampling */
440 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
441 			BIT(ADC_2ND_CHANNEL_ID), samples);
442 
443 	/* Check samples */
444 	check_samples(samples * 2, input1_mv, SEQUENCE_STEP,
445 		      2 /* channels */, 0 /* first channel data */,
446 		      ADC_REF_INTERNAL_MV, ADC_GAIN_1);
447 	check_samples(samples * 2, input2_mv, SEQUENCE_STEP,
448 		      2 /* channels */, 1 /* first channel data */,
449 		      ADC_REF_INTERNAL_MV, ADC_GAIN_1);
450 
451 	check_empty_samples(samples * 2);
452 }
453 
454 /**
455  * @brief Test setting two channels, one with custom function and
456  *        one with constant value.
457  */
ZTEST_USER(adc_emul,test_adc_emul_custom_function_and_value)458 ZTEST_USER(adc_emul, test_adc_emul_custom_function_and_value)
459 {
460 	struct handle_seq_params channel1_param;
461 	const uint16_t input1_mv = 1500;
462 	const uint16_t input2_mv = 1000;
463 	const int samples = 3;
464 	int ret, i;
465 
466 	for (i = 0; i < BUFFER_SIZE; ++i) {
467 		m_sample_buffer[i] = INVALID_ADC_VALUE;
468 	}
469 
470 	/* Generic ADC setup */
471 	const struct device *adc_dev = get_adc_device();
472 
473 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
474 		      ADC_1ST_CHANNEL_ID);
475 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
476 		      ADC_2ND_CHANNEL_ID);
477 
478 	/* ADC emulator-specific setup */
479 	channel1_param.value = input1_mv;
480 
481 	ret = adc_emul_value_func_set(adc_dev, ADC_1ST_CHANNEL_ID,
482 				      handle_seq, &channel1_param);
483 	zassert_ok(ret, "adc_emul_value_func_set() failed with code %d", ret);
484 
485 	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input2_mv);
486 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
487 
488 	/* Test sampling */
489 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
490 			BIT(ADC_2ND_CHANNEL_ID), samples);
491 
492 	/* Check samples */
493 	check_samples(samples * 2, input1_mv, SEQUENCE_STEP,
494 		      2 /* channels */, 0 /* first channel data */,
495 		      ADC_REF_INTERNAL_MV, ADC_GAIN_1);
496 	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
497 		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
498 		      ADC_GAIN_1);
499 
500 	check_empty_samples(samples * 2);
501 }
502 
503 /** @brief Test few different settings of gain argument. */
ZTEST_USER(adc_emul,test_adc_emul_gain)504 ZTEST_USER(adc_emul, test_adc_emul_gain)
505 {
506 	const uint16_t input_mv = 1000;
507 	uint32_t channel_mask;
508 	const int samples = 3;
509 	int ret, i;
510 
511 	for (i = 0; i < BUFFER_SIZE; ++i) {
512 		m_sample_buffer[i] = INVALID_ADC_VALUE;
513 	}
514 
515 	/* Generic ADC setup */
516 	const struct device *adc_dev = get_adc_device();
517 
518 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1_6,
519 		      ADC_1ST_CHANNEL_ID);
520 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_3,
521 		      ADC_2ND_CHANNEL_ID);
522 
523 	/* ADC emulator-specific setup */
524 	channel_mask = BIT(ADC_1ST_CHANNEL_ID) | BIT(ADC_2ND_CHANNEL_ID);
525 
526 	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input_mv);
527 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
528 
529 	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input_mv);
530 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
531 
532 	/* Test sampling */
533 	start_adc_read(adc_dev, channel_mask, samples);
534 
535 	/* Check samples */
536 	check_samples(samples * 2, input_mv, 0 /* step */, 2 /* channels */,
537 		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
538 		      ADC_GAIN_1_6);
539 	check_samples(samples * 2, input_mv, 0 /* step */, 2 /* channels */,
540 		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
541 		      ADC_GAIN_3);
542 
543 	check_empty_samples(samples * 2);
544 
545 	/* Change gain and re-run test */
546 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1_4,
547 		      ADC_1ST_CHANNEL_ID);
548 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_2_3,
549 		      ADC_2ND_CHANNEL_ID);
550 
551 	/* Test sampling */
552 	start_adc_read(adc_dev, channel_mask, samples);
553 
554 	/* Check samples */
555 	check_samples(samples * 2, input_mv, 0 /* step */, 2 /* channels */,
556 		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
557 		      ADC_GAIN_1_4);
558 	check_samples(samples * 2, input_mv, 0 /* step */, 2 /* channels */,
559 		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
560 		      ADC_GAIN_2_3);
561 
562 	check_empty_samples(samples * 2);
563 }
564 
565 /**
566  * @brief Test behaviour on input higher than reference. Return value should be
567  *        cropped to reference value and cannot exceed resolution requested in
568  *        adc_read().
569  */
ZTEST_USER(adc_emul,test_adc_emul_input_higher_than_ref)570 ZTEST_USER(adc_emul, test_adc_emul_input_higher_than_ref)
571 {
572 	const uint16_t input_mv = ADC_REF_INTERNAL_MV + 100;
573 	const int samples = 4;
574 	int ret, i;
575 
576 	for (i = 0; i < BUFFER_SIZE; ++i) {
577 		m_sample_buffer[i] = INVALID_ADC_VALUE;
578 	}
579 
580 	/* Generic ADC setup */
581 	const struct device *adc_dev = get_adc_device();
582 
583 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
584 		      ADC_1ST_CHANNEL_ID);
585 
586 	/* ADC emulator-specific setup */
587 	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input_mv);
588 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
589 
590 	/* Test sampling */
591 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID), samples);
592 
593 	/*
594 	 * Check samples - returned value should max out on reference value.
595 	 * Raw value shouldn't exceed resolution.
596 	 */
597 	check_samples(samples, ADC_REF_INTERNAL_MV, 0 /* step */,
598 		      1 /* channels */, 0 /* first channel data */,
599 		      ADC_REF_INTERNAL_MV, ADC_GAIN_1);
600 
601 	check_empty_samples(samples);
602 
603 	for (i = 0; i < samples; i++) {
604 		zassert_equal(BIT_MASK(ADC_RESOLUTION), m_sample_buffer[i],
605 			      "[%u] raw value isn't max value", i);
606 	}
607 }
608 
609 /**
610  * @brief Test different reference sources and if error is reported when
611  *        unconfigured reference source is requested.
612  */
ZTEST_USER(adc_emul,test_adc_emul_reference)613 ZTEST_USER(adc_emul, test_adc_emul_reference)
614 {
615 	const uint16_t input1_mv = 4000;
616 	const uint16_t input2_mv = 2000;
617 	const int samples = 3;
618 	int ret, i;
619 
620 	for (i = 0; i < BUFFER_SIZE; ++i) {
621 		m_sample_buffer[i] = INVALID_ADC_VALUE;
622 	}
623 
624 	/* Generic ADC setup */
625 	const struct device *adc_dev = get_adc_device();
626 
627 	channel_setup(adc_dev, ADC_REF_EXTERNAL1, ADC_GAIN_1,
628 		      ADC_1ST_CHANNEL_ID);
629 
630 	struct adc_channel_cfg channel_cfg = {
631 		.gain             = ADC_GAIN_1,
632 		/* Reference value not setup in DTS */
633 		.reference        = ADC_REF_EXTERNAL0,
634 		.acquisition_time = ADC_ACQUISITION_TIME,
635 		.channel_id       = ADC_2ND_CHANNEL_ID,
636 	};
637 
638 	ret = adc_channel_setup(adc_dev, &channel_cfg);
639 	zassert_not_equal(ret, 0,
640 			  "Setting up of the %d channel shouldn't succeeded",
641 			  ADC_2ND_CHANNEL_ID);
642 
643 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
644 		      ADC_2ND_CHANNEL_ID);
645 
646 	/* ADC emulator-specific setup */
647 	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input1_mv);
648 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
649 
650 	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input2_mv);
651 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
652 
653 	/* Test sampling */
654 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
655 			BIT(ADC_2ND_CHANNEL_ID), samples);
656 
657 	/* Check samples */
658 	check_samples(samples * 2, input1_mv, 0 /* step */, 2 /* channels */,
659 		      0 /* first channel data */, ADC_REF_EXTERNAL1_MV,
660 		      ADC_GAIN_1);
661 	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
662 		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
663 		      ADC_GAIN_1);
664 
665 	check_empty_samples(samples * 2);
666 }
667 
668 /** @brief Test setting reference value. */
ZTEST_USER(adc_emul,test_adc_emul_ref_voltage_set)669 ZTEST_USER(adc_emul, test_adc_emul_ref_voltage_set)
670 {
671 	const uint16_t input1_mv = 4000;
672 	const uint16_t input2_mv = 2000;
673 	const uint16_t ref1_mv = 6000;
674 	const uint16_t ref2_mv = 9000;
675 	const int samples = 3;
676 	int ret, i;
677 
678 	for (i = 0; i < BUFFER_SIZE; ++i) {
679 		m_sample_buffer[i] = INVALID_ADC_VALUE;
680 	}
681 
682 	/* Generic ADC setup */
683 	const struct device *adc_dev = get_adc_device();
684 
685 	channel_setup(adc_dev, ADC_REF_EXTERNAL1, ADC_GAIN_1,
686 		      ADC_1ST_CHANNEL_ID);
687 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
688 		      ADC_2ND_CHANNEL_ID);
689 
690 	/* ADC emulator-specific setup */
691 	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input1_mv);
692 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
693 
694 	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input2_mv);
695 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
696 
697 	/* Change reference voltage */
698 	ret = adc_emul_ref_voltage_set(adc_dev, ADC_REF_EXTERNAL1, ref1_mv);
699 	zassert_ok(ret, "adc_emul_ref_voltage_set() failed with code %d", ret);
700 
701 	ret = adc_emul_ref_voltage_set(adc_dev, ADC_REF_INTERNAL, ref2_mv);
702 	zassert_ok(ret, "adc_emul_ref_voltage_set() failed with code %d", ret);
703 
704 	/* Test sampling */
705 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
706 			BIT(ADC_2ND_CHANNEL_ID), samples);
707 
708 	/* Check samples */
709 	check_samples(samples * 2, input1_mv, 0 /* step */, 2 /* channels */,
710 		      0 /* first channel data */, ref1_mv, ADC_GAIN_1);
711 	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
712 		      1 /* first channel data */, ref2_mv, ADC_GAIN_1);
713 
714 	check_empty_samples(samples * 2);
715 
716 	/* Set previous reference voltage value */
717 	ret = adc_emul_ref_voltage_set(adc_dev, ADC_REF_EXTERNAL1,
718 				       ADC_REF_EXTERNAL1_MV);
719 	zassert_ok(ret, "adc_emul_ref_voltage_set() failed with code %d", ret);
720 
721 	ret = adc_emul_ref_voltage_set(adc_dev, ADC_REF_INTERNAL,
722 				       ADC_REF_INTERNAL_MV);
723 	zassert_ok(ret, "adc_emul_ref_voltage_set() failed with code %d", ret);
724 
725 	/* Test sampling */
726 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
727 			BIT(ADC_2ND_CHANNEL_ID), samples);
728 
729 	/* Check samples */
730 	check_samples(samples * 2, input1_mv, 0 /* step */, 2 /* channels */,
731 		      0 /* first channel data */, ADC_REF_EXTERNAL1_MV,
732 		      ADC_GAIN_1);
733 	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
734 		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
735 		      ADC_GAIN_1);
736 
737 	check_empty_samples(samples * 2);
738 }
739 
adc_emul_setup(void)740 void *adc_emul_setup(void)
741 {
742 	k_object_access_grant(get_adc_device(), k_current_get());
743 
744 	return NULL;
745 }
746 
747 ZTEST_SUITE(adc_emul, NULL, adc_emul_setup, NULL, NULL, NULL);
748