/*
 * Copyright (c) 2020 PHYTEC Messtechnik GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(dw1000, LOG_LEVEL_INF);

#include <errno.h>
#include <zephyr/kernel.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/debug/stack.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_pkt.h>

#include <zephyr/sys/byteorder.h>
#include <string.h>
#include <zephyr/random/rand32.h>
#include <zephyr/debug/stack.h>
#include <math.h>

#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/spi.h>

#include <zephyr/net/ieee802154_radio.h>
#include "ieee802154_dw1000_regs.h"

#define DT_DRV_COMPAT decawave_dw1000

#define DWT_FCS_LENGTH			2U
#define DWT_SPI_CSWAKEUP_FREQ		500000U
#define DWT_SPI_SLOW_FREQ		2000000U
#define DWT_SPI_TRANS_MAX_HDR_LEN	3
#define DWT_SPI_TRANS_REG_MAX_RANGE	0x3F
#define DWT_SPI_TRANS_SHORT_MAX_OFFSET	0x7F
#define DWT_SPI_TRANS_WRITE_OP		BIT(7)
#define DWT_SPI_TRANS_SUB_ADDR		BIT(6)
#define DWT_SPI_TRANS_EXTEND_ADDR	BIT(7)

#define DWT_TS_TIME_UNITS_FS		15650U /* DWT_TIME_UNITS in fs */

#define DW1000_TX_ANT_DLY		16450
#define DW1000_RX_ANT_DLY		16450

/* SHR Symbol Duration in ns */
#define UWB_PHY_TPSYM_PRF64		1017.63
#define UWB_PHY_TPSYM_PRF16		993.59

#define UWB_PHY_NUMOF_SYM_SHR_SFD	8

/* PHR Symbol Duration Tdsym in ns */
#define UWB_PHY_TDSYM_PHR_110K		8205.13
#define UWB_PHY_TDSYM_PHR_850K		1025.64
#define UWB_PHY_TDSYM_PHR_6M8		1025.64

#define UWB_PHY_NUMOF_SYM_PHR		18

/* Data Symbol Duration Tdsym in ns */
#define UWB_PHY_TDSYM_DATA_110K		8205.13
#define UWB_PHY_TDSYM_DATA_850K		1025.64
#define UWB_PHY_TDSYM_DATA_6M8		128.21

#define DWT_WORK_QUEUE_STACK_SIZE	512

static struct k_work_q dwt_work_queue;
static K_KERNEL_STACK_DEFINE(dwt_work_queue_stack,
			     DWT_WORK_QUEUE_STACK_SIZE);

struct dwt_phy_config {
	uint8_t channel;	/* Channel 1, 2, 3, 4, 5, 7 */
	uint8_t dr;	/* Data rate DWT_BR_110K, DWT_BR_850K, DWT_BR_6M8 */
	uint8_t prf;	/* PRF DWT_PRF_16M or DWT_PRF_64M */

	uint8_t rx_pac_l;		/* DWT_PAC8..DWT_PAC64 */
	uint8_t rx_shr_code;	/* RX SHR preamble code */
	uint8_t rx_ns_sfd;		/* non-standard SFD */
	uint16_t rx_sfd_to;	/* SFD timeout value (in symbols)
				 * (tx_shr_nsync + 1 + SFD_length - rx_pac_l)
				 */

	uint8_t tx_shr_code;	/* TX SHR preamble code */
	uint32_t tx_shr_nsync;	/* PLEN index, e.g. DWT_PLEN_64 */

	float t_shr;
	float t_phr;
	float t_dsym;
};

struct dwt_hi_cfg {
	struct spi_dt_spec bus;
	struct gpio_dt_spec irq_gpio;
	struct gpio_dt_spec rst_gpio;
};

#define DWT_STATE_TX		0
#define DWT_STATE_CCA		1
#define DWT_STATE_RX_DEF_ON	2

struct dwt_context {
	const struct device *dev;
	struct net_if *iface;
	const struct spi_config *spi_cfg;
	struct spi_config spi_cfg_slow;
	struct gpio_callback gpio_cb;
	struct k_sem dev_lock;
	struct k_sem phy_sem;
	struct k_work irq_cb_work;
	struct k_thread thread;
	struct dwt_phy_config rf_cfg;
	atomic_t state;
	bool cca_busy;
	uint16_t sleep_mode;
	uint8_t mac_addr[8];
};

static const struct dwt_hi_cfg dw1000_0_config = {
	.bus = SPI_DT_SPEC_INST_GET(0, SPI_WORD_SET(8), 0),
	.irq_gpio = GPIO_DT_SPEC_INST_GET(0, int_gpios),
	.rst_gpio = GPIO_DT_SPEC_INST_GET(0, reset_gpios),
};

static struct dwt_context dwt_0_context = {
	.dev_lock = Z_SEM_INITIALIZER(dwt_0_context.dev_lock, 1,  1),
	.phy_sem = Z_SEM_INITIALIZER(dwt_0_context.phy_sem, 0,  1),
	.rf_cfg = {
		.channel = 5,
		.dr = DWT_BR_6M8,
		.prf = DWT_PRF_64M,

		.rx_pac_l = DWT_PAC8,
		.rx_shr_code = 10,
		.rx_ns_sfd = 0,
		.rx_sfd_to = (129 + 8 - 8),

		.tx_shr_code = 10,
		.tx_shr_nsync = DWT_PLEN_128,
	},
};

/* This struct is used to read all additional RX frame info at one push */
struct dwt_rx_info_regs {
	uint8_t rx_fqual[DWT_RX_FQUAL_LEN];
	uint8_t rx_ttcki[DWT_RX_TTCKI_LEN];
	uint8_t rx_ttcko[DWT_RX_TTCKO_LEN];
	/* RX_TIME without RX_RAWST */
	uint8_t rx_time[DWT_RX_TIME_FP_RAWST_OFFSET];
} _packed;

static int dwt_configure_rf_phy(const struct device *dev);

static int dwt_spi_read(const struct device *dev,
			uint16_t hdr_len, const uint8_t *hdr_buf,
			uint32_t data_len, uint8_t *data)
{
	struct dwt_context *ctx = dev->data;
	const struct dwt_hi_cfg *hi_cfg = dev->config;
	const struct spi_buf tx_buf = {
		.buf = (uint8_t *)hdr_buf,
		.len = hdr_len
	};
	const struct spi_buf_set tx = {
		.buffers = &tx_buf,
		.count = 1
	};
	struct spi_buf rx_buf[2] = {
		{
			.buf = NULL,
			.len = hdr_len,
		},
		{
			.buf = (uint8_t *)data,
			.len = data_len,
		},
	};
	const struct spi_buf_set rx = {
		.buffers = rx_buf,
		.count = 2
	};

	LOG_DBG("spi read, header length %u, data length %u",
		(uint16_t)hdr_len, (uint32_t)data_len);
	LOG_HEXDUMP_DBG(hdr_buf, (uint16_t)hdr_len, "rd: header");

	if (spi_transceive(hi_cfg->bus.bus, ctx->spi_cfg, &tx, &rx)) {
		LOG_ERR("SPI transfer failed");
		return -EIO;
	}

	LOG_HEXDUMP_DBG(data, (uint32_t)data_len, "rd: data");

	return 0;
}


static int dwt_spi_write(const struct device *dev,
			 uint16_t hdr_len, const uint8_t *hdr_buf,
			 uint32_t data_len, const uint8_t *data)
{
	struct dwt_context *ctx = dev->data;
	const struct dwt_hi_cfg *hi_cfg = dev->config;
	struct spi_buf buf[2] = {
		{.buf = (uint8_t *)hdr_buf, .len = hdr_len},
		{.buf = (uint8_t *)data, .len = data_len}
	};
	struct spi_buf_set buf_set = {.buffers = buf, .count = 2};

	LOG_DBG("spi write, header length %u, data length %u",
		(uint16_t)hdr_len, (uint32_t)data_len);
	LOG_HEXDUMP_DBG(hdr_buf, (uint16_t)hdr_len, "wr: header");
	LOG_HEXDUMP_DBG(data, (uint32_t)data_len, "wr: data");

	if (spi_write(hi_cfg->bus.bus, ctx->spi_cfg, &buf_set)) {
		LOG_ERR("SPI read failed");
		return -EIO;
	}

	return 0;
}

