From 611f4161d6ee78e9de1d0207dd3b78a9df721bce Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sun, 29 Mar 2020 19:44:40 +0200 Subject: [PATCH] drivers/at86rf215: fix reset after deep sleep When the radio is in DEEP SLEEP, reading the state register will return 0. This makes the reset routine abort early even though the device is connected and still waking up. Instead, just add a timeout to the polling of the WAKEUP IRQ bit. In practise it has shown that the loop will be taken two times on 'normal' reset and four times when the radio was in DEEP SLEEP. Polling 255 times sure does not hurt. To reproduce the issue, put both interfaces into SLEEP mode, then reboot the module: ifconfig 7 set state sleep ifconfig 8 set state sleep reboot --- drivers/at86rf215/at86rf215_internal.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/at86rf215/at86rf215_internal.c b/drivers/at86rf215/at86rf215_internal.c index f396cdebea..01b04c9e2f 100644 --- a/drivers/at86rf215/at86rf215_internal.c +++ b/drivers/at86rf215/at86rf215_internal.c @@ -53,22 +53,22 @@ int at86rf215_hardware_reset(at86rf215_t *dev) gpio_set(dev->params.reset_pin); xtimer_usleep(AT86RF215_RESET_DELAY_US); - uint8_t state = _get_reg_with_lock(dev, dev->RF->RG_STATE) & STATE_STATE_MASK; - if (state != RF_STATE_TRXOFF && state != RF_STATE_RESET) { - spi_release(SPIDEV); - return -ENODEV; - } - /* While the device is in RESET / DEEP SLEEP, all registers but STATE will read 0xFF. WAKEUP IRQ signals that the device is ready. */ - state = 0; - while (state == 0xFF || !(state & IRQS_WAKEUP_MASK)) { + uint8_t state = 0; + uint8_t tries = 255; + while (--tries && (state == 0xFF || !(state & IRQS_WAKEUP_MASK))) { state = _get_reg_with_lock(dev, dev->RF->RG_IRQS); } spi_release(SPIDEV); + /* no device connected */ + if (!tries) { + return -ENODEV; + } + /* clear interrupts */ at86rf215_reg_read(dev, RG_RF09_IRQS); at86rf215_reg_read(dev, RG_RF24_IRQS);