From 69eb3c7fe2f6533c11f813e9e1f6e663db939445 Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Thu, 2 Apr 2020 16:48:21 +0200 Subject: [PATCH 1/3] at86rf2xx: add basic mode PHY state --- drivers/include/at86rf2xx.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/include/at86rf2xx.h b/drivers/include/at86rf2xx.h index 91bc88ce3f66..90661d140234 100644 --- a/drivers/include/at86rf2xx.h +++ b/drivers/include/at86rf2xx.h @@ -33,6 +33,7 @@ #include #include "board.h" +#include "kernel_defines.h" #include "net/netdev.h" #include "net/netdev/ieee802154.h" #include "net/gnrc/nettype.h" @@ -207,6 +208,30 @@ extern "C" { /** @} */ +#if IS_ACTIVE(AT86RF2XX_BASIC_MODE) || defined(DOXYGEN) +/** + * @brief Internal radio state equivalent to RX_ON + */ +#define AT86RF2XX_PHY_STATE_RX AT86RF2XX_STATE_RX_ON +/** + * @brief Internal radio state equivalent to RX_BUSY + */ +#define AT86RF2XX_PHY_STATE_RX_BUSY AT86RF2XX_STATE_BUSY_RX +/** + * @brief Internal radio state equivalent to TX_ON + */ +#define AT86RF2XX_PHY_STATE_TX AT86RF2XX_STATE_PLL_ON +/** + * @brief Internal radio state equivalent to TX_BUSY + */ +#define AT86RF2XX_PHY_STATE_TX_BUSY AT86RF2XX_STATE_BUSY_TX +#else +#define AT86RF2XX_PHY_STATE_RX AT86RF2XX_STATE_RX_AACK_ON +#define AT86RF2XX_PHY_STATE_RX_BUSY AT86RF2XX_STATE_BUSY_RX_AACK +#define AT86RF2XX_PHY_STATE_TX AT86RF2XX_STATE_TX_ARET_ON +#define AT86RF2XX_PHY_STATE_TX_BUSY AT86RF2XX_STATE_BUSY_TX_ARET +#endif /* IS_ACTIVE(AT86RF2XX_BASIC_MODE) */ + #if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2) /** * @brief memory mapped radio needs no parameters From d4b0aff8cf54570ae53ff87cf4c4db66d4e17a02 Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Thu, 2 Apr 2020 16:48:34 +0200 Subject: [PATCH 2/3] at86rf2xx: implement basic mode --- drivers/at86rf2xx/at86rf2xx.c | 21 ++-- drivers/at86rf2xx/at86rf2xx_getset.c | 2 + drivers/at86rf2xx/at86rf2xx_netdev.c | 146 ++++++++++++++++----------- 3 files changed, 103 insertions(+), 66 deletions(-) diff --git a/drivers/at86rf2xx/at86rf2xx.c b/drivers/at86rf2xx/at86rf2xx.c index 25dfc1d4d636..8ec4a9f12e71 100644 --- a/drivers/at86rf2xx/at86rf2xx.c +++ b/drivers/at86rf2xx/at86rf2xx.c @@ -112,12 +112,15 @@ void at86rf2xx_reset(at86rf2xx_t *dev) /* set default TX power */ at86rf2xx_set_txpower(dev, AT86RF2XX_DEFAULT_TXPOWER); /* set default options */ - at86rf2xx_set_option(dev, AT86RF2XX_OPT_AUTOACK, true); - at86rf2xx_set_option(dev, AT86RF2XX_OPT_CSMA, true); - static const netopt_enable_t enable = NETOPT_ENABLE; - netdev_ieee802154_set(&dev->netdev, NETOPT_ACK_REQ, - &enable, sizeof(enable)); + if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + at86rf2xx_set_option(dev, AT86RF2XX_OPT_AUTOACK, true); + at86rf2xx_set_option(dev, AT86RF2XX_OPT_CSMA, true); + + static const netopt_enable_t enable = NETOPT_ENABLE; + netdev_ieee802154_set(&dev->netdev, NETOPT_ACK_REQ, + &enable, sizeof(enable)); + } /* enable safe mode (protect RX FIFO until reading data starts) */ at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_CTRL_2, @@ -146,9 +149,9 @@ void at86rf2xx_reset(at86rf2xx_t *dev) at86rf2xx_reg_read(dev, AT86RF2XX_REG__IRQ_STATUS); /* State to return after receiving or transmitting */ - dev->idle_state = AT86RF2XX_STATE_RX_AACK_ON; + dev->idle_state = AT86RF2XX_PHY_STATE_RX; /* go into RX state */ - at86rf2xx_set_state(dev, AT86RF2XX_STATE_RX_AACK_ON); + at86rf2xx_set_state(dev, AT86RF2XX_PHY_STATE_RX); DEBUG("at86rf2xx_reset(): reset complete.\n"); } @@ -171,8 +174,8 @@ void at86rf2xx_tx_prepare(at86rf2xx_t *dev) uint8_t state; dev->pending_tx++; - state = at86rf2xx_set_state(dev, AT86RF2XX_STATE_TX_ARET_ON); - if (state != AT86RF2XX_STATE_TX_ARET_ON) { + state = at86rf2xx_set_state(dev, AT86RF2XX_PHY_STATE_TX); + if (state != AT86RF2XX_PHY_STATE_TX) { dev->idle_state = state; } dev->tx_frame_len = IEEE802154_FCS_LEN; diff --git a/drivers/at86rf2xx/at86rf2xx_getset.c b/drivers/at86rf2xx/at86rf2xx_getset.c index 902e7b7e050b..ed7cd55ba9d2 100644 --- a/drivers/at86rf2xx/at86rf2xx_getset.c +++ b/drivers/at86rf2xx/at86rf2xx_getset.c @@ -498,6 +498,8 @@ uint8_t at86rf2xx_set_state(at86rf2xx_t *dev, uint8_t state) old_state = at86rf2xx_get_status(dev); } while (old_state == AT86RF2XX_STATE_BUSY_RX_AACK || old_state == AT86RF2XX_STATE_BUSY_TX_ARET || + old_state == AT86RF2XX_STATE_BUSY_RX || + old_state == AT86RF2XX_STATE_BUSY_TX || old_state == AT86RF2XX_STATE_IN_PROGRESS); if (state == AT86RF2XX_STATE_FORCE_TRX_OFF) { diff --git a/drivers/at86rf2xx/at86rf2xx_netdev.c b/drivers/at86rf2xx/at86rf2xx_netdev.c index 6daa510ebcdb..d2d5729ba21a 100644 --- a/drivers/at86rf2xx/at86rf2xx_netdev.c +++ b/drivers/at86rf2xx/at86rf2xx_netdev.c @@ -248,7 +248,7 @@ static int _set_state(at86rf2xx_t *dev, netopt_state_t state) at86rf2xx_set_state(dev, AT86RF2XX_STATE_SLEEP); break; case NETOPT_STATE_IDLE: - at86rf2xx_set_state(dev, AT86RF2XX_STATE_RX_AACK_ON); + at86rf2xx_set_state(dev, AT86RF2XX_PHY_STATE_RX); break; case NETOPT_STATE_TX: if (dev->flags & AT86RF2XX_OPT_PRELOADING) { @@ -268,7 +268,7 @@ static int _set_state(at86rf2xx_t *dev, netopt_state_t state) * know when to switch back to the idle state. */ ++dev->pending_tx; } - at86rf2xx_set_state(dev, AT86RF2XX_STATE_TX_ARET_ON); + at86rf2xx_set_state(dev, AT86RF2XX_PHY_STATE_TX); at86rf2xx_tx_exec(dev); } break; @@ -289,12 +289,12 @@ netopt_state_t _get_state(at86rf2xx_t *dev) return NETOPT_STATE_SLEEP; case AT86RF2XX_STATE_TRX_OFF: return NETOPT_STATE_STANDBY; - case AT86RF2XX_STATE_BUSY_RX_AACK: + case AT86RF2XX_PHY_STATE_RX_BUSY: return NETOPT_STATE_RX; - case AT86RF2XX_STATE_BUSY_TX_ARET: - case AT86RF2XX_STATE_TX_ARET_ON: + case AT86RF2XX_PHY_STATE_TX: + case AT86RF2XX_PHY_STATE_TX_BUSY: return NETOPT_STATE_TX; - case AT86RF2XX_STATE_RX_AACK_ON: + case AT86RF2XX_PHY_STATE_RX: default: return NETOPT_STATE_IDLE; } @@ -331,13 +331,16 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len) return sizeof(netopt_enable_t); case NETOPT_PROMISCUOUSMODE: - if (dev->flags & AT86RF2XX_OPT_PROMISCUOUS) { - *((netopt_enable_t *)val) = NETOPT_ENABLE; - } - else { - *((netopt_enable_t *)val) = NETOPT_DISABLE; + if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + if (dev->flags & AT86RF2XX_OPT_PROMISCUOUS) { + *((netopt_enable_t *)val) = NETOPT_ENABLE; + } + else { + *((netopt_enable_t *)val) = NETOPT_DISABLE; + } + return sizeof(netopt_enable_t); } - return sizeof(netopt_enable_t); + break; case NETOPT_RX_START_IRQ: *((netopt_enable_t *)val) = @@ -360,16 +363,22 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len) return sizeof(netopt_enable_t); case NETOPT_CSMA: - *((netopt_enable_t *)val) = - !!(dev->flags & AT86RF2XX_OPT_CSMA); - return sizeof(netopt_enable_t); + if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + *((netopt_enable_t *)val) = + !!(dev->flags & AT86RF2XX_OPT_CSMA); + return sizeof(netopt_enable_t); + } + break; /* Only radios with the XAH_CTRL_2 register support frame retry reporting */ #if AT86RF2XX_HAVE_RETRIES case NETOPT_TX_RETRIES_NEEDED: - assert(max_len >= sizeof(uint8_t)); - *((uint8_t *)val) = dev->tx_retries; - return sizeof(uint8_t); + if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + assert(max_len >= sizeof(uint8_t)); + *((uint8_t *)val) = dev->tx_retries; + return sizeof(uint8_t); + } + break; #endif default: @@ -400,15 +409,19 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len) break; case NETOPT_RETRANS: - assert(max_len >= sizeof(uint8_t)); - *((uint8_t *)val) = at86rf2xx_get_max_retries(dev); - res = sizeof(uint8_t); + if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + assert(max_len >= sizeof(uint8_t)); + *((uint8_t *)val) = at86rf2xx_get_max_retries(dev); + res = sizeof(uint8_t); + } break; case NETOPT_CSMA_RETRIES: - assert(max_len >= sizeof(uint8_t)); - *((uint8_t *)val) = at86rf2xx_get_csma_max_retries(dev); - res = sizeof(uint8_t); + if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + assert(max_len >= sizeof(uint8_t)); + *((uint8_t *)val) = at86rf2xx_get_csma_max_retries(dev); + res = sizeof(uint8_t); + } break; case NETOPT_CCA_THRESHOLD: @@ -430,10 +443,12 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len) break; case NETOPT_AUTOACK: - assert(max_len >= sizeof(netopt_enable_t)); - uint8_t tmp = at86rf2xx_reg_read(dev, AT86RF2XX_REG__CSMA_SEED_1); - *((netopt_enable_t *)val) = (tmp & AT86RF2XX_CSMA_SEED_1__AACK_DIS_ACK) ? false : true; - res = sizeof(netopt_enable_t); + if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + assert(max_len >= sizeof(netopt_enable_t)); + uint8_t tmp = at86rf2xx_reg_read(dev, AT86RF2XX_REG__CSMA_SEED_1); + *((netopt_enable_t *)val) = (tmp & AT86RF2XX_CSMA_SEED_1__AACK_DIS_ACK) ? false : true; + res = sizeof(netopt_enable_t); + } break; default: @@ -532,21 +547,28 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len) break; case NETOPT_AUTOACK: - at86rf2xx_set_option(dev, AT86RF2XX_OPT_AUTOACK, - ((const bool *)val)[0]); - res = sizeof(netopt_enable_t); + + if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + at86rf2xx_set_option(dev, AT86RF2XX_OPT_AUTOACK, + ((const bool *)val)[0]); + res = sizeof(netopt_enable_t); + } break; case NETOPT_ACK_PENDING: - at86rf2xx_set_option(dev, AT86RF2XX_OPT_ACK_PENDING, - ((const bool *)val)[0]); - res = sizeof(netopt_enable_t); + if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + at86rf2xx_set_option(dev, AT86RF2XX_OPT_ACK_PENDING, + ((const bool *)val)[0]); + res = sizeof(netopt_enable_t); + } break; case NETOPT_RETRANS: - assert(len <= sizeof(uint8_t)); - at86rf2xx_set_max_retries(dev, *((const uint8_t *)val)); - res = sizeof(uint8_t); + if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + assert(len <= sizeof(uint8_t)); + at86rf2xx_set_max_retries(dev, *((const uint8_t *)val)); + res = sizeof(uint8_t); + } break; case NETOPT_PRELOADING: @@ -556,9 +578,11 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len) break; case NETOPT_PROMISCUOUSMODE: - at86rf2xx_set_option(dev, AT86RF2XX_OPT_PROMISCUOUS, - ((const bool *)val)[0]); - res = sizeof(netopt_enable_t); + if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + at86rf2xx_set_option(dev, AT86RF2XX_OPT_PROMISCUOUS, + ((const bool *)val)[0]); + res = sizeof(netopt_enable_t); + } break; case NETOPT_RX_START_IRQ: @@ -586,21 +610,25 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len) break; case NETOPT_CSMA: - at86rf2xx_set_option(dev, AT86RF2XX_OPT_CSMA, - ((const bool *)val)[0]); - res = sizeof(netopt_enable_t); + if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + at86rf2xx_set_option(dev, AT86RF2XX_OPT_CSMA, + ((const bool *)val)[0]); + res = sizeof(netopt_enable_t); + } break; case NETOPT_CSMA_RETRIES: - assert(len <= sizeof(uint8_t)); - if (!(dev->flags & AT86RF2XX_OPT_CSMA) || - (*((uint8_t *)val) > 5)) { - /* If CSMA is disabled, don't allow setting retries */ - res = -EINVAL; - } - else { - at86rf2xx_set_csma_max_retries(dev, *((const uint8_t *)val)); - res = sizeof(uint8_t); + if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + assert(len <= sizeof(uint8_t)); + if (!(dev->flags & AT86RF2XX_OPT_CSMA) || + (*((uint8_t *)val) > 5)) { + /* If CSMA is disabled, don't allow setting retries */ + res = -EINVAL; + } + else { + at86rf2xx_set_csma_max_retries(dev, *((const uint8_t *)val)); + res = sizeof(uint8_t); + } } break; @@ -630,6 +658,10 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len) static void _isr_send_complete(at86rf2xx_t *dev, uint8_t trac_status) { netdev_t *netdev = &dev->netdev.netdev; + if (IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE); + return; + } /* Only radios with the XAH_CTRL_2 register support frame retry reporting */ #if AT86RF2XX_HAVE_RETRIES dev->tx_retries = (at86rf2xx_reg_read(dev, AT86RF2XX_REG__XAH_CTRL_2) @@ -704,15 +736,15 @@ static void _isr(netdev_t *netdev) } if (irq_mask & AT86RF2XX_IRQ_STATUS_MASK__TRX_END) { - if ((state == AT86RF2XX_STATE_RX_AACK_ON) - || (state == AT86RF2XX_STATE_BUSY_RX_AACK)) { + if ((state == AT86RF2XX_PHY_STATE_RX) + || (state == AT86RF2XX_PHY_STATE_RX_BUSY)) { DEBUG("[at86rf2xx] EVT - RX_END\n"); if (!(dev->flags & AT86RF2XX_OPT_TELL_RX_END)) { return; } netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE); } - else if (state == AT86RF2XX_STATE_TX_ARET_ON) { + else if (state == AT86RF2XX_PHY_STATE_TX) { /* check for more pending TX calls and return to idle state if * there are none */ assert(dev->pending_tx != 0); @@ -730,7 +762,7 @@ static void _isr(netdev_t *netdev) * dev->pending == 2 means two transmits occurred and this is the isr for * the first. */ - else if (state == AT86RF2XX_STATE_BUSY_TX_ARET) { + else if (state == AT86RF2XX_PHY_STATE_TX_BUSY) { if (dev->pending_tx > 1) { dev->pending_tx--; _isr_send_complete(dev, trac_status); @@ -798,7 +830,7 @@ ISR(TRX24_TX_END_vect, ISR_BLOCK) /* only inform upper layer when a transmission was done, * not for sending acknowledge frames if data was received. */ - if (status != AT86RF2XX_STATE_RX_AACK_ON) { + if (status != AT86RF2XX_PHY_STATE_RX) { dev->irq_status |= AT86RF2XX_IRQ_STATUS_MASK__TX_END; /* Call upper layer to process if data was send successful */ From ab5418ebaba78f4b99659231820797988896cd0b Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Thu, 2 Apr 2020 18:23:26 +0200 Subject: [PATCH 3/3] at86rf2xx: report CRC error in basic mode --- drivers/at86rf2xx/at86rf2xx_netdev.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/at86rf2xx/at86rf2xx_netdev.c b/drivers/at86rf2xx/at86rf2xx_netdev.c index d2d5729ba21a..076b5ae91911 100644 --- a/drivers/at86rf2xx/at86rf2xx_netdev.c +++ b/drivers/at86rf2xx/at86rf2xx_netdev.c @@ -704,6 +704,25 @@ static void _isr_send_complete(at86rf2xx_t *dev, uint8_t trac_status) } } +static inline void _isr_recv_complete(netdev_t *netdev) +{ + at86rf2xx_t *dev = (at86rf2xx_t *) netdev; + if (IS_ACTIVE(AT86RF2XX_BASIC_MODE)) { + uint8_t phy_status = at86rf2xx_reg_read(dev, AT86RF2XX_REG__PHY_RSSI); + bool crc_ok = phy_status & AT86RF2XX_PHY_RSSI_MASK__RX_CRC_VALID; + + if (crc_ok) { + netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE); + } + else { + netdev->event_callback(netdev, NETDEV_EVENT_CRC_ERROR); + } + } + else { + netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE); + } +} + static void _isr(netdev_t *netdev) { at86rf2xx_t *dev = (at86rf2xx_t *) netdev; @@ -742,7 +761,9 @@ static void _isr(netdev_t *netdev) if (!(dev->flags & AT86RF2XX_OPT_TELL_RX_END)) { return; } - netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE); + + _isr_recv_complete(netdev); + } else if (state == AT86RF2XX_PHY_STATE_TX) { /* check for more pending TX calls and return to idle state if