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

#include <ztest.h>
#include <zephyr/drivers/spi.h>

#define TEST_FREQ_HZ 24000000U
#define W25Q128_JEDEC_ID 0x001840efU
#define SPI_DEV DT_LABEL(DT_NODELABEL(spi0))

#define TEST_BUF_SIZE 4096U
#define MAX_TX_BUF 2

#define SPI_STATUS2_QE 0x02U
#define SPI_READ_JEDEC_ID 0x9FU
#define SPI_READ_STATUS1 0x05U
#define SPI_READ_STATUS2 0x35U
#define SPI_WRITE_STATUS2 0x31U
#define SPI_WRITE_ENABLE_VS 0x50U
#define SPI_WRITE_ENABLE 0x06U
#define SPI_SECTOR_ERASE 0x20U
#define SPI_SINGLE_WRITE_DATA 0x02U
#define SPI_QUAD_WRITE_DATA 0x32U

/* bits[7:0] = spi opcode,
 * bits[15:8] = bytes number of dummy clocks */
#define SPI_FAST_READ_DATA 0x080BU
#define SPI_DUAL_FAST_READ_DATA 0x083BU
#define SPI_QUAD_FAST_READ_DATA 0x086BU
#define SPI_OCTAL_QUAD_READ_DATA 0xE3U

#define BUF_SIZE 11
uint8_t buffer_tx[] = "0123456789\0";
#define BUF_SIZE_2 7
uint8_t buffer_tx_2[] = "abcdef\0";

#define SPI_TEST_ADDRESS 0x000010U
#define SPI_TEST_ADDRESS_2 0x000020U

static uint8_t safbuf[TEST_BUF_SIZE] __aligned(4);
static uint8_t safbuf2[TEST_BUF_SIZE] __aligned(4);
static const struct device *spi_dev;
struct spi_buf_set tx_bufs, rx_bufs;
struct spi_buf txb[MAX_TX_BUF], rxb;
struct spi_config spi_cfg_single, spi_cfg_dual, spi_cfg_quad;

/**
 * @brief Test spi device
 * @details
 * - Find spi device
 * - Read flash jedec id
 */
void test_spi_device(void)
{
	uint32_t jedec_id;
	int ret;

	/* configure spi as single mode */
	spi_cfg_single.frequency = TEST_FREQ_HZ;
	spi_cfg_single.operation = SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB
		| SPI_WORD_SET(8) | SPI_LINES_SINGLE;
	spi_cfg_single.slave = 0;
	spi_cfg_single.cs = NULL;

	/* find spi device */
	spi_dev = device_get_binding(SPI_DEV);
	zassert_true(spi_dev, "Failed to find device %s", SPI_DEV);

	/* read jedec id */
	memset(safbuf, 0, TEST_BUF_SIZE);
	safbuf[0] = SPI_READ_JEDEC_ID;
	txb[0].buf = &safbuf;
	txb[0].len = 1U;

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = 1U;

	jedec_id = 0U;
	rxb.buf = &jedec_id;
	rxb.len = 3U;

	rx_bufs.buffers = (const struct spi_buf *)&rxb;
	rx_bufs.count = 1U;

	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_single,
			(const struct spi_buf_set *)&tx_bufs,
			(const struct spi_buf_set *)&rx_bufs);
	zassert_true(ret == 0, "Read JEDEC ID spi_transceive failure: "
			"error %d", ret);
	zassert_true(jedec_id == W25Q128_JEDEC_ID, "JEDEC ID doesn't match");
}

/**
 * @brief Test spi sector erase
 * @details
 * - write enable
 * - erase data in flash device
 * - read register1 and wait for erase operation completed
 */
