diff --git a/drivers/at86rf2xx/at86rf2xx.c b/drivers/at86rf2xx/at86rf2xx.c index 86b7a7ad5d..919bb4fca6 100644 --- a/drivers/at86rf2xx/at86rf2xx.c +++ b/drivers/at86rf2xx/at86rf2xx.c @@ -151,15 +151,11 @@ static void at86rf2xx_disable_clock_output(at86rf2xx_t *dev) #endif } -static void at86rf2xx_enable_smart_idle(at86rf2xx_t *dev) +void at86rf2xx_enable_smart_idle(at86rf2xx_t *dev) { #if AT86RF2XX_SMART_IDLE_LISTENING uint8_t 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); + tmp |= AT86RF2XX_TRX_RPC_MASK__RX_RPC__SMART_IDLE; at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_RPC, tmp); at86rf2xx_set_rxsensitivity(dev, RSSI_BASE_VAL); #else @@ -167,6 +163,17 @@ static void at86rf2xx_enable_smart_idle(at86rf2xx_t *dev) #endif } +void at86rf2xx_disable_smart_idle(at86rf2xx_t *dev) +{ +#if AT86RF2XX_SMART_IDLE_LISTENING + uint8_t tmp = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_RPC); + tmp &= ~AT86RF2XX_TRX_RPC_MASK__RX_RPC__SMART_IDLE; + at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_RPC, tmp); +#else + (void) dev; +#endif +} + void at86rf2xx_reset(at86rf2xx_t *dev) { uint8_t tmp; diff --git a/drivers/at86rf2xx/at86rf2xx_internal.c b/drivers/at86rf2xx/at86rf2xx_internal.c index a592f1cd41..22a118e7a2 100644 --- a/drivers/at86rf2xx/at86rf2xx_internal.c +++ b/drivers/at86rf2xx/at86rf2xx_internal.c @@ -221,8 +221,9 @@ void at86rf2xx_configure_phy(at86rf2xx_t *dev) } #if AT86RF2XX_RANDOM_NUMBER_GENERATOR -void at86rf2xx_get_random(const at86rf2xx_t *dev, uint8_t *data, size_t len) +void at86rf2xx_get_random(at86rf2xx_t *dev, uint8_t *data, size_t len) { + at86rf2xx_disable_smart_idle(dev); for (size_t byteCount = 0; byteCount < len; ++byteCount) { uint8_t rnd = 0; for (uint8_t i = 0; i < 4; ++i) { @@ -236,5 +237,6 @@ void at86rf2xx_get_random(const at86rf2xx_t *dev, uint8_t *data, size_t len) } data[byteCount] = rnd; } + at86rf2xx_enable_smart_idle(dev); } #endif diff --git a/drivers/at86rf2xx/at86rf2xx_netdev.c b/drivers/at86rf2xx/at86rf2xx_netdev.c index c5961c9b5a..885c32d018 100644 --- a/drivers/at86rf2xx/at86rf2xx_netdev.c +++ b/drivers/at86rf2xx/at86rf2xx_netdev.c @@ -459,7 +459,12 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len) return sizeof(uint8_t); #endif /* MODULE_NETDEV_IEEE802154_OQPSK */ - +#if AT86RF2XX_RANDOM_NUMBER_GENERATOR + case NETOPT_RANDOM: + assert(max_len >= sizeof(uint32_t)); + at86rf2xx_get_random(dev, (uint8_t*)val, sizeof(val)); + break; +#endif default: res = -ENOTSUP; break; diff --git a/drivers/at86rf2xx/include/at86rf2xx_internal.h b/drivers/at86rf2xx/include/at86rf2xx_internal.h index 59e4dd94f6..2cad8c34eb 100644 --- a/drivers/at86rf2xx/include/at86rf2xx_internal.h +++ b/drivers/at86rf2xx/include/at86rf2xx_internal.h @@ -239,7 +239,7 @@ void at86rf2xx_configure_phy(at86rf2xx_t *dev); * @param[out] data buffer to copy the random data to * @param[in] len number of random bytes to store in data */ -void at86rf2xx_get_random(const at86rf2xx_t *dev, uint8_t *data, size_t len); +void at86rf2xx_get_random(at86rf2xx_t *dev, uint8_t *data, size_t len); #endif #ifdef __cplusplus diff --git a/drivers/at86rf2xx/include/at86rf2xx_registers.h b/drivers/at86rf2xx/include/at86rf2xx_registers.h index 547e457868..98e7a55967 100644 --- a/drivers/at86rf2xx/include/at86rf2xx_registers.h +++ b/drivers/at86rf2xx/include/at86rf2xx_registers.h @@ -533,6 +533,16 @@ extern "C" { #define AT86RF2XX_TRX_RPC_MASK__XAH_TX_RPC_EN (0x04) #define AT86RF2XX_TRX_RPC_MASK__IPAN_RPC_EN (0x02) +/** + * @brief Bits to set to enable smart idle + */ +#define AT86RF2XX_TRX_RPC_MASK__RX_RPC__SMART_IDLE \ + (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) + #ifdef __cplusplus } #endif diff --git a/drivers/include/at86rf2xx.h b/drivers/include/at86rf2xx.h index d9a20e5eec..b3611b36df 100644 --- a/drivers/include/at86rf2xx.h +++ b/drivers/include/at86rf2xx.h @@ -612,6 +612,24 @@ void at86rf2xx_tx_exec(at86rf2xx_t *dev); */ bool at86rf2xx_cca(at86rf2xx_t *dev); +/** + * @brief Enable the smart receive tecnology (SRT) + * + * The SRT reduces the power consumption during RX listening periods. + * + * @param[in] dev device to use + * + */ +void at86rf2xx_enable_smart_idle(at86rf2xx_t *dev); + +/** + * @brief Disable the smart receive tecnology (SRT) + * + * @param[in] dev device to use + * + */ +void at86rf2xx_disable_smart_idle(at86rf2xx_t *dev); + #ifdef __cplusplus } #endif diff --git a/tests/driver_at86rf2xx/cmd.c b/tests/driver_at86rf2xx/cmd.c index 1404c3d954..fe01506af0 100644 --- a/tests/driver_at86rf2xx/cmd.c +++ b/tests/driver_at86rf2xx/cmd.c @@ -20,7 +20,7 @@ #include "net/netdev/ieee802154.h" #include "net/ieee802154.h" - +#include "at86rf2xx_internal.h" #include "common.h" #include "od.h" @@ -303,4 +303,26 @@ static int send(int iface, le_uint16_t dst_pan, uint8_t *dst, size_t dst_len, return 0; } +#if AT86RF2XX_SMART_IDLE_LISTENING +void random_net_api(uint8_t idx, uint32_t *value) +{ + netdev_ieee802154_t *dev = &devs[idx].netdev; + dev->netdev.driver->get(&dev->netdev, NETOPT_RANDOM, value, sizeof(uint32_t)); +} + +int random_by_at86rf2xx(int argc, char **argv) +{ + (void)argc; + (void)argv; + for (unsigned int i = 0; i < AT86RF2XX_NUM; i++) { + uint32_t test = 0; + at86rf2xx_get_random(&devs[i], (uint8_t *)&test, sizeof(test)); + printf("Random number for device %u via native API: %" PRIx32 "\n", i, test); + test = 0; + random_net_api(i, &test); + printf("Random number for device %u via netopt: %" PRIx32 "\n", i, test); + } + return 0; +} +#endif /** @} */ diff --git a/tests/driver_at86rf2xx/common.h b/tests/driver_at86rf2xx/common.h index 0344d42a1b..a648e37fa3 100644 --- a/tests/driver_at86rf2xx/common.h +++ b/tests/driver_at86rf2xx/common.h @@ -41,6 +41,9 @@ extern at86rf2xx_t devs[AT86RF2XX_NUM]; void recv(netdev_t *dev); int ifconfig(int argc, char **argv); int txtsnd(int argc, char **argv); +#if AT86RF2XX_RANDOM_NUMBER_GENERATOR +int random_by_at86rf2xx(int argc, char **argv); +#endif void print_addr(uint8_t *addr, size_t addr_len); /** * @} diff --git a/tests/driver_at86rf2xx/main.c b/tests/driver_at86rf2xx/main.c index 46da0d403e..30ac73f407 100644 --- a/tests/driver_at86rf2xx/main.c +++ b/tests/driver_at86rf2xx/main.c @@ -38,6 +38,9 @@ at86rf2xx_t devs[AT86RF2XX_NUM]; static const shell_command_t shell_commands[] = { { "ifconfig", "Configure netdev", ifconfig }, { "txtsnd", "Send IEEE 802.15.4 packet", txtsnd }, +#if AT86RF2XX_SMART_IDLE_LISTENING + { "random", "Get a value from Random Number Generator", random_by_at86rf2xx }, +#endif { NULL, NULL, NULL } }; @@ -87,7 +90,6 @@ void *_recv_thread(void *arg) int main(void) { puts("AT86RF2xx device driver test"); - unsigned dev_success = 0; for (unsigned i = 0; i < AT86RF2XX_NUM; i++) { const at86rf2xx_params_t *p = &at86rf2xx_params[i];