1 /*
2  * Copyright (c) 2017 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
8 #include <logging/log.h>
9 LOG_MODULE_REGISTER(main);
10 
11 #include <zephyr.h>
12 #include <sys/printk.h>
13 #include <string.h>
14 #include <stdio.h>
15 #include <ztest.h>
16 
17 #include <drivers/spi.h>
18 
19 #define SPI_DRV_NAME	CONFIG_SPI_LOOPBACK_DRV_NAME
20 #define SPI_SLAVE	CONFIG_SPI_LOOPBACK_SLAVE_NUMBER
21 #define SLOW_FREQ	CONFIG_SPI_LOOPBACK_SLOW_FREQ
22 #define FAST_FREQ	CONFIG_SPI_LOOPBACK_FAST_FREQ
23 
24 #if defined(CONFIG_SPI_LOOPBACK_CS_GPIO)
25 #define CS_CTRL_GPIO_DRV_NAME CONFIG_SPI_LOOPBACK_CS_CTRL_GPIO_DRV_NAME
26 struct spi_cs_control spi_cs = {
27 	.gpio_pin = CONFIG_SPI_LOOPBACK_CS_CTRL_GPIO_PIN,
28 	.gpio_dt_flags = GPIO_ACTIVE_LOW,
29 	.delay = 0,
30 };
31 #define SPI_CS (&spi_cs)
32 #else
33 #define SPI_CS NULL
34 #define CS_CTRL_GPIO_DRV_NAME ""
35 #endif
36 
37 /* to run this test, connect MOSI pin to the MISO of the SPI */
38 
39 #define STACK_SIZE 512
40 #define BUF_SIZE 17
41 uint8_t buffer_tx[] = "0123456789abcdef\0";
42 uint8_t buffer_rx[BUF_SIZE] = {};
43 
44 #define BUF2_SIZE 36
45 uint8_t buffer2_tx[] = "Thequickbrownfoxjumpsoverthelazydog\0";
46 uint8_t buffer2_rx[BUF2_SIZE] = {};
47 
48 /*
49  * We need 5x(buffer size) + 1 to print a comma-separated list of each
50  * byte in hex, plus a null.
51  */
52 uint8_t buffer_print_tx[BUF_SIZE * 5 + 1];
53 uint8_t buffer_print_rx[BUF_SIZE * 5 + 1];
54 
55 uint8_t buffer_print_tx2[BUF2_SIZE * 5 + 1];
56 uint8_t buffer_print_rx2[BUF2_SIZE * 5 + 1];
57 
to_display_format(const uint8_t * src,size_t size,char * dst)58 static void to_display_format(const uint8_t *src, size_t size, char *dst)
59 {
60 	size_t i;
61 
62 	for (i = 0; i < size; i++) {
63 		sprintf(dst + 5 * i, "0x%02x,", src[i]);
64 	}
65 }
66 
67 struct spi_config spi_cfg_slow = {
68 	.frequency = SLOW_FREQ,
69 #if CONFIG_SPI_LOOPBACK_MODE_LOOP
70 	.operation = SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_LOOP |
71 #else
72 	.operation = SPI_OP_MODE_MASTER | SPI_MODE_CPOL |
73 #endif
74 	SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_LINES_SINGLE,
75 	.slave = SPI_SLAVE,
76 	.cs = SPI_CS,
77 };
78 
79 struct spi_config spi_cfg_fast = {
80 	.frequency = FAST_FREQ,
81 #if CONFIG_SPI_LOOPBACK_MODE_LOOP
82 	.operation = SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_LOOP |
83 #else
84 	.operation = SPI_OP_MODE_MASTER | SPI_MODE_CPOL |
85 #endif
86 	SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_LINES_SINGLE,
87 	.slave = SPI_SLAVE,
88 	.cs = SPI_CS,
89 };
90 
91 #if defined(CONFIG_SPI_LOOPBACK_CS_GPIO)
cs_ctrl_gpio_config(void)92 static int cs_ctrl_gpio_config(void)
93 {
94 	spi_cs.gpio_dev = device_get_binding(CS_CTRL_GPIO_DRV_NAME);
95 	if (!spi_cs.gpio_dev) {
96 		LOG_ERR("Cannot find %s!", CS_CTRL_GPIO_DRV_NAME);
97 		zassert_not_null(spi_cs.gpio_dev, "Invalid gpio device");
98 		return -1;
99 	}
100 
101 	return 0;
102 }
103 #endif /* CONFIG_SPI_LOOPBACK_CS_GPIO */
104 
105 /* test transferring different buffers on the same dma channels */
spi_complete_multiple(const struct device * dev,struct spi_config * spi_conf)106 static int spi_complete_multiple(const struct device *dev,
107 				 struct spi_config *spi_conf)
108 {
109 	struct spi_buf tx_bufs[2];
110 	const struct spi_buf_set tx = {
111 		.buffers = tx_bufs,
112 		.count = ARRAY_SIZE(tx_bufs)
113 	};
114 	tx_bufs[0].buf = buffer_tx;
115 	tx_bufs[0].len = BUF_SIZE;
116 
117 	tx_bufs[1].buf = buffer2_tx;
118 	tx_bufs[1].len = BUF2_SIZE;
119 
120 
121 	struct spi_buf rx_bufs[2];
122 	const struct spi_buf_set rx = {
123 		.buffers = rx_bufs,
124 		.count = ARRAY_SIZE(rx_bufs)
125 	};
126 
127 	rx_bufs[0].buf = buffer_rx;
128 	rx_bufs[0].len = BUF_SIZE;
129 
130 	rx_bufs[1].buf = buffer2_rx;
131 	rx_bufs[1].len = BUF2_SIZE;
132 
133 	int ret;
134 
135 	LOG_INF("Start complete multiple");
136 
137 	ret = spi_transceive(dev, spi_conf, &tx, &rx);
138 	if (ret) {
139 		LOG_ERR("Code %d", ret);
140 		zassert_false(ret, "SPI transceive failed");
141 		return ret;
142 	}
143 
144 	if (memcmp(buffer_tx, buffer_rx, BUF_SIZE)) {
145 		to_display_format(buffer_tx, BUF_SIZE, buffer_print_tx);
146 		to_display_format(buffer_rx, BUF_SIZE, buffer_print_rx);
147 		LOG_ERR("Buffer contents are different: %s",
148 			    buffer_print_tx);
149 		LOG_ERR("                           vs: %s",
150 			    buffer_print_rx);
151 		zassert_false(1, "Buffer contents are different");
152 		return -1;
153 	}
154 
155 	if (memcmp(buffer2_tx, buffer2_rx, BUF2_SIZE)) {
156 		to_display_format(buffer2_tx, BUF2_SIZE, buffer_print_tx2);
157 		to_display_format(buffer2_rx, BUF2_SIZE, buffer_print_rx2);
158 		LOG_ERR("Buffer 2 contents are different: %s",
159 			    buffer_print_tx2);
160 		LOG_ERR("                           vs: %s",
161 			    buffer_print_rx2);
162 		zassert_false(1, "Buffer contents are different");
163 		return -1;
164 	}
165 
166 	LOG_INF("Passed");
167 
168 	return 0;
169 }
170 
spi_complete_loop(const struct device * dev,struct spi_config * spi_conf)171 static int spi_complete_loop(const struct device *dev,
172 			     struct spi_config *spi_conf)
173 {
174 	const struct spi_buf tx_bufs[] = {
175 		{
176 			.buf = buffer_tx,
177 			.len = BUF_SIZE,
178 		},
179 	};
180 	const struct spi_buf rx_bufs[] = {
181 		{
182 			.buf = buffer_rx,
183 			.len = BUF_SIZE,
184 		},
185 	};
186 	const struct spi_buf_set tx = {
187 		.buffers = tx_bufs,
188 		.count = ARRAY_SIZE(tx_bufs)
189 	};
190 	const struct spi_buf_set rx = {
191 		.buffers = rx_bufs,
192 		.count = ARRAY_SIZE(rx_bufs)
193 	};
194 
195 	int ret;
196 
197 	LOG_INF("Start complete loop");
198 
199 	ret = spi_transceive(dev, spi_conf, &tx, &rx);
200 	if (ret) {
201 		LOG_ERR("Code %d", ret);
202 		zassert_false(ret, "SPI transceive failed");
203 		return ret;
204 	}
205 
206 	if (memcmp(buffer_tx, buffer_rx, BUF_SIZE)) {
207 		to_display_format(buffer_tx, BUF_SIZE, buffer_print_tx);
208 		to_display_format(buffer_rx, BUF_SIZE, buffer_print_rx);
209 		LOG_ERR("Buffer contents are different: %s",
210 			    buffer_print_tx);
211 		LOG_ERR("                           vs: %s",
212 			    buffer_print_rx);
213 		zassert_false(1, "Buffer contents are different");
214 		return -1;
215 	}
216 
217 	LOG_INF("Passed");
218 
219 	return 0;
220 }
221 
spi_null_tx_buf(const struct device * dev,struct spi_config * spi_conf)222 static int spi_null_tx_buf(const struct device *dev,
223 			   struct spi_config *spi_conf)
224 {
225 	static const uint8_t EXPECTED_NOP_RETURN_BUF[BUF_SIZE] = { 0 };
226 	(void)memset(buffer_rx, 0x77, BUF_SIZE);
227 
228 	const struct spi_buf tx_bufs[] = {
229 		{
230 	       /*
231 		* According to documentation, when sending NULL tx buf -
232 		*  NOP frames should be sent on MOSI line
233 		*/
234 			.buf = NULL,
235 			.len = BUF_SIZE,
236 		},
237 	};
238 	const struct spi_buf rx_bufs[] = {
239 		{
240 			.buf = buffer_rx,
241 			.len = BUF_SIZE,
242 		},
243 	};
244 	const struct spi_buf_set tx = {
245 		.buffers = tx_bufs,
246 		.count = ARRAY_SIZE(tx_bufs)
247 	};
248 	const struct spi_buf_set rx = {
249 		.buffers = rx_bufs,
250 		.count = ARRAY_SIZE(rx_bufs)
251 	};
252 
253 	int ret;
254 
255 	LOG_INF("Start null tx");
256 
257 	ret = spi_transceive(dev, spi_conf, &tx, &rx);
258 	if (ret) {
259 		LOG_ERR("Code %d", ret);
260 		zassert_false(ret, "SPI transceive failed");
261 		return ret;
262 	}
263 
264 
265 	if (memcmp(buffer_rx, EXPECTED_NOP_RETURN_BUF, BUF_SIZE)) {
266 		to_display_format(buffer_rx, BUF_SIZE, buffer_print_rx);
267 		LOG_ERR("Rx Buffer should contain NOP frames but got: %s",
268 			buffer_print_rx);
269 		zassert_false(1, "Buffer not as expected");
270 		return -1;
271 	}
272 
273 	LOG_INF("Passed");
274 
275 	return 0;
276 }
277 
spi_rx_half_start(const struct device * dev,struct spi_config * spi_conf)278 static int spi_rx_half_start(const struct device *dev,
279 			     struct spi_config *spi_conf)
280 {
281 	const struct spi_buf tx_bufs[] = {
282 		{
283 			.buf = buffer_tx,
284 			.len = BUF_SIZE,
285 		},
286 	};
287 	const struct spi_buf rx_bufs[] = {
288 		{
289 			.buf = buffer_rx,
290 			.len = 8,
291 		},
292 	};
293 	const struct spi_buf_set tx = {
294 		.buffers = tx_bufs,
295 		.count = ARRAY_SIZE(tx_bufs)
296 	};
297 	const struct spi_buf_set rx = {
298 		.buffers = rx_bufs,
299 		.count = ARRAY_SIZE(rx_bufs)
300 	};
301 	int ret;
302 
303 	LOG_INF("Start half start");
304 
305 	(void)memset(buffer_rx, 0, BUF_SIZE);
306 
307 	ret = spi_transceive(dev, spi_conf, &tx, &rx);
308 	if (ret) {
309 		LOG_ERR("Code %d", ret);
310 		zassert_false(ret, "SPI transceive failed");
311 		return -1;
312 	}
313 
314 	if (memcmp(buffer_tx, buffer_rx, 8)) {
315 		to_display_format(buffer_tx, 8, buffer_print_tx);
316 		to_display_format(buffer_rx, 8, buffer_print_rx);
317 		LOG_ERR("Buffer contents are different: %s",
318 			    buffer_print_tx);
319 		LOG_ERR("                           vs: %s",
320 			    buffer_print_rx);
321 		zassert_false(1, "Buffer contents are different");
322 		return -1;
323 	}
324 
325 	LOG_INF("Passed");
326 
327 	return 0;
328 }
329 
spi_rx_half_end(const struct device * dev,struct spi_config * spi_conf)330 static int spi_rx_half_end(const struct device *dev,
331 			   struct spi_config *spi_conf)
332 {
333 	const struct spi_buf tx_bufs[] = {
334 		{
335 			.buf = buffer_tx,
336 			.len = BUF_SIZE,
337 		},
338 	};
339 	const struct spi_buf rx_bufs[] = {
340 		{
341 			.buf = NULL,
342 			.len = 8,
343 		},
344 		{
345 			.buf = buffer_rx,
346 			.len = 8,
347 		},
348 	};
349 	const struct spi_buf_set tx = {
350 		.buffers = tx_bufs,
351 		.count = ARRAY_SIZE(tx_bufs)
352 	};
353 	const struct spi_buf_set rx = {
354 		.buffers = rx_bufs,
355 		.count = ARRAY_SIZE(rx_bufs)
356 	};
357 	int ret;
358 
359 	if (IS_ENABLED(CONFIG_SPI_STM32_DMA)) {
360 		LOG_INF("Skip half end");
361 		return 0;
362 	}
363 
364 	LOG_INF("Start half end");
365 
366 	(void)memset(buffer_rx, 0, BUF_SIZE);
367 
368 	ret = spi_transceive(dev, spi_conf, &tx, &rx);
369 	if (ret) {
370 		LOG_ERR("Code %d", ret);
371 		zassert_false(ret, "SPI transceive failed");
372 		return -1;
373 	}
374 
375 	if (memcmp(buffer_tx+8, buffer_rx, 8)) {
376 		to_display_format(buffer_tx + 8, 8, buffer_print_tx);
377 		to_display_format(buffer_rx, 8, buffer_print_rx);
378 		LOG_ERR("Buffer contents are different: %s",
379 			    buffer_print_tx);
380 		LOG_ERR("                           vs: %s",
381 			    buffer_print_rx);
382 		zassert_false(1, "Buffer contents are different");
383 		return -1;
384 	}
385 
386 	LOG_INF("Passed");
387 
388 	return 0;
389 }
390 
spi_rx_every_4(const struct device * dev,struct spi_config * spi_conf)391 static int spi_rx_every_4(const struct device *dev,
392 			  struct spi_config *spi_conf)
393 {
394 	const struct spi_buf tx_bufs[] = {
395 		{
396 			.buf = buffer_tx,
397 			.len = BUF_SIZE,
398 		},
399 	};
400 	const struct spi_buf rx_bufs[] = {
401 		{
402 			.buf = NULL,
403 			.len = 4,
404 		},
405 		{
406 			.buf = buffer_rx,
407 			.len = 4,
408 		},
409 		{
410 			.buf = NULL,
411 			.len = 4,
412 		},
413 		{
414 			.buf = buffer_rx + 4,
415 			.len = 4,
416 		},
417 	};
418 	const struct spi_buf_set tx = {
419 		.buffers = tx_bufs,
420 		.count = ARRAY_SIZE(tx_bufs)
421 	};
422 	const struct spi_buf_set rx = {
423 		.buffers = rx_bufs,
424 		.count = ARRAY_SIZE(rx_bufs)
425 	};
426 	int ret;
427 
428 	if (IS_ENABLED(CONFIG_SPI_STM32_DMA)) {
429 		LOG_INF("Skip every 4");
430 		return 0;
431 	}
432 
433 	if (IS_ENABLED(CONFIG_DSPI_MCUX_EDMA)) {
434 		LOG_INF("Skip every 4");
435 		return 0;
436 	}
437 
438 	LOG_INF("Start every 4");
439 
440 	(void)memset(buffer_rx, 0, BUF_SIZE);
441 
442 	ret = spi_transceive(dev, spi_conf, &tx, &rx);
443 	if (ret) {
444 		LOG_ERR("Code %d", ret);
445 		zassert_false(ret, "SPI transceive failed");
446 		return -1;
447 	}
448 
449 	if (memcmp(buffer_tx + 4, buffer_rx, 4)) {
450 		to_display_format(buffer_tx + 4, 4, buffer_print_tx);
451 		to_display_format(buffer_rx, 4, buffer_print_rx);
452 		LOG_ERR("Buffer contents are different: %s",
453 			    buffer_print_tx);
454 		LOG_ERR("                           vs: %s",
455 			    buffer_print_rx);
456 		zassert_false(1, "Buffer contents are different");
457 		return -1;
458 	} else if (memcmp(buffer_tx + 12, buffer_rx + 4, 4)) {
459 		to_display_format(buffer_tx + 12, 4, buffer_print_tx);
460 		to_display_format(buffer_rx + 4, 4, buffer_print_rx);
461 		LOG_ERR("Buffer contents are different: %s",
462 			    buffer_print_tx);
463 		LOG_ERR("                           vs: %s",
464 			    buffer_print_rx);
465 		zassert_false(1, "Buffer contents are different");
466 		return -1;
467 	}
468 
469 	LOG_INF("Passed");
470 
471 	return 0;
472 }
473 
474 #if (CONFIG_SPI_ASYNC)
475 static struct k_poll_signal async_sig = K_POLL_SIGNAL_INITIALIZER(async_sig);
476 static struct k_poll_event async_evt =
477 	K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
478 				 K_POLL_MODE_NOTIFY_ONLY,
479 				 &async_sig);
480 static K_SEM_DEFINE(caller, 0, 1);
481 K_THREAD_STACK_DEFINE(spi_async_stack, STACK_SIZE);
482 static int result = 1;
483 
spi_async_call_cb(struct k_poll_event * async_evt,struct k_sem * caller_sem,void * unused)484 static void spi_async_call_cb(struct k_poll_event *async_evt,
485 			      struct k_sem *caller_sem,
486 			      void *unused)
487 {
488 	int ret;
489 
490 	LOG_DBG("Polling...");
491 
492 	while (1) {
493 		ret = k_poll(async_evt, 1, K_MSEC(200));
494 		zassert_false(ret, "one or more events are not ready");
495 
496 		result = async_evt->signal->result;
497 		k_sem_give(caller_sem);
498 
499 		/* Reinitializing for next call */
500 		async_evt->signal->signaled = 0U;
501 		async_evt->state = K_POLL_STATE_NOT_READY;
502 	}
503 }
504 
spi_async_call(const struct device * dev,struct spi_config * spi_conf)505 static int spi_async_call(const struct device *dev,
506 			  struct spi_config *spi_conf)
507 {
508 	const struct spi_buf tx_bufs[] = {
509 		{
510 			.buf = buffer_tx,
511 			.len = BUF_SIZE,
512 		},
513 	};
514 	const struct spi_buf rx_bufs[] = {
515 		{
516 			.buf = buffer_rx,
517 			.len = BUF_SIZE,
518 		},
519 	};
520 	const struct spi_buf_set tx = {
521 		.buffers = tx_bufs,
522 		.count = ARRAY_SIZE(tx_bufs)
523 	};
524 	const struct spi_buf_set rx = {
525 		.buffers = rx_bufs,
526 		.count = ARRAY_SIZE(rx_bufs)
527 	};
528 	int ret;
529 
530 	LOG_INF("Start async call");
531 
532 	ret = spi_transceive_async(dev, spi_conf, &tx, &rx, &async_sig);
533 	if (ret == -ENOTSUP) {
534 		LOG_DBG("Not supported");
535 		return 0;
536 	}
537 
538 	if (ret) {
539 		LOG_ERR("Code %d", ret);
540 		zassert_false(ret, "SPI transceive failed");
541 		return -1;
542 	}
543 
544 	k_sem_take(&caller, K_FOREVER);
545 
546 	if (result)  {
547 		LOG_ERR("Call code %d", ret);
548 		zassert_false(result, "SPI transceive failed");
549 		return -1;
550 	}
551 
552 	LOG_INF("Passed");
553 
554 	return 0;
555 }
556 #endif
557 
spi_resource_lock_test(const struct device * lock_dev,struct spi_config * spi_conf_lock,const struct device * try_dev,struct spi_config * spi_conf_try)558 static int spi_resource_lock_test(const struct device *lock_dev,
559 				  struct spi_config *spi_conf_lock,
560 				  const struct device *try_dev,
561 				  struct spi_config *spi_conf_try)
562 {
563 	spi_conf_lock->operation |= SPI_LOCK_ON;
564 
565 	if (spi_complete_loop(lock_dev, spi_conf_lock)) {
566 		return -1;
567 	}
568 
569 	if (spi_release(lock_dev, spi_conf_lock)) {
570 		LOG_ERR("Deadlock now?");
571 		zassert_false(1, "SPI release failed");
572 		return -1;
573 	}
574 
575 	if (spi_complete_loop(try_dev, spi_conf_try)) {
576 		return -1;
577 	}
578 
579 	return 0;
580 }
581 
test_spi_loopback(void)582 void test_spi_loopback(void)
583 {
584 #if (CONFIG_SPI_ASYNC)
585 	struct k_thread async_thread;
586 	k_tid_t async_thread_id;
587 #endif
588 	const struct device *spi_slow;
589 	const struct device *spi_fast;
590 
591 	LOG_INF("SPI test on buffers TX/RX %p/%p", buffer_tx, buffer_rx);
592 
593 #if defined(CONFIG_SPI_LOOPBACK_CS_GPIO)
594 	if (cs_ctrl_gpio_config()) {
595 		return;
596 	}
597 #endif /* CONFIG_SPI_LOOPBACK_CS_GPIO */
598 
599 	spi_slow = device_get_binding(SPI_DRV_NAME);
600 	if (!spi_slow) {
601 		LOG_ERR("Cannot find %s!\n", SPI_DRV_NAME);
602 		zassert_not_null(spi_slow, "Invalid SPI device");
603 		return;
604 	}
605 
606 	spi_fast = spi_slow;
607 
608 #if (CONFIG_SPI_ASYNC)
609 	async_thread_id = k_thread_create(&async_thread,
610 					  spi_async_stack, STACK_SIZE,
611 					  (k_thread_entry_t)spi_async_call_cb,
612 					  &async_evt, &caller, NULL,
613 					  K_PRIO_COOP(7), 0, K_NO_WAIT);
614 #endif
615 
616 	LOG_INF("SPI test slow config");
617 
618 	if (spi_complete_multiple(spi_slow, &spi_cfg_slow) ||
619 	    spi_complete_loop(spi_slow, &spi_cfg_slow) ||
620 	    spi_null_tx_buf(spi_slow, &spi_cfg_slow) ||
621 	    spi_rx_half_start(spi_slow, &spi_cfg_slow) ||
622 	    spi_rx_half_end(spi_slow, &spi_cfg_slow) ||
623 	    spi_rx_every_4(spi_slow, &spi_cfg_slow)
624 #if (CONFIG_SPI_ASYNC)
625 	    || spi_async_call(spi_slow, &spi_cfg_slow)
626 #endif
627 	    ) {
628 		goto end;
629 	}
630 
631 	LOG_INF("SPI test fast config");
632 
633 	if (spi_complete_multiple(spi_fast, &spi_cfg_fast) ||
634 	    spi_complete_loop(spi_fast, &spi_cfg_fast) ||
635 	    spi_null_tx_buf(spi_fast, &spi_cfg_fast) ||
636 	    spi_rx_half_start(spi_fast, &spi_cfg_fast) ||
637 	    spi_rx_half_end(spi_fast, &spi_cfg_fast) ||
638 	    spi_rx_every_4(spi_fast, &spi_cfg_fast)
639 #if (CONFIG_SPI_ASYNC)
640 	    || spi_async_call(spi_fast, &spi_cfg_fast)
641 #endif
642 	    ) {
643 		goto end;
644 	}
645 
646 	if (spi_resource_lock_test(spi_slow, &spi_cfg_slow,
647 				   spi_fast, &spi_cfg_fast)) {
648 		goto end;
649 	}
650 
651 	LOG_INF("All tx/rx passed");
652 end:
653 #if (CONFIG_SPI_ASYNC)
654 	k_thread_abort(async_thread_id);
655 #else
656 	;
657 #endif
658 }
659 
660 /*test case main entry*/
test_main(void)661 void test_main(void)
662 {
663 	ztest_test_suite(test_spi, ztest_unit_test(test_spi_loopback));
664 	ztest_run_test_suite(test_spi);
665 }
666