void test_spi_sector_erase(void)
{
	int ret;

	/* write enable */
	memset(safbuf, 0, TEST_BUF_SIZE);
	safbuf[0] = SPI_WRITE_ENABLE;
	txb[0].buf = &safbuf;
	txb[0].len = 1U;

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = 1U;

	rx_bufs.buffers = NULL;
	rx_bufs.count = 0U;

	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_single,
			(const struct spi_buf_set *)&tx_bufs,
			(const struct spi_buf_set *)&rx_bufs);
	zassert_true(ret == 0, "Send write enable spi_transceive failure: "
			"error %d", ret);

	/* erase data start from address 0x000010 */
	safbuf[0] = SPI_SECTOR_ERASE;
	safbuf[1] = SPI_TEST_ADDRESS & 0xFFFFFFU;

	txb[0].buf = &safbuf;
	txb[0].len = 4;

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = 1U;

	rx_bufs.buffers = NULL;
	rx_bufs.count = 0U;

	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_single,
			(const struct spi_buf_set *)&tx_bufs,
			(const struct spi_buf_set *)&rx_bufs);
	zassert_true(ret == 0, "Send sector erase data spi_transceive failure: "
			"error %d", ret);

	/* read register1 to check whether erase operation completed */
	safbuf[0] = SPI_READ_STATUS1;

	txb[0].buf = &safbuf;
	txb[0].len = 1;

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = 1U;

	memset(safbuf2, 1U, 1U);
	rxb.buf = &safbuf2;
	rxb.len = 1U;

	rx_bufs.buffers = (const struct spi_buf *)&rxb;
	rx_bufs.count = 1U;

	/* waiting for erase operation completed */
	while (safbuf2[0]) {
		ret = spi_transceive(spi_dev,
				(const struct spi_config *)&spi_cfg_single,
				(const struct spi_buf_set *)&tx_bufs,
				(const struct spi_buf_set *)&rx_bufs);
		zassert_true(ret == 0, "Send read register1 spi_transceive "
				"failure: error %d", ret);
	}
}

/**
 * @brief Write data into flash using spi api
 * @details
 * - flash write enable
 * - write data into flash using spi api
 */
void test_spi_single_write(void)
{
	int ret;

	/* write enable */
	memset(safbuf, 0, TEST_BUF_SIZE);
	safbuf[0] = SPI_WRITE_ENABLE;
	txb[0].buf = &safbuf;
	txb[0].len = 1U;

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = 1U;

	rx_bufs.buffers = NULL;
	rx_bufs.count = 0U;

	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_single,
			(const struct spi_buf_set *)&tx_bufs,
			(const struct spi_buf_set *)&rx_bufs);
	zassert_true(ret == 0, "Send write enable spi_transceive failure: "
			"error %d", ret);

	/* write data start from address 0x000010 */
	safbuf[0] = SPI_SINGLE_WRITE_DATA;
	safbuf[1] = SPI_TEST_ADDRESS & 0xFFFFFFU;
	memcpy(&safbuf[4], buffer_tx, BUF_SIZE);

	txb[0].buf = &safbuf;
	txb[0].len = 4 + BUF_SIZE;

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = 1U;

	rx_bufs.buffers = NULL;
	rx_bufs.count = 0U;

	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_single,
			(const struct spi_buf_set *)&tx_bufs,
			(const struct spi_buf_set *)&rx_bufs);
	zassert_true(ret == 0, "Send write data spi_transceive failure: "
			"error %d", ret);
}

/**
 * @brief Read data from flash using spi single mode
 * @details
 * - read data using spi single mode
 * - check read buffer data whether correct
 */
void test_spi_single_read(void)
{
	int ret;
	uint8_t cnt = 0;
	uint16_t spi_opcode;

	spi_opcode = SPI_FAST_READ_DATA;

	/* read data using spi single mode */
	/* set the spi operation code and address */
	memset(safbuf, 0, TEST_BUF_SIZE);
	safbuf[0] = spi_opcode & 0xFFU;
	safbuf[1] = SPI_TEST_ADDRESS & 0xFFFFFFU;

	txb[cnt].buf = &safbuf;
	txb[cnt].len = 4U;

	/* set the dummy clocks */
	if (spi_opcode & 0xFF00U) {
		cnt++;
		txb[cnt].buf = NULL;
		txb[cnt].len = (spi_opcode >> 8) & 0xFFU;
	}

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = cnt + 1;

	memset(safbuf2, 0, BUF_SIZE);
	rxb.buf = &safbuf2;
	rxb.len = BUF_SIZE;

	rx_bufs.buffers = (const struct spi_buf *)&rxb;
	rx_bufs.count = 1U;

	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_single,
			(const struct spi_buf_set *)&tx_bufs,
			(const struct spi_buf_set *)&rx_bufs);
	zassert_true(ret == 0, "Send fast read data spi_transceive failure: "
			"error %d", ret);

	/* check read buffer data whether correct */
	zassert_true(memcmp(buffer_tx, safbuf2, BUF_SIZE) == 0,
			"Buffer read data is different to write data");
}


/**
 * @brief Read data from flash using spi dual mode
 * @details
 * - read data using spi dual mode
 * - check read buffer data whether correct
 */