/* See 2.2.1.2 Transaction formats of the SPI interface */
static int dwt_spi_transfer(const struct device *dev,
			    uint8_t reg, uint16_t offset,
			    size_t buf_len, uint8_t *buf, bool write)
{
	uint8_t hdr[DWT_SPI_TRANS_MAX_HDR_LEN] = {0};
	size_t hdr_len = 0;

	hdr[0] = reg & DWT_SPI_TRANS_REG_MAX_RANGE;
	hdr_len += 1;

	if (offset != 0) {
		hdr[0] |= DWT_SPI_TRANS_SUB_ADDR;
		hdr[1] = (uint8_t)offset & DWT_SPI_TRANS_SHORT_MAX_OFFSET;
		hdr_len += 1;

		if (offset > DWT_SPI_TRANS_SHORT_MAX_OFFSET) {
			hdr[1] |= DWT_SPI_TRANS_EXTEND_ADDR;
			hdr[2] =  (uint8_t)(offset >> 7);
			hdr_len += 1;
		}

	}

	if (write) {
		hdr[0] |= DWT_SPI_TRANS_WRITE_OP;
		return dwt_spi_write(dev, hdr_len, hdr, buf_len, buf);
	} else {
		return dwt_spi_read(dev, hdr_len, hdr, buf_len, buf);
	}
}

static int dwt_register_read(const struct device *dev,
			     uint8_t reg, uint16_t offset, size_t buf_len, uint8_t *buf)
{
	return dwt_spi_transfer(dev, reg, offset, buf_len, buf, false);
}

static int dwt_register_write(const struct device *dev,
			      uint8_t reg, uint16_t offset, size_t buf_len, uint8_t *buf)
{
	return dwt_spi_transfer(dev, reg, offset, buf_len, buf, true);
}

static inline uint32_t dwt_reg_read_u32(const struct device *dev,
				     uint8_t reg, uint16_t offset)
{
	uint8_t buf[sizeof(uint32_t)];

	dwt_spi_transfer(dev, reg, offset, sizeof(buf), buf, false);

	return sys_get_le32(buf);
}

static inline uint16_t dwt_reg_read_u16(const struct device *dev,
				     uint8_t reg, uint16_t offset)
{
	uint8_t buf[sizeof(uint16_t)];

	dwt_spi_transfer(dev, reg, offset, sizeof(buf), buf, false);

	return sys_get_le16(buf);
}

static inline uint8_t dwt_reg_read_u8(const struct device *dev,
				   uint8_t reg, uint16_t offset)
{
	uint8_t buf;

	dwt_spi_transfer(dev, reg, offset, sizeof(buf), &buf, false);

	return buf;
}

static inline void dwt_reg_write_u32(const struct device *dev,
				     uint8_t reg, uint16_t offset, uint32_t val)
{
	uint8_t buf[sizeof(uint32_t)];

	sys_put_le32(val, buf);
	dwt_spi_transfer(dev, reg, offset, sizeof(buf), buf, true);
}

static inline void dwt_reg_write_u16(const struct device *dev,
				     uint8_t reg, uint16_t offset, uint16_t val)
{
	uint8_t buf[sizeof(uint16_t)];

	sys_put_le16(val, buf);
	dwt_spi_transfer(dev, reg, offset, sizeof(buf), buf, true);
}

static inline void dwt_reg_write_u8(const struct device *dev,
				    uint8_t reg, uint16_t offset, uint8_t val)
{
	dwt_spi_transfer(dev, reg, offset, sizeof(uint8_t), &val, true);
}

static ALWAYS_INLINE void dwt_setup_int(const struct device *dev,
					bool enable)
{
	const struct dwt_hi_cfg *hi_cfg = dev->config;

	unsigned int flags = enable
		? GPIO_INT_EDGE_TO_ACTIVE
		: GPIO_INT_DISABLE;

	gpio_pin_interrupt_configure_dt(&hi_cfg->irq_gpio, flags);
}

static void dwt_reset_rfrx(const struct device *dev)
{
	/*
	 * Apply a receiver-only soft reset,
	 * see SOFTRESET field description in DW1000 User Manual.
	 */
	dwt_reg_write_u8(dev, DWT_PMSC_ID, DWT_PMSC_CTRL0_SOFTRESET_OFFSET,
			 DWT_PMSC_CTRL0_RESET_RX);
	dwt_reg_write_u8(dev, DWT_PMSC_ID, DWT_PMSC_CTRL0_SOFTRESET_OFFSET,
			 DWT_PMSC_CTRL0_RESET_CLEAR);
}

static void dwt_disable_txrx(const struct device *dev)
{
	dwt_setup_int(dev, false);

	dwt_reg_write_u8(dev, DWT_SYS_CTRL_ID, DWT_SYS_CTRL_OFFSET,
			 DWT_SYS_CTRL_TRXOFF);

	dwt_reg_write_u32(dev, DWT_SYS_STATUS_ID, DWT_SYS_STATUS_OFFSET,
			  (DWT_SYS_STATUS_ALL_RX_GOOD |
			   DWT_SYS_STATUS_ALL_RX_TO |
			   DWT_SYS_STATUS_ALL_RX_ERR |
			   DWT_SYS_STATUS_ALL_TX));

	dwt_setup_int(dev, true);
}

/* timeout time in units of 1.026 microseconds */
static int dwt_enable_rx(const struct device *dev, uint16_t timeout)
{
	uint32_t sys_cfg;
	uint16_t sys_ctrl = DWT_SYS_CTRL_RXENAB;

	sys_cfg = dwt_reg_read_u32(dev, DWT_SYS_CFG_ID, 0);

	if (timeout != 0) {
		dwt_reg_write_u16(dev, DWT_RX_FWTO_ID, DWT_RX_FWTO_OFFSET,
				  timeout);
		sys_cfg |= DWT_SYS_CFG_RXWTOE;
	} else {
		sys_cfg &= ~DWT_SYS_CFG_RXWTOE;
	}

	dwt_reg_write_u32(dev, DWT_SYS_CFG_ID, 0, sys_cfg);
	dwt_reg_write_u16(dev, DWT_SYS_CTRL_ID, DWT_SYS_CTRL_OFFSET, sys_ctrl);

	return 0;
}

static inline void dwt_irq_handle_rx_cca(const struct device *dev)
{
	struct dwt_context *ctx = dev->data;

	k_sem_give(&ctx->phy_sem);
	ctx->cca_busy = true;

	/* Clear all RX event bits */
	dwt_reg_write_u32(dev, DWT_SYS_STATUS_ID, 0,
			  DWT_SYS_STATUS_ALL_RX_GOOD);
}

