/* Card (ICC) UART driver for the Atmel ASF4 asynchronous USART */

#include <errno.h>

#include <osmocom/core/linuxlist.h>
#include <osmocom/core/utils.h>

#include <hal_usart_async.h>
#include <utils_ringbuffer.h>
#include "driver_init.h"

#include "ncn8025.h"

#include "cuart.h"

static struct usart_async_descriptor* SIM_peripheral_descriptors[] = {&SIM0, &SIM1, &SIM2, &SIM3, &SIM4, &SIM5, &SIM6, NULL};

extern struct card_uart *cuart4slot_nr(uint8_t slot_nr);

/***********************************************************************
 * low-level helper routines
 ***********************************************************************/

static void _SIM_rx_cb(const struct usart_async_descriptor *const io_descr, uint8_t slot_nr)
{
	struct card_uart *cuart = cuart4slot_nr(slot_nr);
	int rc;
	OSMO_ASSERT(cuart);

	if (cuart->rx_threshold == 1) {
		/* bypass ringbuffer and report byte directly */
		uint8_t rx[1];
		rc = io_read((struct io_descriptor * const)&io_descr->io, rx, sizeof(rx));
		OSMO_ASSERT(rc == sizeof(rx));
		card_uart_notification(cuart, CUART_E_RX_SINGLE, rx);
	} else {
		/* go via ringbuffer and notify only after threshold */
		if (ringbuffer_num(&io_descr->rx) >= cuart->rx_threshold)
			card_uart_notification(cuart, CUART_E_RX_COMPLETE, NULL);
	}
}

static void _SIM_tx_cb(const struct usart_async_descriptor *const io_descr, uint8_t slot_nr)
{
	struct card_uart *cuart = cuart4slot_nr(slot_nr);
	OSMO_ASSERT(cuart);
	card_uart_notification(cuart, CUART_E_TX_COMPLETE, io_descr->tx_buffer);
}

#include <hpl_usart_async.h>
#include <hpl_usart_sync.h>


static void _SIM_error_cb(const struct usart_async_descriptor *const descr){
	volatile uint32_t status = hri_sercomusart_read_STATUS_reg(descr->device.hw);
	volatile uint32_t data = hri_sercomusart_read_DATA_reg(descr->device.hw);
	volatile uint32_t errrs = hri_sercomusart_read_RXERRCNT_reg(descr->device.hw);
	OSMO_ASSERT(0 == 1)
}

/* the below ugli-ness is required as the usart_async_descriptor doesn't have
 * some kind of 'private' member that could provide the call-back anty kind of
 * context */
static void SIM0_rx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_rx_cb(io_descr, 0);
}
static void SIM1_rx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_rx_cb(io_descr, 1);
}
static void SIM2_rx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_rx_cb(io_descr, 2);
}
static void SIM3_rx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_rx_cb(io_descr, 3);
}
static void SIM4_rx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_rx_cb(io_descr, 4);
}
static void SIM5_rx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_rx_cb(io_descr, 5);
}
static void SIM6_rx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_rx_cb(io_descr, 6);
}
static void SIM7_rx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_rx_cb(io_descr, 7);
}
static usart_cb_t SIM_rx_cb[8] = {
	SIM0_rx_cb, SIM1_rx_cb, SIM2_rx_cb, SIM3_rx_cb,
	SIM4_rx_cb, SIM5_rx_cb, SIM6_rx_cb, SIM7_rx_cb,
};
static void SIM0_tx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_tx_cb(io_descr, 0);
}
static void SIM1_tx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_tx_cb(io_descr, 1);
}
static void SIM2_tx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_tx_cb(io_descr, 2);
}
static void SIM3_tx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_tx_cb(io_descr, 3);
}
static void SIM4_tx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_tx_cb(io_descr, 4);
}
static void SIM5_tx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_tx_cb(io_descr, 5);
}
static void SIM6_tx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_tx_cb(io_descr, 6);
}
static void SIM7_tx_cb(const struct usart_async_descriptor *const io_descr)
{
	_SIM_tx_cb(io_descr, 7);
}
static usart_cb_t SIM_tx_cb[8] = {
	SIM0_tx_cb, SIM1_tx_cb, SIM2_tx_cb, SIM3_tx_cb,
	SIM4_tx_cb, SIM5_tx_cb, SIM6_tx_cb, SIM7_tx_cb,
};

