Skip to content

Commit

Permalink
drivers/kw2xrf: add IEEE 802.15.4 Radio HAL support
Browse files Browse the repository at this point in the history
Co-authored-by: Michel Rottleuthner <[email protected]>
  • Loading branch information
jia200x and MichelRottleuthner committed Aug 15, 2022
1 parent 4ace2ed commit 4ebcd7c
Show file tree
Hide file tree
Showing 14 changed files with 794 additions and 874 deletions.
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
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

0 comments on commit 4ebcd7c

Please sign in to comment.