void test_spi_dual_read(void)
{
	int ret;
	uint8_t cnt = 0;
	uint16_t spi_opcode;

	/* configure spi dual mode */
	spi_cfg_dual.frequency = TEST_FREQ_HZ;
	spi_cfg_dual.operation = SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB
		| SPI_WORD_SET(8) | SPI_LINES_DUAL;
	spi_cfg_dual.slave = 0;
	spi_cfg_dual.cs = NULL;

	spi_opcode = SPI_DUAL_FAST_READ_DATA;

	/* read data using spi dual mode */
	/* set the spi operation code and address */
	memset(safbuf, 0, TEST_BUF_SIZE);
	safbuf[0] = spi_opcode & 0xFFU;
	safbuf[1] = SPI_TEST_ADDRESS & 0xFFFFFFU;

	txb[cnt].buf = &safbuf;
	txb[cnt].len = 4U;

	/* set the dummy clocks */
	if (spi_opcode & 0xFF00U) {
		cnt++;
		txb[cnt].buf = NULL;
		txb[cnt].len = (spi_opcode >> 8) & 0xFFU;
	}

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = cnt + 1;

	/* send opcode and address using single mode */
	spi_cfg_single.operation |= SPI_HOLD_ON_CS;
	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_single,
			(const struct spi_buf_set *)&tx_bufs, NULL);
	zassert_true(ret == 0, "Send fast read data spi_transceive failure: "
			"error %d", ret);

	memset(safbuf2, 0, BUF_SIZE);
	rxb.buf = &safbuf2;
	rxb.len = BUF_SIZE;

	rx_bufs.buffers = (const struct spi_buf *)&rxb;
	rx_bufs.count = 1U;

	/* get read data using dual mode */
	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_dual,
			NULL, (const struct spi_buf_set *)&rx_bufs);
	zassert_true(ret == 0, "Receive fast read data spi_transceive failure: "
			"error %d", ret);

	/* check read buffer data whether correct */
	zassert_true(memcmp(buffer_tx, safbuf2, BUF_SIZE) == 0,
			"Buffer read data is different to write data");

	/* release spi device */
	spi_cfg_single.operation = SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB
		| SPI_WORD_SET(8) | SPI_LINES_SINGLE;
	ret = spi_release(spi_dev, (const struct spi_config *)&spi_cfg_single);
	zassert_true(ret == 0, "Spi release failure: error %d", ret);
}

/**
 * @brief Write data into flash using spi quad mode
 * @details
 * - check and make sure spi quad mode is enabled
 * - write data using spi quad mode
 */
