/*
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/drivers/pinctrl.h>

#include <nrfx_spim.h>
#include <nrfx_uarte.h>
#include <drivers/src/prs/nrfx_prs.h>
#include <zephyr/irq.h>

#define TRANSFER_LENGTH 10

/* Devicetree nodes corresponding to the peripherals to be used directly via
 * nrfx drivers (SPIM2 and UARTE2).
 */
#define SPIM_NODE  DT_NODELABEL(spi2)
#define UARTE_NODE DT_NODELABEL(uart2)

/* Devicetree node corresponding to the peripheral to be used via Zephyr SPI
 * driver (SPIM1), in the background transfer.
 */
#define SPI_DEV_NODE DT_NODELABEL(spi1)

static nrfx_spim_t spim = NRFX_SPIM_INSTANCE(2);
static nrfx_uarte_t uarte = NRFX_UARTE_INSTANCE(2);
static bool spim_initialized;
static bool uarte_initialized;
static volatile size_t received;
static K_SEM_DEFINE(transfer_finished, 0, 1);

static enum {
	PERFORM_TRANSFER,
	SWITCH_PERIPHERAL
} user_request;
static K_SEM_DEFINE(button_pressed, 0, 1);

static void sw0_handler(const struct device *dev, struct gpio_callback *cb,
			uint32_t pins)
{
	user_request = PERFORM_TRANSFER;
	k_sem_give(&button_pressed);
}

static void sw1_handler(const struct device *dev, struct gpio_callback *cb,
			uint32_t pins)
{
	user_request = SWITCH_PERIPHERAL;
	k_sem_give(&button_pressed);
}

static bool init_buttons(void)
{
	static const struct button_spec {
		struct gpio_dt_spec gpio;
		char const *label;
		char const *action;
		gpio_callback_handler_t handler;
	} btn_spec[] = {
		{
			GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios),
			DT_PROP(DT_ALIAS(sw0), label),
			"trigger a transfer",
			sw0_handler
		},
		{
			GPIO_DT_SPEC_GET(DT_ALIAS(sw1), gpios),
			DT_PROP(DT_ALIAS(sw1), label),
			"switch the type of peripheral",
			sw1_handler
		},
	};
	static struct gpio_callback btn_cb_data[ARRAY_SIZE(btn_spec)];

	for (int i = 0; i < ARRAY_SIZE(btn_spec); ++i) {
		const struct button_spec *btn = &btn_spec[i];
		int ret;

		if (!gpio_is_ready_dt(&btn->gpio)) {
			printk("%s is not ready\n", btn->gpio.port->name);
			return false;
		}

		ret = gpio_pin_configure_dt(&btn->gpio, GPIO_INPUT);
		if (ret < 0) {
			printk("Failed to configure %s pin %d: %d\n",
				btn->gpio.port->name, btn->gpio.pin, ret);
			return false;
		}

		ret = gpio_pin_interrupt_configure_dt(&btn->gpio,
						      GPIO_INT_EDGE_TO_ACTIVE);
		if (ret < 0) {
			printk("Failed to configure interrupt on %s pin %d: %d\n",
				btn->gpio.port->name, btn->gpio.pin, ret);
			return false;
		}

		gpio_init_callback(&btn_cb_data[i],
				   btn->handler, BIT(btn->gpio.pin));
		gpio_add_callback(btn->gpio.port, &btn_cb_data[i]);
		printk("-> press \"%s\" to %s\n", btn->label, btn->action);
	}

	return true;
}

static void spim_handler(const nrfx_spim_evt_t *p_event, void *p_context)
{
	if (p_event->type == NRFX_SPIM_EVENT_DONE) {
		k_sem_give(&transfer_finished);
	}
}

static bool switch_to_spim(void)
{
	int ret;
	nrfx_err_t err;

	PINCTRL_DT_DEFINE(SPIM_NODE);

	if (spim_initialized) {
		return true;
	}

	/* If the UARTE is currently initialized, it must be deinitialized
	 * before the SPIM can be used.
	 */
	if (uarte_initialized) {
		nrfx_uarte_uninit(&uarte);
		uarte_initialized = false;
	}

	nrfx_spim_config_t spim_config = NRFX_SPIM_DEFAULT_CONFIG(
		NRF_SPIM_PIN_NOT_CONNECTED,
		NRF_SPIM_PIN_NOT_CONNECTED,
		NRF_SPIM_PIN_NOT_CONNECTED,
		NRF_DT_GPIOS_TO_PSEL(SPIM_NODE, cs_gpios));
	spim_config.frequency = NRF_SPIM_FREQ_1M;
	spim_config.skip_gpio_cfg = true;
	spim_config.skip_psel_cfg = true;

	ret = pinctrl_apply_state(PINCTRL_DT_DEV_CONFIG_GET(SPIM_NODE),
				  PINCTRL_STATE_DEFAULT);
	if (ret < 0) {
		return ret;
	}

	err = nrfx_spim_init(&spim, &spim_config, spim_handler, NULL);
	if (err != NRFX_SUCCESS) {
		printk("nrfx_spim_init() failed: 0x%08x\n", err);
		return false;
	}

	spim_initialized = true;
	printk("Switched to SPIM\n");
	return true;
}