#include <math.h>
#include "atmel_start.h"
#include "atmel_start_pins.h"
#include "config/hpl_gclk_config.h"
#include "iso7816_3.h"

/** possible clock sources for the SERCOM peripheral
 *  warning: the definition must match the GCLK configuration
 */
static const uint8_t sercom_glck_sources[] = {GCLK_PCHCTRL_GEN_GCLK2_Val, GCLK_PCHCTRL_GEN_GCLK4_Val, GCLK_PCHCTRL_GEN_GCLK6_Val};

 /** possible clock frequencies in MHz for the SERCOM peripheral
  *  warning: the definition must match the GCLK configuration
  */
static const double sercom_glck_freqs[] = {100E6 / CONF_GCLK_GEN_2_DIV, 100E6 / CONF_GCLK_GEN_4_DIV, 120E6 / CONF_GCLK_GEN_6_DIV};

/** the GCLK ID for the SERCOM SIM peripherals
 *  @note: used as index for PCHCTRL
 */
static const uint8_t SIM_peripheral_GCLK_ID[] = {SERCOM0_GCLK_ID_CORE, SERCOM1_GCLK_ID_CORE, SERCOM2_GCLK_ID_CORE, SERCOM3_GCLK_ID_CORE, SERCOM4_GCLK_ID_CORE, SERCOM5_GCLK_ID_CORE, SERCOM6_GCLK_ID_CORE, SERCOM7_GCLK_ID_CORE};


/** change baud rate of card slot
 *  @param[in] slotnr slot number for which the baud rate should be set
 *  @param[in] baudrate baud rate in bps to set
 *  @return if the baud rate has been set, else a parameter is out of range
 */
static bool slot_set_baudrate(uint8_t slotnr, uint32_t baudrate)
{
	ASSERT(slotnr < ARRAY_SIZE(SIM_peripheral_descriptors));

	// calculate the error corresponding to the clock sources
	uint16_t bauds[ARRAY_SIZE(sercom_glck_freqs)];
	double errors[ARRAY_SIZE(sercom_glck_freqs)];
	for (uint8_t i = 0; i < ARRAY_SIZE(sercom_glck_freqs); i++) {
		double freq = sercom_glck_freqs[i]; // remember possible SERCOM frequency
		uint32_t min = freq/16. *  (1. - 65535. / 65536.); // calculate the minimum baud rate for this frequency
		uint32_t max = freq/16. *  (1. - 1. / 65536.); // calculate the maximum baud rate for this frequency
		if (baudrate < min || baudrate > max) { // baud rate it out of supported range
			errors[i] = NAN;
		} else {
			uint16_t baud = round(65536. * (1. - 16. * (baudrate/freq)));
			bauds[i] = baud;
			double actual = freq/16. *  (1. - baud / 65536.);
			errors[i] = fabs(1.0 - (actual / baudrate));
		}
	}

	// find the smallest error
	uint8_t best = ARRAY_SIZE(sercom_glck_freqs);
	for (uint8_t i = 0; i < ARRAY_SIZE(sercom_glck_freqs); i++) {
		if (isnan(errors[i])) {
			continue;
		}
		if (best >= ARRAY_SIZE(sercom_glck_freqs)) {
			best = i;
		} else if (errors[i] < errors[best]) {
			best = i;
		}
	}
	if (best >= ARRAY_SIZE(sercom_glck_freqs)) { // found no clock supporting this baud rate
		return false;
	}

	// set clock and baud rate
	struct usart_async_descriptor* slot = SIM_peripheral_descriptors[slotnr]; // get slot
	if (NULL == slot) {
		return false;
	}
	printf("(%u) switching SERCOM clock to GCLK%u (freq = %lu kHz) and baud rate to %lu bps (baud = %u)\r\n", slotnr, (best + 1) * 2, (uint32_t)(round(sercom_glck_freqs[best] / 1000)), baudrate, bauds[best]);
	while (!usart_async_is_tx_empty(slot)); // wait for transmission to complete (WARNING no timeout)
	usart_async_disable(slot); // disable SERCOM peripheral
	hri_gclk_clear_PCHCTRL_reg(GCLK, SIM_peripheral_GCLK_ID[slotnr], (1 << GCLK_PCHCTRL_CHEN_Pos)); // disable clock for this peripheral
	while (hri_gclk_get_PCHCTRL_reg(GCLK, SIM_peripheral_GCLK_ID[slotnr], (1 << GCLK_PCHCTRL_CHEN_Pos))); // wait until clock is really disabled
	// it does not seem we need to completely disable the peripheral using hri_mclk_clear_APBDMASK_SERCOMn_bit
	hri_gclk_write_PCHCTRL_reg(GCLK, SIM_peripheral_GCLK_ID[slotnr], sercom_glck_sources[best] | (1 << GCLK_PCHCTRL_CHEN_Pos)); // set peripheral core clock and re-enable it
	usart_async_set_baud_rate(slot, bauds[best]); // set the new baud rate
	usart_async_enable(slot); // re-enable SERCOM peripheral

	return true;
}

