/*
 * Copyright (c) 2021 Marc Reilly, Creative Product Design
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(app, LOG_LEVEL_INF);

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <stdio.h>
#include <string.h>
#include <zephyr/drivers/spi.h>

#define SPIBB_NODE	DT_NODELABEL(spibb0)

/*
 * writes 5 9bit words, you can check the output with a logic analyzer
 */
void test_basic_write_9bit_words(const struct device *dev,
				 struct spi_cs_control *cs)
{
	struct spi_config config;

	config.frequency = 125000;
	config.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(9);
	config.slave = 0;
	config.cs = *cs;

	uint16_t buff[5] = { 0x0101, 0x00ff, 0x00a5, 0x0000, 0x0102};
	int len = 5 * sizeof(buff[0]);

	struct spi_buf tx_buf = { .buf = buff, .len = len };
	struct spi_buf_set tx_bufs = { .buffers = &tx_buf, .count = 1 };

	int ret = spi_write(dev, &config, &tx_bufs);

	printf("basic_write_9bit_words; ret: %d\n", ret);
	printf(" wrote %04x %04x %04x %04x %04x\n",
		buff[0], buff[1], buff[2], buff[3], buff[4]);
}

/*
 * A more complicated xfer, sends two words, then sends and receives another
 * 3 words. Connect MOSI to MISO to test read
 */
void test_9bit_loopback_partial(const struct device *dev,
				struct spi_cs_control *cs)
{
	struct spi_config config;

	config.frequency = 125000;
	config.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(9);
	config.slave = 0;
	config.cs = *cs;

	enum { datacount = 5 };
	uint16_t buff[datacount] = { 0x0101, 0x0102, 0x0003, 0x0004, 0x0105};
	uint16_t rxdata[3];

	const int stride = sizeof(buff[0]);

	struct spi_buf tx_buf[2] = {
		{.buf = buff, .len = (2) * stride},
		{.buf = buff + (2), .len = (datacount - 2)*stride},
	};
	struct spi_buf rx_buf[2] = {
		{.buf = 0, .len = (2) * stride},
		{.buf = rxdata, .len = (datacount - 2) * stride},
	};

	struct spi_buf_set tx_set = { .buffers = tx_buf, .count = 2 };
	struct spi_buf_set rx_set = { .buffers = rx_buf, .count = 2 };

	int ret = spi_transceive(dev, &config, &tx_set, &rx_set);

	printf("9bit_loopback_partial; ret: %d\n", ret);
	printf(" tx (i)  : %04x %04x\n", buff[0], buff[1]);
	printf(" tx (ii) : %04x %04x %04x\n", buff[2], buff[3], buff[4]);
	printf(" rx (ii) : %04x %04x %04x\n", rxdata[0], rxdata[1], rxdata[2]);
}

/*
 * Tests 8 bit transfer at higher frequency, at this frequency there won't be
 * any busy waits between clock edges, the rate is limited by gpio calls etc.
 */
void test_8bit_xfer(const struct device *dev, struct spi_cs_control *cs)
{
	struct spi_config config;

	config.frequency = 1000000;
	config.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8);
	config.slave = 0;
	config.cs = *cs;

	enum { datacount = 5 };
	uint8_t buff[datacount] = { 0x01, 0x02, 0x03, 0x04, 0x05};
	uint8_t rxdata[datacount];

	struct spi_buf tx_buf[1] = {
		{.buf = buff, .len = datacount},
	};
	struct spi_buf rx_buf[1] = {
		{.buf = rxdata, .len = datacount},
	};

	struct spi_buf_set tx_set = { .buffers = tx_buf, .count = 1 };
	struct spi_buf_set rx_set = { .buffers = rx_buf, .count = 1 };

	int ret = spi_transceive(dev, &config, &tx_set, &rx_set);

	printf("8bit_loopback_partial; ret: %d\n", ret);
	printf(" tx (i)  : %02x %02x %02x %02x %02x\n",
	       buff[0], buff[1], buff[2], buff[3], buff[4]);
	printf(" rx (i)  : %02x %02x %02x %02x %02x\n",
	       rxdata[0], rxdata[1], rxdata[2], rxdata[3], rxdata[4]);
}

int main(void)
{
	const struct device *const dev = DEVICE_DT_GET(SPIBB_NODE);

	if (!device_is_ready(dev)) {
		printk("%s: device not ready.\n", dev->name);
		return 0;
	}

	struct spi_cs_control cs_ctrl = (struct spi_cs_control){
		.gpio = GPIO_DT_SPEC_GET(SPIBB_NODE, cs_gpios),
		.delay = 0u,
	};

	/*
	 * Loop through the various demo functions, the delays make it easier to
	 * locate on a scope/analyzer, the longer delay at the end helps discern
	 * where the pattern repeats.
	 */
	while (1) {
		test_basic_write_9bit_words(dev, &cs_ctrl);
		k_sleep(K_MSEC(200));

		test_9bit_loopback_partial(dev, &cs_ctrl);
		k_sleep(K_MSEC(200));

		test_8bit_xfer(dev, &cs_ctrl);
		k_sleep(K_MSEC(1000));
	}
	return 0;
}
