/*
 * Copyright (c) 2019 Alexander Wachter
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <drivers/can.h>
#include <ztest.h>
#include <strings.h>

/*
 * @addtogroup t_can_driver
 * @{
 * @defgroup t_can_timing test_basic_can_timing
 * @brief TestPurpose: verify timing algorithm
 * @details
 * - Test Steps
 *   -# Calculate timing for a sample
 *   -# Verify sample point
 *   -# verify bitrate
 * - Expected Results
 *   -# All tests MUST pass
 * @}
 */

#if defined(CONFIG_CAN_LOOPBACK_DEV_NAME)
#define CAN_DEVICE_NAME CONFIG_CAN_LOOPBACK_DEV_NAME
#else
#define CAN_DEVICE_NAME DT_CHOSEN_ZEPHYR_CAN_PRIMARY_LABEL
#endif

const struct device *can_dev;

struct timing_samples {
	uint32_t bitrate;
	uint16_t sp;
	bool inval;
};

const struct timing_samples samples[] = {
	{125000, 875, false},
	{500000, 875, false},
	{1000000, 875, false},
	{125000, 900, false},
	{125000, 800, false},
#ifdef CONFIG_CAN_FD_MODE
	{1000000 + 1, 875, true},
#else
	{8000000 + 1, 875, true},
#endif
	{125000, 1000, true},
};

/*
 * Bitrate must match exactly
 */
static void verify_bitrate(struct can_timing  *timing, uint32_t bitrate)
{
	const uint32_t ts = 1 + timing->prop_seg + timing->phase_seg1 +
			    timing->phase_seg2;
	uint32_t core_clock;
	uint32_t bitrate_calc;
	int ret;

	zassert_not_equal(timing->prescaler, 0, "Prescaler is zero");

	ret = can_get_core_clock(can_dev, &core_clock);
	zassert_equal(ret, 0, "Unable to get core clock");

	bitrate_calc = core_clock / timing->prescaler / ts;
	zassert_equal(bitrate, bitrate_calc, "Bitrate missmatch");
}

/*
 * SP must be withing the margin and in bound of the limits
 */
static void verify_sp(struct can_timing  *timing, uint16_t sp,
		      uint16_t sp_margin)
{
	const struct can_driver_api *api =
		(const struct can_driver_api *)can_dev->api;
	const struct can_timing *max = &api->timing_max;
	const struct can_timing *min = &api->timing_min;
	uint32_t ts = 1 + timing->prop_seg + timing->phase_seg1 +
		      timing->phase_seg2;
	uint16_t sp_calc =
		((1 + timing->prop_seg + timing->phase_seg1) * 1000) / ts;

	zassert_true(timing->prop_seg <= max->prop_seg, "prop_seg exceeds max");
	zassert_true(timing->phase_seg1 <= max->phase_seg1,
		     "phase_seg1 exceeds max");
	zassert_true(timing->phase_seg2 <= max->phase_seg2,
		     "phase_seg2 exceeds max");
	zassert_true(timing->prop_seg >= min->prop_seg,
		     "prop_seg lower than min");
	zassert_true(timing->phase_seg1 >= min->phase_seg1,
		     "phase_seg1 lower than min");
	zassert_true(timing->phase_seg2 >= min->phase_seg2,
		     "phase_seg2 lower than min");

	zassert_within(sp, sp_calc, sp_margin, "SP error %d [%d] not within %d",
		       sp_calc, sp, sp_margin);
}

/*
 * Verify the result of the algorithm
 */
static void test_verify_algo(void)
{
	struct can_timing  timing = {0};
	int ret;

	for (int i = 0; i < ARRAY_SIZE(samples); ++i) {
		ret = can_calc_timing(can_dev, &timing, samples[i].bitrate,
				      samples[i].sp);
		if (samples[i].inval) {
			zassert_equal(ret, -EINVAL,
				      "ret value %d not -EINVAL", ret);
			continue;
		}

		zassert_true(ret >= 0, "Unknown error %d", ret);
		/* For the given values, we expect a sp error < 10% */
		zassert_true(ret < 100, "Huge sample point error %d", ret);
		verify_sp(&timing, samples[i].sp, ret);
		verify_bitrate(&timing, samples[i].bitrate);
	}
}

void test_main(void)
{
	can_dev = device_get_binding(CAN_DEVICE_NAME);
	zassert_not_null(can_dev, "Device not found");

	ztest_test_suite(can_timing,
			 ztest_unit_test(test_verify_algo));
	ztest_run_test_suite(can_timing);
}
