This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit fe32cd0f649ec510a392e4b0d45489b5466fcca2 Author: raiden00pl <[email protected]> AuthorDate: Fri Oct 16 11:11:05 2026 +0200 arch/arm/nrf52: fix energy detection EDCNT is the number of 8-symbol ED iterations minus one (the Nordic nrf_802154 driver writes the iteration count minus one), but the driver wrote the requested number of symbols into it, so every ED measurement lasted 8 times longer than requested: an ED scan of 2 channels took 32.2 s instead of 5.2 s. ED is started by the READY event, but TASKS_RXEN has no effect while the radio is already receiving, so an ED scan on a node with RX enabled never completed and blocked the MAC. Disable the radio first and restore RX when the scan is finished. Assisted-by: Claude Code Signed-off-by: raiden00pl <[email protected]> --- arch/arm/src/nrf52/nrf52_ieee802154_radio.c | 40 ++++++++++++++++++++++++++++- arch/arm/src/nrf52/nrf52_ieee802154_radio.h | 1 + 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/arch/arm/src/nrf52/nrf52_ieee802154_radio.c b/arch/arm/src/nrf52/nrf52_ieee802154_radio.c index ca46bf9f29e..3028efe9faf 100644 --- a/arch/arm/src/nrf52/nrf52_ieee802154_radio.c +++ b/arch/arm/src/nrf52/nrf52_ieee802154_radio.c @@ -51,6 +51,10 @@ #define NRF52_ED_RSSISCALE (4) +/* One ED iteration lasts 8 symbols (128 us) */ + +#define NRF52_ED_ITER_SYMBOLS (8) + /* ED configuration: * - IRQ on EDEND event (sampling of energy detection complete) * - shortcut between READY and EDSTART @@ -725,10 +729,35 @@ static int nrf52_radioi8_energydetect(struct nrf52_radioi8_dev_s *dev, uint32_t nsymbols) { struct nrf52_radio_dev_s *lower = NULL; + uint32_t edcnt = 0; DEBUGASSERT(dev); lower = dev->radio->lower; + /* ED lasts (EDCNT + 1) iterations */ + + edcnt = nsymbols / NRF52_ED_ITER_SYMBOLS; + if (edcnt > 0) + { + edcnt -= 1; + } + + if (edcnt > RADIO_EDCNT_MASK) + { + edcnt = RADIO_EDCNT_MASK; + } + + /* ED starts on the READY event, RXEN has no effect if RX is active */ + + if (dev->radio->state.rxenabled) + { + dev->radio->state.edrestore = true; + dev->radio->ops->rxenable(dev, false); + } + + while (NRF52_RADIO_GETREG(lower, NRF52_RADIO_STATE_OFFSET) != + RADIO_STATE_DISABLED); + /* Clear events */ NRF52_RADIO_PUTREG(lower, NRF52_RADIO_EVENTS_EDEND_OFFSET, 0); @@ -742,7 +771,7 @@ static int nrf52_radioi8_energydetect(struct nrf52_radioi8_dev_s *dev, /* Configure ED symbols */ - NRF52_RADIO_PUTREG(lower, NRF52_RADIO_EDCNT_OFFSET, nsymbols); + NRF52_RADIO_PUTREG(lower, NRF52_RADIO_EDCNT_OFFSET, edcnt); /* Set state to ENERGY_DETECT (ED) */ @@ -1616,6 +1645,15 @@ static void nrf52_radioi8_work_ed(void *arg) /* Callback the receiver in the next highest layer */ dev->radiocb->edresult(dev->radiocb, ed); + + /* Restore RX if it was enabled and no next ED was started */ + + if (dev->radio->state.edrestore && + dev->radio->state.state != NRF52_RADIO_STATE_ED) + { + dev->radio->state.edrestore = false; + dev->radio->ops->rxenable(dev, true); + } } /**************************************************************************** diff --git a/arch/arm/src/nrf52/nrf52_ieee802154_radio.h b/arch/arm/src/nrf52/nrf52_ieee802154_radio.h index 7bb45774258..c64525300f0 100644 --- a/arch/arm/src/nrf52/nrf52_ieee802154_radio.h +++ b/arch/arm/src/nrf52/nrf52_ieee802154_radio.h @@ -88,6 +88,7 @@ struct nrf52_radioi8_radio_data_s bool rxenabled; /* RX enabled now */ bool rxrestore; /* RX needs to be restored */ + bool edrestore; /* RX needs to be restored after ED */ bool rxlong; /* Last RX frame was long */ /* TX state */