static bool spim_transfer(const uint8_t *tx_data, size_t tx_data_len,
			  uint8_t *rx_buf, size_t rx_buf_size)
{
	nrfx_err_t err;
	nrfx_spim_xfer_desc_t xfer_desc = {
		.p_tx_buffer = tx_data,
		.tx_length = tx_data_len,
		.p_rx_buffer = rx_buf,
		.rx_length = rx_buf_size,
	};

	err = nrfx_spim_xfer(&spim, &xfer_desc, 0);
	if (err != NRFX_SUCCESS) {
		printk("nrfx_spim_xfer() failed: 0x%08x\n", err);
		return false;
	}

	if (k_sem_take(&transfer_finished, K_MSEC(100)) != 0) {
		printk("SPIM transfer timeout\n");
		return false;
	}

	received = rx_buf_size;
	return true;
}

static void uarte_handler(const nrfx_uarte_event_t *p_event, void *p_context)
{
	if (p_event->type == NRFX_UARTE_EVT_RX_DONE) {
		received = p_event->data.rx.bytes;
		k_sem_give(&transfer_finished);
	} else if (p_event->type == NRFX_UARTE_EVT_ERROR) {
		received = 0;
		k_sem_give(&transfer_finished);
	}
}

static bool switch_to_uarte(void)
{
	int ret;
	nrfx_err_t err;

	PINCTRL_DT_DEFINE(UARTE_NODE);

	if (uarte_initialized) {
		return true;
	}

	/* If the SPIM is currently initialized, it must be deinitialized
	 * before the UARTE can be used.
	 */
	if (spim_initialized) {
		nrfx_spim_uninit(&spim);
		spim_initialized = false;
	}

	nrfx_uarte_config_t uarte_config = NRFX_UARTE_DEFAULT_CONFIG(
		NRF_UARTE_PSEL_DISCONNECTED,
		NRF_UARTE_PSEL_DISCONNECTED);
	uarte_config.baudrate = NRF_UARTE_BAUDRATE_1000000;
	uarte_config.skip_gpio_cfg = true;
	uarte_config.skip_psel_cfg = true;

	ret = pinctrl_apply_state(PINCTRL_DT_DEV_CONFIG_GET(UARTE_NODE),
				  PINCTRL_STATE_DEFAULT);
	if (ret < 0) {
		return ret;
	}

	err = nrfx_uarte_init(&uarte, &uarte_config, uarte_handler);
	if (err != NRFX_SUCCESS) {
		printk("nrfx_uarte_init() failed: 0x%08x\n", err);
		return false;
	}

	uarte_initialized = true;
	printk("Switched to UARTE\n");
	return true;
}

static bool uarte_transfer(const uint8_t *tx_data, size_t tx_data_len,
			   uint8_t *rx_buf, size_t rx_buf_size)
{
	nrfx_err_t err;

	err = nrfx_uarte_rx(&uarte, rx_buf, rx_buf_size);
	if (err != NRFX_SUCCESS) {
		printk("nrfx_uarte_rx() failed: 0x%08x\n", err);
		return false;
	}

	err = nrfx_uarte_tx(&uarte, tx_data, tx_data_len, 0);
	if (err != NRFX_SUCCESS) {
		printk("nrfx_uarte_tx() failed: 0x%08x\n", err);
		return false;
	}

	if (k_sem_take(&transfer_finished, K_MSEC(100)) != 0) {
		/* The UARTE transfer finishes when the RX buffer is completely
		 * filled. In case the UARTE receives less data (or nothing at
		 * all) within the specified time, taking the semaphore will
		 * fail. In such case, stop the reception and end the transfer
		 * this way. Now taking the semaphore should be successful.
		 */
		nrfx_uarte_rx_abort(&uarte, 0, 0);
		if (k_sem_take(&transfer_finished, K_MSEC(10)) != 0) {
			printk("UARTE transfer timeout\n");
			return false;
		}
	}

	return true;
}

