/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 * Copyright (c) 2016 Intel Corporation
 * Copyright (c) 2020, NXP
 * Copyright (c) 2023, Nobleo Technology
 *
 * SPDX-License-Identifier: Apache-2.0
 */


#include <zephyr/drivers/dma.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/counter.h>
#include <zephyr/kernel.h>
#include <zephyr/ztest.h>

#if defined(CONFIG_BOARD_FRDM_K64F)

#define ADC_DEVICE_NODE DT_INST(0, nxp_kinetis_adc16)
#define ADC_RESOLUTION 12
#define ADC_GAIN ADC_GAIN_1
#define ADC_REFERENCE ADC_REF_INTERNAL
#define ADC_ACQUISITION_TIME ADC_ACQ_TIME_DEFAULT
#define ADC_1ST_CHANNEL_ID 26
#define COUNTER_NODE_NAME pit0
#define HW_TRIGGER_INTERVAL (30000U)
#define SAMPLE_INTERVAL_US HW_TRIGGER_INTERVAL

#elif defined(CONFIG_BOARD_FRDM_K82F)

#define ADC_DEVICE_NODE DT_INST(0, nxp_kinetis_adc16)
#define ADC_RESOLUTION 12
#define ADC_GAIN ADC_GAIN_1
#define ADC_REFERENCE ADC_REF_INTERNAL
#define ADC_ACQUISITION_TIME ADC_ACQ_TIME_DEFAULT
#define ADC_1ST_CHANNEL_ID 26
#define COUNTER_NODE_NAME pit0
#define HW_TRIGGER_INTERVAL (30000U)
#define SAMPLE_INTERVAL_US HW_TRIGGER_INTERVAL

#elif defined(CONFIG_BOARD_NUCLEO_H743ZI)

#define ADC_DEVICE_NODE DT_INST(0, st_stm32_adc)
#define ADC_RESOLUTION 12
#define ADC_GAIN ADC_GAIN_1
#define ADC_REFERENCE ADC_REF_INTERNAL
#define ADC_ACQUISITION_TIME ADC_ACQ_TIME_DEFAULT
#define ADC_1ST_CHANNEL_ID 1
#define ADC_2ND_CHANNEL_ID 7
#define ALIGNMENT 32
#define BUFFER_MEM_REGION __attribute__((__section__("SRAM4.dma")))

#elif defined(CONFIG_BOARD_NUCLEO_U575ZI_Q)

#define ADC_DEVICE_NODE DT_INST(0, st_stm32_adc)
#define ADC_RESOLUTION 12
#define ADC_GAIN ADC_GAIN_1
#define ADC_REFERENCE ADC_REF_INTERNAL
#define ADC_ACQUISITION_TIME ADC_ACQ_TIME_DEFAULT
#define ADC_1ST_CHANNEL_ID 1
#define ADC_2ND_CHANNEL_ID 7
#define ALIGNMENT 32

#endif

/* Invalid value that is not supposed to be written by the driver. It is used
 * to mark the sample buffer entries as empty. If needed, it can be overridden
 * for a particular board by providing a specific definition above.
 */
#if !defined(INVALID_ADC_VALUE)
#define INVALID_ADC_VALUE SHRT_MIN
#endif

/* Memory region where buffers will be placed. By default placed in ZTEST_BMEM
 * but can be overwritten for a particular board.
 */
#if !defined(BUFFER_MEM_REGION)
#define BUFFER_MEM_REGION EMPTY
#endif

/* The sample interval between consecutive samplings. Some drivers require
 * specific values to function.
 */
#if !defined(SAMPLE_INTERVAL_US)
#define SAMPLE_INTERVAL_US 0
#endif

#define BUFFER_SIZE 24
#ifndef ALIGNMENT
#define ALIGNMENT DMA_BUF_ADDR_ALIGNMENT(DT_NODELABEL(test_dma))
#endif

static BUFFER_MEM_REGION __aligned(ALIGNMENT) int16_t m_sample_buffer[BUFFER_SIZE];
static BUFFER_MEM_REGION __aligned(ALIGNMENT) int16_t m_sample_buffer2[2][BUFFER_SIZE];
static int current_buf_inx;

#if defined(CONFIG_ADC_ASYNC)
static struct k_poll_signal async_sig;
#endif

