diff --git a/drivers/at86rf2xx/at86rf2xx_netdev.c b/drivers/at86rf2xx/at86rf2xx_netdev.c index 4e715ce2e1..d6cde3637e 100644 --- a/drivers/at86rf2xx/at86rf2xx_netdev.c +++ b/drivers/at86rf2xx/at86rf2xx_netdev.c @@ -294,6 +294,14 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len) !!(dev->netdev.flags & AT86RF2XX_OPT_CSMA); return sizeof(netopt_enable_t); +/* 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); +#endif + default: /* Can still be handled in second switch */ break; @@ -578,6 +586,12 @@ static void _isr(netdev_t *netdev) at86rf2xx_set_state(dev, dev->idle_state); DEBUG("[at86rf2xx] return to state 0x%x\n", dev->idle_state); } +/* 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) & + AT86RF2XX_XAH_CTRL_2__ARET_FRAME_RETRIES_MASK ) >> + AT86RF2XX_XAH_CTRL_2__ARET_FRAME_RETRIES_OFFSET; +#endif DEBUG("[at86rf2xx] EVT - TX_END\n"); diff --git a/drivers/at86rf2xx/include/at86rf2xx_registers.h b/drivers/at86rf2xx/include/at86rf2xx_registers.h index d89ec7ae64..9c9fa3379d 100644 --- a/drivers/at86rf2xx/include/at86rf2xx_registers.h +++ b/drivers/at86rf2xx/include/at86rf2xx_registers.h @@ -24,6 +24,8 @@ #ifndef AT86RF2XX_REGISTERS_H #define AT86RF2XX_REGISTERS_H +#include "at86rf2xx.h" + #ifdef __cplusplus extern "C" { #endif @@ -93,6 +95,9 @@ extern "C" { #endif #define AT86RF2XX_REG__XAH_CTRL_1 (0x17) #define AT86RF2XX_REG__FTN_CTRL (0x18) +#if AT86RF2XX_HAVE_RETRIES +#define AT86RF2XX_REG__XAH_CTRL_2 (0x19) +#endif #define AT86RF2XX_REG__PLL_CF (0x1A) #define AT86RF2XX_REG__PLL_DCU (0x1B) #define AT86RF2XX_REG__PART_NUM (0x1C) @@ -329,6 +334,23 @@ extern "C" { #define AT86RF2XX_XAH_CTRL_1__AACK_PROM_MODE (0x02) /** @} */ +/** + * @name Bitfield definitions for the XAH_CTRL_2 register + * + * This register contains both the CSMA-CA retry counter and the frame retry + * counter. At this moment only the at86rf232 and the at86rf233 support this + * register. + * + * @{ + */ +#if AT86RF2XX_HAVE_RETRIES +#define AT86RF2XX_XAH_CTRL_2__ARET_FRAME_RETRIES_MASK (0xF0) +#define AT86RF2XX_XAH_CTRL_2__ARET_FRAME_RETRIES_OFFSET (4) +#define AT86RF2XX_XAH_CTRL_2__ARET_CSMA_RETRIES_MASK (0x0E) +#define AT86RF2XX_XAH_CTRL_2__ARET_CSMA_RETRIES_OFFSET (1) +#endif +/** @} */ + /** * @name Bitfield definitions for the CSMA_SEED_1 register * @{ diff --git a/drivers/include/at86rf2xx.h b/drivers/include/at86rf2xx.h index a77f8c4cff..17fb82f064 100644 --- a/drivers/include/at86rf2xx.h +++ b/drivers/include/at86rf2xx.h @@ -91,6 +91,20 @@ extern "C" { # define RSSI_BASE_VAL (-91) #endif +#if defined(DOXYGEN) || defined(MODULE_AT86RF232) || defined(MODULE_AT86RF233) +/** + * @brief Frame retry counter reporting + * + * The AT86RF2XX_HAVE_RETRIES flag enables support for NETOPT_TX_RETRIES NEEDED + * operation. Required for this functionality is the XAH_CTRL_2 register which + * contains the frame retry counter. Only the at86rf232 and the at86rf233 + * support this register. + */ +#define AT86RF2XX_HAVE_RETRIES (1) +#else +#define AT86RF2XX_HAVE_RETRIES (0) +#endif + /** * @name Flags for device internal states (see datasheet) * @{ @@ -167,6 +181,11 @@ typedef struct { uint8_t pending_tx; /**< keep track of pending TX calls this is required to know when to return to @ref at86rf2xx_t::idle_state */ +#if AT86RF2XX_HAVE_RETRIES + /* Only radios with the XAH_CTRL_2 register support frame retry reporting */ + uint8_t tx_retries; /**< Number of NOACK retransmissions */ +#endif + /** @} */ } at86rf2xx_t; /**