static inline void dwt_irq_handle_rx(const struct device *dev, uint32_t sys_stat)
{
	struct dwt_context *ctx = dev->data;
	struct net_pkt *pkt = NULL;
	struct dwt_rx_info_regs rx_inf_reg;
	float a_const;
	uint32_t rx_finfo;
	uint32_t ttcki;
	uint32_t rx_pacc;
	uint32_t cir_pwr;
	uint32_t flags_to_clear;
	int32_t ttcko;
	uint16_t pkt_len;
	uint8_t *fctrl;
	int8_t rx_level = INT8_MIN;

	LOG_DBG("RX OK event, SYS_STATUS 0x%08x", sys_stat);
	flags_to_clear = sys_stat & DWT_SYS_STATUS_ALL_RX_GOOD;

	rx_finfo = dwt_reg_read_u32(dev, DWT_RX_FINFO_ID, DWT_RX_FINFO_OFFSET);
	pkt_len = rx_finfo & DWT_RX_FINFO_RXFLEN_MASK;
	rx_pacc = (rx_finfo & DWT_RX_FINFO_RXPACC_MASK) >>
		   DWT_RX_FINFO_RXPACC_SHIFT;

	if (!(IS_ENABLED(CONFIG_IEEE802154_RAW_MODE))) {
		pkt_len -= DWT_FCS_LENGTH;
	}

	pkt = net_pkt_alloc_with_buffer(ctx->iface, pkt_len,
					AF_UNSPEC, 0, K_NO_WAIT);
	if (!pkt) {
		LOG_ERR("No buf available");
		goto rx_out_enable_rx;
	}

	dwt_register_read(dev, DWT_RX_BUFFER_ID, 0, pkt_len, pkt->buffer->data);
	dwt_register_read(dev, DWT_RX_FQUAL_ID, 0, sizeof(rx_inf_reg),
			  (uint8_t *)&rx_inf_reg);
	net_buf_add(pkt->buffer, pkt_len);
	fctrl = pkt->buffer->data;

	/*
	 * Get Ranging tracking offset and tracking interval
	 * for Crystal characterization
	 */
	ttcki = sys_get_le32(rx_inf_reg.rx_ttcki);
	ttcko = sys_get_le32(rx_inf_reg.rx_ttcko) & DWT_RX_TTCKO_RXTOFS_MASK;
	/* Tracking offset value is a 19-bit signed integer */
	if (ttcko & BIT(18)) {
		ttcko |= ~DWT_RX_TTCKO_RXTOFS_MASK;
	}

	/* TODO add:
	 * net_pkt_set_ieee802154_tcki(pkt, ttcki);
	 * net_pkt_set_ieee802154_tcko(pkt, ttcko);
	 */
	LOG_DBG("ttcko %d ttcki: 0x%08x", ttcko, ttcki);

	if (IS_ENABLED(CONFIG_NET_PKT_TIMESTAMP)) {
		uint8_t ts_buf[sizeof(uint64_t)] = {0};
		struct net_ptp_time timestamp;
		uint64_t ts_fsec;

		memcpy(ts_buf, rx_inf_reg.rx_time, DWT_RX_TIME_RX_STAMP_LEN);
		ts_fsec = sys_get_le64(ts_buf) * DWT_TS_TIME_UNITS_FS;
		timestamp.second = (ts_fsec / 1000000) / NSEC_PER_SEC;
		timestamp.nanosecond = (ts_fsec / 1000000) % NSEC_PER_SEC;
		net_pkt_set_timestamp(pkt, &timestamp);
	}

	/* See 4.7.2 Estimating the receive signal power */
	cir_pwr = sys_get_le16(&rx_inf_reg.rx_fqual[6]);
	if (ctx->rf_cfg.prf == DWT_PRF_16M) {
		a_const = DWT_RX_SIG_PWR_A_CONST_PRF16;
	} else {
		a_const = DWT_RX_SIG_PWR_A_CONST_PRF64;
	}

	if (rx_pacc != 0) {
#if defined(CONFIG_NEWLIB_LIBC)
		/* From 4.7.2 Estimating the receive signal power */
		rx_level = 10.0 * log10f(cir_pwr * BIT(17) /
					 (rx_pacc * rx_pacc)) - a_const;
#endif
	}

	net_pkt_set_ieee802154_rssi(pkt, rx_level);

	/*
	 * Workaround for AAT status bit issue,
	 * From 5.3.5 Host Notification in DW1000 User Manual:
	 * "Note: there is a situation that can result in the AAT bit being set
	 * for the current frame as a result of a previous frame that was
	 * received and rejected due to frame filtering."
	 */
	if ((sys_stat & DWT_SYS_STATUS_AAT) && ((fctrl[0] & 0x20) == 0)) {
		flags_to_clear |= DWT_SYS_STATUS_AAT;
	}

	if (ieee802154_radio_handle_ack(ctx->iface, pkt) == NET_OK) {
		LOG_INF("ACK packet handled");
		goto rx_out_unref_pkt;
	}

	/* LQI not implemented */
	LOG_DBG("Caught a packet (%u) (RSSI: %d)",
		pkt_len, (int8_t)net_pkt_ieee802154_rssi(pkt));
	LOG_HEXDUMP_DBG(pkt->buffer->data, pkt_len, "RX buffer:");

	if (net_recv_data(ctx->iface, pkt) == NET_OK) {
		goto rx_out_enable_rx;
	} else {
		LOG_DBG("Packet dropped by NET stack");
	}

rx_out_unref_pkt:
	if (pkt) {
		net_pkt_unref(pkt);
	}

rx_out_enable_rx:
	dwt_reg_write_u32(dev, DWT_SYS_STATUS_ID, 0, flags_to_clear);
	LOG_DBG("Cleared SYS_STATUS flags 0x%08x", flags_to_clear);
	if (atomic_test_bit(&ctx->state, DWT_STATE_RX_DEF_ON)) {
		/*
		 * Re-enable reception but in contrast to dwt_enable_rx()
		 * without to read SYS_STATUS and set delayed option.
		 */
		dwt_reg_write_u16(dev, DWT_SYS_CTRL_ID, DWT_SYS_CTRL_OFFSET,
				  DWT_SYS_CTRL_RXENAB);
	}
}

static void dwt_irq_handle_tx(const struct device *dev, uint32_t sys_stat)
{
	struct dwt_context *ctx = dev->data;

	/* Clear TX event bits */
	dwt_reg_write_u32(dev, DWT_SYS_STATUS_ID, 0,
			  DWT_SYS_STATUS_ALL_TX);

	LOG_DBG("TX confirmed event");
	k_sem_give(&ctx->phy_sem);
}

static void dwt_irq_handle_rxto(const struct device *dev, uint32_t sys_stat)
{
	struct dwt_context *ctx = dev->data;

	/* Clear RX timeout event bits */
	dwt_reg_write_u32(dev, DWT_SYS_STATUS_ID, 0,
			  DWT_SYS_STATUS_RXRFTO);

	dwt_disable_txrx(dev);
	/* Receiver reset necessary, see 4.1.6 RX Message timestamp */
	dwt_reset_rfrx(dev);

	LOG_DBG("RX timeout event");

	if (atomic_test_bit(&ctx->state, DWT_STATE_CCA)) {
		k_sem_give(&ctx->phy_sem);
		ctx->cca_busy = false;
	}
}

static void dwt_irq_handle_error(const struct device *dev, uint32_t sys_stat)
{
	struct dwt_context *ctx = dev->data;

	/* Clear RX error event bits */
	dwt_reg_write_u32(dev, DWT_SYS_STATUS_ID, 0, DWT_SYS_STATUS_ALL_RX_ERR);

	dwt_disable_txrx(dev);
	/* Receiver reset necessary, see 4.1.6 RX Message timestamp */
	dwt_reset_rfrx(dev);

	LOG_INF("RX error event");
	if (atomic_test_bit(&ctx->state, DWT_STATE_CCA)) {
		k_sem_give(&ctx->phy_sem);
		ctx->cca_busy = true;
		return;
	}

	if (atomic_test_bit(&ctx->state, DWT_STATE_RX_DEF_ON)) {
		dwt_enable_rx(dev, 0);
	}
}

static void dwt_irq_work_handler(struct k_work *item)
{
	struct dwt_context *ctx = CONTAINER_OF(item, struct dwt_context,
					       irq_cb_work);
	const struct device *dev = ctx->dev;
	uint32_t sys_stat;

	k_sem_take(&ctx->dev_lock, K_FOREVER);

	sys_stat = dwt_reg_read_u32(dev, DWT_SYS_STATUS_ID, 0);

	if (sys_stat & DWT_SYS_STATUS_RXFCG) {
		if (atomic_test_bit(&ctx->state, DWT_STATE_CCA)) {
			dwt_irq_handle_rx_cca(dev);
		} else {
			dwt_irq_handle_rx(dev, sys_stat);
		}
	}

	if (sys_stat & DWT_SYS_STATUS_TXFRS) {
		dwt_irq_handle_tx(dev, sys_stat);
	}

	if (sys_stat & DWT_SYS_STATUS_ALL_RX_TO) {
		dwt_irq_handle_rxto(dev, sys_stat);
	}

	if (sys_stat & DWT_SYS_STATUS_ALL_RX_ERR) {
		dwt_irq_handle_error(dev, sys_stat);
	}

	k_sem_give(&ctx->dev_lock);
}

static void dwt_gpio_callback(const struct device *dev,
			      struct gpio_callback *cb, uint32_t pins)
{
	struct dwt_context *ctx = CONTAINER_OF(cb, struct dwt_context, gpio_cb);

	LOG_DBG("IRQ callback triggered %p", ctx);
	k_work_submit_to_queue(&dwt_work_queue, &ctx->irq_cb_work);
}

static enum ieee802154_hw_caps dwt_get_capabilities(const struct device *dev)
{
	return IEEE802154_HW_FCS |
		IEEE802154_HW_2_4_GHZ | /* FIXME: add IEEE802154_HW_UWB_PHY */
		IEEE802154_HW_FILTER;
}

static uint32_t dwt_get_pkt_duration_ns(struct dwt_context *ctx, uint8_t psdu_len)
{
	struct dwt_phy_config *rf_cfg = &ctx->rf_cfg;
	float t_psdu = rf_cfg->t_dsym * psdu_len * 8;

	return (rf_cfg->t_shr + rf_cfg->t_phr + t_psdu);
}

static int dwt_cca(const struct device *dev)
{
	struct dwt_context *ctx = dev->data;
	uint32_t cca_dur = (dwt_get_pkt_duration_ns(ctx, 127) +
			 dwt_get_pkt_duration_ns(ctx, 5)) /
			 UWB_PHY_TDSYM_PHR_6M8;

	if (atomic_test_and_set_bit(&ctx->state, DWT_STATE_CCA)) {
		LOG_ERR("Transceiver busy");
		return -EBUSY;
	}

	/* Perform CCA Mode 5 */
	k_sem_take(&ctx->dev_lock, K_FOREVER);
	dwt_disable_txrx(dev);
	LOG_DBG("CCA duration %u us", cca_dur);

	dwt_enable_rx(dev, cca_dur);
	k_sem_give(&ctx->dev_lock);

	k_sem_take(&ctx->phy_sem, K_FOREVER);
	LOG_DBG("CCA finished %p", ctx);

	atomic_clear_bit(&ctx->state, DWT_STATE_CCA);
	if (atomic_test_bit(&ctx->state, DWT_STATE_RX_DEF_ON)) {
		k_sem_take(&ctx->dev_lock, K_FOREVER);
		dwt_enable_rx(dev, 0);
		k_sem_give(&ctx->dev_lock);
	}

	return ctx->cca_busy ? -EBUSY : 0;
}