static const struct adc_channel_cfg m_1st_channel_cfg = {
	.gain = ADC_GAIN,
	.reference = ADC_REFERENCE,
	.acquisition_time = ADC_ACQUISITION_TIME,
	.channel_id = ADC_1ST_CHANNEL_ID,
#if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
	.input_positive = ADC_1ST_CHANNEL_INPUT,
#endif
};
#if defined(ADC_2ND_CHANNEL_ID)
static const struct adc_channel_cfg m_2nd_channel_cfg = {
	.gain = ADC_GAIN,
	.reference = ADC_REFERENCE,
	.acquisition_time = ADC_ACQUISITION_TIME,
	.channel_id = ADC_2ND_CHANNEL_ID,
#if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
	.input_positive = ADC_2ND_CHANNEL_INPUT,
#endif
};
#endif /* defined(ADC_2ND_CHANNEL_ID) */

#if defined(COUNTER_NODE_NAME)
static void init_counter(void)
{
	int err;
	const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(COUNTER_NODE_NAME));
	struct counter_top_cfg top_cfg = { .callback = NULL,
					   .user_data = NULL,
					   .flags = 0 };

	zassert_true(device_is_ready(dev), "Counter device is not ready");

	counter_start(dev);
	top_cfg.ticks = counter_us_to_ticks(dev, HW_TRIGGER_INTERVAL);
	err = counter_set_top_value(dev, &top_cfg);
	zassert_equal(0, err, "%s: Counter failed to set top value (err: %d)",
		      dev->name, err);
}
#endif

static const struct device *init_adc(void)
{
	int i, ret;
	const struct device *const adc_dev = DEVICE_DT_GET(ADC_DEVICE_NODE);

	zassert_true(device_is_ready(adc_dev), "ADC device is not ready");

	ret = adc_channel_setup(adc_dev, &m_1st_channel_cfg);
	zassert_equal(ret, 0,
		      "Setting up of the first channel failed with code %d",
		      ret);

#if defined(ADC_2ND_CHANNEL_ID)
	ret = adc_channel_setup(adc_dev, &m_2nd_channel_cfg);
	zassert_equal(ret, 0,
		      "Setting up of the second channel failed with code %d",
		      ret);
#endif /* defined(ADC_2ND_CHANNEL_ID) */

	for (i = 0; i < BUFFER_SIZE; ++i) {
		m_sample_buffer[i] = INVALID_ADC_VALUE;
		m_sample_buffer2[0][i] = INVALID_ADC_VALUE;
		m_sample_buffer2[1][i] = INVALID_ADC_VALUE;
	}

#if defined(CONFIG_ADC_ASYNC)
	k_poll_signal_init(&async_sig);
#endif

#if defined(COUNTER_NODE_NAME)
	init_counter();
#endif

	return adc_dev;
}

static void check_samples(int expected_count)
{
	int i;

	TC_PRINT("Samples read: ");
	for (i = 0; i < BUFFER_SIZE; i++) {
		int16_t sample_value = m_sample_buffer[i];

		TC_PRINT("0x%04x ", sample_value);
		if (i && i % 10 == 0) {
			TC_PRINT("\n");
		}

		if (i < expected_count) {
			zassert_not_equal(INVALID_ADC_VALUE, sample_value,
				"[%u] should be filled", i);
		} else {
			zassert_equal(INVALID_ADC_VALUE, sample_value,
				"[%u] should be empty", i);
		}
	}
	TC_PRINT("\n");
}

static void check_samples2(int expected_count)
{
	int i;

	TC_PRINT("Samples read: ");
	for (i = 0; i < BUFFER_SIZE; i++) {
		int16_t sample_value = m_sample_buffer2[current_buf_inx][i];

		TC_PRINT("0x%04x ", sample_value);
		if (i && i % 10 == 0) {
			TC_PRINT("\n");
		}

		if (i < expected_count) {
			zassert_not_equal(INVALID_ADC_VALUE, sample_value,
				"[%u] should be filled", i);
		} else {
			zassert_equal(INVALID_ADC_VALUE, sample_value,
				"[%u] should be empty", i);
		}
	}
	TC_PRINT("\n");
}

/*
 * test_adc_sample_one_channel
 */
static int test_task_one_channel(void)
{
	int ret;
	const struct adc_sequence sequence = {
		.channels = BIT(ADC_1ST_CHANNEL_ID),
		.buffer = m_sample_buffer,
		.buffer_size = sizeof(m_sample_buffer),
		.resolution = ADC_RESOLUTION,
	};

	const struct device *adc_dev = init_adc();

	if (!adc_dev) {
		return TC_FAIL;
	}

	ret = adc_read(adc_dev, &sequence);
	zassert_equal(ret, 0, "adc_read() failed with code %d", ret);

	check_samples(1);

	return TC_PASS;
}

