/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdio.h>
#include <zephyr.h>
#include <sys/timeutil.h>
#include <drivers/clock_control.h>
#include <drivers/clock_control/nrf_clock_control.h>
#include <drivers/counter.h>
#include <nrfx_clock.h>

#define TIMER_NODE DT_NODELABEL(timer0)
#define CLOCK_NODE DT_INST(0, nordic_nrf_clock)
#define UPDATE_INTERVAL_S 10

static const struct device *clock0;
static const struct device *timer0;
static struct timeutil_sync_config sync_config;
static uint64_t counter_ref;
static struct timeutil_sync_state sync_state;
static struct k_work_delayable sync_work;

/* Convert local time in ticks to microseconds. */
uint64_t local_to_us(uint64_t local)
{
	return z_tmcvt(local, sync_config.local_Hz, USEC_PER_SEC, false,
		       false, false, false);
}

/* Convert HFCLK reference to microseconds. */
uint64_t ref_to_us(uint64_t ref)
{
	return z_tmcvt(ref, sync_config.ref_Hz, USEC_PER_SEC, false,
		       false, false, false);
}

/* Format a microsecond timestamp to text as D d HH:MM:SS.SSSSSS. */
static const char *us_to_text_r(uint64_t rem, char *buf, size_t len)
{
	char *bp = buf;
	char *bpe = bp + len;
	uint32_t us;
	uint32_t s;
	uint32_t min;
	uint32_t hr;
	uint32_t d;

	us = rem % USEC_PER_SEC;
	rem /= USEC_PER_SEC;
	s = rem % 60;
	rem /= 60;
	min = rem % 60;
	rem /= 60;
	hr = rem % 24;
	rem /= 24;
	d = rem;

	if (d > 0) {
		bp += snprintf(bp, bpe - bp, "%u d ", d);
	}
	bp += snprintf(bp, bpe - bp, "%02u:%02u:%02u.%06u",
		       hr, min, s, us);
	return buf;
}

static const char *us_to_text(uint64_t rem)
{
	static char ts_buf[32];

	return us_to_text_r(rem, ts_buf, sizeof(ts_buf));
}

/* Show status of various clocks */
static void show_clocks(const char *tag)
{
	static const char *const lfsrc_s[] = {
#if defined(CLOCK_LFCLKSRC_SRC_LFULP)
		[NRF_CLOCK_LFCLK_LFULP] = "LFULP",
#endif
		[NRF_CLOCK_LFCLK_RC] = "LFRC",
		[NRF_CLOCK_LFCLK_Xtal] = "LFXO",
		[NRF_CLOCK_LFCLK_Synth] = "LFSYNT",
	};
	static const char *const hfsrc_s[] = {
		[NRF_CLOCK_HFCLK_LOW_ACCURACY] = "HFINT",
		[NRF_CLOCK_HFCLK_HIGH_ACCURACY] = "HFXO",
	};
	static const char *const clkstat_s[] = {
		[CLOCK_CONTROL_STATUS_STARTING] = "STARTING",
		[CLOCK_CONTROL_STATUS_OFF] = "OFF",
		[CLOCK_CONTROL_STATUS_ON] = "ON",
		[CLOCK_CONTROL_STATUS_UNKNOWN] = "UNKNOWN",
	};
	union {
		unsigned int raw;
		nrf_clock_lfclk_t lf;
		nrf_clock_hfclk_t hf;
	} src;
	enum clock_control_status clkstat;
	bool running;

	clkstat = clock_control_get_status(clock0, CLOCK_CONTROL_NRF_SUBSYS_LF);
	running = nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_LFCLK,
				       &src.lf);
	printk("%s: LFCLK[%s]: %s %s ; ", tag, clkstat_s[clkstat],
	       running ? "Running" : "Off", lfsrc_s[src.lf]);
	clkstat = clock_control_get_status(clock0, CLOCK_CONTROL_NRF_SUBSYS_HF);
	running = nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_HFCLK,
				       &src.hf);
	printk("HFCLK[%s]: %s %s\n", clkstat_s[clkstat],
	       running ? "Running" : "Off", hfsrc_s[src.hf]);
}

