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

at86rf2xx: implement basic mode (v2) #13798

Merged
merged 3 commits into from
Apr 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions drivers/at86rf2xx/at86rf2xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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");
}
Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions drivers/at86rf2xx/at86rf2xx_getset.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 ||
fjmolinas marked this conversation as resolved.
Show resolved Hide resolved
old_state == AT86RF2XX_STATE_IN_PROGRESS);

if (state == AT86RF2XX_STATE_FORCE_TRX_OFF) {
Expand Down
169 changes: 111 additions & 58 deletions drivers/at86rf2xx/at86rf2xx_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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) =
Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -672,6 +704,25 @@ static void _isr_send_complete(at86rf2xx_t *dev, uint8_t trac_status)
}
fjmolinas marked this conversation as resolved.
Show resolved Hide resolved
}

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;
Expand Down Expand Up @@ -704,15 +755,17 @@ 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);

_isr_recv_complete(netdev);

}
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);
Expand All @@ -730,7 +783,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);
Expand Down Expand Up @@ -798,7 +851,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 */
Expand Down
25 changes: 25 additions & 0 deletions drivers/include/at86rf2xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <stdbool.h>

#include "board.h"
#include "kernel_defines.h"
#include "net/netdev.h"
#include "net/netdev/ieee802154.h"
#include "net/gnrc/nettype.h"
Expand Down Expand Up @@ -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
Expand Down