static int dwt_ed(const struct device *dev, uint16_t duration,
		  energy_scan_done_cb_t done_cb)
{
	/* TODO: see description Sub-Register 0x23:02 – AGC_CTRL1 */

	return -ENOTSUP;
}

static int dwt_set_channel(const struct device *dev, uint16_t channel)
{
	struct dwt_context *ctx = dev->data;
	struct dwt_phy_config *rf_cfg = &ctx->rf_cfg;

	rf_cfg->channel = channel;
	LOG_INF("Set channel %u", channel);

	k_sem_take(&ctx->dev_lock, K_FOREVER);

	dwt_disable_txrx(dev);
	dwt_configure_rf_phy(dev);

	if (atomic_test_bit(&ctx->state, DWT_STATE_RX_DEF_ON)) {
		dwt_enable_rx(dev, 0);
	}

	k_sem_give(&ctx->dev_lock);

	return 0;
}

static int dwt_set_pan_id(const struct device *dev, uint16_t pan_id)
{
	struct dwt_context *ctx = dev->data;

	k_sem_take(&ctx->dev_lock, K_FOREVER);
	dwt_reg_write_u16(dev, DWT_PANADR_ID, DWT_PANADR_PAN_ID_OFFSET, pan_id);
	k_sem_give(&ctx->dev_lock);

	LOG_INF("Set PAN ID 0x%04x %p", pan_id, ctx);

	return 0;
}

static int dwt_set_short_addr(const struct device *dev, uint16_t short_addr)
{
	struct dwt_context *ctx = dev->data;

	k_sem_take(&ctx->dev_lock, K_FOREVER);
	dwt_reg_write_u16(dev, DWT_PANADR_ID, DWT_PANADR_SHORT_ADDR_OFFSET,
			  short_addr);
	k_sem_give(&ctx->dev_lock);

	LOG_INF("Set short 0x%x %p", short_addr, ctx);

	return 0;
}

static int dwt_set_ieee_addr(const struct device *dev,
			     const uint8_t *ieee_addr)
{
	struct dwt_context *ctx = dev->data;

	LOG_INF("IEEE address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
		ieee_addr[7], ieee_addr[6], ieee_addr[5], ieee_addr[4],
		ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]);

	k_sem_take(&ctx->dev_lock, K_FOREVER);
	dwt_register_write(dev, DWT_EUI_64_ID, DWT_EUI_64_OFFSET,
			   DWT_EUI_64_LEN, (uint8_t *)ieee_addr);
	k_sem_give(&ctx->dev_lock);

	return 0;
}

static int dwt_filter(const struct device *dev,
		      bool set,
		      enum ieee802154_filter_type type,
		      const struct ieee802154_filter *filter)
{
	if (!set) {
		return -ENOTSUP;
	}

	if (type == IEEE802154_FILTER_TYPE_IEEE_ADDR) {
		return dwt_set_ieee_addr(dev, filter->ieee_addr);
	} else if (type == IEEE802154_FILTER_TYPE_SHORT_ADDR) {
		return dwt_set_short_addr(dev, filter->short_addr);
	} else if (type == IEEE802154_FILTER_TYPE_PAN_ID) {
		return dwt_set_pan_id(dev, filter->pan_id);
	}

	return -ENOTSUP;
}

static int dwt_set_power(const struct device *dev, int16_t dbm)
{
	struct dwt_context *ctx = dev->data;

	LOG_INF("set_txpower not supported %p", ctx);

	return 0;
}

static int dwt_tx(const struct device *dev, enum ieee802154_tx_mode tx_mode,
		  struct net_pkt *pkt, struct net_buf *frag)
{
	struct dwt_context *ctx = dev->data;
	size_t len = frag->len;
	uint32_t tx_time = 0;
	struct net_ptp_time *txts;
	uint64_t tmp_fs;
	uint32_t tx_fctrl;
	uint8_t sys_ctrl = DWT_SYS_CTRL_TXSTRT;

	if (atomic_test_and_set_bit(&ctx->state, DWT_STATE_TX)) {
		LOG_ERR("Transceiver busy");
		return -EBUSY;
	}

	k_sem_reset(&ctx->phy_sem);
	k_sem_take(&ctx->dev_lock, K_FOREVER);

	switch (tx_mode) {
	case IEEE802154_TX_MODE_DIRECT:
		break;
	case IEEE802154_TX_MODE_TXTIME:
		/*
		 * tx_time is the high 32-bit of the 40-bit system
		 * time value at which to send the message.
		 */
		txts = net_pkt_timestamp(pkt);
		tmp_fs = txts->second * NSEC_PER_SEC + txts->nanosecond;
		tmp_fs *= 1000U * 1000U;

		tx_time = (tmp_fs / DWT_TS_TIME_UNITS_FS) >> 8;
		sys_ctrl |= DWT_SYS_CTRL_TXDLYS;
		/* DX_TIME is 40-bit register */
		dwt_reg_write_u32(dev, DWT_DX_TIME_ID, 1, tx_time);

		LOG_DBG("ntx hi32 %x", tx_time);
		LOG_DBG("sys hi32 %x",
			dwt_reg_read_u32(dev, DWT_SYS_TIME_ID, 1));
		break;
	default:
		LOG_ERR("TX mode %d not supported", tx_mode);
		goto error;
	}

	LOG_HEXDUMP_DBG(frag->data, len, "TX buffer:");

	/*
	 * See "3 Message Transmission" in DW1000 User Manual for
	 * more details about transmission configuration.
	 */
	if (dwt_register_write(dev, DWT_TX_BUFFER_ID, 0, len, frag->data)) {
		LOG_ERR("Failed to write TX data");
		goto error;
	}

	tx_fctrl = dwt_reg_read_u32(dev, DWT_TX_FCTRL_ID, 0);
	/* Clear TX buffer index offset, frame length, and length extension */
	tx_fctrl &= ~(DWT_TX_FCTRL_TFLEN_MASK | DWT_TX_FCTRL_TFLE_MASK |
		      DWT_TX_FCTRL_TXBOFFS_MASK);
	/* Set frame length and ranging flag */
	tx_fctrl |= (len + DWT_FCS_LENGTH) & DWT_TX_FCTRL_TFLEN_MASK;
	tx_fctrl |= DWT_TX_FCTRL_TR;
	/* Update Transmit Frame Control register */
	dwt_reg_write_u32(dev, DWT_TX_FCTRL_ID, 0, tx_fctrl);

	dwt_disable_txrx(dev);

	/* Begin transmission */
	dwt_reg_write_u8(dev, DWT_SYS_CTRL_ID, DWT_SYS_CTRL_OFFSET, sys_ctrl);

	if (sys_ctrl & DWT_SYS_CTRL_TXDLYS) {
		uint32_t sys_stat = dwt_reg_read_u32(dev, DWT_SYS_STATUS_ID, 0);

		if (sys_stat & DWT_SYS_STATUS_HPDWARN) {
			LOG_WRN("Half Period Delay Warning");
		}
	}

	k_sem_give(&ctx->dev_lock);
	/* Wait for the TX confirmed event */
	k_sem_take(&ctx->phy_sem, K_FOREVER);

	if (IS_ENABLED(CONFIG_NET_PKT_TIMESTAMP)) {
		uint8_t ts_buf[sizeof(uint64_t)] = {0};
		struct net_ptp_time timestamp;

		k_sem_take(&ctx->dev_lock, K_FOREVER);
		dwt_register_read(dev, DWT_TX_TIME_ID,
				  DWT_TX_TIME_TX_STAMP_OFFSET,
				  DWT_TX_TIME_TX_STAMP_LEN,
				  ts_buf);
		LOG_DBG("ts  hi32 %x", (uint32_t)(sys_get_le64(ts_buf) >> 8));
		LOG_DBG("sys hi32 %x",
			dwt_reg_read_u32(dev, DWT_SYS_TIME_ID, 1));
		k_sem_give(&ctx->dev_lock);

		tmp_fs = sys_get_le64(ts_buf) * DWT_TS_TIME_UNITS_FS;
		timestamp.second = (tmp_fs / 1000000) / NSEC_PER_SEC;
		timestamp.nanosecond = (tmp_fs / 1000000) % NSEC_PER_SEC;
		net_pkt_set_timestamp(pkt, &timestamp);
	}

	atomic_clear_bit(&ctx->state, DWT_STATE_TX);

	if (atomic_test_bit(&ctx->state, DWT_STATE_RX_DEF_ON)) {
		k_sem_take(&ctx->dev_lock, K_FOREVER);
		dwt_enable_rx(dev, 0);
		k_sem_give(&ctx->dev_lock);
	}

	return 0;

error:
	atomic_clear_bit(&ctx->state, DWT_STATE_TX);
	k_sem_give(&ctx->dev_lock);

	return -EIO;
}

static void dwt_set_frame_filter(const struct device *dev,
				 bool ff_enable, uint8_t ff_type)
{
	uint32_t sys_cfg_ff = ff_enable ? DWT_SYS_CFG_FFE : 0;

	sys_cfg_ff |= ff_type & DWT_SYS_CFG_FF_ALL_EN;

	dwt_reg_write_u8(dev, DWT_SYS_CFG_ID, 0, (uint8_t)sys_cfg_ff);
}