static void buffer_dump(const uint8_t *buffer, size_t length)
{
	for (int i = 0; i < length; ++i) {
		printk(" %02X", buffer[i]);
	}
	printk("\n");
}

static bool background_transfer(const struct device *spi_dev)
{
	static const uint8_t tx_buffer[] = "Nordic Semiconductor";
	static uint8_t rx_buffer[sizeof(tx_buffer)];
	static const struct spi_config spi_dev_cfg = {
		.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8) |
			     SPI_TRANSFER_MSB,
		.frequency = 1000000,
		.cs = {
			.gpio = GPIO_DT_SPEC_GET(SPI_DEV_NODE, cs_gpios),
		},
	};
	static const struct spi_buf tx_buf = {
		.buf = (void *)tx_buffer,
		.len = sizeof(tx_buffer)
	};
	static const struct spi_buf_set tx = {
		.buffers = &tx_buf,
		.count = 1
	};
	static const struct spi_buf rx_buf = {
		.buf = rx_buffer,
		.len = sizeof(rx_buffer),
	};
	static const struct spi_buf_set rx = {
		.buffers = &rx_buf,
		.count = 1
	};
	int ret;

	printk("-- Background transfer on \"%s\" --\n", spi_dev->name);

	ret = spi_transceive(spi_dev, &spi_dev_cfg, &tx, &rx);
	if (ret < 0) {
		printk("Background transfer failed: %d\n", ret);
		return false;
	}

	printk("Tx:");
	buffer_dump(tx_buf.buf, tx_buf.len);
	printk("Rx:");
	buffer_dump(rx_buf.buf, rx_buf.len);
	return true;
}

int main(void)
{
	printk("nrfx PRS example on %s\n", CONFIG_BOARD);

	static uint8_t tx_buffer[TRANSFER_LENGTH];
	static uint8_t rx_buffer[sizeof(tx_buffer)];
	uint8_t fill_value = 0;
	const struct device *const spi_dev = DEVICE_DT_GET(SPI_DEV_NODE);

	if (!device_is_ready(spi_dev)) {
		printk("%s is not ready\n", spi_dev->name);
		return 0;
	}

	/* Install a shared interrupt handler for peripherals used via
	 * nrfx drivers. It will dispatch the interrupt handling to the
	 * driver for the currently initialized peripheral.
	 */
	BUILD_ASSERT(
		DT_IRQ(SPIM_NODE, priority) == DT_IRQ(UARTE_NODE, priority),
		"Interrupt priorities for SPIM_NODE and UARTE_NODE need to be equal.");
	IRQ_CONNECT(DT_IRQN(SPIM_NODE), DT_IRQ(SPIM_NODE, priority),
		    nrfx_isr, nrfx_prs_box_2_irq_handler, 0);

	if (!init_buttons()) {
		return 0;
	}

	/* Initially use the SPIM. */
	if (!switch_to_spim()) {
		return 0;
	}

	for (;;) {
		/* Wait 5 seconds for the user to press a button. If no button
		 * is pressed within this time, perform the background transfer.
		 * Otherwise, realize the operation requested by the user.
		 */
		if (k_sem_take(&button_pressed, K_MSEC(5000)) != 0) {
			if (!background_transfer(spi_dev)) {
				return 0;
			}
		} else {
			bool res;

			switch (user_request) {
			case PERFORM_TRANSFER:
				printk("-- %s transfer --\n",
					spim_initialized ? "SPIM" : "UARTE");
				received = 0;
				for (int i = 0; i < sizeof(tx_buffer); ++i) {
					tx_buffer[i] = fill_value++;
				}
				res = (spim_initialized
				       ? spim_transfer(tx_buffer,
						       sizeof(tx_buffer),
						       rx_buffer,
						       sizeof(rx_buffer))
				       : uarte_transfer(tx_buffer,
							sizeof(tx_buffer),
							rx_buffer,
							sizeof(rx_buffer)));
				if (!res) {
					return 0;
				}

				printk("Tx:");
				buffer_dump(tx_buffer, sizeof(tx_buffer));
				printk("Rx:");
				buffer_dump(rx_buffer, received);
				break;

			case SWITCH_PERIPHERAL:
				res = (spim_initialized
				       ? switch_to_uarte()
				       : switch_to_spim());
				if (!res) {
					return 0;
				}
				break;
			}
		}
	}
	return 0;
}