ZTEST_USER(adc_dma, test_adc_sample_one_channel)
{
	zassert_true(test_task_one_channel() == TC_PASS);
}

/*
 * test_adc_sample_two_channels
 */
#if defined(ADC_2ND_CHANNEL_ID)
static int test_task_two_channels(void)
{
	int ret;
	const struct adc_sequence sequence = {
		.channels = BIT(ADC_1ST_CHANNEL_ID) | BIT(ADC_2ND_CHANNEL_ID),
		.buffer = m_sample_buffer,
		.buffer_size = sizeof(m_sample_buffer),
		.resolution = ADC_RESOLUTION,
	};

	const struct device *adc_dev = init_adc();

	if (!adc_dev) {
		return TC_FAIL;
	}

	ret = adc_read(adc_dev, &sequence);
	zassert_equal(ret, 0, "adc_read() failed with code %d", ret);

	check_samples(2);

	return TC_PASS;
}
#endif /* defined(ADC_2ND_CHANNEL_ID) */

ZTEST_USER(adc_dma, test_adc_sample_two_channels)
{
#if defined(ADC_2ND_CHANNEL_ID)
	zassert_true(test_task_two_channels() == TC_PASS);
#else
	ztest_test_skip();
#endif /* defined(ADC_2ND_CHANNEL_ID) */
}

/*
 * test_adc_asynchronous_call
 */
#if defined(CONFIG_ADC_ASYNC)
static int test_task_asynchronous_call(void)
{
	int ret;
	const struct adc_sequence_options options = {
		.extra_samplings = 4,
		/* Start consecutive samplings as fast as possible. */
		.interval_us = SAMPLE_INTERVAL_US,
	};
	const struct adc_sequence sequence = {
		.options = &options,
		.channels = BIT(ADC_1ST_CHANNEL_ID),
		.buffer = m_sample_buffer,
		.buffer_size = sizeof(m_sample_buffer),
		.resolution = ADC_RESOLUTION,
	};
	struct k_poll_event async_evt = K_POLL_EVENT_INITIALIZER(
		K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, &async_sig);
	const struct device *adc_dev = init_adc();

	if (!adc_dev) {
		return TC_FAIL;
	}

	ret = adc_read_async(adc_dev, &sequence, &async_sig);
	zassert_equal(ret, 0, "adc_read_async() failed with code %d", ret);

	ret = k_poll(&async_evt, 1, K_MSEC(1000));
	zassert_equal(ret, 0, "k_poll failed with error %d", ret);

	check_samples(1 + options.extra_samplings);

	return TC_PASS;
}
#endif /* defined(CONFIG_ADC_ASYNC) */

ZTEST_USER(adc_dma, test_adc_asynchronous_call)
{
#if defined(CONFIG_ADC_ASYNC)
	zassert_true(test_task_asynchronous_call() == TC_PASS);
#else
	ztest_test_skip();
#endif /* defined(CONFIG_ADC_ASYNC) */
}

/*
 * test_adc_sample_with_interval
 */
static enum adc_action
sample_with_interval_callback(const struct device *dev,
			      const struct adc_sequence *sequence,
			      uint16_t sampling_index)
{
	struct adc_sequence *seq = (struct adc_sequence *)sequence;
	int _inx = current_buf_inx;

	memcpy(m_sample_buffer, m_sample_buffer2[_inx],
	       sizeof(m_sample_buffer));
	current_buf_inx = (current_buf_inx == 0) ? 1 : 0;
	seq->buffer = m_sample_buffer2[current_buf_inx];
	return ADC_ACTION_CONTINUE;
}

static int test_task_with_interval(void)
{
	int ret;
	int count = 2;
	int64_t time_stamp;
	int64_t milliseconds_spent;

	const struct adc_sequence_options options = {
		.interval_us = 100 * 1000, /* 10 ms - much larger than expected sampling time */
		.callback = sample_with_interval_callback,
		.extra_samplings = 1,
	};
	const struct adc_sequence sequence = {
		.options = &options,
		.channels = BIT(ADC_1ST_CHANNEL_ID),
		.buffer = m_sample_buffer2[0],
		.buffer_size = sizeof(m_sample_buffer2[0]),
		.resolution = ADC_RESOLUTION,
	};

	const struct device *adc_dev = init_adc();

	if (!adc_dev) {
		return TC_FAIL;
	}

	current_buf_inx = 0;

	while (count--) {
		time_stamp = k_uptime_get();
		ret = adc_read(adc_dev, &sequence);
		milliseconds_spent = k_uptime_delta(&time_stamp);
		zassert_true(milliseconds_spent >= (options.interval_us / 1000UL));
		zassert_equal(ret, 0, "adc_read() failed with code %d", ret);
	}
	check_samples2(1 + options.extra_samplings);
	return TC_PASS;
}