/** change ISO baud rate of card slot
 *  @param[in] slotnr slot number for which the baud rate should be set
 *  @param[in] clkdiv can clock divider
 *  @param[in] f clock rate conversion integer F
 *  @param[in] d baud rate adjustment factor D
 *  @return if the baud rate has been set, else a parameter is out of range
 */
static bool slot_set_isorate(uint8_t slotnr, enum ncn8025_sim_clkdiv clkdiv, uint16_t f, uint8_t d)
{
	// input checks
	ASSERT(slotnr < ARRAY_SIZE(SIM_peripheral_descriptors));
	if (clkdiv != SIM_CLKDIV_1 && clkdiv != SIM_CLKDIV_2 && clkdiv != SIM_CLKDIV_4 && clkdiv != SIM_CLKDIV_8) {
		return false;
	}
	if (!iso7816_3_valid_f(f)) {
		return false;
	}
	if (!iso7816_3_valid_d(d)) {
		return false;
	}

	// set clockdiv
	struct ncn8025_settings settings;
	ncn8025_get(slotnr, &settings);
	if (settings.clkdiv != clkdiv) {
		settings.clkdiv = clkdiv;
		ncn8025_set(slotnr, &settings);
	}

	// calculate desired frequency
	uint32_t freq = 20000000UL; // maximum frequency
	switch (clkdiv) {
	case SIM_CLKDIV_1:
		freq /= 1;
		break;
	case SIM_CLKDIV_2:
		freq /= 2;
		break;
	case SIM_CLKDIV_4:
		freq /= 4;
		break;
	case SIM_CLKDIV_8:
		freq /= 8;
		break;
	}

	// set baud rate
	uint32_t baudrate = (freq * d) / f; // calculate actual baud rate
	return slot_set_baudrate(slotnr, baudrate); // set baud rate
}

/***********************************************************************
 * Interface with card_uart (cuart) core
 ***********************************************************************/

/* forward-declaration */
static struct card_uart_driver asf4_usart_driver;
static int asf4_usart_close(struct card_uart *cuart);

static int asf4_usart_open(struct card_uart *cuart, const char *device_name)
{
	struct usart_async_descriptor *usa_pd;
	int slot_nr = atoi(device_name);

	if (slot_nr >= ARRAY_SIZE(SIM_peripheral_descriptors))
		return -ENODEV;
	usa_pd = SIM_peripheral_descriptors[slot_nr];
	if (!usa_pd)
		return -ENODEV;

	cuart->u.asf4.usa_pd = usa_pd;
	cuart->u.asf4.slot_nr = slot_nr;


	usart_async_register_callback(usa_pd, USART_ASYNC_RXC_CB, SIM_rx_cb[slot_nr]);
	usart_async_register_callback(usa_pd, USART_ASYNC_TXC_CB, SIM_tx_cb[slot_nr]);
	usart_async_register_callback(usa_pd, USART_ASYNC_ERROR_CB, _SIM_error_cb);
	usart_async_enable(usa_pd);

	// set USART baud rate to match the interface (f = 2.5 MHz) and card default settings (Fd = 372, Dd = 1)
	slot_set_isorate(cuart->u.asf4.slot_nr, SIM_CLKDIV_8, ISO7816_3_DEFAULT_FD, ISO7816_3_DEFAULT_DD);

        return 0;
}

