1 /*
2 * Copyright (c) 2018 Nordic Semiconductor ASA
3 * Copyright (c) 2016 Intel Corporation
4 * Copyright (c) 2020, NXP
5 * Copyright (c) 2023, Nobleo Technology
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9
10
11 #include <zephyr/drivers/dma.h>
12 #include <zephyr/drivers/adc.h>
13 #include <zephyr/drivers/counter.h>
14 #include <zephyr/kernel.h>
15 #include <zephyr/ztest.h>
16
17 #if defined(CONFIG_BOARD_FRDM_K64F)
18
19 #define ADC_DEVICE_NODE DT_INST(0, nxp_kinetis_adc16)
20 #define ADC_RESOLUTION 12
21 #define ADC_GAIN ADC_GAIN_1
22 #define ADC_REFERENCE ADC_REF_INTERNAL
23 #define ADC_ACQUISITION_TIME ADC_ACQ_TIME_DEFAULT
24 #define ADC_1ST_CHANNEL_ID 26
25 #define COUNTER_NODE_NAME pit0
26 #define HW_TRIGGER_INTERVAL (30000U)
27 #define SAMPLE_INTERVAL_US HW_TRIGGER_INTERVAL
28
29 #elif defined(CONFIG_BOARD_FRDM_K82F)
30
31 #define ADC_DEVICE_NODE DT_INST(0, nxp_kinetis_adc16)
32 #define ADC_RESOLUTION 12
33 #define ADC_GAIN ADC_GAIN_1
34 #define ADC_REFERENCE ADC_REF_INTERNAL
35 #define ADC_ACQUISITION_TIME ADC_ACQ_TIME_DEFAULT
36 #define ADC_1ST_CHANNEL_ID 26
37 #define COUNTER_NODE_NAME pit0
38 #define HW_TRIGGER_INTERVAL (30000U)
39 #define SAMPLE_INTERVAL_US HW_TRIGGER_INTERVAL
40
41 #elif defined(CONFIG_BOARD_NUCLEO_H743ZI)
42
43 #define ADC_DEVICE_NODE DT_INST(0, st_stm32_adc)
44 #define ADC_RESOLUTION 12
45 #define ADC_GAIN ADC_GAIN_1
46 #define ADC_REFERENCE ADC_REF_INTERNAL
47 #define ADC_ACQUISITION_TIME ADC_ACQ_TIME_DEFAULT
48 #define ADC_1ST_CHANNEL_ID 1
49 #define ADC_2ND_CHANNEL_ID 7
50 #define ALIGNMENT 32
51 #define BUFFER_MEM_REGION __attribute__((__section__("SRAM4.dma")))
52
53 #endif
54
55 /* Invalid value that is not supposed to be written by the driver. It is used
56 * to mark the sample buffer entries as empty. If needed, it can be overridden
57 * for a particular board by providing a specific definition above.
58 */
59 #if !defined(INVALID_ADC_VALUE)
60 #define INVALID_ADC_VALUE SHRT_MIN
61 #endif
62
63 /* Memory region where buffers will be placed. By default placed in ZTEST_BMEM
64 * but can be overwritten for a particular board.
65 */
66 #if !defined(BUFFER_MEM_REGION)
67 #define BUFFER_MEM_REGION EMPTY
68 #endif
69
70 /* The sample interval between consecutive samplings. Some drivers require
71 * specific values to function.
72 */
73 #if !defined(SAMPLE_INTERVAL_US)
74 #define SAMPLE_INTERVAL_US 0
75 #endif
76
77 #define BUFFER_SIZE 24
78 #ifndef ALIGNMENT
79 #define ALIGNMENT DMA_BUF_ADDR_ALIGNMENT(DT_NODELABEL(test_dma))
80 #endif
81
82 static BUFFER_MEM_REGION __aligned(ALIGNMENT) int16_t m_sample_buffer[BUFFER_SIZE];
83 static BUFFER_MEM_REGION __aligned(ALIGNMENT) int16_t m_sample_buffer2[2][BUFFER_SIZE];
84 static int current_buf_inx;
85
86 #if defined(CONFIG_ADC_ASYNC)
87 static struct k_poll_signal async_sig;
88 #endif
89
90 static const struct adc_channel_cfg m_1st_channel_cfg = {
91 .gain = ADC_GAIN,
92 .reference = ADC_REFERENCE,
93 .acquisition_time = ADC_ACQUISITION_TIME,
94 .channel_id = ADC_1ST_CHANNEL_ID,
95 #if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
96 .input_positive = ADC_1ST_CHANNEL_INPUT,
97 #endif
98 };
99 #if defined(ADC_2ND_CHANNEL_ID)
100 static const struct adc_channel_cfg m_2nd_channel_cfg = {
101 .gain = ADC_GAIN,
102 .reference = ADC_REFERENCE,
103 .acquisition_time = ADC_ACQUISITION_TIME,
104 .channel_id = ADC_2ND_CHANNEL_ID,
105 #if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
106 .input_positive = ADC_2ND_CHANNEL_INPUT,
107 #endif
108 };
109 #endif /* defined(ADC_2ND_CHANNEL_ID) */
110
111 #if defined(COUNTER_NODE_NAME)
init_counter(void)112 static void init_counter(void)
113 {
114 int err;
115 const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(COUNTER_NODE_NAME));
116 struct counter_top_cfg top_cfg = { .callback = NULL,
117 .user_data = NULL,
118 .flags = 0 };
119
120 zassert_true(device_is_ready(dev), "Counter device is not ready");
121
122 counter_start(dev);
123 top_cfg.ticks = counter_us_to_ticks(dev, HW_TRIGGER_INTERVAL);
124 err = counter_set_top_value(dev, &top_cfg);
125 zassert_equal(0, err, "%s: Counter failed to set top value (err: %d)",
126 dev->name, err);
127 }
128 #endif
129
init_adc(void)130 static const struct device *init_adc(void)
131 {
132 int i, ret;
133 const struct device *const adc_dev = DEVICE_DT_GET(ADC_DEVICE_NODE);
134
135 zassert_true(device_is_ready(adc_dev), "ADC device is not ready");
136
137 ret = adc_channel_setup(adc_dev, &m_1st_channel_cfg);
138 zassert_equal(ret, 0,
139 "Setting up of the first channel failed with code %d",
140 ret);
141
142 #if defined(ADC_2ND_CHANNEL_ID)
143 ret = adc_channel_setup(adc_dev, &m_2nd_channel_cfg);
144 zassert_equal(ret, 0,
145 "Setting up of the second channel failed with code %d",
146 ret);
147 #endif /* defined(ADC_2ND_CHANNEL_ID) */
148
149 for (i = 0; i < BUFFER_SIZE; ++i) {
150 m_sample_buffer[i] = INVALID_ADC_VALUE;
151 m_sample_buffer2[0][i] = INVALID_ADC_VALUE;
152 m_sample_buffer2[1][i] = INVALID_ADC_VALUE;
153 }
154
155 #if defined(CONFIG_ADC_ASYNC)
156 k_poll_signal_init(&async_sig);
157 #endif
158
159 #if defined(COUNTER_NODE_NAME)
160 init_counter();
161 #endif
162
163 return adc_dev;
164 }
165
check_samples(int expected_count)166 static void check_samples(int expected_count)
167 {
168 int i;
169
170 TC_PRINT("Samples read: ");
171 for (i = 0; i < BUFFER_SIZE; i++) {
172 int16_t sample_value = m_sample_buffer[i];
173
174 TC_PRINT("0x%04x ", sample_value);
175 if (i && i % 10 == 0) {
176 TC_PRINT("\n");
177 }
178
179 if (i < expected_count) {
180 zassert_not_equal(INVALID_ADC_VALUE, sample_value,
181 "[%u] should be filled", i);
182 } else {
183 zassert_equal(INVALID_ADC_VALUE, sample_value,
184 "[%u] should be empty", i);
185 }
186 }
187 TC_PRINT("\n");
188 }
189
check_samples2(int expected_count)190 static void check_samples2(int expected_count)
191 {
192 int i;
193
194 TC_PRINT("Samples read: ");
195 for (i = 0; i < BUFFER_SIZE; i++) {
196 int16_t sample_value = m_sample_buffer2[current_buf_inx][i];
197
198 TC_PRINT("0x%04x ", sample_value);
199 if (i && i % 10 == 0) {
200 TC_PRINT("\n");
201 }
202
203 if (i < expected_count) {
204 zassert_not_equal(INVALID_ADC_VALUE, sample_value,
205 "[%u] should be filled", i);
206 } else {
207 zassert_equal(INVALID_ADC_VALUE, sample_value,
208 "[%u] should be empty", i);
209 }
210 }
211 TC_PRINT("\n");
212 }
213
214 /*
215 * test_adc_sample_one_channel
216 */
test_task_one_channel(void)217 static int test_task_one_channel(void)
218 {
219 int ret;
220 const struct adc_sequence sequence = {
221 .channels = BIT(ADC_1ST_CHANNEL_ID),
222 .buffer = m_sample_buffer,
223 .buffer_size = sizeof(m_sample_buffer),
224 .resolution = ADC_RESOLUTION,
225 };
226
227 const struct device *adc_dev = init_adc();
228
229 if (!adc_dev) {
230 return TC_FAIL;
231 }
232
233 ret = adc_read(adc_dev, &sequence);
234 zassert_equal(ret, 0, "adc_read() failed with code %d", ret);
235
236 check_samples(1);
237
238 return TC_PASS;
239 }
240
ZTEST_USER(adc_dma,test_adc_sample_one_channel)241 ZTEST_USER(adc_dma, test_adc_sample_one_channel)
242 {
243 zassert_true(test_task_one_channel() == TC_PASS);
244 }
245
246 /*
247 * test_adc_sample_two_channels
248 */
249 #if defined(ADC_2ND_CHANNEL_ID)
test_task_two_channels(void)250 static int test_task_two_channels(void)
251 {
252 int ret;
253 const struct adc_sequence sequence = {
254 .channels = BIT(ADC_1ST_CHANNEL_ID) | BIT(ADC_2ND_CHANNEL_ID),
255 .buffer = m_sample_buffer,
256 .buffer_size = sizeof(m_sample_buffer),
257 .resolution = ADC_RESOLUTION,
258 };
259
260 const struct device *adc_dev = init_adc();
261
262 if (!adc_dev) {
263 return TC_FAIL;
264 }
265
266 ret = adc_read(adc_dev, &sequence);
267 zassert_equal(ret, 0, "adc_read() failed with code %d", ret);
268
269 check_samples(2);
270
271 return TC_PASS;
272 }
273 #endif /* defined(ADC_2ND_CHANNEL_ID) */
274
ZTEST_USER(adc_dma,test_adc_sample_two_channels)275 ZTEST_USER(adc_dma, test_adc_sample_two_channels)
276 {
277 #if defined(ADC_2ND_CHANNEL_ID)
278 zassert_true(test_task_two_channels() == TC_PASS);
279 #else
280 ztest_test_skip();
281 #endif /* defined(ADC_2ND_CHANNEL_ID) */
282 }
283
284 /*
285 * test_adc_asynchronous_call
286 */
287 #if defined(CONFIG_ADC_ASYNC)
test_task_asynchronous_call(void)288 static int test_task_asynchronous_call(void)
289 {
290 int ret;
291 const struct adc_sequence_options options = {
292 .extra_samplings = 4,
293 /* Start consecutive samplings as fast as possible. */
294 .interval_us = SAMPLE_INTERVAL_US,
295 };
296 const struct adc_sequence sequence = {
297 .options = &options,
298 .channels = BIT(ADC_1ST_CHANNEL_ID),
299 .buffer = m_sample_buffer,
300 .buffer_size = sizeof(m_sample_buffer),
301 .resolution = ADC_RESOLUTION,
302 };
303 struct k_poll_event async_evt = K_POLL_EVENT_INITIALIZER(
304 K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, &async_sig);
305 const struct device *adc_dev = init_adc();
306
307 if (!adc_dev) {
308 return TC_FAIL;
309 }
310
311 ret = adc_read_async(adc_dev, &sequence, &async_sig);
312 zassert_equal(ret, 0, "adc_read_async() failed with code %d", ret);
313
314 ret = k_poll(&async_evt, 1, K_MSEC(1000));
315 zassert_equal(ret, 0, "k_poll failed with error %d", ret);
316
317 check_samples(1 + options.extra_samplings);
318
319 return TC_PASS;
320 }
321 #endif /* defined(CONFIG_ADC_ASYNC) */
322
ZTEST_USER(adc_dma,test_adc_asynchronous_call)323 ZTEST_USER(adc_dma, test_adc_asynchronous_call)
324 {
325 #if defined(CONFIG_ADC_ASYNC)
326 zassert_true(test_task_asynchronous_call() == TC_PASS);
327 #else
328 ztest_test_skip();
329 #endif /* defined(CONFIG_ADC_ASYNC) */
330 }
331
332 /*
333 * test_adc_sample_with_interval
334 */
335 static enum adc_action
sample_with_interval_callback(const struct device * dev,const struct adc_sequence * sequence,uint16_t sampling_index)336 sample_with_interval_callback(const struct device *dev,
337 const struct adc_sequence *sequence,
338 uint16_t sampling_index)
339 {
340 struct adc_sequence *seq = (struct adc_sequence *)sequence;
341 int _inx = current_buf_inx;
342
343 memcpy(m_sample_buffer, m_sample_buffer2[_inx],
344 sizeof(m_sample_buffer));
345 current_buf_inx = (current_buf_inx == 0) ? 1 : 0;
346 seq->buffer = m_sample_buffer2[current_buf_inx];
347 return ADC_ACTION_CONTINUE;
348 }
349
test_task_with_interval(void)350 static int test_task_with_interval(void)
351 {
352 int ret;
353 int count = 2;
354 int64_t time_stamp;
355 int64_t milliseconds_spent;
356
357 const struct adc_sequence_options options = {
358 .interval_us = 100 * 1000, /* 10 ms - much larger than expected sampling time */
359 .callback = sample_with_interval_callback,
360 .extra_samplings = 1,
361 };
362 const struct adc_sequence sequence = {
363 .options = &options,
364 .channels = BIT(ADC_1ST_CHANNEL_ID),
365 .buffer = m_sample_buffer2[0],
366 .buffer_size = sizeof(m_sample_buffer2[0]),
367 .resolution = ADC_RESOLUTION,
368 };
369
370 const struct device *adc_dev = init_adc();
371
372 if (!adc_dev) {
373 return TC_FAIL;
374 }
375
376 current_buf_inx = 0;
377
378 while (count--) {
379 time_stamp = k_uptime_get();
380 ret = adc_read(adc_dev, &sequence);
381 milliseconds_spent = k_uptime_delta(&time_stamp);
382 zassert_true(milliseconds_spent >= (options.interval_us / 1000UL));
383 zassert_equal(ret, 0, "adc_read() failed with code %d", ret);
384 }
385 check_samples2(1 + options.extra_samplings);
386 return TC_PASS;
387 }
388
ZTEST(adc_dma,test_adc_sample_with_interval)389 ZTEST(adc_dma, test_adc_sample_with_interval)
390 {
391 zassert_true(test_task_with_interval() == TC_PASS);
392 }
393
394 /*
395 * test_adc_repeated_samplings
396 */
397 static uint8_t m_samplings_done;
398 static enum adc_action
repeated_samplings_callback(const struct device * dev,const struct adc_sequence * sequence,uint16_t sampling_index)399 repeated_samplings_callback(const struct device *dev,
400 const struct adc_sequence *sequence,
401 uint16_t sampling_index)
402 {
403 ++m_samplings_done;
404 TC_PRINT("%s: done %d\n", __func__, m_samplings_done);
405 if (m_samplings_done == 1U) {
406 #if defined(ADC_2ND_CHANNEL_ID)
407 check_samples(2);
408 #else
409 check_samples(1);
410 #endif /* defined(ADC_2ND_CHANNEL_ID) */
411
412 /* After first sampling continue normally. */
413 return ADC_ACTION_CONTINUE;
414 }
415 #if defined(ADC_2ND_CHANNEL_ID)
416 check_samples(4);
417 #else
418 check_samples(2);
419 #endif /* defined(ADC_2ND_CHANNEL_ID) */
420
421 /*
422 * The second sampling is repeated 9 times (the samples are
423 * written in the same place), then the sequence is finished
424 * prematurely.
425 */
426 if (m_samplings_done < 10) {
427 return ADC_ACTION_REPEAT;
428 } else {
429 return ADC_ACTION_FINISH;
430 }
431
432 }
433
test_task_repeated_samplings(void)434 static int test_task_repeated_samplings(void)
435 {
436 int ret;
437 const struct adc_sequence_options options = {
438 .callback = repeated_samplings_callback,
439 /*
440 * This specifies that 3 samplings are planned. However,
441 * the callback function above is constructed in such way
442 * that the first sampling is done normally, the second one
443 * is repeated 9 times, and then the sequence is finished.
444 * Hence, the third sampling will not take place.
445 */
446 .extra_samplings = 2,
447 /* Start consecutive samplings as fast as possible. */
448 .interval_us = SAMPLE_INTERVAL_US,
449 };
450 const struct adc_sequence sequence = {
451 .options = &options,
452 #if defined(ADC_2ND_CHANNEL_ID)
453 .channels = BIT(ADC_1ST_CHANNEL_ID) | BIT(ADC_2ND_CHANNEL_ID),
454 #else
455 .channels = BIT(ADC_1ST_CHANNEL_ID),
456 #endif /* defined(ADC_2ND_CHANNEL_ID) */
457 .buffer = m_sample_buffer,
458 .buffer_size = sizeof(m_sample_buffer),
459 .resolution = ADC_RESOLUTION,
460 };
461
462 const struct device *adc_dev = init_adc();
463
464 if (!adc_dev) {
465 return TC_FAIL;
466 }
467
468 ret = adc_read(adc_dev, &sequence);
469 zassert_equal(ret, 0, "adc_read() failed with code %d", ret);
470
471 return TC_PASS;
472 }
473
ZTEST(adc_dma,test_adc_repeated_samplings)474 ZTEST(adc_dma, test_adc_repeated_samplings)
475 {
476 zassert_true(test_task_repeated_samplings() == TC_PASS);
477 }
478
479 /*
480 * test_adc_invalid_request
481 */
test_task_invalid_request(void)482 static int test_task_invalid_request(void)
483 {
484 int ret;
485 struct adc_sequence sequence = {
486 .channels = BIT(ADC_1ST_CHANNEL_ID),
487 .buffer = m_sample_buffer,
488 .buffer_size = sizeof(m_sample_buffer),
489 .resolution = 0, /* intentionally invalid value */
490 };
491
492 const struct device *adc_dev = init_adc();
493
494 if (!adc_dev) {
495 return TC_FAIL;
496 }
497
498 ret = adc_read(adc_dev, &sequence);
499 zassert_not_equal(ret, 0, "adc_read() unexpectedly succeeded");
500
501 #if defined(CONFIG_ADC_ASYNC)
502 ret = adc_read_async(adc_dev, &sequence, &async_sig);
503 zassert_not_equal(ret, 0, "adc_read_async() unexpectedly succeeded");
504 #endif
505
506 /*
507 * Make the sequence parameters valid, now the request should succeed.
508 */
509 sequence.resolution = ADC_RESOLUTION;
510
511 ret = adc_read(adc_dev, &sequence);
512 zassert_equal(ret, 0, "adc_read() failed with code %d", ret);
513
514 check_samples(1);
515
516 return TC_PASS;
517 }
518
ZTEST_USER(adc_dma,test_adc_invalid_request)519 ZTEST_USER(adc_dma, test_adc_invalid_request)
520 {
521 zassert_true(test_task_invalid_request() == TC_PASS);
522 }
523