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

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

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

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

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

#include <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
