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

#include <stddef.h>
#include <string.h>

#include <toolchain.h>
#include <zephyr/types.h>
#include <clock_control.h>

#include "hal/cntr.h"
#include "hal/ccm.h"
#include "hal/radio.h"

#include "util/util.h"
#include "ll_sw/pdu.h"
#include "ll_sw/ctrl.h"

#include "ll_test.h"

#define CNTR_MIN_DELTA 3

static const u32_t test_sync_word = 0x71764129;
static u8_t        test_phy;
static u8_t        test_phy_flags;
static u16_t       test_num_rx;
static bool        started;

/* NOTE: The PRBS9 sequence used as packet payload.
 * The bytes in the sequence are in the right order, but the bits of each byte
 * in the array are reverse from that found by running the PRBS9 algorithm. This
 * is done to transmit MSbit first on air.
 */

static const u8_t prbs9[] = {
	0xFF, 0xC1, 0xFB, 0xE8, 0x4C, 0x90, 0x72, 0x8B,
	0xE7, 0xB3, 0x51, 0x89, 0x63, 0xAB, 0x23, 0x23,
	0x02, 0x84, 0x18, 0x72, 0xAA, 0x61, 0x2F, 0x3B,
	0x51, 0xA8, 0xE5, 0x37, 0x49, 0xFB, 0xC9, 0xCA,
	0x0C, 0x18, 0x53, 0x2C, 0xFD, 0x45, 0xE3, 0x9A,
	0xE6, 0xF1, 0x5D, 0xB0, 0xB6, 0x1B, 0xB4, 0xBE,
	0x2A, 0x50, 0xEA, 0xE9, 0x0E, 0x9C, 0x4B, 0x5E,
	0x57, 0x24, 0xCC, 0xA1, 0xB7, 0x59, 0xB8, 0x87,
	0xFF, 0xE0, 0x7D, 0x74, 0x26, 0x48, 0xB9, 0xC5,
	0xF3, 0xD9, 0xA8, 0xC4, 0xB1, 0xD5, 0x91, 0x11,
	0x01, 0x42, 0x0C, 0x39, 0xD5, 0xB0, 0x97, 0x9D,
	0x28, 0xD4, 0xF2, 0x9B, 0xA4, 0xFD, 0x64, 0x65,
	0x06, 0x8C, 0x29, 0x96, 0xFE, 0xA2, 0x71, 0x4D,
	0xF3, 0xF8, 0x2E, 0x58, 0xDB, 0x0D, 0x5A, 0x5F,
	0x15, 0x28, 0xF5, 0x74, 0x07, 0xCE, 0x25, 0xAF,
	0x2B, 0x12, 0xE6, 0xD0, 0xDB, 0x2C, 0xDC, 0xC3,
	0x7F, 0xF0, 0x3E, 0x3A, 0x13, 0xA4, 0xDC, 0xE2,
	0xF9, 0x6C, 0x54, 0xE2, 0xD8, 0xEA, 0xC8, 0x88,
	0x00, 0x21, 0x86, 0x9C, 0x6A, 0xD8, 0xCB, 0x4E,
	0x14, 0x6A, 0xF9, 0x4D, 0xD2, 0x7E, 0xB2, 0x32,
	0x03, 0xC6, 0x14, 0x4B, 0x7F, 0xD1, 0xB8, 0xA6,
	0x79, 0x7C, 0x17, 0xAC, 0xED, 0x06, 0xAD, 0xAF,
	0x0A, 0x94, 0x7A, 0xBA, 0x03, 0xE7, 0x92, 0xD7,
	0x15, 0x09, 0x73, 0xE8, 0x6D, 0x16, 0xEE, 0xE1,
	0x3F, 0x78, 0x1F, 0x9D, 0x09, 0x52, 0x6E, 0xF1,
	0x7C, 0x36, 0x2A, 0x71, 0x6C, 0x75, 0x64, 0x44,
	0x80, 0x10, 0x43, 0x4E, 0x35, 0xEC, 0x65, 0x27,
	0x0A, 0xB5, 0xFC, 0x26, 0x69, 0x3F, 0x59, 0x99,
	0x01, 0x63, 0x8A, 0xA5, 0xBF, 0x68, 0x5C, 0xD3,
	0x3C, 0xBE, 0x0B, 0xD6, 0x76, 0x83, 0xD6, 0x57,
	0x05, 0x4A, 0x3D, 0xDD, 0x81, 0x73, 0xC9, 0xEB,
	0x8A, 0x84, 0x39, 0xF4, 0x36, 0x0B, 0xF7};

/* TODO: fill correct prbs15 */
static const u8_t prbs15[255] = { 0x00, };

