diff --git a/drivers/at86rf2xx/at86rf2xx.c b/drivers/at86rf2xx/at86rf2xx.c index a697a70d92c66f583b709d0c332454346b870b72..397904a38fb930cd34dd16aee04a23d042884e6f 100644 --- a/drivers/at86rf2xx/at86rf2xx.c +++ b/drivers/at86rf2xx/at86rf2xx.c @@ -94,6 +94,18 @@ void at86rf2xx_reset(at86rf2xx_t *dev) tmp &= ~(AT86RF2XX_TRX_CTRL_1_MASK__IRQ_MASK_MODE); at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_CTRL_1, tmp); + /* configure smart idle listening feature */ +#if AT86RF2XX_SMART_IDLE_LISTENING + tmp = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_RPC); + tmp |= (AT86RF2XX_TRX_RPC_MASK__RX_RPC_EN | + AT86RF2XX_TRX_RPC_MASK__PDT_RPC_EN | + AT86RF2XX_TRX_RPC_MASK__PLL_RPC_EN | + AT86RF2XX_TRX_RPC_MASK__XAH_TX_RPC_EN | + AT86RF2XX_TRX_RPC_MASK__IPAN_RPC_EN); + at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_RPC, tmp); + at86rf2xx_set_rxsensitivity(dev, RSSI_BASE_VAL); +#endif + /* disable clock output to save power */ tmp = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_CTRL_0); tmp &= ~(AT86RF2XX_TRX_CTRL_0_MASK__CLKM_CTRL); diff --git a/drivers/at86rf2xx/at86rf2xx_getset.c b/drivers/at86rf2xx/at86rf2xx_getset.c index 5d0df031dbeec979c2269d4543870ff9caa0d091..96bdd37a15c239984f5c7d9023f903b84f36e0ff 100644 --- a/drivers/at86rf2xx/at86rf2xx_getset.c +++ b/drivers/at86rf2xx/at86rf2xx_getset.c @@ -49,6 +49,19 @@ static const uint8_t dbm_to_tx_pow_915[] = { 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x17, 0x04, 0x03, 0x02, 0x01, 0x00, 0x86, 0x40, 0x84, 0x83, 0x82, 0x80, 0xc1, 0xc0 }; +static const int16_t rx_sens_to_dbm[] = { -110, -98, -94, -91, -88, -85, -82, + -79, -76, -73, -70, -67, -63, -60, -57, + -54 }; +static const uint8_t dbm_to_rx_sens[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, + 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, + 0x04, 0x05, 0x05, 0x05, 0x06, 0x06, + 0x06, 0x07, 0x07, 0x07, 0x08, 0x08, + 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, + 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, + 0x0e, 0x0e, 0x0f }; static int16_t _tx_pow_to_dbm_212b(uint8_t channel, uint8_t page, uint8_t reg) { @@ -84,6 +97,18 @@ static const uint8_t dbm_to_tx_pow[] = { 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x03, 0x00 }; +static const int16_t rx_sens_to_dbm[] = { -101, -94, -91, -88, -85, -82, -79, + -76, -73, -70, -67, -64, -61, -58, -55, + -52 }; +static const uint8_t dbm_to_rx_sens[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, + 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, + 0x04, 0x05, 0x05, 0x05, 0x06, 0x06, + 0x06, 0x07, 0x07, 0x07, 0x08, 0x08, + 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, + 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, + 0x0e, 0x0f }; #else static const int16_t tx_pow_to_dbm[] = { 3, 3, 2, 2, 1, 1, 0, -1, -2, -3, -4, -5, -7, -9, -12, -17 }; @@ -91,6 +116,18 @@ static const uint8_t dbm_to_tx_pow[] = { 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x03, 0x00 }; +static const int16_t rx_sens_to_dbm[] = { -101, -91, -88, -85, -82, -79, -76 + -73, -70, -67, -64, -61, -58, -55, -52, + -49 }; +static const uint8_t dbm_to_rx_sens[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, + 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, + 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, + 0x05, 0x06, 0x06, 0x06, 0x07, 0x07, + 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, + 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, + 0x0b, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, + 0x0d, 0x0e, 0x0e, 0x0e, 0x0f }; #endif uint16_t at86rf2xx_get_addr_short(const at86rf2xx_t *dev) @@ -229,6 +266,30 @@ void at86rf2xx_set_txpower(const at86rf2xx_t *dev, int16_t txpower) #endif } +int16_t at86rf2xx_get_rxsensitivity(const at86rf2xx_t *dev) +{ + uint8_t rxsens = at86rf2xx_reg_read(dev, AT86RF2XX_REG__RX_SYN) + & AT86RF2XX_RX_SYN__RX_PDT_LEVEL; + return rx_sens_to_dbm[rxsens]; +} + +void at86rf2xx_set_rxsensitivity(const at86rf2xx_t *dev, int16_t rxsens) +{ + rxsens += MIN_RX_SENSITIVITY; + + if (rxsens < 0) { + rxsens = 0; + } + else if (rxsens > MAX_RX_SENSITIVITY) { + rxsens = MAX_RX_SENSITIVITY; + } + + uint8_t tmp = at86rf2xx_reg_read(dev, AT86RF2XX_REG__RX_SYN); + tmp &= ~(AT86RF2XX_RX_SYN__RX_PDT_LEVEL); + tmp |= (dbm_to_rx_sens[rxsens] & AT86RF2XX_RX_SYN__RX_PDT_LEVEL); + at86rf2xx_reg_write(dev, AT86RF2XX_REG__RX_SYN, tmp); +} + uint8_t at86rf2xx_get_max_retries(const at86rf2xx_t *dev) { return (at86rf2xx_reg_read(dev, AT86RF2XX_REG__XAH_CTRL_0) >> 4); diff --git a/drivers/at86rf2xx/include/at86rf2xx_registers.h b/drivers/at86rf2xx/include/at86rf2xx_registers.h index 9c9fa3379ddf7cda1bd330b837bb597ae49befaf..2b770eeefbdfacd3f3a2460eb03aaa9553c58330 100644 --- a/drivers/at86rf2xx/include/at86rf2xx_registers.h +++ b/drivers/at86rf2xx/include/at86rf2xx_registers.h @@ -92,6 +92,8 @@ extern "C" { #define AT86RF2XX_REG__RX_SYN (0x15) #ifdef MODULE_AT86RF212B #define AT86RF2XX_REG__RF_CTRL_0 (0x16) +#elif defined(MODULE_AT86RF233) +#define AT86RF2XX_REG__TRX_RPC (0x16) #endif #define AT86RF2XX_REG__XAH_CTRL_1 (0x17) #define AT86RF2XX_REG__FTN_CTRL (0x18) @@ -375,6 +377,19 @@ extern "C" { #endif /** @} */ +/** + * @name Bitfield definitions for the TRX_RPC register + * @{ + */ +#ifdef MODULE_AT86RF233 +#define AT86RF2XX_TRX_RPC_MASK__RX_RPC_CTRL_MAXPWR (0xC0) +#define AT86RF2XX_TRX_RPC_MASK__RX_RPC_EN (0x20) +#define AT86RF2XX_TRX_RPC_MASK__PDT_RPC_EN (0x10) +#define AT86RF2XX_TRX_RPC_MASK__PLL_RPC_EN (0x08) +#define AT86RF2XX_TRX_RPC_MASK__XAH_TX_RPC_EN (0x04) +#define AT86RF2XX_TRX_RPC_MASK__IPAN_RPC_EN (0x02) +#endif + #ifdef __cplusplus } #endif diff --git a/drivers/include/at86rf2xx.h b/drivers/include/at86rf2xx.h index 76038f4fc5b6e477cccc4b29a434f29bd5ae6a92..72bfd6025fca25d943a016b2bb7864837eed155c 100644 --- a/drivers/include/at86rf2xx.h +++ b/drivers/include/at86rf2xx.h @@ -94,6 +94,28 @@ extern "C" { # define RSSI_BASE_VAL (-91) #endif +/** + * @brief Max Receiver sensitivity value in dBm + */ +#if MODULE_AT86RF233 +# define MAX_RX_SENSITIVITY (-52) +#elif MODULE_AT86RF212B +# define MAX_RX_SENSITIVITY (-54) +#else +# define MAX_RX_SENSITIVITY (-49) +#endif + +/** + * @brief Min Receiver sensitivity value in dBm + */ +#if MODULE_AT86RF233 +# define MIN_RX_SENSITIVITY (-101) +#elif MODULE_AT86RF212B +# define MIN_RX_SENSITIVITY (-110) +#else +# define MIN_RX_SENSITIVITY (-101) +#endif + #if defined(DOXYGEN) || defined(MODULE_AT86RF232) || defined(MODULE_AT86RF233) /** * @brief Frame retry counter reporting @@ -108,6 +130,20 @@ extern "C" { #define AT86RF2XX_HAVE_RETRIES (0) #endif +/** + * @brief Smart idle listening feature + * + * This feature optimizes radio operation in the listening mode, reducing + * current consumption by ~50%. It is supported by only at86rf233. + */ +#ifdef MODULE_AT86RF233 +#ifndef AT86RF2XX_SMART_IDLE_LISTENING +#define AT86RF2XX_SMART_IDLE_LISTENING (1) +#endif +#else +#define AT86RF2XX_SMART_IDLE_LISTENING (0) +#endif + /** * @name Flags for device internal states (see datasheet) * @{ @@ -310,6 +346,28 @@ int16_t at86rf2xx_get_txpower(const at86rf2xx_t *dev); */ void at86rf2xx_set_txpower(const at86rf2xx_t *dev, int16_t txpower); +/** + * @brief Get the configured receiver sensitivity of the given device [in dBm] + * + * @param[in] dev device to read from + * + * @return configured receiver sensitivity in dBm + */ +int16_t at86rf2xx_get_rxsensitivity(const at86rf2xx_t *dev); + +/** + * @brief Set the receiver sensitivity of the given device [in dBm] + * + * If the device does not support the exact dBm value given, it will set a value + * as close as possible to the given value. If the given value is larger or + * lower then the maximal or minimal possible value, the min or max value is + * set, respectively. + * + * @param[in] dev device to write to + * @param[in] rxsens rx sensitivity in dBm + */ +void at86rf2xx_set_rxsensitivity(const at86rf2xx_t *dev, int16_t rxsens); + /** * @brief Get the maximum number of retransmissions *