Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers/kw2xrf: add support for IEEE 802.15.4 Radio HAL #18383

Merged
merged 9 commits into from
Aug 16, 2022
1 change: 1 addition & 0 deletions boards/pba-d-01-kw2x/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ extern "C"
#define KW2XRF_PARAM_SPI_CLK (SPI_CLK_10MHZ)
#define KW2XRF_PARAM_CS GPIO_PIN(KW2XDRF_PORT, KW2XDRF_PCS0_PIN)
#define KW2XRF_PARAM_INT GPIO_PIN(KW2XDRF_PORT, KW2XDRF_IRQ_PIN)
#define KW2XRF_PARAM_RESET GPIO_PIN(KW2XDRF_IRQ_PIN, KW2XDRF_RST_PIN)
#define KW2XRF_SHARED_SPI (0)
/** @}*/

Expand Down
1 change: 1 addition & 0 deletions dist/tools/doccheck/exclude_patterns
Original file line number Diff line number Diff line change
Expand Up @@ -4325,6 +4325,7 @@ boards/pba\-d\-01\-kw2x/include/board\.h:[0-9]+: warning: Member KW2XRF_PARAM_CS
boards/pba\-d\-01\-kw2x/include/board\.h:[0-9]+: warning: Member KW2XRF_PARAM_INT \(macro definition\) of file board\.h is not documented\.
boards/pba\-d\-01\-kw2x/include/board\.h:[0-9]+: warning: Member KW2XRF_PARAM_SPI \(macro definition\) of file board\.h is not documented\.
boards/pba\-d\-01\-kw2x/include/board\.h:[0-9]+: warning: Member KW2XRF_PARAM_SPI_CLK \(macro definition\) of file board\.h is not documented\.
boards/pba\-d\-01\-kw2x/include/board\.h:[0-9]+: warning: Member KW2XRF_PARAM_RESET \(macro definition\) of file board\.h is not documented\.
boards/pba\-d\-01\-kw2x/include/board\.h:[0-9]+: warning: Member KW2XRF_SHARED_SPI \(macro definition\) of file board\.h is not documented\.
boards/pba\-d\-01\-kw2x/include/board\.h:[0-9]+: warning: Member LED0_MASK \(macro definition\) of file board\.h is not documented\.
boards/pba\-d\-01\-kw2x/include/board\.h:[0-9]+: warning: Member LED0_OFF \(macro definition\) of file board\.h is not documented\.
Expand Down
2 changes: 1 addition & 1 deletion drivers/at86rf215/at86rf215_o-qpsk.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ static void _set_legacy(at86rf215_t *dev, bool high_rate)

static inline void _set_ack_timeout_legacy(at86rf215_t *dev)
{
dev->ack_timeout_usec = AT86RF215_ACK_PERIOD_IN_SYMBOLS * LEGACY_QPSK_SYMBOL_TIME_US;
dev->ack_timeout_usec = IEEE802154_ACK_TIMEOUT_SYMS * LEGACY_QPSK_SYMBOL_TIME_US;
DEBUG("[%s] ACK timeout: %"PRIu32" µs\n", "legacy O-QPSK", dev->ack_timeout_usec);
}

Expand Down
6 changes: 0 additions & 6 deletions drivers/at86rf215/include/at86rf215_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,6 @@ extern "C" {
/** An ACK consists of 5 payload bytes */
#define AT86RF215_ACK_PSDU_BYTES (5)

/**
* This is used to calculate the ACK timeout based on the bitrate.
* AT86RF233 uses an ACK timeout of 54 symbol periods, or 864 µs @ 250 kbit/s
* -> 864µs * 250kbit/s = 216 bit */
#define AT86RF215_ACK_PERIOD_IN_SYMBOLS (54U)

#define AT86RF215_OQPSK_MODE_LEGACY (0x1) /**< legacy mode, 250 kbit/s */
#define AT86RF215_OQPSK_MODE_LEGACY_HDR (0x3) /**< legacy mode, high data rate */
#define AT86RF215_MR_OQPSK_MODE(n) ((n) << OQPSKPHRTX_MOD_SHIFT) /**< MR-QPSK */
Expand Down
27 changes: 23 additions & 4 deletions drivers/include/kw2xrf.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "net/netdev/ieee802154.h"
#include "net/gnrc/nettype.h"
#include "thread.h"
#include "net/ieee802154/radio.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -107,6 +108,7 @@ typedef struct kw2xrf_params {
spi_clk_t spi_clk; /**< SPI clock speed to use */
gpio_t cs_pin; /**< GPIO pin connected to chip select */
gpio_t int_pin; /**< GPIO pin connected to the interrupt pin */
gpio_t rst_pin; /**< GPIO pin connected to RST_B */
} kw2xrf_params_t;