ZTEST(adc_dma, test_adc_sample_with_interval)
{
	zassert_true(test_task_with_interval() == TC_PASS);
}

/*
 * test_adc_repeated_samplings
 */
static uint8_t m_samplings_done;
static enum adc_action
repeated_samplings_callback(const struct device *dev,
			    const struct adc_sequence *sequence,
			    uint16_t sampling_index)
{
	++m_samplings_done;
	TC_PRINT("%s: done %d\n", __func__, m_samplings_done);
	if (m_samplings_done == 1U) {
#if defined(ADC_2ND_CHANNEL_ID)
		check_samples(2);
#else
		check_samples(1);
#endif /* defined(ADC_2ND_CHANNEL_ID) */

		/* After first sampling continue normally. */
		return ADC_ACTION_CONTINUE;
	}
#if defined(ADC_2ND_CHANNEL_ID)
	check_samples(4);
#else
	check_samples(2);
#endif /* defined(ADC_2ND_CHANNEL_ID) */

	/*
	 * The second sampling is repeated 9 times (the samples are
	 * written in the same place), then the sequence is finished
	 * prematurely.
	 */
	if (m_samplings_done < 10) {
		return ADC_ACTION_REPEAT;
	} else {
		return ADC_ACTION_FINISH;
	}

}

static int test_task_repeated_samplings(void)
{
	int ret;
	const struct adc_sequence_options options = {
		.callback = repeated_samplings_callback,
		/*
		 * This specifies that 3 samplings are planned. However,
		 * the callback function above is constructed in such way
		 * that the first sampling is done normally, the second one
		 * is repeated 9 times, and then the sequence is finished.
		 * Hence, the third sampling will not take place.
		 */
		.extra_samplings = 2,
		/* Start consecutive samplings as fast as possible. */
		.interval_us = SAMPLE_INTERVAL_US,
	};
	const struct adc_sequence sequence = {
		.options = &options,
#if defined(ADC_2ND_CHANNEL_ID)
		.channels = BIT(ADC_1ST_CHANNEL_ID) | BIT(ADC_2ND_CHANNEL_ID),
#else
		.channels = BIT(ADC_1ST_CHANNEL_ID),
#endif /* defined(ADC_2ND_CHANNEL_ID) */
		.buffer = m_sample_buffer,
		.buffer_size = sizeof(m_sample_buffer),
		.resolution = ADC_RESOLUTION,
	};

	const struct device *adc_dev = init_adc();

	if (!adc_dev) {
		return TC_FAIL;
	}

	ret = adc_read(adc_dev, &sequence);
	zassert_equal(ret, 0, "adc_read() failed with code %d", ret);

	return TC_PASS;
}

ZTEST(adc_dma, test_adc_repeated_samplings)
{
	zassert_true(test_task_repeated_samplings() == TC_PASS);
}

/*
 * test_adc_invalid_request
 */
static int test_task_invalid_request(void)
{
	int ret;
	struct adc_sequence sequence = {
		.channels = BIT(ADC_1ST_CHANNEL_ID),
		.buffer = m_sample_buffer,
		.buffer_size = sizeof(m_sample_buffer),
		.resolution = 0, /* intentionally invalid value */
	};

	const struct device *adc_dev = init_adc();

	if (!adc_dev) {
		return TC_FAIL;
	}

	ret = adc_read(adc_dev, &sequence);
	zassert_not_equal(ret, 0, "adc_read() unexpectedly succeeded");

#if defined(CONFIG_ADC_ASYNC)
	ret = adc_read_async(adc_dev, &sequence, &async_sig);
	zassert_not_equal(ret, 0, "adc_read_async() unexpectedly succeeded");
#endif

	/*
	 * Make the sequence parameters valid, now the request should succeed.
	 */
	sequence.resolution = ADC_RESOLUTION;

	ret = adc_read(adc_dev, &sequence);
	zassert_equal(ret, 0, "adc_read() failed with code %d", ret);

	check_samples(1);

	return TC_PASS;
}

ZTEST_USER(adc_dma, test_adc_invalid_request)
{
	zassert_true(test_task_invalid_request() == TC_PASS);
}