static void isr_tx(void)
{
	u8_t trx_done;
	u32_t l, i, s, t;

	/* Read radio status and events */
	trx_done = radio_is_done();

	/* Clear radio status and events */
	radio_status_reset();
	radio_tmr_status_reset();

	/* Exit if radio disabled */
	if (!trx_done) {
		return;
	}

	/* LE Test Packet Interval */
	l = radio_tmr_end_get() - radio_tmr_ready_get();
	i = ((l + 249 + 624) / 625) * 625;
	t = radio_tmr_end_get() - l + i;
	t -= radio_tx_ready_delay_get(test_phy, test_phy_flags);

	/* Set timer capture in the future. */
	radio_tmr_sample();
	s = radio_tmr_sample_get();
	while (t < s) {
		t += 625;
	}

	/* Setup next Tx */
	radio_switch_complete_and_disable();
	radio_tmr_start_us(1, t);
	radio_tmr_aa_capture();
	radio_tmr_end_capture();

	/* TODO: check for probable stall timer capture being set */
}

static void isr_rx(void)
{
	u8_t crc_ok = 0;
	u8_t trx_done;

	/* Read radio status and events */
	trx_done = radio_is_done();
	if (trx_done) {
		crc_ok = radio_crc_is_valid();
	}

	/* Clear radio status and events */
	radio_status_reset();
	radio_tmr_status_reset();

	/* Exit if radio disabled */
	if (!trx_done) {
		return;
	}

	/* Setup next Rx */
	radio_switch_complete_and_rx(test_phy);

	/* Count Rx-ed packets */
	if (crc_ok) {
		test_num_rx++;
	}
}

static u32_t init(u8_t chan, u8_t phy, void (*isr)(void))
{
	struct device *hf_clock;

	if (started) {
		return 1;
	}

	/* start coarse timer */
	cntr_start();

	/* Setup resources required by Radio */
	hf_clock = radio_hf_clock_get();
	clock_control_on(hf_clock, (void *)1); /* start clock, blocking. */

	/* Reset Radio h/w */
	radio_reset();
	radio_isr_set(isr);

	/* Store value needed in Tx/Rx ISR */
	if (phy < 0x04) {
		test_phy = BIT(phy - 1);
		test_phy_flags = 1;
	} else {
		test_phy = BIT(2);
		test_phy_flags = 0;
	}

	/* Setup Radio in Tx/Rx */
	/* NOTE: No whitening in test mode. */
	radio_phy_set(test_phy, test_phy_flags);
	radio_tx_power_set(0);
	radio_freq_chan_set((chan << 1) + 2);
	radio_aa_set((u8_t *)&test_sync_word);
	radio_crc_configure(0x65b, 0x555555);
	radio_pkt_configure(8, 255, (test_phy << 1));

	return 0;
}

u32_t ll_test_tx(u8_t chan, u8_t len, u8_t type, u8_t phy)
{
	u8_t *payload;
	u8_t *pdu;
	u32_t err;

	if ((type > 0x07) || !phy || (phy > 0x04)) {
		return 1;
	}

	err = init(chan, phy, isr_tx);
	if (err) {
		return err;
	}

	pdu = radio_pkt_scratch_get();
	payload = &pdu[2];

	switch (type) {
	case 0x00:
		memcpy(payload, prbs9, len);
		break;

	case 0x01:
		memset(payload, 0x0f, len);
		break;

	case 0x02:
		memset(payload, 0x55, len);
		break;

	case 0x03:
		memcpy(payload, prbs15, len);
		break;

	case 0x04:
		memset(payload, 0xff, len);
		break;

	case 0x05:
		memset(payload, 0x00, len);
		break;

	case 0x06:
		memset(payload, 0xf0, len);
		break;

	case 0x07:
		memset(payload, 0xaa, len);
		break;
	}

	pdu[0] = type;
	pdu[1] = len;

	radio_pkt_tx_set(pdu);
	radio_switch_complete_and_disable();
	radio_tmr_start(1, cntr_cnt_get() + CNTR_MIN_DELTA, 0);
	radio_tmr_aa_capture();
	radio_tmr_end_capture();

	started = true;

	return 0;
}

u32_t ll_test_rx(u8_t chan, u8_t phy, u8_t mod_idx)
{
	u32_t err;

	if (!phy || (phy > 0x03)) {
		return 1;
	}

	err = init(chan, phy, isr_rx);
	if (err) {
		return err;
	}

	radio_pkt_rx_set(radio_pkt_scratch_get());
	radio_switch_complete_and_rx(test_phy);
	radio_tmr_start(0, cntr_cnt_get() + CNTR_MIN_DELTA, 0);

	started = true;

	return 0;
}

u32_t ll_test_end(u16_t *num_rx)
{
	struct device *hf_clock;

	if (!started) {
		return 1;
	}

	/* Return packets Rx-ed/Completed */
	*num_rx = test_num_rx;
	test_num_rx = 0;

	/* Disable Radio */
	radio_disable();

	/* Stop packet timer */
	radio_tmr_stop();

	/* Release resources acquired for Radio */
	hf_clock = radio_hf_clock_get();
	clock_control_off(hf_clock, NULL);

	/* Stop coarse timer */
	cntr_stop();

	started = false;

	return 0;
}