/**
Expand All @@ -115,13 +117,12 @@ typedef struct kw2xrf_params {
* @extends netdev_ieee802154_t
*/
typedef struct {
netdev_ieee802154_t netdev; /**< netdev parent struct */
/**
* @brief device specific fields
* @{
*/
thread_t *thread; /**< Network driver thread, for providing feedback from IRQ handler */
kw2xrf_params_t params; /**< parameters for initialization */
const kw2xrf_params_t *params; /**< parameters for initialization */
uint8_t buf[KW2XRF_MAX_PKT_LENGTH]; /**< Buffer for incoming or outgoing packets */
uint8_t state; /**< current state of the radio */
uint8_t tx_frame_len; /**< length of the current TX frame */
Expand All @@ -130,6 +131,13 @@ typedef struct {
this is required to know when to
return to @ref kw2xrf_t::idle_state */
int16_t tx_power; /**< The current tx-power setting of the device */
bool ack_requested; /**< ACK was requested for last frame */
bool ch_clear; /**< CCA indicated channel clear */
bool waiting_for_cca; /**< Indicate whether CCA is still ongoing */
bool tx_done; /**< Indicate whether TX completed */
bool ack_rcvd; /**< Indicate if ACK was received for last transmission */
bool cca_before_tx; /**< true if CCA shall be performed before TX */
bool tx_cca_pending; /**< true a manual CCA was started and a TX should be triggered on channel clear indication */
/** @} */
} kw2xrf_t;

Expand All @@ -146,12 +154,16 @@ void kw2xrf_setup(kw2xrf_t *dev, const kw2xrf_params_t *params, uint8_t index);
/**
* @brief Initialize the given KW2XRF device
* @param[out] dev device descriptor
* @param[in] cb irq callback
* @param[in] params parameters for device initialization
* @param[in] hal pointer to IEEE 802.15.4 Radio HAL descriptor
* @param[in] cb isr callback
* @param[in] ctx context pointer handed to isr
*
* @return 0 on success
* @return <0 on error
*/
int kw2xrf_init(kw2xrf_t *dev, gpio_cb_t cb);
int kw2xrf_init(kw2xrf_t *dev, const kw2xrf_params_t *params, ieee802154_dev_t *hal,
gpio_cb_t cb, void *ctx);

/**
* @brief Configure radio with default values
Expand All @@ -160,6 +172,13 @@ int kw2xrf_init(kw2xrf_t *dev, gpio_cb_t cb);
*/
void kw2xrf_reset_phy(kw2xrf_t *dev);

/**
* @brief IRQ Handler for the KW2XRF device
*
* @param[in] dev pointer to the IEEE 802.15.4 Radio HAL descriptor
*/
void kw2xrf_radio_hal_irq_handler(void *dev);

#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 2 additions & 0 deletions drivers/kw2xrf/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ menuconfig MODULE_KW2XRF
select MODULE_NETDEV
select MODULE_NETDEV_IEEE802154
select MODULE_CORE_THREAD_FLAGS
select MODULE_IOLIST
select HAVE_BHP_IRQ_HANDLER

config MODULE_KW2XRF_TESTMODE
bool "Test mode"
Expand Down
6 changes: 5 additions & 1 deletion drivers/kw2xrf/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
SUBMODULES := 1

SRC := kw2xrf.c kw2xrf_getset.c kw2xrf_intern.c kw2xrf_netdev.c kw2xrf_spi.c
SRC := kw2xrf.c kw2xrf_getset.c kw2xrf_intern.c kw2xrf_radio_hal.c kw2xrf_spi.c

ifneq (,$(filter kw2xrf_testmode,$(USEMODULE)))
SRC += kw2xrf_tm.c
endif

include $(RIOTBASE)/Makefile.base
8 changes: 7 additions & 1 deletion drivers/kw2xrf/Makefile.dep
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
USEMODULE += luid
USEMODULE += ieee802154
USEMODULE += netdev_ieee802154
USEMODULE += core_thread_flags
USEMODULE += iolist
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will need to udpate the Kconfig dependencies as well

USEMODULE += bhp

ifneq (,$(filter netdev,$(USEMODULE)))
USEMODULE += netdev_ieee802154_submac
endif

FEATURES_REQUIRED += periph_spi
FEATURES_REQUIRED += periph_gpio
FEATURES_REQUIRED += periph_gpio_irq
2 changes: 2 additions & 0 deletions drivers/kw2xrf/Makefile.include
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
USEMODULE_INCLUDES_kw2xrf := $(LAST_MAKEFILEDIR)/include
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_kw2xrf)

PSEUDOMODULES += kw2xrf_testmode
1 change: 1 addition & 0 deletions drivers/kw2xrf/include/kw2xrf_getset.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#ifndef KW2XRF_GETSET_H
#define KW2XRF_GETSET_H

#include "kw2xrf_reg.h"
#include "kw2xrf.h"

#ifdef __cplusplus
Expand Down
3 changes: 2 additions & 1 deletion drivers/kw2xrf/include/kw2xrf_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ extern "C" {
#define KW2XRF_PARAMS { .spi = KW2XRF_PARAM_SPI, \
.spi_clk = KW2XRF_PARAM_SPI_CLK, \
.cs_pin = KW2XRF_PARAM_CS, \
.int_pin = KW2XRF_PARAM_INT }
.int_pin = KW2XRF_PARAM_INT, \
.rst_pin = KW2XRF_PARAM_RESET }
#endif
/**@}*/

