/*
 * Copyright (c) 2019 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 *
 * @brief Test app to illustrate I2S transmission/reception on Intel S1000 CRB
 *
 * The i2s_cavs driver is being used.
 *
 * In this test app, I2S transmission and reception are tested as follows:
 * I2S port #3 of Intel S1000 is configured for bidirectional mode
 *     i.e., I2S_DIR_TX and I2S_DIR_RX
 * After each frame is received, it is sent/looped back on the same I2S
 * The transmit direction is started after 2 frames are queued. This is done to
 * ensure that there is enough data for the DMA and I2S are available when the
 * start operation is triggered
 */

#include <zephyr.h>
#include <sys/printk.h>

#include <device.h>
#include <drivers/i2s.h>

#define I2S_DEV_NAME "I2S_3"
#define NUM_I2S_BUFFERS 4

/* size of stack area used by each thread */
#define STACKSIZE               2048

/* scheduling priority used by each thread */
#define PRIORITY                7

/* delay between greetings (in ms) */
#define SLEEPTIME               K_MSEC(500)

extern struct k_sem thread_sem;

#define NUM_OF_CHANNELS		2
#define FRAME_CLK_FREQ		48000
#define I2S_WORDSIZE		32
#define BLOCK_SIZE		192
#define BLOCK_SIZE_BYTES	(BLOCK_SIZE * sizeof(int32_t))
#define FRAMES_PER_ITERATION	50
#define TIMEOUT			2000

static char __aligned(4) audio_buffers[BLOCK_SIZE_BYTES * NUM_I2S_BUFFERS];
static struct k_mem_slab i2s_mem_slab;

/** Configure I2S bidirectional transfer. */
void test_i2s_bidirectional_transfer_configure(void)
{
	int ret;
	const struct device *dev_i2s;
	struct i2s_config i2s_cfg;

	k_mem_slab_init(&i2s_mem_slab, audio_buffers, BLOCK_SIZE_BYTES,
			NUM_I2S_BUFFERS);

	dev_i2s = device_get_binding(I2S_DEV_NAME);
	if (!dev_i2s) {
		printk("I2S: Device driver not found.\n");
		return;
	}

	/* Configure */
	i2s_cfg.word_size = I2S_WORDSIZE;
	i2s_cfg.channels = NUM_OF_CHANNELS;
	i2s_cfg.format = I2S_FMT_DATA_FORMAT_I2S | I2S_FMT_CLK_NF_NB;
	i2s_cfg.options = I2S_OPT_FRAME_CLK_MASTER | I2S_OPT_BIT_CLK_MASTER;
	i2s_cfg.frame_clk_freq = FRAME_CLK_FREQ;
	i2s_cfg.block_size = BLOCK_SIZE_BYTES;
	i2s_cfg.mem_slab = &i2s_mem_slab;
	i2s_cfg.timeout = TIMEOUT;

	ret = i2s_configure(dev_i2s, I2S_DIR_TX, &i2s_cfg);
	if (ret != 0) {
		printk("I2S_TX configuration failed with %d error\n", ret);
		return;
	}
	ret = i2s_configure(dev_i2s, I2S_DIR_RX, &i2s_cfg);
	if (ret != 0) {
		printk("I2S_RX configuration failed with %d error\n", ret);
		return;
	}
}

/** @brief Bi-Directional I2S transfer.
 *
 * - TX/RX stream START trigger starts transmission/reception.
 * - TX/RX stream STOP trigger stops the transmission/reception.
 */
void test_i2s_bidirectional_transfer(void)
{
	const struct device *dev_i2s;
	int frames = 0;
	void *buffer;
	size_t size;
	int ret;

	printk("Testing I2S bidirectional transfer\n");
	dev_i2s = device_get_binding(I2S_DEV_NAME);
	if (!dev_i2s) {
		printk("I2S: Device driver not found.\n");
		return;
	}

	/* Start reception */
	ret = i2s_trigger(dev_i2s, I2S_DIR_RX, I2S_TRIGGER_START);
	if (ret != 0) {
		printk("RX Start failed with %d error\n", ret);
		return;
	}

	/* iteratively receive a frame and send it back */
	while (frames++ < FRAMES_PER_ITERATION) {
		ret = i2s_read(dev_i2s, &buffer, &size);
		if (ret != 0) {
			printk("i2s_read failed with %d error\n", ret);
			return;
		}

		/* send the buffer */
		ret = i2s_write(dev_i2s, buffer, size);
		if (ret != 0) {
			printk("i2s_write failed with %d error\n", ret);
			return;
		}

		/* Start transmission after 2 frames are queued */
		if (frames == 2) {
			ret = i2s_trigger(dev_i2s, I2S_DIR_TX,
					I2S_TRIGGER_START);
			if (ret != 0) {
				printk("TX Start failed with %d error\n", ret);
				return;
			}
		}
	}

	/* Stop transmission */
	ret = i2s_trigger(dev_i2s, I2S_DIR_TX, I2S_TRIGGER_STOP);
	if (ret != 0) {
		printk("TX Stop failed with %d error\n", ret);
		return;
	}

	/* Stop reception */
	ret = i2s_trigger(dev_i2s, I2S_DIR_RX, I2S_TRIGGER_STOP);
	if (ret != 0) {
		printk("RX Stop failed with %d error\n", ret);
		return;
	}
	printk("Completed %d bidirectional frames on " I2S_DEV_NAME "\n",
			FRAMES_PER_ITERATION);
}

/* i2s_thread is a static thread that is spawned automatically */
void i2s_thread(void *dummy1, void *dummy2, void *dummy3)
{
	ARG_UNUSED(dummy1);
	ARG_UNUSED(dummy2);
	ARG_UNUSED(dummy3);

	test_i2s_bidirectional_transfer_configure();

	while (1) {
		k_sem_take(&thread_sem, K_FOREVER);

		test_i2s_bidirectional_transfer();

		/* let other threads have a turn */
		k_sem_give(&thread_sem);

		/* wait a while */
		k_sleep(SLEEPTIME);
	}
}

K_THREAD_DEFINE(i2s_thread_id, STACKSIZE, i2s_thread, NULL, NULL, NULL,
		PRIORITY, 0, 0);
