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 */,
221 		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
222 		      ADC_GAIN_1);
223 
224 	check_empty_samples(samples);
225 }
226 
227 /** @brief Test setting two channels with different constant output */
ZTEST_USER(adc_emul,test_adc_emul_single_value_2ch)228 ZTEST_USER(adc_emul, test_adc_emul_single_value_2ch)
229 {
230 	const uint16_t input1_mv = 3000;
231 	const uint16_t input2_mv = 2000;
232 	const int samples = 3;
233 	int ret, i;
234 
235 	for (i = 0; i < BUFFER_SIZE; ++i) {
236 		m_sample_buffer[i] = INVALID_ADC_VALUE;
237 	}
238 
239 	/* Generic ADC setup */
240 	const struct device *adc_dev = get_adc_device();
241 
242 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
243 		      ADC_1ST_CHANNEL_ID);
244 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
245 		      ADC_2ND_CHANNEL_ID);
246 
247 	/* ADC emulator-specific setup */
248 	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input1_mv);
249 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
250 
251 	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input2_mv);
252 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
253 
254 	/* Test sampling */
255 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
256 			BIT(ADC_2ND_CHANNEL_ID), samples);
257 
258 	/* Check samples */
259 	check_samples(samples * 2, input1_mv, 0 /* step */, 2 /* channels */,
260 		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
261 		      ADC_GAIN_1);
262 	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
263 		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
264 		      ADC_GAIN_1);
265 
266 	check_empty_samples(samples * 2);
267 }
268 
269 /** @brief Test setting one channel with custom function. */
ZTEST_USER(adc_emul,test_adc_emul_custom_function)270 ZTEST_USER(adc_emul, test_adc_emul_custom_function)
271 {
272 	struct handle_seq_params channel1_param;
273 	const uint16_t input_mv = 1500;
274 	const int samples = 4;
275 	int ret, i;
276 
277 	for (i = 0; i < BUFFER_SIZE; ++i) {
278 		m_sample_buffer[i] = INVALID_ADC_VALUE;
279 	}
280 
281 	/* Generic ADC setup */
282 	const struct device *adc_dev = get_adc_device();
283 
284 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
285 		      ADC_1ST_CHANNEL_ID);
286 
287 	/* ADC emulator-specific setup */
288 	channel1_param.value = input_mv;
289 
290 	ret = adc_emul_value_func_set(adc_dev, ADC_1ST_CHANNEL_ID,
291 				      handle_seq, &channel1_param);
292 	zassert_ok(ret, "adc_emul_value_func_set() failed with code %d", ret);
293 
294 	/* Test sampling */
295 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID), samples);
296 
297 	/* Check samples */
298 	check_samples(samples, input_mv, SEQUENCE_STEP, 1 /* channels */,
299 		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
300 		      ADC_GAIN_1);
301 
302 	check_empty_samples(samples);
303 }
304 
305 /**
306  * @brief Test setting two channels with custom function and different
307  *        params.
308  */
ZTEST_USER(adc_emul,test_adc_emul_custom_function_2ch)309 ZTEST_USER(adc_emul, test_adc_emul_custom_function_2ch)
310 {
311 	struct handle_seq_params channel1_param;
312 	struct handle_seq_params channel2_param;
313 	const uint16_t input1_mv = 1500;
314 	const uint16_t input2_mv = 1000;
315 	const int samples = 3;
316 	int ret, i;
317 
318 	for (i = 0; i < BUFFER_SIZE; ++i) {
319 		m_sample_buffer[i] = INVALID_ADC_VALUE;
320 	}
321 
322 	/* Generic ADC setup */
323 	const struct device *adc_dev = get_adc_device();
324 
325 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
326 		      ADC_1ST_CHANNEL_ID);
327 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
328 		      ADC_2ND_CHANNEL_ID);
329 
330 	/* ADC emulator-specific setup */
331 	channel1_param.value = input1_mv;
332 	channel2_param.value = input2_mv;
333 
334 	ret = adc_emul_value_func_set(adc_dev, ADC_1ST_CHANNEL_ID,
335 				      handle_seq, &channel1_param);
336 	zassert_ok(ret, "adc_emul_value_func_set() failed with code %d", ret);
337 
338 	ret = adc_emul_value_func_set(adc_dev, ADC_2ND_CHANNEL_ID,
339 				      handle_seq, &channel2_param);
340 	zassert_ok(ret, "adc_emul_value_func_set() failed with code %d", ret);
341 
342 	/* Test sampling */
343 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
344 			BIT(ADC_2ND_CHANNEL_ID), samples);
345 
346 	/* Check samples */
347 	check_samples(samples * 2, input1_mv, SEQUENCE_STEP,
348 		      2 /* channels */, 0 /* first channel data */,
349 		      ADC_REF_INTERNAL_MV, ADC_GAIN_1);
350 	check_samples(samples * 2, input2_mv, SEQUENCE_STEP,
351 		      2 /* channels */, 1 /* first channel data */,
352 		      ADC_REF_INTERNAL_MV, ADC_GAIN_1);
353 
354 	check_empty_samples(samples * 2);
355 }
356 
357 /**
358  * @brief Test setting two channels, one with custom function and
359  *        one with constant value.
360  */
ZTEST_USER(adc_emul,test_adc_emul_custom_function_and_value)361 ZTEST_USER(adc_emul, test_adc_emul_custom_function_and_value)
362 {
363 	struct handle_seq_params channel1_param;
364 	const uint16_t input1_mv = 1500;
365 	const uint16_t input2_mv = 1000;
366 	const int samples = 3;
367 	int ret, i;
368 
369 	for (i = 0; i < BUFFER_SIZE; ++i) {
370 		m_sample_buffer[i] = INVALID_ADC_VALUE;
371 	}
372 
373 	/* Generic ADC setup */
374 	const struct device *adc_dev = get_adc_device();
375 
376 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
377 		      ADC_1ST_CHANNEL_ID);
378 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
379 		      ADC_2ND_CHANNEL_ID);
380 
381 	/* ADC emulator-specific setup */
382 	channel1_param.value = input1_mv;
383 
384 	ret = adc_emul_value_func_set(adc_dev, ADC_1ST_CHANNEL_ID,
385 				      handle_seq, &channel1_param);
386 	zassert_ok(ret, "adc_emul_value_func_set() failed with code %d", ret);
387 
388 	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input2_mv);
389 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
390 
391 	/* Test sampling */
392 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
393 			BIT(ADC_2ND_CHANNEL_ID), samples);
394 
395 	/* Check samples */
396 	check_samples(samples * 2, input1_mv, SEQUENCE_STEP,
397 		      2 /* channels */, 0 /* first channel data */,
398 		      ADC_REF_INTERNAL_MV, ADC_GAIN_1);
399 	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
400 		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
401 		      ADC_GAIN_1);
402 
403 	check_empty_samples(samples * 2);
404 }
405 
406 /** @brief Test few different settings of gain argument. */
ZTEST_USER(adc_emul,test_adc_emul_gain)407 ZTEST_USER(adc_emul, test_adc_emul_gain)
408 {
409 	const uint16_t input_mv = 1000;
410 	uint32_t channel_mask;
411 	const int samples = 3;
412 	int ret, i;
413 
414 	for (i = 0; i < BUFFER_SIZE; ++i) {
415 		m_sample_buffer[i] = INVALID_ADC_VALUE;
416 	}
417 
418 	/* Generic ADC setup */
419 	const struct device *adc_dev = get_adc_device();
420 
421 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1_6,
422 		      ADC_1ST_CHANNEL_ID);
423 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_3,
424 		      ADC_2ND_CHANNEL_ID);
425 
426 	/* ADC emulator-specific setup */
427 	channel_mask = BIT(ADC_1ST_CHANNEL_ID) | BIT(ADC_2ND_CHANNEL_ID);
428 
429 	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input_mv);
430 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
431 
432 	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input_mv);
433 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
434 
435 	/* Test sampling */
436 	start_adc_read(adc_dev, channel_mask, samples);
437 
438 	/* Check samples */
439 	check_samples(samples * 2, input_mv, 0 /* step */, 2 /* channels */,
440 		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
441 		      ADC_GAIN_1_6);
442 	check_samples(samples * 2, input_mv, 0 /* step */, 2 /* channels */,
443 		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
444 		      ADC_GAIN_3);
445 
446 	check_empty_samples(samples * 2);
447 
448 	/* Change gain and re-run test */
449 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1_4,
450 		      ADC_1ST_CHANNEL_ID);
451 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_2_3,
452 		      ADC_2ND_CHANNEL_ID);
453 
454 	/* Test sampling */
455 	start_adc_read(adc_dev, channel_mask, samples);
456 
457 	/* Check samples */
458 	check_samples(samples * 2, input_mv, 0 /* step */, 2 /* channels */,
459 		      0 /* first channel data */, ADC_REF_INTERNAL_MV,
460 		      ADC_GAIN_1_4);
461 	check_samples(samples * 2, input_mv, 0 /* step */, 2 /* channels */,
462 		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
463 		      ADC_GAIN_2_3);
464 
465 	check_empty_samples(samples * 2);
466 }
467 
468 /**
469  * @brief Test behaviour on input higher than reference. Return value should be
470  *        cropped to reference value and cannot exceed resolution requested in
471  *        adc_read().
472  */
ZTEST_USER(adc_emul,test_adc_emul_input_higher_than_ref)473 ZTEST_USER(adc_emul, test_adc_emul_input_higher_than_ref)
474 {
475 	const uint16_t input_mv = ADC_REF_INTERNAL_MV + 100;
476 	const int samples = 4;
477 	int ret, i;
478 
479 	for (i = 0; i < BUFFER_SIZE; ++i) {
480 		m_sample_buffer[i] = INVALID_ADC_VALUE;
481 	}
482 
483 	/* Generic ADC setup */
484 	const struct device *adc_dev = get_adc_device();
485 
486 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
487 		      ADC_1ST_CHANNEL_ID);
488 
489 	/* ADC emulator-specific setup */
490 	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input_mv);
491 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
492 
493 	/* Test sampling */
494 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID), samples);
495 
496 	/*
497 	 * Check samples - returned value should max out on reference value.
498 	 * Raw value shouldn't exceed resolution.
499 	 */
500 	check_samples(samples, ADC_REF_INTERNAL_MV, 0 /* step */,
501 		      1 /* channels */, 0 /* first channel data */,
502 		      ADC_REF_INTERNAL_MV, ADC_GAIN_1);
503 
504 	check_empty_samples(samples);
505 
506 	for (i = 0; i < samples; i++) {
507 		zassert_equal(BIT_MASK(ADC_RESOLUTION), m_sample_buffer[i],
508 			      "[%u] raw value isn't max value", i);
509 	}
510 }
511 
512 /**
513  * @brief Test different reference sources and if error is reported when
514  *        unconfigured reference source is requested.
515  */
ZTEST_USER(adc_emul,test_adc_emul_reference)516 ZTEST_USER(adc_emul, test_adc_emul_reference)
517 {
518 	const uint16_t input1_mv = 4000;
519 	const uint16_t input2_mv = 2000;
520 	const int samples = 3;
521 	int ret, i;
522 
523 	for (i = 0; i < BUFFER_SIZE; ++i) {
524 		m_sample_buffer[i] = INVALID_ADC_VALUE;
525 	}
526 
527 	/* Generic ADC setup */
528 	const struct device *adc_dev = get_adc_device();
529 
530 	channel_setup(adc_dev, ADC_REF_EXTERNAL1, ADC_GAIN_1,
531 		      ADC_1ST_CHANNEL_ID);
532 
533 	struct adc_channel_cfg channel_cfg = {
534 		.gain             = ADC_GAIN_1,
535 		/* Reference value not setup in DTS */
536 		.reference        = ADC_REF_EXTERNAL0,
537 		.acquisition_time = ADC_ACQUISITION_TIME,
538 		.channel_id       = ADC_2ND_CHANNEL_ID,
539 	};
540 
541 	ret = adc_channel_setup(adc_dev, &channel_cfg);
542 	zassert_not_equal(ret, 0,
543 			  "Setting up of the %d channel shouldn't succeeded",
544 			  ADC_2ND_CHANNEL_ID);
545 
546 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
547 		      ADC_2ND_CHANNEL_ID);
548 
549 	/* ADC emulator-specific setup */
550 	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input1_mv);
551 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
552 
553 	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input2_mv);
554 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
555 
556 	/* Test sampling */
557 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
558 			BIT(ADC_2ND_CHANNEL_ID), samples);
559 
560 	/* Check samples */
561 	check_samples(samples * 2, input1_mv, 0 /* step */, 2 /* channels */,
562 		      0 /* first channel data */, ADC_REF_EXTERNAL1_MV,
563 		      ADC_GAIN_1);
564 	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
565 		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
566 		      ADC_GAIN_1);
567 
568 	check_empty_samples(samples * 2);
569 }
570 
571 /** @brief Test setting reference value. */
ZTEST_USER(adc_emul,test_adc_emul_ref_voltage_set)572 ZTEST_USER(adc_emul, test_adc_emul_ref_voltage_set)
573 {
574 	const uint16_t input1_mv = 4000;
575 	const uint16_t input2_mv = 2000;
576 	const uint16_t ref1_mv = 6000;
577 	const uint16_t ref2_mv = 9000;
578 	const int samples = 3;
579 	int ret, i;
580 
581 	for (i = 0; i < BUFFER_SIZE; ++i) {
582 		m_sample_buffer[i] = INVALID_ADC_VALUE;
583 	}
584 
585 	/* Generic ADC setup */
586 	const struct device *adc_dev = get_adc_device();
587 
588 	channel_setup(adc_dev, ADC_REF_EXTERNAL1, ADC_GAIN_1,
589 		      ADC_1ST_CHANNEL_ID);
590 	channel_setup(adc_dev, ADC_REF_INTERNAL, ADC_GAIN_1,
591 		      ADC_2ND_CHANNEL_ID);
592 
593 	/* ADC emulator-specific setup */
594 	ret = adc_emul_const_value_set(adc_dev, ADC_1ST_CHANNEL_ID, input1_mv);
595 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
596 
597 	ret = adc_emul_const_value_set(adc_dev, ADC_2ND_CHANNEL_ID, input2_mv);
598 	zassert_ok(ret, "adc_emul_const_value_set() failed with code %d", ret);
599 
600 	/* Change reference voltage */
601 	ret = adc_emul_ref_voltage_set(adc_dev, ADC_REF_EXTERNAL1, ref1_mv);
602 	zassert_ok(ret, "adc_emul_ref_voltage_set() failed with code %d", ret);
603 
604 	ret = adc_emul_ref_voltage_set(adc_dev, ADC_REF_INTERNAL, ref2_mv);
605 	zassert_ok(ret, "adc_emul_ref_voltage_set() failed with code %d", ret);
606 
607 	/* Test sampling */
608 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
609 			BIT(ADC_2ND_CHANNEL_ID), samples);
610 
611 	/* Check samples */
612 	check_samples(samples * 2, input1_mv, 0 /* step */, 2 /* channels */,
613 		      0 /* first channel data */, ref1_mv, ADC_GAIN_1);
614 	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
615 		      1 /* first channel data */, ref2_mv, ADC_GAIN_1);
616 
617 	check_empty_samples(samples * 2);
618 
619 	/* Set previous reference voltage value */
620 	ret = adc_emul_ref_voltage_set(adc_dev, ADC_REF_EXTERNAL1,
621 				       ADC_REF_EXTERNAL1_MV);
622 	zassert_ok(ret, "adc_emul_ref_voltage_set() failed with code %d", ret);
623 
624 	ret = adc_emul_ref_voltage_set(adc_dev, ADC_REF_INTERNAL,
625 				       ADC_REF_INTERNAL_MV);
626 	zassert_ok(ret, "adc_emul_ref_voltage_set() failed with code %d", ret);
627 
628 	/* Test sampling */
629 	start_adc_read(adc_dev, BIT(ADC_1ST_CHANNEL_ID) |
630 			BIT(ADC_2ND_CHANNEL_ID), samples);
631 
632 	/* Check samples */
633 	check_samples(samples * 2, input1_mv, 0 /* step */, 2 /* channels */,
634 		      0 /* first channel data */, ADC_REF_EXTERNAL1_MV,
635 		      ADC_GAIN_1);
636 	check_samples(samples * 2, input2_mv, 0 /* step */, 2 /* channels */,
637 		      1 /* first channel data */, ADC_REF_INTERNAL_MV,
638 		      ADC_GAIN_1);
639 
640 	check_empty_samples(samples * 2);
641 }
642 
adc_emul_setup(void)643 void *adc_emul_setup(void)
644 {
645 	k_object_access_grant(get_adc_device(), k_current_get());
646 
647 	return NULL;
648 }
649 
650 ZTEST_SUITE(adc_emul, NULL, adc_emul_setup, NULL, NULL, NULL);
651