static int dwt_configure(const struct device *dev,
			 enum ieee802154_config_type type,
			 const struct ieee802154_config *config)
{
	struct dwt_context *ctx = dev->data;

	LOG_DBG("API configure %p", ctx);

	switch (type) {
	case IEEE802154_CONFIG_AUTO_ACK_FPB:
		LOG_DBG("IEEE802154_CONFIG_AUTO_ACK_FPB");
		break;

	case IEEE802154_CONFIG_ACK_FPB:
		LOG_DBG("IEEE802154_CONFIG_ACK_FPB");
		break;

	case IEEE802154_CONFIG_PAN_COORDINATOR:
		LOG_DBG("IEEE802154_CONFIG_PAN_COORDINATOR");
		break;

	case IEEE802154_CONFIG_PROMISCUOUS:
		LOG_DBG("IEEE802154_CONFIG_PROMISCUOUS");
		break;

	case IEEE802154_CONFIG_EVENT_HANDLER:
		LOG_DBG("IEEE802154_CONFIG_EVENT_HANDLER");
		break;

	default:
		return -EINVAL;
	}

	return -ENOTSUP;
}

/*
 * Note, the DW_RESET pin should not be driven high externally.
 */
static int dwt_hw_reset(const struct device *dev)
{
	const struct dwt_hi_cfg *hi_cfg = dev->config;

	if (gpio_pin_configure_dt(&hi_cfg->rst_gpio, GPIO_OUTPUT_ACTIVE)) {
		LOG_ERR("Failed to configure GPIO pin %u", hi_cfg->rst_gpio.pin);
		return -EINVAL;
	}

	k_sleep(K_MSEC(1));
	gpio_pin_set_dt(&hi_cfg->rst_gpio, 0);
	k_sleep(K_MSEC(5));

	if (gpio_pin_configure_dt(&hi_cfg->rst_gpio, GPIO_INPUT)) {
		LOG_ERR("Failed to configure GPIO pin %u", hi_cfg->rst_gpio.pin);
		return -EINVAL;
	}

	return 0;
}

/*
 * SPI speed in INIT state or for wake-up sequence,
 * see 2.3.2 Overview of main operational states
 */
static void dwt_set_spi_slow(const struct device *dev, const uint32_t freq)
{
	struct dwt_context *ctx = dev->data;

	ctx->spi_cfg_slow.frequency = freq;
	ctx->spi_cfg = &ctx->spi_cfg_slow;
}

/* SPI speed in IDLE, RX, and TX state */
static void dwt_set_spi_fast(const struct device *dev)
{
	const struct dwt_hi_cfg *hi_cfg = dev->config;
	struct dwt_context *ctx = dev->data;

	ctx->spi_cfg = &hi_cfg->bus.config;
}

static void dwt_set_rx_mode(const struct device *dev)
{
	struct dwt_context *ctx = dev->data;
	struct dwt_phy_config *rf_cfg = &ctx->rf_cfg;
	uint32_t pmsc_ctrl0;
	uint32_t t_on_us;
	uint8_t rx_sniff[2];

	/* SNIFF Mode ON time in units of PAC */
	rx_sniff[0] = CONFIG_IEEE802154_DW1000_SNIFF_ONT &
		      DWT_RX_SNIFF_SNIFF_ONT_MASK;
	/* SNIFF Mode OFF time in microseconds */
	rx_sniff[1] = CONFIG_IEEE802154_DW1000_SNIFF_OFFT;

	t_on_us = (rx_sniff[0] + 1) * (BIT(3) << rf_cfg->rx_pac_l);
	LOG_INF("RX duty cycle %u%%", t_on_us * 100 / (t_on_us + rx_sniff[1]));

	dwt_register_write(dev, DWT_RX_SNIFF_ID, DWT_RX_SNIFF_OFFSET,
			   sizeof(rx_sniff), rx_sniff);

	pmsc_ctrl0 = dwt_reg_read_u32(dev, DWT_PMSC_ID, DWT_PMSC_CTRL0_OFFSET);
	/* Enable PLL2 on/off sequencing for SNIFF mode */
	pmsc_ctrl0 |= DWT_PMSC_CTRL0_PLL2_SEQ_EN;
	dwt_reg_write_u32(dev, DWT_PMSC_ID, DWT_PMSC_CTRL0_OFFSET, pmsc_ctrl0);
}

static int dwt_start(const struct device *dev)
{
	struct dwt_context *ctx = dev->data;
	uint8_t cswakeup_buf[32] = {0};

	k_sem_take(&ctx->dev_lock, K_FOREVER);

	/* Set SPI clock to lowest frequency */
	dwt_set_spi_slow(dev, DWT_SPI_CSWAKEUP_FREQ);

	if (dwt_reg_read_u32(dev, DWT_DEV_ID_ID, 0) != DWT_DEVICE_ID) {
		/* Keep SPI CS line low for 500 microseconds */
		dwt_register_read(dev, 0, 0, sizeof(cswakeup_buf),
				  cswakeup_buf);
		/* Give device time to initialize */
		k_sleep(K_MSEC(5));

		if (dwt_reg_read_u32(dev, DWT_DEV_ID_ID, 0) != DWT_DEVICE_ID) {
			LOG_ERR("Failed to wake-up %p", dev);
			k_sem_give(&ctx->dev_lock);
			return -1;
		}
	} else {
		LOG_WRN("Device not in a sleep mode");
	}

	/* Restore SPI clock settings */
	dwt_set_spi_slow(dev, DWT_SPI_SLOW_FREQ);
	dwt_set_spi_fast(dev);

	dwt_setup_int(dev, true);
	dwt_disable_txrx(dev);
	dwt_reset_rfrx(dev);

	if (CONFIG_IEEE802154_DW1000_SNIFF_ONT != 0) {
		dwt_set_rx_mode(dev);
	}

	/* Re-enable RX after packet reception */
	atomic_set_bit(&ctx->state, DWT_STATE_RX_DEF_ON);
	dwt_enable_rx(dev, 0);
	k_sem_give(&ctx->dev_lock);

	LOG_INF("Started %p", dev);

	return 0;
}

static int dwt_stop(const struct device *dev)
{
	struct dwt_context *ctx = dev->data;

	k_sem_take(&ctx->dev_lock, K_FOREVER);
	dwt_disable_txrx(dev);
	dwt_reset_rfrx(dev);
	dwt_setup_int(dev, false);

	/* Copy the user configuration and enter sleep mode */
	dwt_reg_write_u8(dev, DWT_AON_ID, DWT_AON_CTRL_OFFSET,
			 DWT_AON_CTRL_SAVE);
	k_sem_give(&ctx->dev_lock);

	LOG_INF("Stopped %p", dev);

	return 0;
}

static inline void dwt_set_sysclks_xti(const struct device *dev, bool ldeload)
{
	uint16_t clks = BIT(9) | DWT_PMSC_CTRL0_SYSCLKS_19M;

	/*
	 * See Table 4: Register accesses required to load LDE microcode,
	 * set PMSC_CTRL0 0x0301, load LDE, set PMSC_CTRL0 0x0200.
	 */
	if (ldeload) {
		clks |= BIT(8);
	}

	/* Force system clock to be the 19.2 MHz XTI clock */
	dwt_reg_write_u16(dev, DWT_PMSC_ID, DWT_PMSC_CTRL0_OFFSET, clks);
}

static inline void dwt_set_sysclks_auto(const struct device *dev)
{
	uint8_t sclks = DWT_PMSC_CTRL0_SYSCLKS_AUTO |
		     DWT_PMSC_CTRL0_RXCLKS_AUTO |
		     DWT_PMSC_CTRL0_TXCLKS_AUTO;

	dwt_reg_write_u8(dev, DWT_PMSC_ID, DWT_PMSC_CTRL0_OFFSET, sclks);
}

static uint32_t dwt_otpmem_read(const struct device *dev, uint16_t otp_addr)
{
	dwt_reg_write_u16(dev, DWT_OTP_IF_ID, DWT_OTP_ADDR, otp_addr);

	dwt_reg_write_u8(dev, DWT_OTP_IF_ID, DWT_OTP_CTRL,
				DWT_OTP_CTRL_OTPREAD | DWT_OTP_CTRL_OTPRDEN);
	/* OTPREAD is self clearing but OTPRDEN is not */
	dwt_reg_write_u8(dev, DWT_OTP_IF_ID, DWT_OTP_CTRL, 0x00);

	/* Read read data, available 40ns after rising edge of OTP_READ */
	return dwt_reg_read_u32(dev, DWT_OTP_IF_ID, DWT_OTP_RDAT);
}

