| /* |
| * Copyright (c) 2016 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| /* |
| * @addtogroup t_uart_basic |
| * @{ |
| * @defgroup t_uart_fifo test_uart_fifo |
| * @brief TestPurpose: verify UART works well in fifo mode |
| * @details |
| * - Test Steps |
| * - FIFO Output: |
| * -# Set UART IRQ callback using uart_irq_callback_set(). |
| * -# Enable UART TX IRQ using uart_irq_tx_enable(). |
| * -# Output the prepared data using uart_fifo_fill(). |
| * -# Disable UART TX IRQ using uart_irq_tx_disable(). |
| * -# Compare the number of characters sent out with the |
| * original data size. |
| * - FIFO Input: |
| * -# Set UART IRQ callback using uart_irq_callback_set(). |
| * -# Enable UART RX IRQ using uart_irq_rx_enable(). |
| * -# Wait for data sent to UART console and trigger RX IRQ. |
| * -# Read data from UART console using uart_fifo_read(). |
| * -# Disable UART TX IRQ using uart_irq_rx_disable(). |
| * - Expected Results |
| * -# When test UART FIFO output, the number of characters actually |
| * sent out will be equal to the original length of the characters. |
| * -# When test UART FIFO input, the app will wait for input from UART |
| * console and exit after receiving one character. |
| * @} |
| */ |
| |
| #include "test_uart.h" |
| |
| static volatile bool data_transmitted; |
| static volatile bool data_received; |
| static int char_sent; |
| static const char fifo_data[] = "This is a FIFO test.\r\n"; |
| |
| #define DATA_SIZE (sizeof(fifo_data) - 1) |
| |
| static void uart_fifo_callback(const struct device *dev, void *user_data) |
| { |
| uint8_t recvData; |
| static int tx_data_idx; |
| int ret; |
| |
| ARG_UNUSED(user_data); |
| |
| /* Verify uart_irq_update() */ |
| if (!uart_irq_update(dev)) { |
| TC_PRINT("retval should always be 1\n"); |
| return; |
| } |
| |
| /* Verify uart_irq_tx_ready() */ |
| /* Note that TX IRQ may be disabled, but uart_irq_tx_ready() may |
| * still return true when ISR is called for another UART interrupt, |
| * hence additional check for i < DATA_SIZE. |
| */ |
| if (uart_irq_tx_ready(dev) && tx_data_idx < DATA_SIZE) { |
| /* We arrive here by "tx ready" interrupt, so should always |
| * be able to put at least one byte into a FIFO. If not, |
| * well, we'll fail test. |
| */ |
| ret = uart_fifo_fill(dev, (uint8_t *)&fifo_data[tx_data_idx], |
| DATA_SIZE - char_sent); |
| if (ret > 0) { |
| data_transmitted = true; |
| char_sent += ret; |
| tx_data_idx += ret; |
| } else { |
| uart_irq_tx_disable(dev); |
| return; |
| } |
| |
| if (tx_data_idx == DATA_SIZE) { |
| /* If we transmitted everything, stop IRQ stream, |
| * otherwise main app might never run. |
| */ |
| uart_irq_tx_disable(dev); |
| } |
| } |
| |
| /* Verify uart_irq_rx_ready() */ |
| if (uart_irq_rx_ready(dev)) { |
| /* Verify uart_fifo_read() */ |
| uart_fifo_read(dev, &recvData, 1); |
| TC_PRINT("%c", recvData); |
| |
| if ((recvData == '\n') || (recvData == '\r')) { |
| data_received = true; |
| } |
| } |
| } |
| |
| static int test_fifo_read(void) |
| { |
| const struct device *const uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console)); |
| |
| if (!device_is_ready(uart_dev)) { |
| TC_PRINT("UART device not ready\n"); |
| return TC_FAIL; |
| } |
| |
| /* Verify uart_irq_callback_set() */ |
| uart_irq_callback_set(uart_dev, uart_fifo_callback); |
| |
| /* Enable Tx/Rx interrupt before using fifo */ |
| /* Verify uart_irq_rx_enable() */ |
| uart_irq_rx_enable(uart_dev); |
| |
| TC_PRINT("Please send characters to serial console\n"); |
| |
| data_received = false; |
| while (data_received == false) { |
| /* Allow other thread/workqueue to work. */ |
| k_yield(); |
| } |
| |
| /* Verify uart_irq_rx_disable() */ |
| uart_irq_rx_disable(uart_dev); |
| |
| return TC_PASS; |
| } |
| |
| static int test_fifo_fill(void) |
| { |
| const struct device *const uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console)); |
| |
| if (!device_is_ready(uart_dev)) { |
| TC_PRINT("UART device not ready\n"); |
| return TC_FAIL; |
| } |
| |
| char_sent = 0; |
| |
| /* Verify uart_irq_callback_set() */ |
| uart_irq_callback_set(uart_dev, uart_fifo_callback); |
| |
| /* Enable Tx/Rx interrupt before using fifo */ |
| /* Verify uart_irq_tx_enable() */ |
| uart_irq_tx_enable(uart_dev); |
| |
| k_sleep(K_MSEC(500)); |
| |
| /* Verify uart_irq_tx_disable() */ |
| uart_irq_tx_disable(uart_dev); |
| |
| if (!data_transmitted) { |
| return TC_FAIL; |
| } |
| |
| if (char_sent == DATA_SIZE) { |
| return TC_PASS; |
| } else { |
| return TC_FAIL; |
| } |
| |
| } |
| |
| #if CONFIG_SHELL |
| void test_uart_fifo_fill(void) |
| #else |
| ZTEST(uart_basic_api, test_uart_fifo_fill) |
| #endif |
| { |
| #ifndef CONFIG_UART_INTERRUPT_DRIVEN |
| ztest_test_skip(); |
| #endif |
| zassert_true(test_fifo_fill() == TC_PASS); |
| } |
| |
| #if CONFIG_SHELL |
| void test_uart_fifo_read(void) |
| #else |
| ZTEST(uart_basic_api, test_uart_fifo_read) |
| #endif |
| { |
| #ifndef CONFIG_UART_INTERRUPT_DRIVEN |
| ztest_test_skip(); |
| #endif |
| zassert_true(test_fifo_read() == TC_PASS); |
| } |