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


#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/counter.h>
#include <zephyr/zephyr.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
static ZTEST_BMEM int16_t m_sample_buffer[BUFFER_SIZE];
static ZTEST_BMEM 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 *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 *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 *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 *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, NULL);
}

/*
 * 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, NULL);
#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, NULL);
#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, NULL);
}

/*
 * 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, NULL);
}

/*
 * 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, NULL);
}