static int dwt_initialise_dev(const struct device *dev)
{
	struct dwt_context *ctx = dev->data;
	uint32_t otp_val = 0;
	uint8_t xtal_trim;

	dwt_set_sysclks_xti(dev, false);
	ctx->sleep_mode = 0;

	/* Disable PMSC control of analog RF subsystem */
	dwt_reg_write_u16(dev, DWT_PMSC_ID, DWT_PMSC_CTRL1_OFFSET,
			  DWT_PMSC_CTRL1_PKTSEQ_DISABLE);

	/* Clear all status flags */
	dwt_reg_write_u32(dev, DWT_SYS_STATUS_ID, 0, DWT_SYS_STATUS_MASK_32);

	/*
	 * Apply soft reset,
	 * see SOFTRESET field description in DW1000 User Manual.
	 */
	dwt_reg_write_u8(dev, DWT_PMSC_ID, DWT_PMSC_CTRL0_SOFTRESET_OFFSET,
			 DWT_PMSC_CTRL0_RESET_ALL);
	k_sleep(K_MSEC(1));
	dwt_reg_write_u8(dev, DWT_PMSC_ID, DWT_PMSC_CTRL0_SOFTRESET_OFFSET,
			 DWT_PMSC_CTRL0_RESET_CLEAR);

	dwt_set_sysclks_xti(dev, false);

	/*
	 * This bit (a.k.a PLLLDT) should be set to ensure reliable
	 * operation of the CPLOCK bit.
	 */
	dwt_reg_write_u8(dev, DWT_EXT_SYNC_ID, DWT_EC_CTRL_OFFSET,
			 DWT_EC_CTRL_PLLLCK);

	/* Kick LDO if there is a value programmed. */
	otp_val = dwt_otpmem_read(dev, DWT_OTP_LDOTUNE_ADDR);
	if ((otp_val & 0xFF) != 0) {
		dwt_reg_write_u8(dev, DWT_OTP_IF_ID, DWT_OTP_SF,
				 DWT_OTP_SF_LDO_KICK);
		ctx->sleep_mode |= DWT_AON_WCFG_ONW_LLDO;
		LOG_INF("Load LDOTUNE_CAL parameter");
	}

	otp_val = dwt_otpmem_read(dev, DWT_OTP_XTRIM_ADDR);
	xtal_trim = otp_val & DWT_FS_XTALT_MASK;
	LOG_INF("OTP Revision 0x%02x, XTAL Trim 0x%02x",
		(uint8_t)(otp_val >> 8), xtal_trim);

	LOG_DBG("CHIP ID 0x%08x", dwt_otpmem_read(dev, DWT_OTP_PARTID_ADDR));
	LOG_DBG("LOT ID 0x%08x", dwt_otpmem_read(dev, DWT_OTP_LOTID_ADDR));
	LOG_DBG("Vbat 0x%02x", dwt_otpmem_read(dev, DWT_OTP_VBAT_ADDR));
	LOG_DBG("Vtemp 0x%02x", dwt_otpmem_read(dev, DWT_OTP_VTEMP_ADDR));

	if (xtal_trim == 0) {
		/* Set to default */
		xtal_trim = DWT_FS_XTALT_MIDRANGE;
	}

	/* For FS_XTALT bits 7:5 must always be set to binary “011” */
	xtal_trim |= BIT(6) | BIT(5);
	dwt_reg_write_u8(dev, DWT_FS_CTRL_ID, DWT_FS_XTALT_OFFSET, xtal_trim);

	/* Load LDE microcode into RAM, see 2.5.5.10 LDELOAD */
	dwt_set_sysclks_xti(dev, true);
	dwt_reg_write_u16(dev, DWT_OTP_IF_ID, DWT_OTP_CTRL,
			  DWT_OTP_CTRL_LDELOAD);
	k_sleep(K_MSEC(1));
	dwt_set_sysclks_xti(dev, false);
	ctx->sleep_mode |= DWT_AON_WCFG_ONW_LLDE;

	dwt_set_sysclks_auto(dev);

	if (!(dwt_reg_read_u8(dev, DWT_SYS_STATUS_ID, 0) &
	     DWT_SYS_STATUS_CPLOCK)) {
		LOG_WRN("PLL has not locked");
		return -EIO;
	}

	dwt_set_spi_fast(dev);

	/* Setup antenna delay values */
	dwt_reg_write_u16(dev, DWT_LDE_IF_ID, DWT_LDE_RXANTD_OFFSET,
			  DW1000_RX_ANT_DLY);
	dwt_reg_write_u16(dev, DWT_TX_ANTD_ID, DWT_TX_ANTD_OFFSET,
			  DW1000_TX_ANT_DLY);

	/* Clear AON_CFG1 register */
	dwt_reg_write_u8(dev, DWT_AON_ID, DWT_AON_CFG1_OFFSET, 0);
	/*
	 * Configure sleep mode:
	 *  - On wake-up load configurations from the AON memory
	 *  - preserve sleep mode configuration
	 *  - On Wake-up load the LDE microcode
	 *  - When available, on wake-up load the LDO tune value
	 */
	ctx->sleep_mode |= DWT_AON_WCFG_ONW_LDC |
			   DWT_AON_WCFG_PRES_SLEEP;
	dwt_reg_write_u16(dev, DWT_AON_ID, DWT_AON_WCFG_OFFSET,
			  ctx->sleep_mode);
	LOG_DBG("sleep mode 0x%04x", ctx->sleep_mode);
	/* Enable sleep and wake using SPI CSn */
	dwt_reg_write_u8(dev, DWT_AON_ID, DWT_AON_CFG0_OFFSET,
			 DWT_AON_CFG0_WAKE_SPI | DWT_AON_CFG0_SLEEP_EN);

	return 0;
}

/*
 * RF PHY configuration. Must be carried out as part of initialization and
 * for every channel change. See also 2.5 Default Configuration on Power Up.
 */