void test_spi_quad_write(void)
{
	int ret;
	uint8_t spi_status2;

	/* read register2 to judge whether quad mode is enabled */
	safbuf[0] = SPI_READ_STATUS2;
	txb[0].buf = &safbuf;
	txb[0].len = 1U;

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = 1U;

	memset(safbuf2, 0, 1U);
	rxb.buf = &safbuf2;
	rxb.len = 1U;

	rx_bufs.buffers = (const struct spi_buf *)&rxb;
	rx_bufs.count = 1U;

	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_single,
			(const struct spi_buf_set *)&tx_bufs,
			(const struct spi_buf_set *)&rx_bufs);
	zassert_true(ret == 0, "Read register2 status spi_transceive failure: "
			"error %d", ret);

	spi_status2 = safbuf2[0];
	/* set register2 QE=1 to enable quad mode */
	if ((spi_status2 & SPI_STATUS2_QE) == 0U) {
		safbuf[0] = SPI_WRITE_ENABLE_VS;

		txb[0].buf = &safbuf;
		txb[0].len = 1U;

		tx_bufs.buffers = (const struct spi_buf *)&txb[0];
		tx_bufs.count = 1U;

		rx_bufs.buffers = NULL;
		rx_bufs.count = 0U;

		ret = spi_transceive(spi_dev,
				(const struct spi_config *)&spi_cfg_single,
				(const struct spi_buf_set *)&tx_bufs,
				(const struct spi_buf_set *)&rx_bufs);
		zassert_true(ret == 0,
				"Send write enable volatile spi_transceive failure: "
				"error %d", ret);

		safbuf[0] = SPI_WRITE_STATUS2;
		safbuf[1] = spi_status2 | SPI_STATUS2_QE;

		txb[0].buf = &safbuf;
		txb[0].len = 2U;

		tx_bufs.buffers = (const struct spi_buf *)&txb[0];
		tx_bufs.count = 1U;

		rx_bufs.buffers = NULL;
		rx_bufs.count = 0U;

		ret = spi_transceive(spi_dev,
				(const struct spi_config *)&spi_cfg_single,
				(const struct spi_buf_set *)&tx_bufs,
				(const struct spi_buf_set *)&rx_bufs);
		zassert_true(ret == 0,
				"Write spi status2 QE=1 spi_transceive failure: "
				"error %d", ret);

		/* read register2 to confirm quad mode is enabled */
		safbuf[0] = SPI_READ_STATUS2;
		txb[0].buf = &safbuf;
		txb[0].len = 1U;

		tx_bufs.buffers = (const struct spi_buf *)&txb[0];
		tx_bufs.count = 1U;

		memset(safbuf2, 0, 1U);
		rxb.buf = &safbuf2;
		rxb.len = 1U;

		rx_bufs.buffers = (const struct spi_buf *)&rxb;
		rx_bufs.count = 1U;

		ret = spi_transceive(spi_dev,
				(const struct spi_config *)&spi_cfg_single,
				(const struct spi_buf_set *)&tx_bufs,
				(const struct spi_buf_set *)&rx_bufs);
		zassert_true(ret == 0, "Read register2 status spi_transceive failure: "
				"error %d", ret);

		spi_status2 = safbuf2[0];
		zassert_true((spi_status2 & SPI_STATUS2_QE) == SPI_STATUS2_QE,
				"Enable QSPI mode failure");
	}

	/* write enable */
	safbuf[0] = SPI_WRITE_ENABLE;
	txb[0].buf = &safbuf;
	txb[0].len = 1U;

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = 1U;

	rx_bufs.buffers = NULL;
	rx_bufs.count = 0U;

	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_single,
			(const struct spi_buf_set *)&tx_bufs,
			(const struct spi_buf_set *)&rx_bufs);
	zassert_true(ret == 0, "Send write enable spi_transceive failure: "
			"error %d", ret);

	/* configure spi quad mode */
	spi_cfg_quad.frequency = TEST_FREQ_HZ;
	spi_cfg_quad.operation = SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB
		| SPI_WORD_SET(8) | SPI_LINES_QUAD;
	spi_cfg_quad.slave = 0;
	spi_cfg_quad.cs = NULL;

	/* write data using spi quad mode */
	/* send quad write opcode and address using single mode */
	memset(safbuf, 0, TEST_BUF_SIZE);
	safbuf[0] = SPI_QUAD_WRITE_DATA;
	safbuf[1] = SPI_TEST_ADDRESS_2 & 0xFFFFFFU;

	txb[0].buf = &safbuf;
	txb[0].len = 4;

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = 1U;

	rx_bufs.buffers = NULL;
	rx_bufs.count = 0U;

	spi_cfg_single.operation |= SPI_HOLD_ON_CS;
	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_single,
			(const struct spi_buf_set *)&tx_bufs,
			(const struct spi_buf_set *)&rx_bufs);
	zassert_true(ret == 0, "Send quad write data spi_transceive failure: "
			"error %d", ret);

	/* send data using quad mode */
	memset(safbuf, 0, TEST_BUF_SIZE);
	memcpy(&safbuf[0], buffer_tx_2, BUF_SIZE_2);

	txb[0].buf = &safbuf;
	txb[0].len = BUF_SIZE_2;

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = 1U;

	rx_bufs.buffers = NULL;
	rx_bufs.count = 0U;

	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_quad,
			(const struct spi_buf_set *)&tx_bufs,
			(const struct spi_buf_set *)&rx_bufs);
	zassert_true(ret == 0, "Send quad write data spi_transceive failure: "
			"error %d", ret);

	spi_cfg_single.operation = SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB
		| SPI_WORD_SET(8) | SPI_LINES_SINGLE;
	ret = spi_release(spi_dev, (const struct spi_config *)&spi_cfg_single);
	zassert_true(ret == 0, "Spi release failure: error %d", ret);
}

/**
 * @brief Read data from flash using spi quad mode
 * @details
 * - read data using spi quad mode
 * - check read buffer data whether correct
 */
