/*
 * 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;

	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.
		 */
		if (uart_fifo_fill(dev,
				   (uint8_t *)&fifo_data[tx_data_idx++], 1) > 0) {
			data_transmitted = true;
			char_sent++;
		}

		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);
}