static int dwt_configure_rf_phy(const struct device *dev)
{
	struct dwt_context *ctx = dev->data;
	struct dwt_phy_config *rf_cfg = &ctx->rf_cfg;
	uint8_t chan = rf_cfg->channel;
	uint8_t prf_idx = rf_cfg->prf;
	uint32_t chan_ctrl = 0;
	uint8_t rxctrlh;
	uint8_t pll_tune;
	uint8_t tune4h;
	uint8_t pgdelay;
	uint16_t lde_repc;
	uint16_t agc_tune1;
	uint16_t sfdto;
	uint16_t tune1a;
	uint16_t tune0b;
	uint16_t tune1b;
	uint32_t txctrl;
	uint32_t pll_cfg;
	uint32_t tune2;
	uint32_t sys_cfg;
	uint32_t tx_fctrl;
	uint32_t power;

	if ((chan < 1) || (chan > 7) || (chan == 6)) {
		LOG_ERR("Channel not supported %u", chan);
		return -ENOTSUP;
	}

	if (rf_cfg->rx_shr_code >= ARRAY_SIZE(dwt_lde_repc_defs)) {
		LOG_ERR("Preamble code not supported %u",
			rf_cfg->rx_shr_code);
		return -ENOTSUP;
	}

	if (prf_idx >= DWT_NUMOF_PRFS) {
		LOG_ERR("PRF not supported %u", prf_idx);
		return -ENOTSUP;
	}

	if (rf_cfg->rx_pac_l >= DWT_NUMOF_PACS) {
		LOG_ERR("RX PAC not supported %u", rf_cfg->rx_pac_l);
		return -ENOTSUP;
	}

	if (rf_cfg->rx_ns_sfd > 1) {
		LOG_ERR("Wrong NS SFD configuration");
		return -ENOTSUP;
	}

	if (rf_cfg->tx_shr_nsync >= DWT_NUM_OF_PLEN) {
		LOG_ERR("Wrong SHR configuration");
		return -ENOTSUP;
	}

	lde_repc = dwt_lde_repc_defs[rf_cfg->rx_shr_code];
	agc_tune1 = dwt_agc_tune1_defs[prf_idx];
	sfdto = rf_cfg->rx_sfd_to;
	rxctrlh = dwt_rxctrlh_defs[dwt_ch_to_cfg[chan]];
	txctrl = dwt_txctrl_defs[dwt_ch_to_cfg[chan]];
	pll_tune = dwt_plltune_defs[dwt_ch_to_cfg[chan]];
	pll_cfg = dwt_pllcfg_defs[dwt_ch_to_cfg[chan]];
	tune2 = dwt_tune2_defs[prf_idx][rf_cfg->rx_pac_l];
	tune1a = dwt_tune1a_defs[prf_idx];
	tune0b = dwt_tune0b_defs[rf_cfg->dr][rf_cfg->rx_ns_sfd];
	pgdelay = dwt_pgdelay_defs[dwt_ch_to_cfg[chan]];

	sys_cfg = dwt_reg_read_u32(dev, DWT_SYS_CFG_ID, 0);
	tx_fctrl = dwt_reg_read_u32(dev, DWT_TX_FCTRL_ID, 0);

	/* Don't allow 0 - SFD timeout will always be enabled */
	if (sfdto == 0) {
		sfdto = DWT_SFDTOC_DEF;
	}

	/* Set IEEE 802.15.4 compliant mode */
	sys_cfg &= ~DWT_SYS_CFG_PHR_MODE_11;

	if (rf_cfg->dr == DWT_BR_110K) {
		/* Set Receiver Mode 110 kbps data rate */
		sys_cfg |= DWT_SYS_CFG_RXM110K;
		lde_repc = lde_repc >> 3;
		tune1b = DWT_DRX_TUNE1b_110K;
		tune4h = DWT_DRX_TUNE4H_PRE64;
	} else {
		sys_cfg &= ~DWT_SYS_CFG_RXM110K;
		if (rf_cfg->tx_shr_nsync == DWT_PLEN_64) {
			tune1b = DWT_DRX_TUNE1b_6M8_PRE64;
			tune4h = DWT_DRX_TUNE4H_PRE64;
		} else {
			tune1b = DWT_DRX_TUNE1b_850K_6M8;
			tune4h = DWT_DRX_TUNE4H_PRE128PLUS;
		}
	}

	if (sys_cfg & DWT_SYS_CFG_DIS_STXP) {
		if (rf_cfg->prf == DWT_PRF_64M) {
			power = dwt_txpwr_stxp1_64[dwt_ch_to_cfg[chan]];
		} else {
			power = dwt_txpwr_stxp1_16[dwt_ch_to_cfg[chan]];
		}
	} else {
		if (rf_cfg->prf == DWT_PRF_64M) {
			power = dwt_txpwr_stxp0_64[dwt_ch_to_cfg[chan]];
		} else {
			power = dwt_txpwr_stxp0_16[dwt_ch_to_cfg[chan]];
		}
	}

	dwt_reg_write_u32(dev, DWT_SYS_CFG_ID, 0, sys_cfg);
	LOG_DBG("SYS_CFG: 0x%08x", sys_cfg);

	dwt_reg_write_u16(dev, DWT_LDE_IF_ID, DWT_LDE_REPC_OFFSET, lde_repc);
	LOG_DBG("LDE_REPC: 0x%04x", lde_repc);

	dwt_reg_write_u8(dev, DWT_LDE_IF_ID, DWT_LDE_CFG1_OFFSET,
			 DWT_DEFAULT_LDE_CFG1);

	if (rf_cfg->prf == DWT_PRF_64M) {
		dwt_reg_write_u16(dev, DWT_LDE_IF_ID, DWT_LDE_CFG2_OFFSET,
				  DWT_DEFAULT_LDE_CFG2_PRF64);
		LOG_DBG("LDE_CFG2: 0x%04x", DWT_DEFAULT_LDE_CFG2_PRF64);
	} else {
		dwt_reg_write_u16(dev, DWT_LDE_IF_ID, DWT_LDE_CFG2_OFFSET,
				  DWT_DEFAULT_LDE_CFG2_PRF16);
		LOG_DBG("LDE_CFG2: 0x%04x", DWT_DEFAULT_LDE_CFG2_PRF16);
	}

	/* Configure PLL2/RF PLL block CFG/TUNE (for a given channel) */
	dwt_reg_write_u32(dev, DWT_FS_CTRL_ID, DWT_FS_PLLCFG_OFFSET, pll_cfg);
	LOG_DBG("PLLCFG: 0x%08x", pll_cfg);
	dwt_reg_write_u8(dev, DWT_FS_CTRL_ID, DWT_FS_PLLTUNE_OFFSET, pll_tune);
	LOG_DBG("PLLTUNE: 0x%02x", pll_tune);
	/* Configure RF RX blocks (for specified channel/bandwidth) */
	dwt_reg_write_u8(dev, DWT_RF_CONF_ID, DWT_RF_RXCTRLH_OFFSET, rxctrlh);
	LOG_DBG("RXCTRLH: 0x%02x", rxctrlh);
	/* Configure RF/TX blocks for specified channel and PRF */
	dwt_reg_write_u32(dev, DWT_RF_CONF_ID, DWT_RF_TXCTRL_OFFSET, txctrl);
	LOG_DBG("TXCTRL: 0x%08x", txctrl);

	/* Digital receiver configuration, DRX_CONF */
	dwt_reg_write_u16(dev, DWT_DRX_CONF_ID, DWT_DRX_TUNE0b_OFFSET, tune0b);
	LOG_DBG("DRX_TUNE0b: 0x%04x", tune0b);
	dwt_reg_write_u16(dev, DWT_DRX_CONF_ID, DWT_DRX_TUNE1a_OFFSET, tune1a);
	LOG_DBG("DRX_TUNE1a: 0x%04x", tune1a);
	dwt_reg_write_u16(dev, DWT_DRX_CONF_ID, DWT_DRX_TUNE1b_OFFSET, tune1b);
	LOG_DBG("DRX_TUNE1b: 0x%04x", tune1b);
	dwt_reg_write_u32(dev, DWT_DRX_CONF_ID, DWT_DRX_TUNE2_OFFSET, tune2);
	LOG_DBG("DRX_TUNE2: 0x%08x", tune2);
	dwt_reg_write_u8(dev, DWT_DRX_CONF_ID, DWT_DRX_TUNE4H_OFFSET, tune4h);
	LOG_DBG("DRX_TUNE4H: 0x%02x", tune4h);
	dwt_reg_write_u16(dev, DWT_DRX_CONF_ID, DWT_DRX_SFDTOC_OFFSET, sfdto);
	LOG_DBG("DRX_SFDTOC: 0x%04x", sfdto);

	/* Automatic Gain Control configuration and control, AGC_CTRL */
	dwt_reg_write_u16(dev, DWT_AGC_CTRL_ID, DWT_AGC_TUNE1_OFFSET,
			  agc_tune1);
	LOG_DBG("AGC_TUNE1: 0x%04x", agc_tune1);
	dwt_reg_write_u32(dev, DWT_AGC_CTRL_ID, DWT_AGC_TUNE2_OFFSET,
			  DWT_AGC_TUNE2_VAL);

	if (rf_cfg->rx_ns_sfd) {
		/*
		 * SFD_LENGTH, length of the SFD sequence used when
		 * the data rate is 850 kbps or 6.8 Mbps,
		 * must be set to either 8 or 16.
		 */
		dwt_reg_write_u8(dev, DWT_USR_SFD_ID, 0x00,
				 dwt_ns_sfdlen[rf_cfg->dr]);
		LOG_DBG("USR_SFDLEN: 0x%02x", dwt_ns_sfdlen[rf_cfg->dr]);
		chan_ctrl |= DWT_CHAN_CTRL_DWSFD;
	}

	/* Set RX_CHAN and TX CHAN */
	chan_ctrl |= (chan & DWT_CHAN_CTRL_TX_CHAN_MASK) |
		     ((chan << DWT_CHAN_CTRL_RX_CHAN_SHIFT) &
		      DWT_CHAN_CTRL_RX_CHAN_MASK);

	/* Set RXPRF */
	chan_ctrl |= (BIT(rf_cfg->prf) << DWT_CHAN_CTRL_RXFPRF_SHIFT) &
		     DWT_CHAN_CTRL_RXFPRF_MASK;

	/* Set TX_PCOD */
	chan_ctrl |= (rf_cfg->tx_shr_code << DWT_CHAN_CTRL_TX_PCOD_SHIFT) &
		     DWT_CHAN_CTRL_TX_PCOD_MASK;

	/* Set RX_PCOD */
	chan_ctrl |= (rf_cfg->rx_shr_code << DWT_CHAN_CTRL_RX_PCOD_SHIFT) &
		     DWT_CHAN_CTRL_RX_PCOD_MASK;

	/* Set Channel Control */
	dwt_reg_write_u32(dev, DWT_CHAN_CTRL_ID, 0, chan_ctrl);
	LOG_DBG("CHAN_CTRL 0x%08x", chan_ctrl);

	/* Set up TX Preamble Size, PRF and Data Rate */
	tx_fctrl = dwt_plen_cfg[rf_cfg->tx_shr_nsync] |
		   (BIT(rf_cfg->prf) << DWT_TX_FCTRL_TXPRF_SHFT) |
		   (rf_cfg->dr << DWT_TX_FCTRL_TXBR_SHFT);

	dwt_reg_write_u32(dev, DWT_TX_FCTRL_ID, 0, tx_fctrl);
	LOG_DBG("TX_FCTRL 0x%08x", tx_fctrl);

	/* Set the Pulse Generator Delay */
	dwt_reg_write_u8(dev, DWT_TX_CAL_ID, DWT_TC_PGDELAY_OFFSET, pgdelay);
	LOG_DBG("PGDELAY 0x%02x", pgdelay);
	/* Set Transmit Power Control */
	dwt_reg_write_u32(dev, DWT_TX_POWER_ID, 0, power);
	LOG_DBG("TX_POWER 0x%08x", power);

	/*
	 * From 5.3.1.2 SFD Initialisation,
	 * SFD sequence initialisation for Auto ACK frame.
	 */
	dwt_reg_write_u8(dev, DWT_SYS_CTRL_ID, DWT_SYS_CTRL_OFFSET,
			 DWT_SYS_CTRL_TXSTRT | DWT_SYS_CTRL_TRXOFF);

	/*
	 * Calculate PHY timing parameters
	 *
	 * From (9.4) Std 802.15.4-2011
	 * Tshr = Tpsym * (NSYNC + NSFD )
	 * Tphr = NPHR * Tdsym1m
	 * Tpsdu = Tdsym * NPSDU * NSYMPEROCTET / Rfec
	 *
	 * PRF: pulse repetition frequency
	 * PSR: preamble symbol repetitions
	 * SFD: start of frame delimiter
	 * SHR: synchronisation header (SYNC + SFD)
	 * PHR: PHY header
	 */
	uint16_t nsync = BIT(rf_cfg->tx_shr_nsync + 6);

	if (rf_cfg->prf == DWT_PRF_64M) {
		rf_cfg->t_shr = UWB_PHY_TPSYM_PRF64 *
				(nsync + UWB_PHY_NUMOF_SYM_SHR_SFD);
	} else {
		rf_cfg->t_shr = UWB_PHY_TPSYM_PRF16 *
				(nsync + UWB_PHY_NUMOF_SYM_SHR_SFD);
	}

	if (rf_cfg->dr == DWT_BR_6M8) {
		rf_cfg->t_phr = UWB_PHY_NUMOF_SYM_PHR * UWB_PHY_TDSYM_PHR_6M8;
		rf_cfg->t_dsym = UWB_PHY_TDSYM_DATA_6M8 / 0.44;
	} else if (rf_cfg->dr == DWT_BR_850K) {
		rf_cfg->t_phr = UWB_PHY_NUMOF_SYM_PHR * UWB_PHY_TDSYM_PHR_850K;
		rf_cfg->t_dsym = UWB_PHY_TDSYM_DATA_850K / 0.44;
	} else {
		rf_cfg->t_phr = UWB_PHY_NUMOF_SYM_PHR * UWB_PHY_TDSYM_PHR_110K;
		rf_cfg->t_dsym = UWB_PHY_TDSYM_DATA_110K / 0.44;
	}

	return 0;
}