void test_spi_quad_read(void)
{
	int ret;
	uint8_t cnt = 0;
	uint16_t spi_opcode;

	spi_opcode = SPI_QUAD_FAST_READ_DATA;

	/* read data using spi quad mode */
	/* set the spi operation code and address */
	memset(safbuf, 0, TEST_BUF_SIZE);
	safbuf[0] = spi_opcode & 0xFFU;
	safbuf[1] = SPI_TEST_ADDRESS_2 & 0xFFFFFFU;

	txb[cnt].buf = &safbuf;
	txb[cnt].len = 4U;

	/* set the dummy clocks */
	if (spi_opcode & 0xFF00U) {
		cnt++;
		txb[cnt].buf = NULL;
		txb[cnt].len = (spi_opcode >> 8) & 0xFFU;
	}

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = cnt + 1;

	/* send opcode and address using single mode */
	spi_cfg_single.operation |= SPI_HOLD_ON_CS;
	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_single,
			(const struct spi_buf_set *)&tx_bufs, NULL);
	zassert_true(ret == 0, "Send fast read data spi_transceive failure: "
			"error %d", ret);

	memset(safbuf2, 0, TEST_BUF_SIZE);
	rxb.buf = &safbuf2;
	rxb.len = BUF_SIZE_2;

	rx_bufs.buffers = (const struct spi_buf *)&rxb;
	rx_bufs.count = 1U;

	/* get read data using quad mode */
	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_quad,
			NULL, (const struct spi_buf_set *)&rx_bufs);
	zassert_true(ret == 0, "Receive fast read data spi_transceive failure: "
			"error %d", ret);

	/* check read buffer data whether correct */
	zassert_true(memcmp(buffer_tx_2, safbuf2, BUF_SIZE_2) == 0,
			"Buffer read data is different to write data");

	/* release spi device */
	spi_cfg_single.operation = SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB
		| SPI_WORD_SET(8) | SPI_LINES_SINGLE;
	ret = spi_release(spi_dev, (const struct spi_config *)&spi_cfg_single);
	zassert_true(ret == 0, "Spi release failure: error %d", ret);
}

/**
 * @brief Read data from flash using spi octal quad mode
 * @details
 * - read data using spi octal quad mode
 * - check read buffer data whether correct
 */
void test_spi_octal_read(void)
{
	int ret;

	/* read data using spi octal quad mode */
	/* send octal read opcode using single mode */
	memset(safbuf, 0, TEST_BUF_SIZE);
	safbuf[0] = SPI_OCTAL_QUAD_READ_DATA;

	txb[0].buf = &safbuf;
	txb[0].len = 1;

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = 1U;

	rx_bufs.buffers = NULL;
	rx_bufs.count = 0U;

	spi_cfg_single.operation |= SPI_HOLD_ON_CS;
	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_single,
			(const struct spi_buf_set *)&tx_bufs,
			(const struct spi_buf_set *)&rx_bufs);
	zassert_true(ret == 0, "Send octal quad read opcode "
			"spi_transceive failure: error %d", ret);

	/* send address using quad mode */
	safbuf[0] = SPI_TEST_ADDRESS & 0xFFFFF0U;
	safbuf[3] = 0xFFU;
	txb[0].buf = &safbuf;
	txb[0].len = 4;

	tx_bufs.buffers = (const struct spi_buf *)&txb[0];
	tx_bufs.count = 1U;

	memset(safbuf2, 0, TEST_BUF_SIZE);
	rxb.buf = &safbuf2;
	rxb.len = BUF_SIZE;

	rx_bufs.buffers = (const struct spi_buf *)&rxb;
	rx_bufs.count = 1U;

	ret = spi_transceive(spi_dev,
			(const struct spi_config *)&spi_cfg_quad,
			(const struct spi_buf_set *)&tx_bufs,
			(const struct spi_buf_set *)&rx_bufs);
	zassert_true(ret == 0, "Send quad read address spi_transceive "
			"failure: error %d", ret);

	/* check read buffer data whether correct */
	zassert_true(memcmp(buffer_tx, safbuf2, BUF_SIZE) == 0,
			"Buffer read data is different to write data");

	/* release spi device */
	spi_cfg_single.operation = SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB
		| SPI_WORD_SET(8) | SPI_LINES_SINGLE;
	ret = spi_release(spi_dev, (const struct spi_config *)&spi_cfg_single);
	zassert_true(ret == 0, "Spi release failure: error %d", ret);
}

void test_main(void)
{
	ztest_test_suite(test_spi,
			ztest_user_unit_test(test_spi_device),
			ztest_user_unit_test(test_spi_sector_erase),
			ztest_user_unit_test(test_spi_single_write),
			ztest_user_unit_test(test_spi_single_read),
			ztest_user_unit_test(test_spi_dual_read),
			ztest_user_unit_test(test_spi_quad_write),
			ztest_user_unit_test(test_spi_quad_read),
			ztest_user_unit_test(test_spi_octal_read)
			);
	ztest_run_test_suite(test_spi);
}
