1 /*
2  * Copyright (c) 2016 Intel Corporation
3  * Copyright (c) 2025 Analog Devices, Inc
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include "test_uart.h"
9 
10 static volatile bool data_received;
11 static volatile bool data_transmit_done;
12 static volatile bool data_receive_done;
13 static int char_sent;
14 static int tx_size;
15 static const char fifo_data[] = "This is a FIFO test.";
16 
17 #define DATA_SIZE (sizeof(fifo_data))
18 
uart_fifo_callback(const struct device * dev,void * user_data)19 static void uart_fifo_callback(const struct device *dev, void *user_data)
20 {
21 	static int tx_data_idx;
22 	int ret;
23 
24 	ARG_UNUSED(user_data);
25 
26 	/* Verify uart_irq_update() */
27 	if (!uart_irq_update(dev)) {
28 		TC_PRINT("retval should always be 1\n");
29 		return;
30 	}
31 
32 	/* Verify uart_irq_tx_ready() */
33 	/* Note that TX IRQ may be disabled, but uart_irq_tx_ready() may
34 	 * still return true when ISR is called for another UART interrupt,
35 	 * hence additional check for i < DATA_SIZE.
36 	 */
37 	if (uart_irq_tx_ready(dev) && tx_data_idx < DATA_SIZE) {
38 		/* We arrive here by "tx ready" interrupt, so should always
39 		 * be able to put at least one byte into a FIFO. If not,
40 		 * well, we'll fail test.
41 		 */
42 		tx_size++;
43 		ret = uart_fifo_fill(dev, (uint8_t *)&fifo_data[tx_data_idx],
44 				     MIN(tx_size, DATA_SIZE - char_sent));
45 		if (ret > 0) {
46 			char_sent += ret;
47 			tx_data_idx += ret;
48 		} else {
49 			TC_PRINT("Failed to fill %d to %s\n", ret, dev->name);
50 			return;
51 		}
52 
53 		if (tx_data_idx == DATA_SIZE) {
54 			/* If we transmitted everything, stop IRQ stream,
55 			 * otherwise main app might never run.
56 			 */
57 			data_transmit_done = true;
58 		}
59 	}
60 }
61 
test_fifo_tx_sizes(void)62 static int test_fifo_tx_sizes(void)
63 {
64 	const struct device *const uart_dev = DEVICE_DT_GET(UART_NODE);
65 
66 	if (!device_is_ready(uart_dev)) {
67 		TC_PRINT("UART device not ready\n");
68 		return TC_FAIL;
69 	}
70 
71 	char_sent = 0;
72 
73 	/* Verify uart_irq_callback_set() */
74 	uart_irq_callback_set(uart_dev, uart_fifo_callback);
75 
76 	/* Enable Tx/Rx interrupt before using fifo */
77 	/* Verify uart_irq_tx_enable() */
78 	uart_irq_tx_enable(uart_dev);
79 
80 	k_sleep(K_MSEC(500));
81 
82 	/* Verify uart_irq_tx_disable() */
83 	uart_irq_tx_disable(uart_dev);
84 
85 	if (!data_transmit_done) {
86 		return TC_FAIL;
87 	}
88 
89 	return TC_PASS;
90 }
91 
ZTEST(uart_interrupt_api,test_uart_fifo_tx_sizes)92 ZTEST(uart_interrupt_api, test_uart_fifo_tx_sizes)
93 {
94 #ifndef CONFIG_UART_INTERRUPT_DRIVEN
95 	ztest_test_skip();
96 #endif
97 	zassert_true(test_fifo_tx_sizes() == TC_PASS);
98 }
99 
100 ZTEST_SUITE(uart_interrupt_api, NULL, NULL, NULL, NULL, NULL);
101