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