static int asf4_usart_close(struct card_uart *cuart)
{
	struct usart_async_descriptor *usa_pd = cuart->u.asf4.usa_pd;

	OSMO_ASSERT(cuart->driver == &asf4_usart_driver);

	usart_async_disable(usa_pd);

	return 0;
}

static int asf4_usart_async_tx(struct card_uart *cuart, const uint8_t *data, size_t len)
{
	struct usart_async_descriptor *usa_pd = cuart->u.asf4.usa_pd;
	int rc;

	OSMO_ASSERT(cuart->driver == &asf4_usart_driver);
	OSMO_ASSERT(usart_async_is_tx_empty(usa_pd));

	rc = io_write(&usa_pd->io, data, len);
	if (rc < 0)
		return rc;

	cuart->tx_busy = true;

	return rc;
}

static int asf4_usart_async_rx(struct card_uart *cuart, uint8_t *data, size_t len)
{
	struct usart_async_descriptor *usa_pd = cuart->u.asf4.usa_pd;

	OSMO_ASSERT(cuart->driver == &asf4_usart_driver);

	return io_read(&usa_pd->io, data, len);
}

static int asf4_usart_ctrl(struct card_uart *cuart, enum card_uart_ctl ctl, int arg)
{
	struct ncn8025_settings settings;
	Sercom *sercom = cuart->u.asf4.usa_pd->device.hw;

	switch (ctl) {
	case CUART_CTL_RX:
		if (arg){
			sercom->USART.CTRLB.bit.RXEN = 1;
			sercom->USART.CTRLB.bit.TXEN = 0;
		} else {
			delay_us(100);
			sercom->USART.CTRLB.bit.RXEN = 0;
			sercom->USART.CTRLB.bit.TXEN = 1;
		}
		break;
	case CUART_CTL_RST:
		ncn8025_get(cuart->u.asf4.slot_nr, &settings);
		settings.rstin = arg ? true : false;
		ncn8025_set(cuart->u.asf4.slot_nr, &settings);
		usart_async_flush_rx_buffer(cuart->u.asf4.usa_pd);
		break;
	case CUART_CTL_POWER:
		ncn8025_get(cuart->u.asf4.slot_nr, &settings);
		settings.cmdvcc = arg ? true : false;
		settings.led = arg ? true : false;
		settings.vsel = SIM_VOLT_5V0;

		// set USART baud rate to match the interface (f = 2.5 MHz) and card default settings (Fd = 372, Dd = 1)
		if(arg)
			slot_set_isorate(cuart->u.asf4.slot_nr, SIM_CLKDIV_8, ISO7816_3_DEFAULT_FD, ISO7816_3_DEFAULT_DD);

		ncn8025_set(cuart->u.asf4.slot_nr, &settings);
		break;
	case CUART_CTL_WTIME:
		/* no driver-specific handling of this */
		break;
	case CUART_CTL_CLOCK:
		/* FIXME */
	default:
		return -EINVAL;
	}
	return 0;
}

static const struct card_uart_ops asf4_usart_ops = {
	.open = asf4_usart_open,
	.close = asf4_usart_close,
	.async_tx = asf4_usart_async_tx,
	.async_rx = asf4_usart_async_rx,
	.ctrl = asf4_usart_ctrl,
};

static struct card_uart_driver asf4_usart_driver = {
	.name = "asf4",
	.ops = &asf4_usart_ops,
};

static __attribute__((constructor)) void on_dso_load_cuart_asf4(void)
{
	card_uart_driver_register(&asf4_usart_driver);
}
