/*
 * Copyright (c) 2019 omSquare s.r.o.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/drivers/uart.h>
#include <zephyr/kernel.h>
#include <SEGGER_RTT.h>

#define DT_DRV_COMPAT segger_rtt_uart

struct uart_rtt_config {
	void *up_buffer;
	size_t up_size;
	void *down_buffer;
	size_t down_size;
	uint8_t channel;
};

struct uart_rtt_data {
#ifdef CONFIG_UART_ASYNC_API
	uart_callback_t callback;
	void *user_data;
#endif /* CONFIG_UART_ASYNC_API */
};

static int uart_rtt_init(const struct device *dev)
{
	/*
	 * Channel 0 is initialized at compile-time, Kconfig ensures that
	 * it is configured in correct, non-blocking mode. Other channels
	 * need to be configured at run-time.
	 */
	if (dev->config) {
		const struct uart_rtt_config *cfg = dev->config;

		SEGGER_RTT_ConfigUpBuffer(cfg->channel, dev->name,
					  cfg->up_buffer, cfg->up_size,
					  SEGGER_RTT_MODE_NO_BLOCK_SKIP);
		SEGGER_RTT_ConfigDownBuffer(cfg->channel, dev->name,
					    cfg->down_buffer, cfg->down_size,
					    SEGGER_RTT_MODE_NO_BLOCK_SKIP);
	}
	return 0;
}

/**
 * @brief Poll the device for input.
 *
 * @param dev UART device struct
 * @param c Pointer to character
 *
 * @return 0 if a character arrived, -1 if the input buffer if empty.
 */

static int uart_rtt_poll_in(const struct device *dev, unsigned char *c)
{
	const struct uart_rtt_config *config = dev->config;
	unsigned int ch = config ? config->channel : 0;
	unsigned int ret = SEGGER_RTT_Read(ch, c, 1);

	return ret ? 0 : -1;
}

/**
 * @brief Output a character in polled mode.
 *
 * @param dev UART device struct
 * @param c Character to send
 */
static void uart_rtt_poll_out(const struct device *dev, unsigned char c)
{
	const struct uart_rtt_config *config = dev->config;
	unsigned int ch = config ? config->channel : 0;

	SEGGER_RTT_Write(ch, &c, 1);
}

#ifdef CONFIG_UART_ASYNC_API

static int uart_rtt_callback_set(const struct device *dev,
				 uart_callback_t callback, void *user_data)
{
	struct uart_rtt_data *data = dev->data;

	data->callback = callback;
	data->user_data = user_data;
	return 0;
}

static int uart_rtt_tx(const struct device *dev,
		       const uint8_t *buf, size_t len, int32_t timeout)
{
	const struct uart_rtt_config *cfg = dev->config;
	struct uart_rtt_data *data = dev->data;
	unsigned int ch = cfg ? cfg->channel : 0;

	ARG_UNUSED(timeout);

	/* Output the buffer */
	SEGGER_RTT_Write(ch, buf, len);

	/* Send the TX complete callback */
	if (data->callback) {
		struct uart_event evt = {
			.type = UART_TX_DONE,
			.data.tx.buf = buf,
			.data.tx.len = len
		};
		data->callback(dev, &evt, data->user_data);
	}

	return 0;
}

static int uart_rtt_tx_abort(const struct device *dev)
{
	/* RTT TX is a memcpy, there is never a transmission to abort */
	ARG_UNUSED(dev);

	return -EFAULT;
}

static int uart_rtt_rx_enable(const struct device *dev,
			      uint8_t *buf, size_t len, int32_t timeout)
{
	/* SEGGER RTT reception is implemented as a direct memory write to RAM
	 * by a connected debugger. As such there is no hardware interrupt
	 * or other mechanism to know when the debugger has added data to be
	 * read. Asynchronous RX does not make sense in such a context, and is
	 * therefore not supported.
	 */
	ARG_UNUSED(dev);
	ARG_UNUSED(buf);
	ARG_UNUSED(len);
	ARG_UNUSED(timeout);

	return -ENOTSUP;
}

static int uart_rtt_rx_disable(const struct device *dev)
{
	/* Asynchronous RX not supported, see uart_rtt_rx_enable */
	ARG_UNUSED(dev);

	return -EFAULT;
}

static int uart_rtt_rx_buf_rsp(const struct device *dev,
			       uint8_t *buf, size_t len)
{
	/* Asynchronous RX not supported, see uart_rtt_rx_enable */
	ARG_UNUSED(dev);
	ARG_UNUSED(buf);
	ARG_UNUSED(len);

	return -ENOTSUP;
}

#endif /* CONFIG_UART_ASYNC_API */

static const struct uart_driver_api uart_rtt_driver_api = {
	.poll_in = uart_rtt_poll_in,
	.poll_out = uart_rtt_poll_out,
#ifdef CONFIG_UART_ASYNC_API
	.callback_set = uart_rtt_callback_set,
	.tx = uart_rtt_tx,
	.tx_abort = uart_rtt_tx_abort,
	.rx_enable = uart_rtt_rx_enable,
	.rx_buf_rsp = uart_rtt_rx_buf_rsp,
	.rx_disable = uart_rtt_rx_disable,
#endif /* CONFIG_UART_ASYNC_API */
};

#define UART_RTT(idx)                   DT_NODELABEL(rtt##idx)
#define UART_RTT_PROP(idx, prop)        DT_PROP(UART_RTT(idx), prop)
#define UART_RTT_CONFIG_NAME(idx)       uart_rtt##idx##_config

#define UART_RTT_CONFIG(idx)						    \
	static								    \
	uint8_t uart_rtt##idx##_tx_buf[UART_RTT_PROP(idx, tx_buffer_size)]; \
	static								    \
	uint8_t uart_rtt##idx##_rx_buf[UART_RTT_PROP(idx, rx_buffer_size)]; \
									    \
	static const struct uart_rtt_config UART_RTT_CONFIG_NAME(idx) = {   \
		.up_buffer = uart_rtt##idx##_tx_buf,			    \
		.up_size = sizeof(uart_rtt##idx##_tx_buf),		    \
		.down_buffer = uart_rtt##idx##_rx_buf,			    \
		.down_size = sizeof(uart_rtt##idx##_rx_buf),		    \
		.channel = idx,						    \
	}

#define UART_RTT_INIT(idx, config)					      \
	struct uart_rtt_data uart_rtt##idx##_data;			      \
									      \
	DEVICE_DT_DEFINE(UART_RTT(idx), uart_rtt_init, NULL, \
			    &uart_rtt##idx##_data, config,		      \
			    PRE_KERNEL_2, CONFIG_SERIAL_INIT_PRIORITY,	      \
			    &uart_rtt_driver_api)

#ifdef CONFIG_UART_RTT_0
UART_RTT_INIT(0, NULL);
#endif

#ifdef CONFIG_UART_RTT_1
UART_RTT_CONFIG(1);
UART_RTT_INIT(1, &UART_RTT_CONFIG_NAME(1));
#endif

#ifdef CONFIG_UART_RTT_2
UART_RTT_CONFIG(2);
UART_RTT_INIT(2, &UART_RTT_CONFIG_NAME(2));
#endif

#ifdef CONFIG_UART_RTT_3
UART_RTT_CONFIG(3);
UART_RTT_INIT(3, &UART_RTT_CONFIG_NAME(3));
#endif