static void sync_work_handler(struct k_work *work)
{
	uint32_t ctr;
	int rc = counter_get_value(timer0, &ctr);
	const struct timeutil_sync_instant *base = &sync_state.base;
	const struct timeutil_sync_instant *latest = &sync_state.latest;

	if (rc == 0) {
		struct timeutil_sync_instant inst;
		uint64_t ref_span_us;

		counter_ref += ctr - (uint32_t)counter_ref;
		inst.ref = counter_ref;
		inst.local = k_uptime_ticks();

		rc = timeutil_sync_state_update(&sync_state, &inst);
		printf("\nTy  Latest           Base             Span             Err\n");
		printf("HF  %s", us_to_text(ref_to_us(inst.ref)));
		if (rc > 0) {
			printf("  %s", us_to_text(ref_to_us(base->ref)));
			ref_span_us = ref_to_us(latest->ref - base->ref);
			printf("  %s", us_to_text(ref_span_us));
		}
		printf("\nLF  %s", us_to_text(local_to_us(inst.local)));
		if (rc > 0) {
			uint64_t err_us;
			uint64_t local_span_us;
			char err_sign = ' ';

			printf("  %s", us_to_text(local_to_us(base->local)));

			local_span_us = local_to_us(latest->local - base->local);
			printf("  %s", us_to_text(local_span_us));

			if (ref_span_us >= local_span_us) {
				err_us = ref_span_us - local_span_us;
				err_sign = '-';
			} else {
				err_us = local_span_us - ref_span_us;
			}
			printf(" %c%s", err_sign, us_to_text(err_us));
		}
		printf("\n");
		if (rc > 0) {
			float skew = timeutil_sync_estimate_skew(&sync_state);

			/* Create a state with the current skew estimate.  Use
			 * it to reconstruct the expected reference time from
			 * the latest local time, then display that time and
			 * its error from the latest reference time.
			 */
			uint64_t rec_ref;
			struct timeutil_sync_state st2 = sync_state;

			(void)timeutil_sync_state_set_skew(&st2, skew, NULL);
			(void)timeutil_sync_ref_from_local(&st2, latest->local,
							   &rec_ref);

			char err_sign = ' ';
			uint64_t err_us;

			if (rec_ref < latest->ref) {
				err_sign = '-';
				err_us = ref_to_us(latest->ref - rec_ref);
			} else {
				err_us = ref_to_us(rec_ref - latest->ref);
			}

			printf("RHF %s                                   ",
			       us_to_text(ref_to_us(rec_ref)));
			printf("%c%s\n", err_sign, us_to_text(err_us));

			printf("Skew %f ; err %d ppb\n", skew,
			       timeutil_sync_skew_to_ppb(skew));
		} else if (rc < 0) {
			printf("Sync update error: %d\n", rc);
		}
	}
	(void)k_work_schedule(k_work_delayable_from_work(work),
			      K_SECONDS(UPDATE_INTERVAL_S));
}

void main(void)
{
	const char *clock_label = DT_LABEL(CLOCK_NODE);
	const char *timer0_label = DT_LABEL(TIMER_NODE);
	uint32_t top;
	int rc;

	/* Grab the clock driver */
	clock0 = device_get_binding(clock_label);
	if (clock0 == NULL) {
		printk("Failed to fetch clock %s\n", clock_label);
	}

	show_clocks("Power-up clocks");

	if (IS_ENABLED(CONFIG_APP_ENABLE_HFXO)) {
		rc = clock_control_on(clock0, CLOCK_CONTROL_NRF_SUBSYS_HF);
		printk("Enable HFXO got %d\n", rc);
	}

	/* Grab the timer. */
	timer0 = device_get_binding(timer0_label);
	if (timer0 == NULL) {
		printk("Failed to fetch timer0 %s\n", timer0_label);
		return;
	}

	/* Apparently there's no API to configure a frequency at
	 * runtime, so live with whatever we get.
	 */
	sync_config.ref_Hz = counter_get_frequency(timer0);
	if (sync_config.ref_Hz == 0) {
		printk("Timer %s has no fixed frequency\n",
			timer0_label);
		return;
	}

	top = counter_get_top_value(timer0);
	if (top != UINT32_MAX) {
		printk("Timer %s wraps at %u (0x%08x) not at 32 bits\n",
		       timer0_label, top, top);
		return;
	}

	rc = counter_start(timer0);
	printk("Start %s: %d\n", timer0_label, rc);

	show_clocks("Timer-running clocks");

	sync_config.local_Hz = CONFIG_SYS_CLOCK_TICKS_PER_SEC;

	sync_state.cfg = &sync_config;

	printf("Checking %s at %u Hz against ticks at %u Hz\n",
	       timer0_label, sync_config.ref_Hz, sync_config.local_Hz);
	printf("Timer wraps every %u s\n",
	       (uint32_t)(BIT64(32) / sync_config.ref_Hz));

	k_work_init_delayable(&sync_work, sync_work_handler);
	rc = k_work_schedule(&sync_work, K_NO_WAIT);

	printk("Started sync: %d\n", rc);
}
