mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-25 14:33:52 +01:00
at86rf2xx: implement sleep mode
This commit is contained in:
parent
7bf121903a
commit
502786b9f7
@ -23,7 +23,6 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "xtimer.h"
|
||||
#include "periph/cpuid.h"
|
||||
#include "byteorder.h"
|
||||
#include "net/ieee802154.h"
|
||||
@ -36,9 +35,6 @@
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
#define RESET_DELAY (1U) /* must be > 625ns */
|
||||
|
||||
|
||||
static void _irq_handler(void *arg)
|
||||
{
|
||||
msg_t msg;
|
||||
@ -62,6 +58,7 @@ int at86rf2xx_init(at86rf2xx_t *dev, spi_t spi, spi_speed_t spi_speed,
|
||||
dev->sleep_pin = sleep_pin;
|
||||
dev->reset_pin = reset_pin;
|
||||
dev->idle_state = AT86RF2XX_STATE_TRX_OFF;
|
||||
dev->state = AT86RF2XX_STATE_SLEEP;
|
||||
|
||||
/* initialise SPI */
|
||||
spi_init_master(dev->spi, SPI_CONF_FIRST_RISING, spi_speed);
|
||||
@ -74,6 +71,9 @@ int at86rf2xx_init(at86rf2xx_t *dev, spi_t spi, spi_speed_t spi_speed,
|
||||
gpio_set(dev->reset_pin);
|
||||
gpio_init_int(dev->int_pin, GPIO_NOPULL, GPIO_RISING, _irq_handler, dev);
|
||||
|
||||
/* make sure device is not sleeping, so we can query part number */
|
||||
at86rf2xx_assert_awake(dev);
|
||||
|
||||
/* test if the SPI is set up correctly and the device is responding */
|
||||
if (at86rf2xx_reg_read(dev, AT86RF2XX_REG__PART_NUM) !=
|
||||
AT86RF2XX_PARTNUM) {
|
||||
@ -83,6 +83,7 @@ int at86rf2xx_init(at86rf2xx_t *dev, spi_t spi, spi_speed_t spi_speed,
|
||||
|
||||
/* reset device to default values and put it into RX state */
|
||||
at86rf2xx_reset(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -93,12 +94,7 @@ void at86rf2xx_reset(at86rf2xx_t *dev)
|
||||
eui64_t addr_long;
|
||||
#endif
|
||||
|
||||
/* wake from sleep in case radio is sleeping */
|
||||
gpio_clear(dev->sleep_pin);
|
||||
/* trigger hardware reset */
|
||||
gpio_clear(dev->reset_pin);
|
||||
xtimer_usleep(RESET_DELAY);
|
||||
gpio_set(dev->reset_pin);
|
||||
at86rf2xx_hardware_reset(dev);
|
||||
|
||||
/* Reset state machine to ensure a known state */
|
||||
at86rf2xx_reset_state_machine(dev);
|
||||
@ -184,6 +180,8 @@ bool at86rf2xx_cca(at86rf2xx_t *dev)
|
||||
uint8_t tmp;
|
||||
uint8_t status;
|
||||
|
||||
at86rf2xx_assert_awake(dev);
|
||||
|
||||
/* trigger CCA measurment */
|
||||
tmp = at86rf2xx_reg_read(dev, AT86RF2XX_REG__PHY_CC_CCA);
|
||||
tmp &= AT86RF2XX_PHY_CC_CCA_MASK__CCA_REQUEST;
|
||||
|
||||
@ -399,6 +399,7 @@ static inline void _set_state(at86rf2xx_t *dev, uint8_t state)
|
||||
{
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_STATE, state);
|
||||
while (at86rf2xx_get_status(dev) != state);
|
||||
dev->state = state;
|
||||
}
|
||||
|
||||
void at86rf2xx_set_state(at86rf2xx_t *dev, uint8_t state)
|
||||
@ -426,15 +427,17 @@ void at86rf2xx_set_state(at86rf2xx_t *dev, uint8_t state)
|
||||
/* check if we need to wake up from sleep mode */
|
||||
else if (old_state == AT86RF2XX_STATE_SLEEP) {
|
||||
DEBUG("at86rf2xx: waking up from sleep mode\n");
|
||||
gpio_clear(dev->sleep_pin);
|
||||
while (at86rf2xx_get_status(dev) != AT86RF2XX_STATE_TRX_OFF);
|
||||
at86rf2xx_assert_awake(dev);
|
||||
}
|
||||
|
||||
if (state == AT86RF2XX_STATE_SLEEP) {
|
||||
/* First go to TRX_OFF */
|
||||
at86rf2xx_force_trx_off(dev);
|
||||
/* Discard all IRQ flags, framebuffer is lost anyway */
|
||||
at86rf2xx_reg_read(dev, AT86RF2XX_REG__IRQ_STATUS);
|
||||
/* Go to SLEEP mode from TRX_OFF */
|
||||
gpio_set(dev->sleep_pin);
|
||||
dev->state = state;
|
||||
} else {
|
||||
_set_state(dev, state);
|
||||
}
|
||||
@ -444,8 +447,7 @@ void at86rf2xx_reset_state_machine(at86rf2xx_t *dev)
|
||||
{
|
||||
uint8_t old_state;
|
||||
|
||||
/* Wake up */
|
||||
gpio_clear(dev->sleep_pin);
|
||||
at86rf2xx_assert_awake(dev);
|
||||
|
||||
/* Wait for any state transitions to complete before forcing TRX_OFF */
|
||||
do {
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
|
||||
#include "periph/spi.h"
|
||||
#include "periph/gpio.h"
|
||||
#include "xtimer.h"
|
||||
#include "at86rf2xx_internal.h"
|
||||
#include "at86rf2xx_registers.h"
|
||||
|
||||
@ -101,8 +102,38 @@ void at86rf2xx_fb_read(const at86rf2xx_t *dev,
|
||||
|
||||
uint8_t at86rf2xx_get_status(const at86rf2xx_t *dev)
|
||||
{
|
||||
return (at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_STATUS)
|
||||
& AT86RF2XX_TRX_STATUS_MASK__TRX_STATUS);
|
||||
/* if sleeping immediately return state */
|
||||
if(dev->state == AT86RF2XX_STATE_SLEEP)
|
||||
return dev->state;
|
||||
|
||||
return at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_STATUS)
|
||||
& AT86RF2XX_TRX_STATUS_MASK__TRX_STATUS;
|
||||
}
|
||||
|
||||
void at86rf2xx_assert_awake(at86rf2xx_t *dev)
|
||||
{
|
||||
if(at86rf2xx_get_status(dev) == AT86RF2XX_STATE_SLEEP) {
|
||||
|
||||
/* wake up and wait for transition to TRX_OFF */
|
||||
gpio_clear(dev->sleep_pin);
|
||||
xtimer_usleep(AT86RF2XX_WAKEUP_DELAY);
|
||||
|
||||
/* update state */
|
||||
dev->state = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_STATUS)
|
||||
& AT86RF2XX_TRX_STATUS_MASK__TRX_STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
void at86rf2xx_hardware_reset(at86rf2xx_t *dev)
|
||||
{
|
||||
/* wake up from sleep in case radio is sleeping */
|
||||
at86rf2xx_assert_awake(dev);
|
||||
|
||||
/* trigger hardware reset */
|
||||
gpio_clear(dev->reset_pin);
|
||||
xtimer_usleep(AT86RF2XX_RESET_PULSE_WIDTH);
|
||||
gpio_set(dev->reset_pin);
|
||||
xtimer_usleep(AT86RF2XX_RESET_DELAY);
|
||||
}
|
||||
|
||||
void at86rf2xx_force_trx_off(const at86rf2xx_t *dev)
|
||||
|
||||
@ -322,7 +322,7 @@ static int _set_state(at86rf2xx_t *dev, netopt_state_t state)
|
||||
{
|
||||
switch (state) {
|
||||
case NETOPT_STATE_SLEEP:
|
||||
at86rf2xx_set_state(dev, AT86RF2XX_STATE_TRX_OFF);
|
||||
at86rf2xx_set_state(dev, AT86RF2XX_STATE_SLEEP);
|
||||
break;
|
||||
case NETOPT_STATE_IDLE:
|
||||
at86rf2xx_set_state(dev, AT86RF2XX_STATE_RX_AACK_ON);
|
||||
@ -359,11 +359,13 @@ netopt_state_t _get_state(at86rf2xx_t *dev)
|
||||
|
||||
static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len)
|
||||
{
|
||||
at86rf2xx_t *dev = (at86rf2xx_t *) device;
|
||||
|
||||
if (device == NULL) {
|
||||
return -ENODEV;
|
||||
}
|
||||
at86rf2xx_t *dev = (at86rf2xx_t *) device;
|
||||
|
||||
/* getting these options doesn't require the transceiver to be responsive */
|
||||
switch (opt) {
|
||||
|
||||
case NETOPT_ADDRESS:
|
||||
@ -435,13 +437,6 @@ static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len)
|
||||
((uint8_t *)val)[0] = at86rf2xx_get_chan(dev);
|
||||
return sizeof(uint16_t);
|
||||
|
||||
case NETOPT_TX_POWER:
|
||||
if (max_len < sizeof(int16_t)) {
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
*((uint16_t *)val) = at86rf2xx_get_txpower(dev);
|
||||
return sizeof(uint16_t);
|
||||
|
||||
case NETOPT_MAX_PACKET_SIZE:
|
||||
if (max_len < sizeof(int16_t)) {
|
||||
return -EOVERFLOW;
|
||||
@ -454,7 +449,7 @@ static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len)
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
*((netopt_state_t*)val) = _get_state(dev);
|
||||
break;
|
||||
return sizeof(netopt_state_t);
|
||||
|
||||
case NETOPT_PRELOADING:
|
||||
if (dev->options & AT86RF2XX_OPT_PRELOADING) {
|
||||
@ -474,13 +469,6 @@ static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len)
|
||||
}
|
||||
return sizeof(netopt_enable_t);
|
||||
|
||||
case NETOPT_RETRANS:
|
||||
if (max_len < sizeof(uint8_t)) {
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
*((uint8_t *)val) = at86rf2xx_get_max_retries(dev);
|
||||
return sizeof(uint8_t);
|
||||
|
||||
case NETOPT_PROMISCUOUSMODE:
|
||||
if (dev->options & AT86RF2XX_OPT_PROMISCUOUS) {
|
||||
*((netopt_enable_t *)val) = NETOPT_ENABLE;
|
||||
@ -499,15 +487,6 @@ static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len)
|
||||
}
|
||||
return sizeof(netopt_enable_t);
|
||||
|
||||
case NETOPT_IS_CHANNEL_CLR:
|
||||
if (at86rf2xx_cca(dev)) {
|
||||
*((netopt_enable_t *)val) = NETOPT_ENABLE;
|
||||
}
|
||||
else {
|
||||
*((netopt_enable_t *)val) = NETOPT_DISABLE;
|
||||
}
|
||||
return sizeof(netopt_enable_t);
|
||||
|
||||
case NETOPT_RX_START_IRQ:
|
||||
*((netopt_enable_t *)val) =
|
||||
!!(dev->options & AT86RF2XX_OPT_TELL_RX_START);
|
||||
@ -533,161 +512,253 @@ static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len)
|
||||
!!(dev->options & AT86RF2XX_OPT_CSMA);
|
||||
return sizeof(netopt_enable_t);
|
||||
|
||||
case NETOPT_CSMA_RETRIES:
|
||||
if (max_len < sizeof(uint8_t)) {
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
*((uint8_t *)val) = at86rf2xx_get_csma_max_retries(dev);
|
||||
return sizeof(uint8_t);
|
||||
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
/* Can still be handled in second switch */
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
uint8_t old_state = at86rf2xx_get_status(dev);
|
||||
int res = 0;
|
||||
|
||||
/* temporarily wake up if sleeping */
|
||||
if(old_state == AT86RF2XX_STATE_SLEEP) {
|
||||
at86rf2xx_assert_awake(dev);
|
||||
}
|
||||
|
||||
/* these options require the transceiver to be not sleeping*/
|
||||
switch (opt) {
|
||||
case NETOPT_TX_POWER:
|
||||
if (max_len < sizeof(int16_t)) {
|
||||
res = -EOVERFLOW;
|
||||
} else {
|
||||
*((uint16_t *)val) = at86rf2xx_get_txpower(dev);
|
||||
res = sizeof(uint16_t);
|
||||
}
|
||||
break;
|
||||
|
||||
case NETOPT_RETRANS:
|
||||
if (max_len < sizeof(uint8_t)) {
|
||||
res = -EOVERFLOW;
|
||||
} else {
|
||||
*((uint8_t *)val) = at86rf2xx_get_max_retries(dev);
|
||||
res = sizeof(uint8_t);
|
||||
}
|
||||
break;
|
||||
|
||||
case NETOPT_IS_CHANNEL_CLR:
|
||||
if (at86rf2xx_cca(dev)) {
|
||||
*((netopt_enable_t *)val) = NETOPT_ENABLE;
|
||||
}
|
||||
else {
|
||||
*((netopt_enable_t *)val) = NETOPT_DISABLE;
|
||||
}
|
||||
res = sizeof(netopt_enable_t);
|
||||
break;
|
||||
|
||||
case NETOPT_CSMA_RETRIES:
|
||||
if (max_len < sizeof(uint8_t)) {
|
||||
res = -EOVERFLOW;
|
||||
} else {
|
||||
*((uint8_t *)val) = at86rf2xx_get_csma_max_retries(dev);
|
||||
res = sizeof(uint8_t);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
res = -ENOTSUP;
|
||||
}
|
||||
|
||||
/* go back to sleep if were sleeping */
|
||||
if(old_state == AT86RF2XX_STATE_SLEEP) {
|
||||
at86rf2xx_set_state(dev, AT86RF2XX_STATE_SLEEP);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len)
|
||||
{
|
||||
at86rf2xx_t *dev = (at86rf2xx_t *) device;
|
||||
uint8_t old_state = at86rf2xx_get_status(dev);
|
||||
int res = 0;
|
||||
|
||||
if (dev == NULL) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* temporarily wake up if sleeping */
|
||||
if(old_state == AT86RF2XX_STATE_SLEEP) {
|
||||
at86rf2xx_assert_awake(dev);
|
||||
}
|
||||
|
||||
switch (opt) {
|
||||
case NETOPT_ADDRESS:
|
||||
if (len > sizeof(uint16_t)) {
|
||||
return -EOVERFLOW;
|
||||
res = -EOVERFLOW;
|
||||
} else {
|
||||
at86rf2xx_set_addr_short(dev, *((uint16_t*)val));
|
||||
res = sizeof(uint16_t);
|
||||
}
|
||||
at86rf2xx_set_addr_short(dev, *((uint16_t*)val));
|
||||
return sizeof(uint16_t);
|
||||
break;
|
||||
|
||||
case NETOPT_ADDRESS_LONG:
|
||||
if (len > sizeof(uint64_t)) {
|
||||
return -EOVERFLOW;
|
||||
res = -EOVERFLOW;
|
||||
} else {
|
||||
at86rf2xx_set_addr_long(dev, *((uint64_t*)val));
|
||||
res = sizeof(uint64_t);
|
||||
}
|
||||
at86rf2xx_set_addr_long(dev, *((uint64_t*)val));
|
||||
return sizeof(uint64_t);
|
||||
break;
|
||||
|
||||
case NETOPT_SRC_LEN:
|
||||
if (len > sizeof(uint16_t)) {
|
||||
return -EOVERFLOW;
|
||||
res = -EOVERFLOW;
|
||||
} else {
|
||||
if (*((uint16_t *)val) == 2) {
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_SRC_ADDR_LONG,
|
||||
false);
|
||||
}
|
||||
else if (*((uint16_t *)val) == 8) {
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_SRC_ADDR_LONG,
|
||||
true);
|
||||
}
|
||||
else {
|
||||
res = -ENOTSUP;
|
||||
break;
|
||||
}
|
||||
res = sizeof(uint16_t);
|
||||
}
|
||||
if (*((uint16_t *)val) == 2) {
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_SRC_ADDR_LONG,
|
||||
false);
|
||||
}
|
||||
else if (*((uint16_t *)val) == 8) {
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_SRC_ADDR_LONG,
|
||||
true);
|
||||
}
|
||||
else {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
return sizeof(uint16_t);
|
||||
break;
|
||||
|
||||
case NETOPT_NID:
|
||||
if (len > sizeof(uint16_t)) {
|
||||
return -EOVERFLOW;
|
||||
res = -EOVERFLOW;
|
||||
} else {
|
||||
at86rf2xx_set_pan(dev, *((uint16_t *)val));
|
||||
res = sizeof(uint16_t);
|
||||
}
|
||||
at86rf2xx_set_pan(dev, *((uint16_t *)val));
|
||||
return sizeof(uint16_t);
|
||||
break;
|
||||
|
||||
case NETOPT_CHANNEL:
|
||||
if (len != sizeof(uint16_t)) {
|
||||
return -EINVAL;
|
||||
res = -EINVAL;
|
||||
} else {
|
||||
uint8_t chan = ((uint8_t *)val)[0];
|
||||
if (chan < AT86RF2XX_MIN_CHANNEL ||
|
||||
chan > AT86RF2XX_MAX_CHANNEL) {
|
||||
res = -ENOTSUP;
|
||||
break;
|
||||
}
|
||||
at86rf2xx_set_chan(dev, chan);
|
||||
res = sizeof(uint16_t);
|
||||
}
|
||||
uint8_t chan = ((uint8_t *)val)[0];
|
||||
if (chan < AT86RF2XX_MIN_CHANNEL ||
|
||||
chan > AT86RF2XX_MAX_CHANNEL) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
at86rf2xx_set_chan(dev, chan);
|
||||
return sizeof(uint16_t);
|
||||
break;
|
||||
|
||||
case NETOPT_TX_POWER:
|
||||
if (len > sizeof(int16_t)) {
|
||||
return -EOVERFLOW;
|
||||
res = -EOVERFLOW;
|
||||
} else {
|
||||
at86rf2xx_set_txpower(dev, *((int16_t *)val));
|
||||
res = sizeof(uint16_t);
|
||||
}
|
||||
at86rf2xx_set_txpower(dev, *((int16_t *)val));
|
||||
return sizeof(uint16_t);
|
||||
break;
|
||||
|
||||
case NETOPT_STATE:
|
||||
if (len > sizeof(netopt_state_t)) {
|
||||
return -EOVERFLOW;
|
||||
res = -EOVERFLOW;
|
||||
} else {
|
||||
res = _set_state(dev, *((netopt_state_t *)val));
|
||||
}
|
||||
return _set_state(dev, *((netopt_state_t *)val));
|
||||
break;
|
||||
|
||||
case NETOPT_AUTOACK:
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_AUTOACK,
|
||||
((bool *)val)[0]);
|
||||
return sizeof(netopt_enable_t);
|
||||
res = sizeof(netopt_enable_t);
|
||||
break;
|
||||
|
||||
case NETOPT_RETRANS:
|
||||
if (len > sizeof(uint8_t)) {
|
||||
return -EOVERFLOW;
|
||||
res = -EOVERFLOW;
|
||||
} else {
|
||||
at86rf2xx_set_max_retries(dev, *((uint8_t *)val));
|
||||
res = sizeof(uint8_t);
|
||||
}
|
||||
at86rf2xx_set_max_retries(dev, *((uint8_t *)val));
|
||||
return sizeof(uint8_t);
|
||||
break;
|
||||
|
||||
case NETOPT_PRELOADING:
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_PRELOADING,
|
||||
((bool *)val)[0]);
|
||||
return sizeof(netopt_enable_t);
|
||||
res = sizeof(netopt_enable_t);
|
||||
break;
|
||||
|
||||
case NETOPT_PROMISCUOUSMODE:
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_PROMISCUOUS,
|
||||
((bool *)val)[0]);
|
||||
return sizeof(netopt_enable_t);
|
||||
res = sizeof(netopt_enable_t);
|
||||
break;
|
||||
|
||||
case NETOPT_RAWMODE:
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_RAWDUMP,
|
||||
((bool *)val)[0]);
|
||||
return sizeof(netopt_enable_t);
|
||||
res = sizeof(netopt_enable_t);
|
||||
break;
|
||||
|
||||
case NETOPT_RX_START_IRQ:
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_TELL_RX_START,
|
||||
((bool *)val)[0]);
|
||||
return sizeof(netopt_enable_t);
|
||||
res = sizeof(netopt_enable_t);
|
||||
break;
|
||||
|
||||
case NETOPT_RX_END_IRQ:
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_TELL_RX_END,
|
||||
((bool *)val)[0]);
|
||||
return sizeof(netopt_enable_t);
|
||||
res = sizeof(netopt_enable_t);
|
||||
break;
|
||||
|
||||
case NETOPT_TX_START_IRQ:
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_TELL_TX_START,
|
||||
((bool *)val)[0]);
|
||||
return sizeof(netopt_enable_t);
|
||||
res = sizeof(netopt_enable_t);
|
||||
break;
|
||||
|
||||
case NETOPT_TX_END_IRQ:
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_TELL_TX_END,
|
||||
((bool *)val)[0]);
|
||||
return sizeof(netopt_enable_t);
|
||||
res = sizeof(netopt_enable_t);
|
||||
break;
|
||||
|
||||
case NETOPT_CSMA:
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_CSMA,
|
||||
((bool *)val)[0]);
|
||||
return sizeof(netopt_enable_t);
|
||||
res = sizeof(netopt_enable_t);
|
||||
break;
|
||||
|
||||
case NETOPT_CSMA_RETRIES:
|
||||
if( (len > sizeof(uint8_t)) ||
|
||||
(*((uint8_t *)val) > 5) ) {
|
||||
return -EOVERFLOW;
|
||||
res = -EOVERFLOW;
|
||||
} else if( !(dev->options & AT86RF2XX_OPT_CSMA) ) {
|
||||
/* If CSMA is disabled, don't allow setting retries */
|
||||
res = -ENOTSUP;
|
||||
} else {
|
||||
at86rf2xx_set_csma_max_retries(dev, *((uint8_t *)val));
|
||||
res = sizeof(uint8_t);
|
||||
}
|
||||
/* If CSMA is disabled, don't allow setting retries */
|
||||
if( !(dev->options & AT86RF2XX_OPT_CSMA) ) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
at86rf2xx_set_csma_max_retries(dev, *((uint8_t *)val));
|
||||
return sizeof(uint8_t);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
res = -ENOTSUP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* go back to sleep if were sleeping and state hasn't been changed */
|
||||
if( (old_state == AT86RF2XX_STATE_SLEEP) &&
|
||||
(opt != NETOPT_STATE) ) {
|
||||
at86rf2xx_set_state(dev, AT86RF2XX_STATE_SLEEP);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _add_event_cb(gnrc_netdev_t *dev, gnrc_netdev_event_cb_t cb)
|
||||
@ -723,10 +794,16 @@ static void _isr_event(gnrc_netdev_t *device, uint32_t event_type)
|
||||
uint8_t state;
|
||||
uint8_t trac_status;
|
||||
|
||||
/* If transceiver is sleeping register access is impossible and frames are
|
||||
* lost anyway, so return immediately.
|
||||
*/
|
||||
state = at86rf2xx_get_status(dev);
|
||||
if(state == AT86RF2XX_STATE_SLEEP)
|
||||
return;
|
||||
|
||||
/* read (consume) device status */
|
||||
irq_mask = at86rf2xx_reg_read(dev, AT86RF2XX_REG__IRQ_STATUS);
|
||||
|
||||
state = at86rf2xx_get_status(dev);
|
||||
trac_status = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_STATE) &
|
||||
AT86RF2XX_TRX_STATE_MASK__TRAC;
|
||||
|
||||
|
||||
@ -31,6 +31,23 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Transition time from SLEEP to TRX_OFF in us, refer figure 7-4, p.42.
|
||||
* For different environments refer figure 13-13, p.201
|
||||
*/
|
||||
#define AT86RF2XX_WAKEUP_DELAY (300U)
|
||||
|
||||
/**
|
||||
* @brief Minimum reset pulse width, refer p.190
|
||||
*/
|
||||
#define AT86RF2XX_RESET_PULSE_WIDTH (1U)
|
||||
|
||||
/**
|
||||
* @brief Transition time to TRX_OFF after reset pulse in us, refer
|
||||
* figure 7-8, p. 44.
|
||||
*/
|
||||
#define AT86RF2XX_RESET_DELAY (26U)
|
||||
|
||||
/**
|
||||
* @brief Read from a register at address `addr` from device `dev`.
|
||||
*
|
||||
@ -106,6 +123,21 @@ void at86rf2xx_force_trx_off(const at86rf2xx_t *dev);
|
||||
*/
|
||||
uint8_t at86rf2xx_get_status(const at86rf2xx_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Make sure that device is not sleeping
|
||||
*
|
||||
* @param[in] dev device to eventually wake up
|
||||
*/
|
||||
void at86rf2xx_assert_awake(at86rf2xx_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Trigger a hardware reset
|
||||
*
|
||||
* @param[in] dev device to reset
|
||||
*/
|
||||
void at86rf2xx_hardware_reset(at86rf2xx_t *dev);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user