at86rf2xx: implement basic mode

This commit is contained in:
Jose Alamos 2020-04-02 16:48:34 +02:00
parent 69eb3c7fe2
commit d4b0aff8cf
3 changed files with 103 additions and 66 deletions

View File

@ -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;

View File

@ -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) {

View File

@ -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;
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);
}
else {
*((netopt_enable_t *)val) = NETOPT_DISABLE;
}
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 */