Expand Down
48 changes: 4 additions & 44 deletions drivers/kw2xrf/kw2xrf.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,51 +54,8 @@ static void kw2xrf_set_address(kw2xrf_t *dev)
kw2xrf_set_addr_short(dev, ntohs(addr_long.uint16[0].u16));
}

void kw2xrf_setup(kw2xrf_t *dev, const kw2xrf_params_t *params, uint8_t index)
{
netdev_t *netdev = &dev->netdev.netdev;

netdev->driver = &kw2xrf_driver;
/* initialize device descriptor */
dev->params = *params;
dev->idle_state = XCVSEQ_RECEIVE;
dev->state = 0;
dev->pending_tx = 0;
kw2xrf_spi_init(dev);
kw2xrf_set_power_mode(dev, KW2XRF_IDLE);
DEBUG("[kw2xrf] enabling RX/TX completion and start events");
kw2xrf_clear_dreg_bit(dev, MKW2XDM_PHY_CTRL2, MKW2XDM_PHY_CTRL2_RX_WMRK_MSK);
kw2xrf_clear_dreg_bit(dev, MKW2XDM_PHY_CTRL2, MKW2XDM_PHY_CTRL2_RXMSK);
kw2xrf_clear_dreg_bit(dev, MKW2XDM_PHY_CTRL2, MKW2XDM_PHY_CTRL2_TXMSK);
DEBUG("[kw2xrf] setup finished\n");

/* register with netdev */
netdev_register(netdev, NETDEV_KW2XRF, index);
}

int kw2xrf_init(kw2xrf_t *dev, gpio_cb_t cb)
{
if (dev == NULL) {
return -ENODEV;
}

kw2xrf_set_out_clk(dev);
kw2xrf_disable_interrupts(dev);
/* set up GPIO-pin used for IRQ */
gpio_init_int(dev->params.int_pin, GPIO_IN, GPIO_FALLING, cb, dev);

kw2xrf_abort_sequence(dev);
kw2xrf_update_overwrites(dev);
kw2xrf_timer_init(dev, KW2XRF_TIMEBASE_62500HZ);
DEBUG("[kw2xrf] init finished\n");

return 0;
}

void kw2xrf_reset_phy(kw2xrf_t *dev)
{
netdev_ieee802154_reset(&dev->netdev);

dev->tx_power = KW2XRF_DEFAULT_TX_POWER;
kw2xrf_set_tx_power(dev, dev->tx_power);

Expand All @@ -110,7 +67,10 @@ void kw2xrf_reset_phy(kw2xrf_t *dev)

kw2xrf_set_rx_watermark(dev, 1);

kw2xrf_set_option(dev, KW2XRF_OPT_AUTOACK, true);
if (!IS_ACTIVE(CONFIG_IEEE802154_AUTO_ACK_DISABLE)) {
kw2xrf_set_option(dev, KW2XRF_OPT_AUTOACK, true);
}

kw2xrf_set_option(dev, KW2XRF_OPT_ACK_REQ, true);
kw2xrf_set_option(dev, KW2XRF_OPT_AUTOCCA, true);

Expand Down
12 changes: 0 additions & 12 deletions drivers/kw2xrf/kw2xrf_getset.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,6 @@ void kw2xrf_set_option(kw2xrf_t *dev, uint16_t option, bool state)

/* set option field */
if (state) {
dev->netdev.flags |= option;

/* trigger option specific actions */
switch (option) {
case KW2XRF_OPT_AUTOCCA:
Expand Down Expand Up @@ -404,7 +402,6 @@ void kw2xrf_set_option(kw2xrf_t *dev, uint16_t option, bool state)
}
}
else {
dev->netdev.flags &= ~(option);
/* trigger option specific actions */
switch (option) {
case KW2XRF_OPT_AUTOCCA:
Expand All @@ -416,15 +413,6 @@ void kw2xrf_set_option(kw2xrf_t *dev, uint16_t option, bool state)
/* disable promiscuous mode */
kw2xrf_clear_dreg_bit(dev, MKW2XDM_PHY_CTRL4,
MKW2XDM_PHY_CTRL4_PROMISCUOUS);
/* re-enable AUTOACK only if the option is set */
if (dev->netdev.flags & KW2XRF_OPT_AUTOACK) {
kw2xrf_set_dreg_bit(dev, MKW2XDM_PHY_CTRL1,
MKW2XDM_PHY_CTRL1_AUTOACK);
}
if (dev->netdev.flags & KW2XRF_OPT_ACK_REQ) {
kw2xrf_set_dreg_bit(dev, MKW2XDM_PHY_CTRL1,
MKW2XDM_PHY_CTRL1_RXACKRQD);
}
break;

case KW2XRF_OPT_AUTOACK:
Expand Down
Loading