/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 * Copyright (c) 2016 Intel Corporation
 * Copyright (c) 2020, NXP
 *
 * 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

#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

#endif

#define HW_TRIGGER_INTERVAL (2U)
/* for DMA HW trigger interval need large than HW trigger interval*/
#define SAMPLE_INTERVAL_US (10000U)

#define BUFFER_SIZE 24
#define ALIGNMENT DMA_BUF_ALIGNMENT(DT_NODELABEL(test_dma))
static ZTEST_BMEM __aligned(ALIGNMENT) int16_t m_sample_buffer[BUFFER_SIZE];
static ZTEST_BMEM __aligned(ALIGNMENT) int16_t m_sample_buffer2[2][BUFFER_SIZE];
static int current_buf_inx;

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) */

const struct device *get_adc_device(void)
{
	const struct device *const dev = DEVICE_DT_GET(ADC_DEVICE_NODE);

	if (!device_is_ready(dev)) {
		printk("ADC device is not ready\n");
		return NULL;
	}

	return dev;
}

const struct device *get_count_device(void)
{
	const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(pit0));

	if (!device_is_ready(dev)) {
		printk("count device is not ready\n");
		return NULL;
	}

	return dev;
}

static void init_pit(void)
{
	int err;
	const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(pit0));
	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);
}

static const struct device *init_adc(void)
{
	int 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) */

	(void)memset(m_sample_buffer, 0, sizeof(m_sample_buffer));

	init_pit();

	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");
		}
	}
	TC_PRINT("%d sampled\n", BUFFER_SIZE);
}

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");
		}
	}
	TC_PRINT("%d sampled\n", BUFFER_SIZE);
}

/*
 * 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)
struct k_poll_signal async_sig;

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 = HW_TRIGGER_INTERVAL,
	};
	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 = 500UL, /*make this double to sample 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);
		printk("now spend = %lldms\n", milliseconds_spent);
		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. */
		/* but the interval shall be larger than the HW trigger*/
		.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);
}