static int dw1000_init(const struct device *dev)
{
	struct dwt_context *ctx = dev->data;
	const struct dwt_hi_cfg *hi_cfg = dev->config;

	LOG_INF("Initialize DW1000 Transceiver");
	k_sem_init(&ctx->phy_sem, 0, 1);

	/* slow SPI config */
	memcpy(&ctx->spi_cfg_slow, &hi_cfg->bus.config, sizeof(ctx->spi_cfg_slow));
	ctx->spi_cfg_slow.frequency = DWT_SPI_SLOW_FREQ;

	if (!spi_is_ready(&hi_cfg->bus)) {
		LOG_ERR("SPI device not ready");
		return -ENODEV;
	}

	dwt_set_spi_slow(dev, DWT_SPI_SLOW_FREQ);

	/* Initialize IRQ GPIO */
	if (!device_is_ready(hi_cfg->irq_gpio.port)) {
		LOG_ERR("IRQ GPIO device not ready");
		return -ENODEV;
	}

	if (gpio_pin_configure_dt(&hi_cfg->irq_gpio, GPIO_INPUT)) {
		LOG_ERR("Unable to configure GPIO pin %u", hi_cfg->irq_gpio.pin);
		return -EINVAL;
	}

	gpio_init_callback(&(ctx->gpio_cb), dwt_gpio_callback,
			   BIT(hi_cfg->irq_gpio.pin));

	if (gpio_add_callback(hi_cfg->irq_gpio.port, &(ctx->gpio_cb))) {
		LOG_ERR("Failed to add IRQ callback");
		return -EINVAL;
	}

	/* Initialize RESET GPIO */
	if (!device_is_ready(hi_cfg->rst_gpio.port)) {
		LOG_ERR("Reset GPIO device not ready");
		return -ENODEV;
	}

	if (gpio_pin_configure_dt(&hi_cfg->rst_gpio, GPIO_INPUT)) {
		LOG_ERR("Unable to configure GPIO pin %u", hi_cfg->rst_gpio.pin);
		return -EINVAL;
	}

	LOG_INF("GPIO and SPI configured");

	dwt_hw_reset(dev);

	if (dwt_reg_read_u32(dev, DWT_DEV_ID_ID, 0) != DWT_DEVICE_ID) {
		LOG_ERR("Failed to read device ID %p", dev);
		return -ENODEV;
	}

	if (dwt_initialise_dev(dev)) {
		LOG_ERR("Failed to initialize DW1000");
		return -EIO;
	}

	if (dwt_configure_rf_phy(dev)) {
		LOG_ERR("Failed to configure RF PHY");
		return -EIO;
	}

	/* Allow Beacon, Data, Acknowledgement, MAC command */
	dwt_set_frame_filter(dev, true, DWT_SYS_CFG_FFAB | DWT_SYS_CFG_FFAD |
			     DWT_SYS_CFG_FFAA | DWT_SYS_CFG_FFAM);

	/*
	 * Enable system events:
	 *  - transmit frame sent,
	 *  - receiver FCS good,
	 *  - receiver PHY header error,
	 *  - receiver FCS error,
	 *  - receiver Reed Solomon Frame Sync Loss,
	 *  - receive Frame Wait Timeout,
	 *  - preamble detection timeout,
	 *  - receive SFD timeout
	 */
	dwt_reg_write_u32(dev, DWT_SYS_MASK_ID, 0,
			  DWT_SYS_MASK_MTXFRS |
			  DWT_SYS_MASK_MRXFCG |
			  DWT_SYS_MASK_MRXPHE |
			  DWT_SYS_MASK_MRXFCE |
			  DWT_SYS_MASK_MRXRFSL |
			  DWT_SYS_MASK_MRXRFTO |
			  DWT_SYS_MASK_MRXPTO |
			  DWT_SYS_MASK_MRXSFDTO);

	/* Initialize IRQ event work queue */
	ctx->dev = dev;

	k_work_queue_start(&dwt_work_queue, dwt_work_queue_stack,
			   K_KERNEL_STACK_SIZEOF(dwt_work_queue_stack),
			   CONFIG_SYSTEM_WORKQUEUE_PRIORITY, NULL);

	k_work_init(&ctx->irq_cb_work, dwt_irq_work_handler);

	dwt_setup_int(dev, true);

	LOG_INF("DW1000 device initialized and configured");

	return 0;
}

static inline uint8_t *get_mac(const struct device *dev)
{
	struct dwt_context *dw1000 = dev->data;
	uint32_t *ptr = (uint32_t *)(dw1000->mac_addr);

	UNALIGNED_PUT(sys_rand32_get(), ptr);
	ptr = (uint32_t *)(dw1000->mac_addr + 4);
	UNALIGNED_PUT(sys_rand32_get(), ptr);

	dw1000->mac_addr[0] = (dw1000->mac_addr[0] & ~0x01) | 0x02;

	return dw1000->mac_addr;
}

static void dwt_iface_api_init(struct net_if *iface)
{
	const struct device *dev = net_if_get_device(iface);
	struct dwt_context *dw1000 = dev->data;
	uint8_t *mac = get_mac(dev);

	net_if_set_link_addr(iface, mac, 8, NET_LINK_IEEE802154);

	dw1000->iface = iface;

	ieee802154_init(iface);

	LOG_INF("Iface initialized");
}

static struct ieee802154_radio_api dwt_radio_api = {
	.iface_api.init		= dwt_iface_api_init,

	.get_capabilities	= dwt_get_capabilities,
	.cca			= dwt_cca,
	.set_channel		= dwt_set_channel,
	.filter			= dwt_filter,
	.set_txpower		= dwt_set_power,
	.start			= dwt_start,
	.stop			= dwt_stop,
	.configure		= dwt_configure,
	.ed_scan		= dwt_ed,
	.tx			= dwt_tx,
};

#define DWT_PSDU_LENGTH		(127 - DWT_FCS_LENGTH)

#if defined(CONFIG_IEEE802154_RAW_MODE)
DEVICE_DT_INST_DEFINE(0, dw1000_init, NULL,
		    &dwt_0_context, &dw1000_0_config,
		    POST_KERNEL, CONFIG_IEEE802154_DW1000_INIT_PRIO,
		    &dwt_radio_api);
#else
NET_DEVICE_DT_INST_DEFINE(0,
		dw1000_init,
		NULL,
		&dwt_0_context,
		&dw1000_0_config,
		CONFIG_IEEE802154_DW1000_INIT_PRIO,
		&dwt_radio_api,
		IEEE802154_L2,
		NET_L2_GET_CTX_TYPE(IEEE802154_L2),
		DWT_PSDU_LENGTH);
#endif
