/*
 * Copyright (c) 2020 Vestas Wind Systems A/S
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/drivers/sensor/mcux_acmp.h>
#include <zephyr/zephyr.h>

#include <stdio.h>

#ifdef CONFIG_BOARD_TWR_KE18F
#define ACMP_NODE  DT_NODELABEL(cmp2)
#define ACMP_POSITIVE 5
#define ACMP_NEGATIVE 5
#define ACMP_DAC_VREF 0
#else
#error Unsupported board
#endif

#define ACMP_DAC_VALUE 128

struct acmp_attr {
	int16_t attr;
	int32_t val;
};

static const struct acmp_attr attrs[] = {
	/* Positive input port set to MUX */
	{ .attr = SENSOR_ATTR_MCUX_ACMP_POSITIVE_PORT_INPUT, .val = 1 },
	/* Positive input channel */
	{ .attr = SENSOR_ATTR_MCUX_ACMP_POSITIVE_MUX_INPUT,
	  .val = ACMP_POSITIVE },
	/* Negative input port set to DAC */
	{ .attr = SENSOR_ATTR_MCUX_ACMP_NEGATIVE_PORT_INPUT, .val = 0 },
	/* Negative input channel */
	{ .attr = SENSOR_ATTR_MCUX_ACMP_NEGATIVE_MUX_INPUT,
	  .val = ACMP_NEGATIVE },
	/* DAC voltage reference */
	{ .attr = SENSOR_ATTR_MCUX_ACMP_DAC_VOLTAGE_REFERENCE,
	  .val = ACMP_DAC_VREF },
	/* DAC value */
	{ .attr = SENSOR_ATTR_MCUX_ACMP_DAC_VALUE, .val = ACMP_DAC_VALUE },
	/* Hysteresis level */
	{ .attr = SENSOR_ATTR_MCUX_ACMP_HYSTERESIS_LEVEL, .val = 3 },
	/* Offset level */
	{ .attr = SENSOR_ATTR_MCUX_ACMP_OFFSET_LEVEL, .val = 0 },
};

static const int16_t triggers[] = {
	SENSOR_TRIG_MCUX_ACMP_OUTPUT_RISING,
	SENSOR_TRIG_MCUX_ACMP_OUTPUT_FALLING,
};

static void acmp_input_handler(bool above_threshold)
{
	if (above_threshold) {
		printf("ACMP input above threshold\n");
	} else {
		printf("ACMP input below threshold\n");
	}
}

static void acmp_trigger_handler(const struct device *dev,
				 const struct sensor_trigger *trigger)
{
	ARG_UNUSED(dev);

	acmp_input_handler((int16_t)trigger->type ==
			   SENSOR_TRIG_MCUX_ACMP_OUTPUT_RISING);
}

void main(void)
{
	struct sensor_trigger trigger;
	const struct device *acmp = DEVICE_DT_GET(ACMP_NODE);
	struct sensor_value val;
	int err;
	int i;

	if (!device_is_ready(acmp)) {
		printf("ACMP device not ready");
		return;
	}

	/* Set ACMP attributes */
	val.val2 = 0;
	for (i = 0; i < ARRAY_SIZE(attrs); i++) {
		val.val1 = attrs[i].val;
		err = sensor_attr_set(acmp, SENSOR_CHAN_MCUX_ACMP_OUTPUT,
				      attrs[i].attr, &val);
		if (err) {
			printf("failed to set attribute %d (err %d)", i, err);
			return;
		}
	}

	/* Delay for analog components (DAC, CMP, ...) to settle */
	k_sleep(K_MSEC(1));

	/* Set ACMP triggers */
	trigger.chan = SENSOR_CHAN_MCUX_ACMP_OUTPUT;
	for (i = 0; i < ARRAY_SIZE(triggers); i++) {
		trigger.type = triggers[i];
		err = sensor_trigger_set(acmp, &trigger, acmp_trigger_handler);
		if (err) {
			printf("failed to set trigger %d (err %d)", i, err);
			return;
		}
	}

	printf("Adjust ACMP input voltage by turning the potentiometer\n");

	/* Read initial state */
	err = sensor_sample_fetch(acmp);
	if (err) {
		printf("failed to fetch sample (err %d)", err);
		return;
	}

	err = sensor_channel_get(acmp, SENSOR_CHAN_MCUX_ACMP_OUTPUT, &val);
	if (err) {
		printf("failed to get channel (err %d)", err);
		return;
	}

	acmp_input_handler(val.val1 == 1);

	/* Await trigger */
	while (true) {
		k_sleep(K_MSEC(1));
	}
}
