From fe851d30de487a167c6ad6ee47d123808acb5565 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 31 Jan 2022 23:02:24 +0100 Subject: [PATCH] drivers: ieee802154: dw1000: use spi_dt_spec Simplify driver implementation by using spi_dt_spec. Note that driver has 2 SPI configurations, identical except the speed. For this reason, the slow config is still kept in RAM and copied from the one obtained via the SPI dt_spec macros. A better solution would be to have macros that allow to override the SPI frequency, but this can be improved later. Most internal helpers have been adjusted to accept a device reference to make SPI (and future GPIO) transition easier. Signed-off-by: Gerard Marull-Paretas --- drivers/ieee802154/ieee802154_dw1000.c | 433 ++++++++++++------------- 1 file changed, 212 insertions(+), 221 deletions(-) diff --git a/drivers/ieee802154/ieee802154_dw1000.c b/drivers/ieee802154/ieee802154_dw1000.c index 94205be1486..e95e27e6ba8 100644 --- a/drivers/ieee802154/ieee802154_dw1000.c +++ b/drivers/ieee802154/ieee802154_dw1000.c @@ -90,18 +90,13 @@ struct dwt_phy_config { }; struct dwt_hi_cfg { + struct spi_dt_spec bus; const char *irq_port; uint8_t irq_pin; gpio_dt_flags_t irq_flags; const char *rst_port; uint8_t rst_pin; gpio_dt_flags_t rst_flags; - const char *spi_port; - uint8_t spi_cs_pin; - gpio_dt_flags_t spi_cs_flags; - const char *spi_cs_port; - uint32_t spi_freq; - uint8_t spi_slave; }; #define DWT_STATE_TX 0 @@ -109,14 +104,12 @@ struct dwt_hi_cfg { #define DWT_STATE_RX_DEF_ON 2 struct dwt_context { + const struct device *dev; struct net_if *iface; const struct device *irq_gpio; const struct device *rst_gpio; - const struct device *spi; - struct spi_cs_control spi_cs; - struct spi_config *spi_cfg; + const struct spi_config *spi_cfg; struct spi_config spi_cfg_slow; - struct spi_config spi_cfg_fast; struct gpio_callback gpio_cb; struct k_sem dev_lock; struct k_sem phy_sem; @@ -130,20 +123,13 @@ struct dwt_context { }; static const struct dwt_hi_cfg dw1000_0_config = { + .bus = SPI_DT_SPEC_INST_GET(0, SPI_WORD_SET(8), 0), .irq_port = DT_INST_GPIO_LABEL(0, int_gpios), .irq_pin = DT_INST_GPIO_PIN(0, int_gpios), .irq_flags = DT_INST_GPIO_FLAGS(0, int_gpios), .rst_port = DT_INST_GPIO_LABEL(0, reset_gpios), .rst_pin = DT_INST_GPIO_PIN(0, reset_gpios), .rst_flags = DT_INST_GPIO_FLAGS(0, reset_gpios), - .spi_port = DT_INST_BUS_LABEL(0), - .spi_freq = DT_INST_PROP(0, spi_max_frequency), - .spi_slave = DT_INST_REG_ADDR(0), -#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0) - .spi_cs_port = DT_INST_SPI_DEV_CS_GPIOS_LABEL(0), - .spi_cs_pin = DT_INST_SPI_DEV_CS_GPIOS_PIN(0), - .spi_cs_flags = DT_INST_SPI_DEV_CS_GPIOS_FLAGS(0), -#endif }; static struct dwt_context dwt_0_context = { @@ -173,12 +159,14 @@ struct dwt_rx_info_regs { uint8_t rx_time[DWT_RX_TIME_FP_RAWST_OFFSET]; } _packed; -static int dwt_configure_rf_phy(struct dwt_context *ctx); +static int dwt_configure_rf_phy(const struct device *dev); -static int dwt_spi_read(struct dwt_context *ctx, +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 @@ -206,7 +194,7 @@ static int dwt_spi_read(struct dwt_context *ctx, (uint16_t)hdr_len, (uint32_t)data_len); LOG_HEXDUMP_DBG(hdr_buf, (uint16_t)hdr_len, "rd: header"); - if (spi_transceive(ctx->spi, ctx->spi_cfg, &tx, &rx)) { + if (spi_transceive(hi_cfg->bus.bus, ctx->spi_cfg, &tx, &rx)) { LOG_ERR("SPI transfer failed"); return -EIO; } @@ -217,10 +205,12 @@ static int dwt_spi_read(struct dwt_context *ctx, } -static int dwt_spi_write(struct dwt_context *ctx, +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} @@ -232,7 +222,7 @@ static int dwt_spi_write(struct dwt_context *ctx, LOG_HEXDUMP_DBG(hdr_buf, (uint16_t)hdr_len, "wr: header"); LOG_HEXDUMP_DBG(data, (uint32_t)data_len, "wr: data"); - if (spi_write(ctx->spi, ctx->spi_cfg, &buf_set)) { + if (spi_write(hi_cfg->bus.bus, ctx->spi_cfg, &buf_set)) { LOG_ERR("SPI read failed"); return -EIO; } @@ -241,7 +231,7 @@ static int dwt_spi_write(struct dwt_context *ctx, } /* See 2.2.1.2 Transaction formats of the SPI interface */ -static int dwt_spi_transfer(struct dwt_context *ctx, +static int dwt_spi_transfer(const struct device *dev, uint8_t reg, uint16_t offset, size_t buf_len, uint8_t *buf, bool write) { @@ -266,82 +256,83 @@ static int dwt_spi_transfer(struct dwt_context *ctx, if (write) { hdr[0] |= DWT_SPI_TRANS_WRITE_OP; - return dwt_spi_write(ctx, hdr_len, hdr, buf_len, buf); + return dwt_spi_write(dev, hdr_len, hdr, buf_len, buf); } else { - return dwt_spi_read(ctx, hdr_len, hdr, buf_len, buf); + return dwt_spi_read(dev, hdr_len, hdr, buf_len, buf); } } -static int dwt_register_read(struct dwt_context *ctx, +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(ctx, reg, offset, buf_len, buf, false); + return dwt_spi_transfer(dev, reg, offset, buf_len, buf, false); } -static int dwt_register_write(struct dwt_context *ctx, +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(ctx, reg, offset, buf_len, buf, true); + return dwt_spi_transfer(dev, reg, offset, buf_len, buf, true); } -static inline uint32_t dwt_reg_read_u32(struct dwt_context *ctx, +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(ctx, reg, offset, sizeof(buf), buf, false); + dwt_spi_transfer(dev, reg, offset, sizeof(buf), buf, false); return sys_get_le32(buf); } -static inline uint16_t dwt_reg_read_u16(struct dwt_context *ctx, +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(ctx, reg, offset, sizeof(buf), buf, false); + dwt_spi_transfer(dev, reg, offset, sizeof(buf), buf, false); return sys_get_le16(buf); } -static inline uint8_t dwt_reg_read_u8(struct dwt_context *ctx, +static inline uint8_t dwt_reg_read_u8(const struct device *dev, uint8_t reg, uint16_t offset) { uint8_t buf; - dwt_spi_transfer(ctx, reg, offset, sizeof(buf), &buf, false); + dwt_spi_transfer(dev, reg, offset, sizeof(buf), &buf, false); return buf; } -static inline void dwt_reg_write_u32(struct dwt_context *ctx, +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(ctx, reg, offset, sizeof(buf), buf, true); + dwt_spi_transfer(dev, reg, offset, sizeof(buf), buf, true); } -static inline void dwt_reg_write_u16(struct dwt_context *ctx, +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(ctx, reg, offset, sizeof(buf), buf, true); + dwt_spi_transfer(dev, reg, offset, sizeof(buf), buf, true); } -static inline void dwt_reg_write_u8(struct dwt_context *ctx, +static inline void dwt_reg_write_u8(const struct device *dev, uint8_t reg, uint16_t offset, uint8_t val) { - dwt_spi_transfer(ctx, reg, offset, sizeof(uint8_t), &val, true); + dwt_spi_transfer(dev, reg, offset, sizeof(uint8_t), &val, true); } -static ALWAYS_INLINE void dwt_setup_int(struct dwt_context *ctx, +static ALWAYS_INLINE void dwt_setup_int(const struct device *dev, bool enable) { - const struct dwt_hi_cfg *hi_cfg = &dw1000_0_config; + struct dwt_context *ctx = dev->data; + const struct dwt_hi_cfg *hi_cfg = dev->config; unsigned int flags = enable ? GPIO_INT_EDGE_TO_ACTIVE @@ -352,68 +343,71 @@ static ALWAYS_INLINE void dwt_setup_int(struct dwt_context *ctx, flags); } -static void dwt_reset_rfrx(struct dwt_context *ctx) +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(ctx, DWT_PMSC_ID, DWT_PMSC_CTRL0_SOFTRESET_OFFSET, + dwt_reg_write_u8(dev, DWT_PMSC_ID, DWT_PMSC_CTRL0_SOFTRESET_OFFSET, DWT_PMSC_CTRL0_RESET_RX); - dwt_reg_write_u8(ctx, DWT_PMSC_ID, DWT_PMSC_CTRL0_SOFTRESET_OFFSET, + dwt_reg_write_u8(dev, DWT_PMSC_ID, DWT_PMSC_CTRL0_SOFTRESET_OFFSET, DWT_PMSC_CTRL0_RESET_CLEAR); } -static void dwt_disable_txrx(struct dwt_context *ctx) +static void dwt_disable_txrx(const struct device *dev) { - dwt_setup_int(ctx, false); + dwt_setup_int(dev, false); - dwt_reg_write_u8(ctx, DWT_SYS_CTRL_ID, DWT_SYS_CTRL_OFFSET, + dwt_reg_write_u8(dev, DWT_SYS_CTRL_ID, DWT_SYS_CTRL_OFFSET, DWT_SYS_CTRL_TRXOFF); - dwt_reg_write_u32(ctx, DWT_SYS_STATUS_ID, DWT_SYS_STATUS_OFFSET, + 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(ctx, true); + dwt_setup_int(dev, true); } /* timeout time in units of 1.026 microseconds */ -static int dwt_enable_rx(struct dwt_context *ctx, uint16_t timeout) +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(ctx, DWT_SYS_CFG_ID, 0); + sys_cfg = dwt_reg_read_u32(dev, DWT_SYS_CFG_ID, 0); if (timeout != 0) { - dwt_reg_write_u16(ctx, DWT_RX_FWTO_ID, DWT_RX_FWTO_OFFSET, + 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(ctx, DWT_SYS_CFG_ID, 0, sys_cfg); - dwt_reg_write_u16(ctx, DWT_SYS_CTRL_ID, DWT_SYS_CTRL_OFFSET, sys_ctrl); + 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(struct dwt_context *ctx) +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(ctx, DWT_SYS_STATUS_ID, 0, + dwt_reg_write_u32(dev, DWT_SYS_STATUS_ID, 0, DWT_SYS_STATUS_ALL_RX_GOOD); } -static inline void dwt_irq_handle_rx(struct dwt_context *ctx, uint32_t sys_stat) +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; @@ -430,7 +424,7 @@ static inline void dwt_irq_handle_rx(struct dwt_context *ctx, uint32_t sys_stat) 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(ctx, DWT_RX_FINFO_ID, DWT_RX_FINFO_OFFSET); + 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; @@ -446,8 +440,8 @@ static inline void dwt_irq_handle_rx(struct dwt_context *ctx, uint32_t sys_stat) goto rx_out_enable_rx; } - dwt_register_read(ctx, DWT_RX_BUFFER_ID, 0, pkt_len, pkt->buffer->data); - dwt_register_read(ctx, DWT_RX_FQUAL_ID, 0, sizeof(rx_inf_reg), + 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; @@ -532,37 +526,41 @@ rx_out_unref_pkt: } rx_out_enable_rx: - dwt_reg_write_u32(ctx, DWT_SYS_STATUS_ID, 0, flags_to_clear); + 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(ctx, DWT_SYS_CTRL_ID, DWT_SYS_CTRL_OFFSET, + dwt_reg_write_u16(dev, DWT_SYS_CTRL_ID, DWT_SYS_CTRL_OFFSET, DWT_SYS_CTRL_RXENAB); } } -static void dwt_irq_handle_tx(struct dwt_context *ctx, uint32_t sys_stat) +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(ctx, DWT_SYS_STATUS_ID, 0, + 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(struct dwt_context *ctx, uint32_t sys_stat) +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(ctx, DWT_SYS_STATUS_ID, 0, + dwt_reg_write_u32(dev, DWT_SYS_STATUS_ID, 0, DWT_SYS_STATUS_RXRFTO); - dwt_disable_txrx(ctx); + dwt_disable_txrx(dev); /* Receiver reset necessary, see 4.1.6 RX Message timestamp */ - dwt_reset_rfrx(ctx); + dwt_reset_rfrx(dev); LOG_DBG("RX timeout event"); @@ -572,14 +570,16 @@ static void dwt_irq_handle_rxto(struct dwt_context *ctx, uint32_t sys_stat) } } -static void dwt_irq_handle_error(struct dwt_context *ctx, uint32_t sys_stat) +static void dwt_irq_handle_error(const struct device *dev, uint32_t sys_stat) { - /* Clear RX error event bits */ - dwt_reg_write_u32(ctx, DWT_SYS_STATUS_ID, 0, DWT_SYS_STATUS_ALL_RX_ERR); + struct dwt_context *ctx = dev->data; - dwt_disable_txrx(ctx); + /* 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(ctx); + dwt_reset_rfrx(dev); LOG_INF("RX error event"); if (atomic_test_bit(&ctx->state, DWT_STATE_CCA)) { @@ -589,7 +589,7 @@ static void dwt_irq_handle_error(struct dwt_context *ctx, uint32_t sys_stat) } if (atomic_test_bit(&ctx->state, DWT_STATE_RX_DEF_ON)) { - dwt_enable_rx(ctx, 0); + dwt_enable_rx(dev, 0); } } @@ -597,30 +597,31 @@ 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(ctx, DWT_SYS_STATUS_ID, 0); + 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(ctx); + dwt_irq_handle_rx_cca(dev); } else { - dwt_irq_handle_rx(ctx, sys_stat); + dwt_irq_handle_rx(dev, sys_stat); } } if (sys_stat & DWT_SYS_STATUS_TXFRS) { - dwt_irq_handle_tx(ctx, sys_stat); + dwt_irq_handle_tx(dev, sys_stat); } if (sys_stat & DWT_SYS_STATUS_ALL_RX_TO) { - dwt_irq_handle_rxto(ctx, sys_stat); + dwt_irq_handle_rxto(dev, sys_stat); } if (sys_stat & DWT_SYS_STATUS_ALL_RX_ERR) { - dwt_irq_handle_error(ctx, sys_stat); + dwt_irq_handle_error(dev, sys_stat); } k_sem_give(&ctx->dev_lock); @@ -664,10 +665,10 @@ static int dwt_cca(const struct device *dev) /* Perform CCA Mode 5 */ k_sem_take(&ctx->dev_lock, K_FOREVER); - dwt_disable_txrx(ctx); + dwt_disable_txrx(dev); LOG_DBG("CCA duration %u us", cca_dur); - dwt_enable_rx(ctx, cca_dur); + dwt_enable_rx(dev, cca_dur); k_sem_give(&ctx->dev_lock); k_sem_take(&ctx->phy_sem, K_FOREVER); @@ -676,7 +677,7 @@ static int dwt_cca(const struct device *dev) 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(ctx, 0); + dwt_enable_rx(dev, 0); k_sem_give(&ctx->dev_lock); } @@ -701,11 +702,11 @@ static int dwt_set_channel(const struct device *dev, uint16_t channel) k_sem_take(&ctx->dev_lock, K_FOREVER); - dwt_disable_txrx(ctx); - dwt_configure_rf_phy(ctx); + dwt_disable_txrx(dev); + dwt_configure_rf_phy(dev); if (atomic_test_bit(&ctx->state, DWT_STATE_RX_DEF_ON)) { - dwt_enable_rx(ctx, 0); + dwt_enable_rx(dev, 0); } k_sem_give(&ctx->dev_lock); @@ -718,7 +719,7 @@ 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(ctx, DWT_PANADR_ID, DWT_PANADR_PAN_ID_OFFSET, pan_id); + 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); @@ -731,7 +732,7 @@ 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(ctx, DWT_PANADR_ID, DWT_PANADR_SHORT_ADDR_OFFSET, + dwt_reg_write_u16(dev, DWT_PANADR_ID, DWT_PANADR_SHORT_ADDR_OFFSET, short_addr); k_sem_give(&ctx->dev_lock); @@ -750,7 +751,7 @@ static int dwt_set_ieee_addr(const struct device *dev, ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]); k_sem_take(&ctx->dev_lock, K_FOREVER); - dwt_register_write(ctx, DWT_EUI_64_ID, DWT_EUI_64_OFFSET, + 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); @@ -820,11 +821,11 @@ static int dwt_tx(const struct device *dev, enum ieee802154_tx_mode tx_mode, 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(ctx, DWT_DX_TIME_ID, 1, tx_time); + 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(ctx, DWT_SYS_TIME_ID, 1)); + dwt_reg_read_u32(dev, DWT_SYS_TIME_ID, 1)); break; default: LOG_ERR("TX mode %d not supported", tx_mode); @@ -837,12 +838,12 @@ static int dwt_tx(const struct device *dev, enum ieee802154_tx_mode tx_mode, * See "3 Message Transmission" in DW1000 User Manual for * more details about transmission configuration. */ - if (dwt_register_write(ctx, DWT_TX_BUFFER_ID, 0, len, frag->data)) { + 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(ctx, DWT_TX_FCTRL_ID, 0); + 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); @@ -850,15 +851,15 @@ static int dwt_tx(const struct device *dev, enum ieee802154_tx_mode tx_mode, 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(ctx, DWT_TX_FCTRL_ID, 0, tx_fctrl); + dwt_reg_write_u32(dev, DWT_TX_FCTRL_ID, 0, tx_fctrl); - dwt_disable_txrx(ctx); + dwt_disable_txrx(dev); /* Begin transmission */ - dwt_reg_write_u8(ctx, DWT_SYS_CTRL_ID, DWT_SYS_CTRL_OFFSET, sys_ctrl); + 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(ctx, DWT_SYS_STATUS_ID, 0); + 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"); @@ -874,13 +875,13 @@ static int dwt_tx(const struct device *dev, enum ieee802154_tx_mode tx_mode, struct net_ptp_time timestamp; k_sem_take(&ctx->dev_lock, K_FOREVER); - dwt_register_read(ctx, DWT_TX_TIME_ID, + 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(ctx, DWT_SYS_TIME_ID, 1)); + 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; @@ -893,7 +894,7 @@ static int dwt_tx(const struct device *dev, enum ieee802154_tx_mode tx_mode, if (atomic_test_bit(&ctx->state, DWT_STATE_RX_DEF_ON)) { k_sem_take(&ctx->dev_lock, K_FOREVER); - dwt_enable_rx(ctx, 0); + dwt_enable_rx(dev, 0); k_sem_give(&ctx->dev_lock); } @@ -906,14 +907,14 @@ error: return -EIO; } -static void dwt_set_frame_filter(struct dwt_context *ctx, +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(ctx, DWT_SYS_CFG_ID, 0, (uint8_t)sys_cfg_ff); + dwt_reg_write_u8(dev, DWT_SYS_CFG_ID, 0, (uint8_t)sys_cfg_ff); } static int dwt_configure(const struct device *dev, @@ -983,20 +984,26 @@ static int dwt_hw_reset(const struct device *dev) * 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(struct dwt_context *ctx, const uint32_t freq) +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(struct dwt_context *ctx) +static void dwt_set_spi_fast(const struct device *dev) { - ctx->spi_cfg = &ctx->spi_cfg_fast; + 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(struct dwt_context *ctx) +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; @@ -1011,13 +1018,13 @@ static void dwt_set_rx_mode(struct dwt_context *ctx) 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(ctx, DWT_RX_SNIFF_ID, DWT_RX_SNIFF_OFFSET, + dwt_register_write(dev, DWT_RX_SNIFF_ID, DWT_RX_SNIFF_OFFSET, sizeof(rx_sniff), rx_sniff); - pmsc_ctrl0 = dwt_reg_read_u32(ctx, DWT_PMSC_ID, DWT_PMSC_CTRL0_OFFSET); + 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(ctx, DWT_PMSC_ID, DWT_PMSC_CTRL0_OFFSET, pmsc_ctrl0); + dwt_reg_write_u32(dev, DWT_PMSC_ID, DWT_PMSC_CTRL0_OFFSET, pmsc_ctrl0); } static int dwt_start(const struct device *dev) @@ -1028,16 +1035,16 @@ static int dwt_start(const struct device *dev) k_sem_take(&ctx->dev_lock, K_FOREVER); /* Set SPI clock to lowest frequency */ - dwt_set_spi_slow(ctx, DWT_SPI_CSWAKEUP_FREQ); + dwt_set_spi_slow(dev, DWT_SPI_CSWAKEUP_FREQ); - if (dwt_reg_read_u32(ctx, DWT_DEV_ID_ID, 0) != DWT_DEVICE_ID) { + 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(ctx, 0, 0, sizeof(cswakeup_buf), + 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(ctx, DWT_DEV_ID_ID, 0) != DWT_DEVICE_ID) { + 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; @@ -1047,20 +1054,20 @@ static int dwt_start(const struct device *dev) } /* Restore SPI clock settings */ - dwt_set_spi_slow(ctx, DWT_SPI_SLOW_FREQ); - dwt_set_spi_fast(ctx); + dwt_set_spi_slow(dev, DWT_SPI_SLOW_FREQ); + dwt_set_spi_fast(dev); - dwt_setup_int(ctx, true); - dwt_disable_txrx(ctx); - dwt_reset_rfrx(ctx); + dwt_setup_int(dev, true); + dwt_disable_txrx(dev); + dwt_reset_rfrx(dev); if (CONFIG_IEEE802154_DW1000_SNIFF_ONT != 0) { - dwt_set_rx_mode(ctx); + dwt_set_rx_mode(dev); } /* Re-enable RX after packet reception */ atomic_set_bit(&ctx->state, DWT_STATE_RX_DEF_ON); - dwt_enable_rx(ctx, 0); + dwt_enable_rx(dev, 0); k_sem_give(&ctx->dev_lock); LOG_INF("Started %p", dev); @@ -1073,12 +1080,12 @@ 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(ctx); - dwt_reset_rfrx(ctx); - dwt_setup_int(ctx, false); + 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(ctx, DWT_AON_ID, DWT_AON_CTRL_OFFSET, + dwt_reg_write_u8(dev, DWT_AON_ID, DWT_AON_CTRL_OFFSET, DWT_AON_CTRL_SAVE); k_sem_give(&ctx->dev_lock); @@ -1087,7 +1094,7 @@ static int dwt_stop(const struct device *dev) return 0; } -static inline void dwt_set_sysclks_xti(struct dwt_context *ctx, bool ldeload) +static inline void dwt_set_sysclks_xti(const struct device *dev, bool ldeload) { uint16_t clks = BIT(9) | DWT_PMSC_CTRL0_SYSCLKS_19M; @@ -1100,83 +1107,84 @@ static inline void dwt_set_sysclks_xti(struct dwt_context *ctx, bool ldeload) } /* Force system clock to be the 19.2 MHz XTI clock */ - dwt_reg_write_u16(ctx, DWT_PMSC_ID, DWT_PMSC_CTRL0_OFFSET, clks); + dwt_reg_write_u16(dev, DWT_PMSC_ID, DWT_PMSC_CTRL0_OFFSET, clks); } -static inline void dwt_set_sysclks_auto(struct dwt_context *ctx) +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(ctx, DWT_PMSC_ID, DWT_PMSC_CTRL0_OFFSET, sclks); + dwt_reg_write_u8(dev, DWT_PMSC_ID, DWT_PMSC_CTRL0_OFFSET, sclks); } -static uint32_t dwt_otpmem_read(struct dwt_context *ctx, uint16_t otp_addr) +static uint32_t dwt_otpmem_read(const struct device *dev, uint16_t otp_addr) { - dwt_reg_write_u16(ctx, DWT_OTP_IF_ID, DWT_OTP_ADDR, otp_addr); + dwt_reg_write_u16(dev, DWT_OTP_IF_ID, DWT_OTP_ADDR, otp_addr); - dwt_reg_write_u8(ctx, DWT_OTP_IF_ID, DWT_OTP_CTRL, + 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(ctx, DWT_OTP_IF_ID, DWT_OTP_CTRL, 0x00); + 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(ctx, DWT_OTP_IF_ID, DWT_OTP_RDAT); + return dwt_reg_read_u32(dev, DWT_OTP_IF_ID, DWT_OTP_RDAT); } -static int dwt_initialise_dev(struct dwt_context *ctx) +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(ctx, false); + dwt_set_sysclks_xti(dev, false); ctx->sleep_mode = 0; /* Disable PMSC control of analog RF subsystem */ - dwt_reg_write_u16(ctx, DWT_PMSC_ID, DWT_PMSC_CTRL1_OFFSET, + 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(ctx, DWT_SYS_STATUS_ID, 0, DWT_SYS_STATUS_MASK_32); + 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(ctx, DWT_PMSC_ID, DWT_PMSC_CTRL0_SOFTRESET_OFFSET, + 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(ctx, DWT_PMSC_ID, DWT_PMSC_CTRL0_SOFTRESET_OFFSET, + dwt_reg_write_u8(dev, DWT_PMSC_ID, DWT_PMSC_CTRL0_SOFTRESET_OFFSET, DWT_PMSC_CTRL0_RESET_CLEAR); - dwt_set_sysclks_xti(ctx, false); + 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(ctx, DWT_EXT_SYNC_ID, DWT_EC_CTRL_OFFSET, + 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(ctx, DWT_OTP_LDOTUNE_ADDR); + otp_val = dwt_otpmem_read(dev, DWT_OTP_LDOTUNE_ADDR); if ((otp_val & 0xFF) != 0) { - dwt_reg_write_u8(ctx, DWT_OTP_IF_ID, DWT_OTP_SF, + 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(ctx, DWT_OTP_XTRIM_ADDR); + 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(ctx, DWT_OTP_PARTID_ADDR)); - LOG_DBG("LOT ID 0x%08x", dwt_otpmem_read(ctx, DWT_OTP_LOTID_ADDR)); - LOG_DBG("Vbat 0x%02x", dwt_otpmem_read(ctx, DWT_OTP_VBAT_ADDR)); - LOG_DBG("Vtemp 0x%02x", dwt_otpmem_read(ctx, DWT_OTP_VTEMP_ADDR)); + 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 */ @@ -1185,34 +1193,34 @@ static int dwt_initialise_dev(struct dwt_context *ctx) /* For FS_XTALT bits 7:5 must always be set to binary “011” */ xtal_trim |= BIT(6) | BIT(5); - dwt_reg_write_u8(ctx, DWT_FS_CTRL_ID, DWT_FS_XTALT_OFFSET, xtal_trim); + 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(ctx, true); - dwt_reg_write_u16(ctx, DWT_OTP_IF_ID, DWT_OTP_CTRL, + 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(ctx, false); + dwt_set_sysclks_xti(dev, false); ctx->sleep_mode |= DWT_AON_WCFG_ONW_LLDE; - dwt_set_sysclks_auto(ctx); + dwt_set_sysclks_auto(dev); - if (!(dwt_reg_read_u8(ctx, DWT_SYS_STATUS_ID, 0) & + 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(ctx); + dwt_set_spi_fast(dev); /* Setup antenna delay values */ - dwt_reg_write_u16(ctx, DWT_LDE_IF_ID, DWT_LDE_RXANTD_OFFSET, + dwt_reg_write_u16(dev, DWT_LDE_IF_ID, DWT_LDE_RXANTD_OFFSET, DW1000_RX_ANT_DLY); - dwt_reg_write_u16(ctx, DWT_TX_ANTD_ID, DWT_TX_ANTD_OFFSET, + 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(ctx, DWT_AON_ID, DWT_AON_CFG1_OFFSET, 0); + 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 @@ -1222,11 +1230,11 @@ static int dwt_initialise_dev(struct dwt_context *ctx) */ ctx->sleep_mode |= DWT_AON_WCFG_ONW_LDC | DWT_AON_WCFG_PRES_SLEEP; - dwt_reg_write_u16(ctx, DWT_AON_ID, DWT_AON_WCFG_OFFSET, + 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(ctx, DWT_AON_ID, DWT_AON_CFG0_OFFSET, + dwt_reg_write_u8(dev, DWT_AON_ID, DWT_AON_CFG0_OFFSET, DWT_AON_CFG0_WAKE_SPI | DWT_AON_CFG0_SLEEP_EN); return 0; @@ -1236,8 +1244,9 @@ static int dwt_initialise_dev(struct dwt_context *ctx) * 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(struct dwt_context *ctx) +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; @@ -1302,8 +1311,8 @@ static int dwt_configure_rf_phy(struct dwt_context *ctx) 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(ctx, DWT_SYS_CFG_ID, 0); - tx_fctrl = dwt_reg_read_u32(ctx, DWT_TX_FCTRL_ID, 0); + 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) { @@ -1344,56 +1353,56 @@ static int dwt_configure_rf_phy(struct dwt_context *ctx) } } - dwt_reg_write_u32(ctx, DWT_SYS_CFG_ID, 0, sys_cfg); + dwt_reg_write_u32(dev, DWT_SYS_CFG_ID, 0, sys_cfg); LOG_DBG("SYS_CFG: 0x%08x", sys_cfg); - dwt_reg_write_u16(ctx, DWT_LDE_IF_ID, DWT_LDE_REPC_OFFSET, lde_repc); + 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(ctx, DWT_LDE_IF_ID, DWT_LDE_CFG1_OFFSET, + 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(ctx, DWT_LDE_IF_ID, DWT_LDE_CFG2_OFFSET, + 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(ctx, DWT_LDE_IF_ID, DWT_LDE_CFG2_OFFSET, + 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(ctx, DWT_FS_CTRL_ID, DWT_FS_PLLCFG_OFFSET, pll_cfg); + 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(ctx, DWT_FS_CTRL_ID, DWT_FS_PLLTUNE_OFFSET, pll_tune); + 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(ctx, DWT_RF_CONF_ID, DWT_RF_RXCTRLH_OFFSET, rxctrlh); + 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(ctx, DWT_RF_CONF_ID, DWT_RF_TXCTRL_OFFSET, txctrl); + 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(ctx, DWT_DRX_CONF_ID, DWT_DRX_TUNE0b_OFFSET, tune0b); + 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(ctx, DWT_DRX_CONF_ID, DWT_DRX_TUNE1a_OFFSET, tune1a); + 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(ctx, DWT_DRX_CONF_ID, DWT_DRX_TUNE1b_OFFSET, tune1b); + 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(ctx, DWT_DRX_CONF_ID, DWT_DRX_TUNE2_OFFSET, tune2); + 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(ctx, DWT_DRX_CONF_ID, DWT_DRX_TUNE4H_OFFSET, tune4h); + 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(ctx, DWT_DRX_CONF_ID, DWT_DRX_SFDTOC_OFFSET, sfdto); + 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(ctx, DWT_AGC_CTRL_ID, DWT_AGC_TUNE1_OFFSET, + 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(ctx, DWT_AGC_CTRL_ID, DWT_AGC_TUNE2_OFFSET, + dwt_reg_write_u32(dev, DWT_AGC_CTRL_ID, DWT_AGC_TUNE2_OFFSET, DWT_AGC_TUNE2_VAL); if (rf_cfg->rx_ns_sfd) { @@ -1402,7 +1411,7 @@ static int dwt_configure_rf_phy(struct dwt_context *ctx) * the data rate is 850 kbps or 6.8 Mbps, * must be set to either 8 or 16. */ - dwt_reg_write_u8(ctx, DWT_USR_SFD_ID, 0x00, + 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; @@ -1426,7 +1435,7 @@ static int dwt_configure_rf_phy(struct dwt_context *ctx) DWT_CHAN_CTRL_RX_PCOD_MASK; /* Set Channel Control */ - dwt_reg_write_u32(ctx, DWT_CHAN_CTRL_ID, 0, chan_ctrl); + 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 */ @@ -1434,21 +1443,21 @@ static int dwt_configure_rf_phy(struct dwt_context *ctx) (BIT(rf_cfg->prf) << DWT_TX_FCTRL_TXPRF_SHFT) | (rf_cfg->dr << DWT_TX_FCTRL_TXBR_SHFT); - dwt_reg_write_u32(ctx, DWT_TX_FCTRL_ID, 0, tx_fctrl); + 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(ctx, DWT_TX_CAL_ID, DWT_TC_PGDELAY_OFFSET, pgdelay); + 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(ctx, DWT_TX_POWER_ID, 0, power); + 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(ctx, DWT_SYS_CTRL_ID, DWT_SYS_CTRL_OFFSET, + dwt_reg_write_u8(dev, DWT_SYS_CTRL_ID, DWT_SYS_CTRL_OFFSET, DWT_SYS_CTRL_TXSTRT | DWT_SYS_CTRL_TRXOFF); /* @@ -1497,36 +1506,16 @@ static int dw1000_init(const struct device *dev) LOG_INF("Initialize DW1000 Transceiver"); k_sem_init(&ctx->phy_sem, 0, 1); - /* SPI config */ - ctx->spi_cfg_slow.operation = SPI_WORD_SET(8); + /* 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; - ctx->spi_cfg_slow.slave = hi_cfg->spi_slave; - ctx->spi_cfg_fast.operation = SPI_WORD_SET(8); - ctx->spi_cfg_fast.frequency = hi_cfg->spi_freq; - ctx->spi_cfg_fast.slave = hi_cfg->spi_slave; - - ctx->spi = device_get_binding((char *)hi_cfg->spi_port); - if (!ctx->spi) { - LOG_ERR("SPI master port %s not found", hi_cfg->spi_port); - return -EINVAL; + if (!spi_is_ready(&hi_cfg->bus)) { + LOG_ERR("SPI device not ready"); + return -ENODEV; } -#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0) - ctx->spi_cs.gpio_dev = - device_get_binding((char *)hi_cfg->spi_cs_port); - if (!ctx->spi_cs.gpio_dev) { - LOG_ERR("SPI CS port %s not found", hi_cfg->spi_cs_port); - return -EINVAL; - } - - ctx->spi_cs.gpio_pin = hi_cfg->spi_cs_pin; - ctx->spi_cs.gpio_dt_flags = hi_cfg->spi_cs_flags; - ctx->spi_cfg_slow.cs = &ctx->spi_cs; - ctx->spi_cfg_fast.cs = &ctx->spi_cs; -#endif - - dwt_set_spi_slow(ctx, DWT_SPI_SLOW_FREQ); + dwt_set_spi_slow(dev, DWT_SPI_SLOW_FREQ); /* Initialize IRQ GPIO */ ctx->irq_gpio = device_get_binding((char *)hi_cfg->irq_port); @@ -1566,23 +1555,23 @@ static int dw1000_init(const struct device *dev) dwt_hw_reset(dev); - if (dwt_reg_read_u32(ctx, DWT_DEV_ID_ID, 0) != DWT_DEVICE_ID) { + 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(ctx)) { + if (dwt_initialise_dev(dev)) { LOG_ERR("Failed to initialize DW1000"); return -EIO; } - if (dwt_configure_rf_phy(ctx)) { + 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(ctx, true, DWT_SYS_CFG_FFAB | DWT_SYS_CFG_FFAD | + dwt_set_frame_filter(dev, true, DWT_SYS_CFG_FFAB | DWT_SYS_CFG_FFAD | DWT_SYS_CFG_FFAA | DWT_SYS_CFG_FFAM); /* @@ -1596,7 +1585,7 @@ static int dw1000_init(const struct device *dev) * - preamble detection timeout, * - receive SFD timeout */ - dwt_reg_write_u32(ctx, DWT_SYS_MASK_ID, 0, + dwt_reg_write_u32(dev, DWT_SYS_MASK_ID, 0, DWT_SYS_MASK_MTXFRS | DWT_SYS_MASK_MRXFCG | DWT_SYS_MASK_MRXPHE | @@ -1607,13 +1596,15 @@ static int dw1000_init(const struct device *dev) 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(ctx, true); + dwt_setup_int(dev, true); LOG_INF("DW1000 device initialized and configured");