This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 6fb7d2e7fa947d29260d3357c06877d15ad55e9f
Author: raiden00pl <[email protected]>
AuthorDate: Thu Oct 22 16:24:46 2026 +0200

    arch/arm/nrf52,nrf53: implement the slotted CSMA-CA
    
    A beacon-enabled PAN asserted on the first CSMA-CA transmission.  Count
    the backoff periods down on the boundaries of the CAP, run the CCAs and
    the TX on a boundary, pause at the end of the CAP and continue in the
    next one, and transmit only when the CCAs, the frame, its ACK and the IFS
    fit before the end of the CAP (IEEE 802.15.4-2003 7.5.1.1.1, 7.5.1.3).
    A frame paused for the next CAP starts again un-slotted when the PAN
    leaves the beacon-enabled mode.
    
    Assisted-by: Claude Code
    Signed-off-by: raiden00pl <[email protected]>
---
 arch/arm/src/nrf52/nrf52_ieee802154.c       |  35 ++-
 arch/arm/src/nrf52/nrf52_ieee802154_radio.c | 359 +++++++++++++++++++++-------
 arch/arm/src/nrf52/nrf52_ieee802154_radio.h |  13 +-
 arch/arm/src/nrf52/nrf52_ieee802154_trace.c |   1 +
 arch/arm/src/nrf52/nrf52_ieee802154_trace.h |   1 +
 arch/arm/src/nrf53/nrf53_ieee802154.c       |  35 ++-
 arch/arm/src/nrf53/nrf53_ieee802154_radio.c | 359 +++++++++++++++++++++-------
 arch/arm/src/nrf53/nrf53_ieee802154_radio.h |  13 +-
 arch/arm/src/nrf53/nrf53_ieee802154_trace.c |   1 +
 arch/arm/src/nrf53/nrf53_ieee802154_trace.h |   1 +
 10 files changed, 622 insertions(+), 196 deletions(-)

diff --git a/arch/arm/src/nrf52/nrf52_ieee802154.c 
b/arch/arm/src/nrf52/nrf52_ieee802154.c
index 3089c5046b0..6930c4b70e0 100644
--- a/arch/arm/src/nrf52/nrf52_ieee802154.c
+++ b/arch/arm/src/nrf52/nrf52_ieee802154.c
@@ -751,6 +751,11 @@ nrf52_radioi8_beaconstart(struct ieee802154_radio_s *radio,
                                         beacon->bf_len);
           dev->radio->state.bsn = rand();
 
+          /* Slotted CSMA-CA in the CAP */
+
+          dev->radio->state.slotted = true;
+          dev->radio->state.ble     = sfspec->ble;
+
           /* The PAN coordinator defines the superframe */
 
           dev->radio->state.sftrack = false;
@@ -809,6 +814,31 @@ nrf52_radioi8_beaconupdate(struct ieee802154_radio_s 
*radio,
 #endif
 }
 
+#ifdef CONFIG_NRF52_RADIO_IEEE802154_SUPERFRAME
+/****************************************************************************
+ * Name: nrf52_radioi8_unslotted
+ *
+ * Description:
+ *   Switch to un-slotted CSMA-CA, a transaction paused for the next CAP
+ *   starts again un-slotted.  Must be called with the radio locked.
+ *
+ ****************************************************************************/
+
+static void nrf52_radioi8_unslotted(struct nrf52_radioi8_dev_s *dev)
+{
+  dev->radio->state.slotted = false;
+  dev->radio->state.sftrack = false;
+
+  if (dev->radio->state.csma_paused)
+    {
+      dev->radio->state.csma_paused = false;
+      dev->radio->state.csma_busy   = false;
+      dev->state.csma_pending       = true;
+      dev->radio->ops->txnext(dev, 0);
+    }
+}
+#endif
+
 /****************************************************************************
  * Name: nrf52_radioi8_beaconstop
  *
@@ -828,6 +858,7 @@ static int nrf52_radioi8_beaconstop(struct 
ieee802154_radio_s *radio)
   /* Stop RTC */
 
   dev->rtc->ops->stop(dev);
+  nrf52_radioi8_unslotted(dev);
 
   leave_critical_section(flags);
 
@@ -873,6 +904,7 @@ nrf52_radioi8_sfupdate(struct ieee802154_radio_s *radio,
           /* Need slotted CSMA-CA */
 
           dev->radio->state.slotted = true;
+          dev->radio->state.ble     = sfspec->ble;
 
           /* Sync with the beacons */
 
@@ -884,8 +916,7 @@ nrf52_radioi8_sfupdate(struct ieee802154_radio_s *radio,
       /* Need un-slotted CSMA-CA */
 
       dev->rtc->ops->stop(dev);
-      dev->radio->state.slotted = false;
-      dev->radio->state.sftrack = false;
+      nrf52_radioi8_unslotted(dev);
     }
 
   leave_critical_section(flags);
diff --git a/arch/arm/src/nrf52/nrf52_ieee802154_radio.c 
b/arch/arm/src/nrf52/nrf52_ieee802154_radio.c
index a2c88dbb6f9..14eb9929760 100644
--- a/arch/arm/src/nrf52/nrf52_ieee802154_radio.c
+++ b/arch/arm/src/nrf52/nrf52_ieee802154_radio.c
@@ -160,6 +160,18 @@
 #define IEEE802154_ACKTX_INT            (RADIO_INT_PHYEND)
 #define IEEE802154_ACKTX_SHORTS         (RADIO_SHORTS_PHYEND_DISABLE)
 
+/* aUnitBackoffPeriod in us */
+
+#define NRF52_BACKOFF_US                (IEEE802154_UNIT_BACKOFF_PERIOD * \
+                                         IEEE802154_SYMBOL_US)
+
+/* Time to set up a slotted CSMA-CA step before its boundary: the ramp-up
+ * and two timer ticks
+ */
+
+#define NRF52_SLOTTED_GUARD_US          (NRF52_RADIOI8_RAMPUP_US + \
+                                         2 * IEEE802154_SYMBOL_US)
+
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
@@ -195,6 +207,12 @@ static void nrf52_radioi8_norm_setup(struct 
nrf52_radioi8_dev_s *dev,
                                      struct iob_s *frame, bool csma);
 static void nrf52_radioi8_norm_trigger(struct nrf52_radioi8_dev_s *dev);
 #ifdef CONFIG_NRF52_RADIO_IEEE802154_SUPERFRAME
+static void nrf52_radioi8_slotted_at(struct nrf52_radioi8_dev_s *dev,
+                                     uint8_t chan);
+static void nrf52_radioi8_slotted_pause(struct nrf52_radioi8_dev_s *dev);
+static void nrf52_radioi8_slotted_backoff(struct nrf52_radioi8_dev_s *dev,
+                                          uint32_t guard);
+static void nrf52_radioi8_slotted_resume(struct nrf52_radioi8_dev_s *dev);
 static void nrf52_radioi8_beacon_setup(struct nrf52_radioi8_dev_s *dev,
                                        uint8_t *data, uint8_t len);
 static void nrf52_radioi8_beacon_tx(struct nrf52_radioi8_dev_s *dev);
@@ -703,6 +721,16 @@ static void nrf52_radioi8_ccastart(struct 
nrf52_radioi8_dev_s *dev)
   DEBUGASSERT(dev);
   lower = dev->radio->lower;
 
+#ifdef CONFIG_NRF52_RADIO_IEEE802154_SUPERFRAME
+  /* Slotted CCA starts with the RXREADY-CCASTART short */
+
+  if (dev->radio->state.slotted)
+    {
+      NRF52_RADIO_PUTREG(lower, NRF52_RADIO_TASKS_RXEN_OFFSET, 1);
+      return;
+    }
+#endif
+
   NRF52_RADIO_PUTREG(lower, NRF52_RADIO_TASKS_CCASTART_OFFSET, 1);
 }
 
@@ -1067,6 +1095,177 @@ static void nrf52_radioi8_norm_setup(struct 
nrf52_radioi8_dev_s *dev,
   nrf52_radioi8_norm_setup_buf(dev, dev->radio->txbuf, csma);
 }
 
+#ifdef CONFIG_NRF52_RADIO_IEEE802154_SUPERFRAME
+/****************************************************************************
+ * Name: nrf52_radioi8_slotted_at
+ *
+ * Description:
+ *   Run the next slotted CSMA-CA step on its backoff period boundary, the
+ *   radio ramps up before it.
+ *
+ ****************************************************************************/
+
+static void nrf52_radioi8_slotted_at(struct nrf52_radioi8_dev_s *dev,
+                                     uint8_t chan)
+{
+  uint32_t elapsed = 0;
+  uint32_t at;
+
+  at = dev->radio->state.boundary * NRF52_BACKOFF_US -
+       NRF52_RADIOI8_RAMPUP_US;
+
+  dev->rtc->ops->elapsed(dev, &elapsed);
+
+  dev->tim->ops->setup(dev, chan, at > elapsed ?
+                       (at - elapsed) / IEEE802154_SYMBOL_US : 0);
+}
+
+/****************************************************************************
+ * Name: nrf52_radioi8_slotted_pause
+ *
+ * Description:
+ *   Wait for the next CAP, receive in the meantime.
+ *
+ ****************************************************************************/
+
+static void nrf52_radioi8_slotted_pause(struct nrf52_radioi8_dev_s *dev)
+{
+  struct nrf52_radio_dev_s *lower = dev->radio->lower;
+
+  nrf52_radioi8_trace_put(RADIO_TRACE_CSMAPAUSE,
+                          dev->radio->state.backoffs);
+
+  dev->radio->state.csma_paused = true;
+  dev->radio->state.waitack     = false;
+  dev->radio->state.state       = NRF52_RADIO_STATE_DISABLED;
+
+  NRF52_RADIO_INTCLR(lower, 0xffffffff);
+  NRF52_RADIO_SHRTSET(lower, 0);
+
+  if (dev->radio->state.rxrestore)
+    {
+      dev->radio->state.rxrestore = false;
+
+      while (NRF52_RADIO_GETREG(lower, NRF52_RADIO_STATE_OFFSET) !=
+             RADIO_STATE_DISABLED);
+
+      dev->macops.rxenable((struct ieee802154_radio_s *)dev, true);
+    }
+}
+
+/****************************************************************************
+ * Name: nrf52_radioi8_slotted_backoff
+ *
+ * Description:
+ *   Count down the backoff periods in the CAP and schedule the first CCA
+ *   (IEEE 802.15.4-2003 7.5.1.3).
+ *
+ ****************************************************************************/
+
+static void nrf52_radioi8_slotted_backoff(struct nrf52_radioi8_dev_s *dev,
+                                          uint32_t guard)
+{
+  struct nrf52_radioi8_radio_data_s *state   = &dev->radio->state;
+  struct nrf52_radioi8_rtc_s        *rtc     = dev->rtc;
+  uint32_t                           elapsed = 0;
+  uint32_t                           end;
+  uint32_t                           b;
+  uint32_t                           need;
+
+  /* Not synchronized or the CAP is over */
+
+  if (!rtc->ops->elapsed(dev, &elapsed) || elapsed >= rtc->cap)
+    {
+      nrf52_radioi8_slotted_pause(dev);
+      return;
+    }
+
+  /* The first boundary after the beacon IFS that can still be set up */
+
+  b = (MAX(elapsed + guard, rtc->capstart) + NRF52_BACKOFF_US - 1) /
+      NRF52_BACKOFF_US;
+
+  /* The last boundary of the countdown and of the TX start: the CAP end,
+   * with battery life extension the sixth full backoff period after the
+   * beacon IFS
+   */
+
+  end = rtc->cap / NRF52_BACKOFF_US;
+  if (state->ble)
+    {
+      end = MIN(end, (rtc->capstart + NRF52_BACKOFF_US - 1) /
+                     NRF52_BACKOFF_US + 5);
+    }
+
+  /* Pause the countdown at the end of the CAP */
+
+  if (b + state->backoffs > end)
+    {
+      if (end > b)
+        {
+          state->backoffs -= end - b;
+        }
+
+      nrf52_radioi8_slotted_pause(dev);
+      return;
+    }
+
+  b += state->backoffs;
+  state->backoffs = 0;
+
+  /* The CCAs, the frame, its ACK and the IFS must end before the end of
+   * the CAP (7.5.1.1.1), otherwise evaluate again in the next CAP
+   */
+
+  need = state->CW * NRF52_BACKOFF_US +
+         NRF52_RADIOI8_FRAME_US(dev->radio->txbuf[0]) +
+         NRF52_RADIOI8_IFS_US(dev->radio->txbuf[0]);
+  if (dev->radio->txbuf[1] & IEEE802154_FRAMECTRL_ACKREQ)
+    {
+      need += IEEE802154_ACK_WAIT * IEEE802154_SYMBOL_US;
+    }
+
+  if (b * NRF52_BACKOFF_US + need > rtc->cap || b + state->CW > end)
+    {
+      nrf52_radioi8_slotted_pause(dev);
+      return;
+    }
+
+  /* CCA on the boundary */
+
+  state->boundary = b;
+  nrf52_radioi8_slotted_at(dev, NRF52_TIMER_CHAN_CSMADELAY);
+}
+
+/****************************************************************************
+ * Name: nrf52_radioi8_slotted_resume
+ *
+ * Description:
+ *   Continue the slotted CSMA-CA paused for this CAP.  Must be called with
+ *   the radio locked.
+ *
+ ****************************************************************************/
+
+static void nrf52_radioi8_slotted_resume(struct nrf52_radioi8_dev_s *dev)
+{
+  uint32_t elapsed = 0;
+
+  /* Not in a CAP, stay paused */
+
+  if (!dev->rtc->ops->elapsed(dev, &elapsed) || elapsed >= dev->rtc->cap)
+    {
+      return;
+    }
+
+  dev->radio->state.csma_paused = false;
+
+  nrf52_radioi8_norm_setup_buf(dev, dev->radio->txbuf, true);
+  dev->radio->state.state = NRF52_RADIO_STATE_TX;
+
+  nrf52_radioi8_slotted_backoff(dev, NRF52_SLOTTED_GUARD_US);
+}
+#endif
+
 /****************************************************************************
  * Name: nrf52_radioi8_trg_csma
  *
@@ -1090,33 +1289,29 @@ static void nrf52_radioi8_trg_csma(struct 
nrf52_radioi8_dev_s *dev)
 #ifdef CONFIG_NRF52_RADIO_IEEE802154_SUPERFRAME
       if (!dev->radio->state.csma_busy)
         {
-          /* Initial backoff state */
+          /* Initial backoff state, battery life extension limits BE
+           * (IEEE 802.15.4-2003 7.5.1.3)
+           */
 
           dev->radio->state.NB = 0;
-          dev->radio->state.CW = IEEE802154_CW0;
+          dev->radio->state.BE = dev->radio->state.ble ?
+                                 MIN(2, dev->radio->state.min_be) :
+                                 dev->radio->state.min_be;
         }
 
-      /* Battery life extension */
+      /* CW is reset for each attempt */
 
-      if (dev->radio->state.ble)
-        {
-          dev->radio->state.BE = MIN(2, dev->radio->state.min_be);
-        }
-      else
-        {
-          dev->radio->state.BE = dev->radio->state.min_be;
-        }
+      dev->radio->state.CW       = IEEE802154_CW0;
+      dev->radio->state.backoffs = rand() % (1 << dev->radio->state.BE);
 
-      /* Get random unit backoff period delay */
+      /* CSMA is in use */
 
-      delay = rand() % (1 << dev->radio->state.BE);
-
-      /* TODO:
-       *  - locate backoff period boundary
-       *  - perform CCA on backoff period boundary
-       */
+      dev->radio->state.csma_busy = true;
+      nrf52_radioi8_trace_put(RADIO_TRACE_CSMATRIGGER,
+                              dev->radio->state.backoffs);
 
-      ASSERT(0);
+      nrf52_radioi8_slotted_backoff(dev, NRF52_SLOTTED_GUARD_US);
+      return;
 #else
       ASSERT(0);
 #endif
@@ -1394,10 +1589,13 @@ static void nrf52_radioi8_txnext(struct 
nrf52_radioi8_dev_s *dev,
 
   flags = enter_critical_section();
 
-  /* A frame on the air, an ACK TX or an energy detection owns the radio */
+  /* A frame on the air, an ACK TX, an energy detection or a timed step
+   * owns the radio
+   */
 
-  if (dev->radio->state.state != NRF52_RADIO_STATE_DISABLED &&
-      dev->radio->state.state != NRF52_RADIO_STATE_RX)
+  if ((dev->radio->state.state != NRF52_RADIO_STATE_DISABLED &&
+       dev->radio->state.state != NRF52_RADIO_STATE_RX) ||
+      dev->tim->tim_pending)
     {
       leave_critical_section(flags);
       return;
@@ -1429,10 +1627,10 @@ static void nrf52_radioi8_txnext(struct 
nrf52_radioi8_dev_s *dev,
 #endif
 
   /* An armed frame or a CSMA transaction between its backoffs owns the
-   * radio.
+   * radio, a slotted one paused for the next CAP does not.
    */
 
-  if (dev->radio->state.csma_busy ||
+  if ((dev->radio->state.csma_busy && !dev->radio->state.csma_paused) ||
       (dev->state.txdelayed_busy && !dev->state.txdelayed_pending))
     {
       leave_critical_section(flags);
@@ -1467,6 +1665,15 @@ static void nrf52_radioi8_txnext(struct 
nrf52_radioi8_dev_s *dev,
       nrf52_radioi8_norm_trigger(dev);
     }
 
+#ifdef CONFIG_NRF52_RADIO_IEEE802154_SUPERFRAME
+  /* Then the slotted CSMA TX paused for this CAP */
+
+  else if (dev->radio->state.csma_paused)
+    {
+      nrf52_radioi8_slotted_resume(dev);
+    }
+#endif
+
   /* Nothing to send, restore RX */
 
   else if (dev->radio->state.rxrestore)
@@ -1947,6 +2154,10 @@ static void nrf52_radioi8_state_rx(struct 
nrf52_radioi8_dev_s *dev)
       nrf52_radioi8_coordbeacon(dev))
     {
       dev->rtc->ops->sync(dev, rxbuf[0]);
+
+      /* The CAP starts, continue the TX that waited for it */
+
+      nrf52_radioi8_txnext(dev, 0);
     }
 #endif
 
@@ -2064,80 +2275,36 @@ static void nrf52_radioi8_state_tx(struct 
nrf52_radioi8_dev_s *dev)
 
       NRF52_RADIO_PUTREG(lower, NRF52_RADIO_EVENTS_CCABUSY_OFFSET, 0);
 
-      /* Slotted CSMA-CA */
+      /* Update backoff */
 
-      if (dev->radio->state.slotted == true)
-        {
-#ifdef CONFIG_NRF52_RADIO_IEEE802154_SUPERFRAME
-          dev->radio->state.NB += 1;
-          dev->radio->state.CW = IEEE802154_CW0;
-          dev->radio->state.BE = MIN(2, dev->radio->state.min_be);
-
-          if (dev->radio->state.NB > dev->radio->state.max_csma_backoffs)
-            {
-              /* Return failure to MAC, no frame was sent */
+      dev->radio->state.NB += 1;
+      dev->radio->state.BE = MIN(dev->radio->state.BE + 1,
+                                 dev->radio->state.max_be);
 
-              dev->radio->state.waitack = false;
+      if (dev->radio->state.NB > dev->radio->state.max_csma_backoffs)
+        {
+          /* Return failure to MAC, no frame was sent */
 
-              if (work_available(&dev->radio->irqwork))
-                {
-                  work_queue(HPWORK, &dev->radio->irqwork,
-                             nrf52_radioi8_work_busy, (void *)dev, 0);
-                }
+          dev->radio->state.waitack = false;
 
-              goto out;
-            }
-          else
+          if (work_available(&dev->radio->irqwork))
             {
-              /* Try again, shorts and interrupts were reset in ISR */
-
-              nrf52_radioi8_norm_setup_buf(dev, dev->radio->txbuf, true);
-              nrf52_radioi8_norm_trigger(dev);
-
-              /* Do not restore RX */
-
-              return;
+              work_queue(HPWORK, &dev->radio->irqwork,
+                         nrf52_radioi8_work_busy, (void *)dev, 0);
             }
-#else
-          ASSERT(0);
-#endif
-        }
-
-      /* Un-slotted CSMA-CA */
 
+          goto out;
+        }
       else
         {
-          /* Update backoff */
-
-          dev->radio->state.NB += 1;
-          dev->radio->state.BE = MIN(dev->radio->state.BE + 1,
-                                     dev->radio->state.max_be);
-
-          if (dev->radio->state.NB > dev->radio->state.max_csma_backoffs)
-            {
-              /* Return failure to MAC, no frame was sent */
+          /* Try again, shorts and interrupts were reset in ISR */
 
-              dev->radio->state.waitack = false;
-
-              if (work_available(&dev->radio->irqwork))
-                {
-                  work_queue(HPWORK, &dev->radio->irqwork,
-                             nrf52_radioi8_work_busy, (void *)dev, 0);
-                }
-
-              goto out;
-            }
-          else
-            {
-              /* Try again, shorts and interrupts were reset in ISR */
-
-              nrf52_radioi8_norm_setup_buf(dev, dev->radio->txbuf, true);
-              nrf52_radioi8_norm_trigger(dev);
+          nrf52_radioi8_norm_setup_buf(dev, dev->radio->txbuf, true);
+          nrf52_radioi8_norm_trigger(dev);
 
-              /* Do not restore RX */
+          /* Do not restore RX */
 
-              return;
-            }
+          return;
         }
     }
 
@@ -2154,20 +2321,30 @@ static void nrf52_radioi8_state_tx(struct 
nrf52_radioi8_dev_s *dev)
       if (dev->radio->state.slotted == true)
         {
 #ifdef CONFIG_NRF52_RADIO_IEEE802154_SUPERFRAME
-          dev->radio->state.CW -= 1;
+          /* The next step starts on the next boundary */
+
+          dev->radio->state.CW       -= 1;
+          dev->radio->state.boundary += 1;
 
           if (dev->radio->state.CW == 0)
             {
-              /* Enable TX - short TXREADY-START is enabled */
+              /* Transmit, the ACK wait starts with the TX */
 
-              NRF52_RADIO_PUTREG(lower, NRF52_RADIO_TASKS_TXEN_OFFSET, 1);
+              nrf52_radioi8_norm_setup_buf(dev, dev->radio->txbuf, false);
+              nrf52_radioi8_slotted_at(dev, NRF52_TIMER_CHAN_TXDELAY);
             }
           else
             {
-              /* Do not restore RX */
+              /* Next CCA */
 
-              return;
+              nrf52_radioi8_norm_setup_buf(dev, dev->radio->txbuf, true);
+              dev->radio->state.state = NRF52_RADIO_STATE_TX;
+              nrf52_radioi8_slotted_at(dev, NRF52_TIMER_CHAN_CSMADELAY);
             }
+
+          /* Do not restore RX */
+
+          return;
 #else
           ASSERT(0);
 #endif
diff --git a/arch/arm/src/nrf52/nrf52_ieee802154_radio.h 
b/arch/arm/src/nrf52/nrf52_ieee802154_radio.h
index 359bfaf43f8..b1f9a1af9ff 100644
--- a/arch/arm/src/nrf52/nrf52_ieee802154_radio.h
+++ b/arch/arm/src/nrf52/nrf52_ieee802154_radio.h
@@ -114,7 +114,8 @@ struct nrf52_radioi8_radio_data_s
 
   bool     waitack;             /* TX needs ACK */
   bool     framepending;        /* Frame pending from the last TX ACK */
-  bool     csma_busy;           /* Un-slotted CSMA busy */
+  bool     csma_busy;           /* CSMA-CA transaction in progress */
+  bool     csma_paused;         /* Slotted CSMA-CA waits for the next CAP */
   bool     slotted;             /* Slotted CSMA-CA */
 
   /* Radio configuration */
@@ -127,10 +128,12 @@ struct nrf52_radioi8_radio_data_s
 #ifdef CONFIG_NRF52_RADIO_IEEE802154_SUPERFRAME
   /* Superframe data */
 
-  bool    sftrack;              /* Device tracks the beacons */
-  bool    ble;                  /* Batter life extension */
-  bool    beacon_pending;       /* A beacon waits for the radio */
-  uint8_t bsn;                  /* macBSN, the beacon sequence number */
+  bool     sftrack;             /* Device tracks the beacons */
+  bool     ble;                 /* Battery life extension */
+  bool     beacon_pending;      /* A beacon waits for the radio */
+  uint8_t  bsn;                 /* macBSN, the beacon sequence number */
+  uint8_t  backoffs;            /* Backoff periods before the next CCA */
+  uint32_t boundary;            /* Backoff period boundary of the next step */
 #endif
 };
 
diff --git a/arch/arm/src/nrf52/nrf52_ieee802154_trace.c 
b/arch/arm/src/nrf52/nrf52_ieee802154_trace.c
index e58a01fa4d7..f9fe8384731 100644
--- a/arch/arm/src/nrf52/nrf52_ieee802154_trace.c
+++ b/arch/arm/src/nrf52/nrf52_ieee802154_trace.c
@@ -77,6 +77,7 @@ static const char *g_radio_trace_str[] =
   "DROPFRAME",
   "TXTRYAGAIN",
   "SFSYNC",
+  "CSMAPAUSE",
 };
 
 /* Trace data */
diff --git a/arch/arm/src/nrf52/nrf52_ieee802154_trace.h 
b/arch/arm/src/nrf52/nrf52_ieee802154_trace.h
index b2be03d9e3b..1e43c1e3e46 100644
--- a/arch/arm/src/nrf52/nrf52_ieee802154_trace.h
+++ b/arch/arm/src/nrf52/nrf52_ieee802154_trace.h
@@ -92,6 +92,7 @@ enum radio_trace_type_e
   RADIO_TRACE_DROPFRAME,
   RADIO_TRACE_TXRETRY,
   RADIO_TRACE_SFSYNC,
+  RADIO_TRACE_CSMAPAUSE,
 };
 
 /****************************************************************************
diff --git a/arch/arm/src/nrf53/nrf53_ieee802154.c 
b/arch/arm/src/nrf53/nrf53_ieee802154.c
index a6b40e32034..87fc55bfe28 100644
--- a/arch/arm/src/nrf53/nrf53_ieee802154.c
+++ b/arch/arm/src/nrf53/nrf53_ieee802154.c
@@ -751,6 +751,11 @@ nrf53_radioi8_beaconstart(struct ieee802154_radio_s *radio,
                                         beacon->bf_len);
           dev->radio->state.bsn = rand();
 
+          /* Slotted CSMA-CA in the CAP */
+
+          dev->radio->state.slotted = true;
+          dev->radio->state.ble     = sfspec->ble;
+
           /* The PAN coordinator defines the superframe */
 
           dev->radio->state.sftrack = false;
@@ -809,6 +814,31 @@ nrf53_radioi8_beaconupdate(struct ieee802154_radio_s 
*radio,
 #endif
 }
 
+#ifdef CONFIG_NRF53_RADIO_IEEE802154_SUPERFRAME
+/****************************************************************************
+ * Name: nrf53_radioi8_unslotted
+ *
+ * Description:
+ *   Switch to un-slotted CSMA-CA, a transaction paused for the next CAP
+ *   starts again un-slotted.  Must be called with the radio locked.
+ *
+ ****************************************************************************/
+
+static void nrf53_radioi8_unslotted(struct nrf53_radioi8_dev_s *dev)
+{
+  dev->radio->state.slotted = false;
+  dev->radio->state.sftrack = false;
+
+  if (dev->radio->state.csma_paused)
+    {
+      dev->radio->state.csma_paused = false;
+      dev->radio->state.csma_busy   = false;
+      dev->state.csma_pending       = true;
+      dev->radio->ops->txnext(dev, 0);
+    }
+}
+#endif
+
 /****************************************************************************
  * Name: nrf53_radioi8_beaconstop
  *
@@ -828,6 +858,7 @@ static int nrf53_radioi8_beaconstop(struct 
ieee802154_radio_s *radio)
   /* Stop RTC */
 
   dev->rtc->ops->stop(dev);
+  nrf53_radioi8_unslotted(dev);
 
   leave_critical_section(flags);
 
@@ -873,6 +904,7 @@ nrf53_radioi8_sfupdate(struct ieee802154_radio_s *radio,
           /* Need slotted CSMA-CA */
 
           dev->radio->state.slotted = true;
+          dev->radio->state.ble     = sfspec->ble;
 
           /* Sync with the beacons */
 
@@ -884,8 +916,7 @@ nrf53_radioi8_sfupdate(struct ieee802154_radio_s *radio,
       /* Need un-slotted CSMA-CA */
 
       dev->rtc->ops->stop(dev);
-      dev->radio->state.slotted = false;
-      dev->radio->state.sftrack = false;
+      nrf53_radioi8_unslotted(dev);
     }
 
   leave_critical_section(flags);
diff --git a/arch/arm/src/nrf53/nrf53_ieee802154_radio.c 
b/arch/arm/src/nrf53/nrf53_ieee802154_radio.c
index 0709edb4fbd..f79fc14e360 100644
--- a/arch/arm/src/nrf53/nrf53_ieee802154_radio.c
+++ b/arch/arm/src/nrf53/nrf53_ieee802154_radio.c
@@ -160,6 +160,18 @@
 #define IEEE802154_ACKTX_INT            (RADIO_INT_PHYEND)
 #define IEEE802154_ACKTX_SHORTS         (RADIO_SHORTS_PHYEND_DISABLE)
 
+/* aUnitBackoffPeriod in us */
+
+#define NRF53_BACKOFF_US                (IEEE802154_UNIT_BACKOFF_PERIOD * \
+                                         IEEE802154_SYMBOL_US)
+
+/* Time to set up a slotted CSMA-CA step before its boundary: the ramp-up
+ * and two timer ticks
+ */
+
+#define NRF53_SLOTTED_GUARD_US          (NRF53_RADIOI8_RAMPUP_US + \
+                                         2 * IEEE802154_SYMBOL_US)
+
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
@@ -195,6 +207,12 @@ static void nrf53_radioi8_norm_setup(struct 
nrf53_radioi8_dev_s *dev,
                                      struct iob_s *frame, bool csma);
 static void nrf53_radioi8_norm_trigger(struct nrf53_radioi8_dev_s *dev);
 #ifdef CONFIG_NRF53_RADIO_IEEE802154_SUPERFRAME
+static void nrf53_radioi8_slotted_at(struct nrf53_radioi8_dev_s *dev,
+                                     uint8_t chan);
+static void nrf53_radioi8_slotted_pause(struct nrf53_radioi8_dev_s *dev);
+static void nrf53_radioi8_slotted_backoff(struct nrf53_radioi8_dev_s *dev,
+                                          uint32_t guard);
+static void nrf53_radioi8_slotted_resume(struct nrf53_radioi8_dev_s *dev);
 static void nrf53_radioi8_beacon_setup(struct nrf53_radioi8_dev_s *dev,
                                        uint8_t *data, uint8_t len);
 static void nrf53_radioi8_beacon_tx(struct nrf53_radioi8_dev_s *dev);
@@ -703,6 +721,16 @@ static void nrf53_radioi8_ccastart(struct 
nrf53_radioi8_dev_s *dev)
   DEBUGASSERT(dev);
   lower = dev->radio->lower;
 
+#ifdef CONFIG_NRF53_RADIO_IEEE802154_SUPERFRAME
+  /* Slotted CCA starts with the RXREADY-CCASTART short */
+
+  if (dev->radio->state.slotted)
+    {
+      NRF53_RADIO_PUTREG(lower, NRF53_RADIO_TASKS_RXEN_OFFSET, 1);
+      return;
+    }
+#endif
+
   NRF53_RADIO_PUTREG(lower, NRF53_RADIO_TASKS_CCASTART_OFFSET, 1);
 }
 
@@ -1067,6 +1095,177 @@ static void nrf53_radioi8_norm_setup(struct 
nrf53_radioi8_dev_s *dev,
   nrf53_radioi8_norm_setup_buf(dev, dev->radio->txbuf, csma);
 }
 
+#ifdef CONFIG_NRF53_RADIO_IEEE802154_SUPERFRAME
+/****************************************************************************
+ * Name: nrf53_radioi8_slotted_at
+ *
+ * Description:
+ *   Run the next slotted CSMA-CA step on its backoff period boundary, the
+ *   radio ramps up before it.
+ *
+ ****************************************************************************/
+
+static void nrf53_radioi8_slotted_at(struct nrf53_radioi8_dev_s *dev,
+                                     uint8_t chan)
+{
+  uint32_t elapsed = 0;
+  uint32_t at;
+
+  at = dev->radio->state.boundary * NRF53_BACKOFF_US -
+       NRF53_RADIOI8_RAMPUP_US;
+
+  dev->rtc->ops->elapsed(dev, &elapsed);
+
+  dev->tim->ops->setup(dev, chan, at > elapsed ?
+                       (at - elapsed) / IEEE802154_SYMBOL_US : 0);
+}
+
+/****************************************************************************
+ * Name: nrf53_radioi8_slotted_pause
+ *
+ * Description:
+ *   Wait for the next CAP, receive in the meantime.
+ *
+ ****************************************************************************/
+
+static void nrf53_radioi8_slotted_pause(struct nrf53_radioi8_dev_s *dev)
+{
+  struct nrf53_radio_dev_s *lower = dev->radio->lower;
+
+  nrf53_radioi8_trace_put(RADIO_TRACE_CSMAPAUSE,
+                          dev->radio->state.backoffs);
+
+  dev->radio->state.csma_paused = true;
+  dev->radio->state.waitack     = false;
+  dev->radio->state.state       = NRF53_RADIO_STATE_DISABLED;
+
+  NRF53_RADIO_INTCLR(lower, 0xffffffff);
+  NRF53_RADIO_SHRTSET(lower, 0);
+
+  if (dev->radio->state.rxrestore)
+    {
+      dev->radio->state.rxrestore = false;
+
+      while (NRF53_RADIO_GETREG(lower, NRF53_RADIO_STATE_OFFSET) !=
+             RADIO_STATE_DISABLED);
+
+      dev->macops.rxenable((struct ieee802154_radio_s *)dev, true);
+    }
+}
+
+/****************************************************************************
+ * Name: nrf53_radioi8_slotted_backoff
+ *
+ * Description:
+ *   Count down the backoff periods in the CAP and schedule the first CCA
+ *   (IEEE 802.15.4-2003 7.5.1.3).
+ *
+ ****************************************************************************/
+
+static void nrf53_radioi8_slotted_backoff(struct nrf53_radioi8_dev_s *dev,
+                                          uint32_t guard)
+{
+  struct nrf53_radioi8_radio_data_s *state   = &dev->radio->state;
+  struct nrf53_radioi8_rtc_s        *rtc     = dev->rtc;
+  uint32_t                           elapsed = 0;
+  uint32_t                           end;
+  uint32_t                           b;
+  uint32_t                           need;
+
+  /* Not synchronized or the CAP is over */
+
+  if (!rtc->ops->elapsed(dev, &elapsed) || elapsed >= rtc->cap)
+    {
+      nrf53_radioi8_slotted_pause(dev);
+      return;
+    }
+
+  /* The first boundary after the beacon IFS that can still be set up */
+
+  b = (MAX(elapsed + guard, rtc->capstart) + NRF53_BACKOFF_US - 1) /
+      NRF53_BACKOFF_US;
+
+  /* The last boundary of the countdown and of the TX start: the CAP end,
+   * with battery life extension the sixth full backoff period after the
+   * beacon IFS
+   */
+
+  end = rtc->cap / NRF53_BACKOFF_US;
+  if (state->ble)
+    {
+      end = MIN(end, (rtc->capstart + NRF53_BACKOFF_US - 1) /
+                     NRF53_BACKOFF_US + 5);
+    }
+
+  /* Pause the countdown at the end of the CAP */
+
+  if (b + state->backoffs > end)
+    {
+      if (end > b)
+        {
+          state->backoffs -= end - b;
+        }
+
+      nrf53_radioi8_slotted_pause(dev);
+      return;
+    }
+
+  b += state->backoffs;
+  state->backoffs = 0;
+
+  /* The CCAs, the frame, its ACK and the IFS must end before the end of
+   * the CAP (7.5.1.1.1), otherwise evaluate again in the next CAP
+   */
+
+  need = state->CW * NRF53_BACKOFF_US +
+         NRF53_RADIOI8_FRAME_US(dev->radio->txbuf[0]) +
+         NRF53_RADIOI8_IFS_US(dev->radio->txbuf[0]);
+  if (dev->radio->txbuf[1] & IEEE802154_FRAMECTRL_ACKREQ)
+    {
+      need += IEEE802154_ACK_WAIT * IEEE802154_SYMBOL_US;
+    }
+
+  if (b * NRF53_BACKOFF_US + need > rtc->cap || b + state->CW > end)
+    {
+      nrf53_radioi8_slotted_pause(dev);
+      return;
+    }
+
+  /* CCA on the boundary */
+
+  state->boundary = b;
+  nrf53_radioi8_slotted_at(dev, NRF53_TIMER_CHAN_CSMADELAY);
+}
+
+/****************************************************************************
+ * Name: nrf53_radioi8_slotted_resume
+ *
+ * Description:
+ *   Continue the slotted CSMA-CA paused for this CAP.  Must be called with
+ *   the radio locked.
+ *
+ ****************************************************************************/
+
+static void nrf53_radioi8_slotted_resume(struct nrf53_radioi8_dev_s *dev)
+{
+  uint32_t elapsed = 0;
+
+  /* Not in a CAP, stay paused */
+
+  if (!dev->rtc->ops->elapsed(dev, &elapsed) || elapsed >= dev->rtc->cap)
+    {
+      return;
+    }
+
+  dev->radio->state.csma_paused = false;
+
+  nrf53_radioi8_norm_setup_buf(dev, dev->radio->txbuf, true);
+  dev->radio->state.state = NRF53_RADIO_STATE_TX;
+
+  nrf53_radioi8_slotted_backoff(dev, NRF53_SLOTTED_GUARD_US);
+}
+#endif
+
 /****************************************************************************
  * Name: nrf53_radioi8_trg_csma
  *
@@ -1090,33 +1289,29 @@ static void nrf53_radioi8_trg_csma(struct 
nrf53_radioi8_dev_s *dev)
 #ifdef CONFIG_NRF53_RADIO_IEEE802154_SUPERFRAME
       if (!dev->radio->state.csma_busy)
         {
-          /* Initial backoff state */
+          /* Initial backoff state, battery life extension limits BE
+           * (IEEE 802.15.4-2003 7.5.1.3)
+           */
 
           dev->radio->state.NB = 0;
-          dev->radio->state.CW = IEEE802154_CW0;
+          dev->radio->state.BE = dev->radio->state.ble ?
+                                 MIN(2, dev->radio->state.min_be) :
+                                 dev->radio->state.min_be;
         }
 
-      /* Battery life extension */
+      /* CW is reset for each attempt */
 
-      if (dev->radio->state.ble)
-        {
-          dev->radio->state.BE = MIN(2, dev->radio->state.min_be);
-        }
-      else
-        {
-          dev->radio->state.BE = dev->radio->state.min_be;
-        }
+      dev->radio->state.CW       = IEEE802154_CW0;
+      dev->radio->state.backoffs = rand() % (1 << dev->radio->state.BE);
 
-      /* Get random unit backoff period delay */
+      /* CSMA is in use */
 
-      delay = rand() % (1 << dev->radio->state.BE);
-
-      /* TODO:
-       *  - locate backoff period boundary
-       *  - perform CCA on backoff period boundary
-       */
+      dev->radio->state.csma_busy = true;
+      nrf53_radioi8_trace_put(RADIO_TRACE_CSMATRIGGER,
+                              dev->radio->state.backoffs);
 
-      ASSERT(0);
+      nrf53_radioi8_slotted_backoff(dev, NRF53_SLOTTED_GUARD_US);
+      return;
 #else
       ASSERT(0);
 #endif
@@ -1394,10 +1589,13 @@ static void nrf53_radioi8_txnext(struct 
nrf53_radioi8_dev_s *dev,
 
   flags = enter_critical_section();
 
-  /* A frame on the air, an ACK TX or an energy detection owns the radio */
+  /* A frame on the air, an ACK TX, an energy detection or a timed step
+   * owns the radio
+   */
 
-  if (dev->radio->state.state != NRF53_RADIO_STATE_DISABLED &&
-      dev->radio->state.state != NRF53_RADIO_STATE_RX)
+  if ((dev->radio->state.state != NRF53_RADIO_STATE_DISABLED &&
+       dev->radio->state.state != NRF53_RADIO_STATE_RX) ||
+      dev->tim->tim_pending)
     {
       leave_critical_section(flags);
       return;
@@ -1429,10 +1627,10 @@ static void nrf53_radioi8_txnext(struct 
nrf53_radioi8_dev_s *dev,
 #endif
 
   /* An armed frame or a CSMA transaction between its backoffs owns the
-   * radio.
+   * radio, a slotted one paused for the next CAP does not.
    */
 
-  if (dev->radio->state.csma_busy ||
+  if ((dev->radio->state.csma_busy && !dev->radio->state.csma_paused) ||
       (dev->state.txdelayed_busy && !dev->state.txdelayed_pending))
     {
       leave_critical_section(flags);
@@ -1467,6 +1665,15 @@ static void nrf53_radioi8_txnext(struct 
nrf53_radioi8_dev_s *dev,
       nrf53_radioi8_norm_trigger(dev);
     }
 
+#ifdef CONFIG_NRF53_RADIO_IEEE802154_SUPERFRAME
+  /* Then the slotted CSMA TX paused for this CAP */
+
+  else if (dev->radio->state.csma_paused)
+    {
+      nrf53_radioi8_slotted_resume(dev);
+    }
+#endif
+
   /* Nothing to send, restore RX */
 
   else if (dev->radio->state.rxrestore)
@@ -1947,6 +2154,10 @@ static void nrf53_radioi8_state_rx(struct 
nrf53_radioi8_dev_s *dev)
       nrf53_radioi8_coordbeacon(dev))
     {
       dev->rtc->ops->sync(dev, rxbuf[0]);
+
+      /* The CAP starts, continue the TX that waited for it */
+
+      nrf53_radioi8_txnext(dev, 0);
     }
 #endif
 
@@ -2064,80 +2275,36 @@ static void nrf53_radioi8_state_tx(struct 
nrf53_radioi8_dev_s *dev)
 
       NRF53_RADIO_PUTREG(lower, NRF53_RADIO_EVENTS_CCABUSY_OFFSET, 0);
 
-      /* Slotted CSMA-CA */
+      /* Update backoff */
 
-      if (dev->radio->state.slotted == true)
-        {
-#ifdef CONFIG_NRF53_RADIO_IEEE802154_SUPERFRAME
-          dev->radio->state.NB += 1;
-          dev->radio->state.CW = IEEE802154_CW0;
-          dev->radio->state.BE = MIN(2, dev->radio->state.min_be);
-
-          if (dev->radio->state.NB > dev->radio->state.max_csma_backoffs)
-            {
-              /* Return failure to MAC, no frame was sent */
+      dev->radio->state.NB += 1;
+      dev->radio->state.BE = MIN(dev->radio->state.BE + 1,
+                                 dev->radio->state.max_be);
 
-              dev->radio->state.waitack = false;
+      if (dev->radio->state.NB > dev->radio->state.max_csma_backoffs)
+        {
+          /* Return failure to MAC, no frame was sent */
 
-              if (work_available(&dev->radio->irqwork))
-                {
-                  work_queue(HPWORK, &dev->radio->irqwork,
-                             nrf53_radioi8_work_busy, (void *)dev, 0);
-                }
+          dev->radio->state.waitack = false;
 
-              goto out;
-            }
-          else
+          if (work_available(&dev->radio->irqwork))
             {
-              /* Try again, shorts and interrupts were reset in ISR */
-
-              nrf53_radioi8_norm_setup_buf(dev, dev->radio->txbuf, true);
-              nrf53_radioi8_norm_trigger(dev);
-
-              /* Do not restore RX */
-
-              return;
+              work_queue(HPWORK, &dev->radio->irqwork,
+                         nrf53_radioi8_work_busy, (void *)dev, 0);
             }
-#else
-          ASSERT(0);
-#endif
-        }
-
-      /* Un-slotted CSMA-CA */
 
+          goto out;
+        }
       else
         {
-          /* Update backoff */
-
-          dev->radio->state.NB += 1;
-          dev->radio->state.BE = MIN(dev->radio->state.BE + 1,
-                                     dev->radio->state.max_be);
-
-          if (dev->radio->state.NB > dev->radio->state.max_csma_backoffs)
-            {
-              /* Return failure to MAC, no frame was sent */
+          /* Try again, shorts and interrupts were reset in ISR */
 
-              dev->radio->state.waitack = false;
-
-              if (work_available(&dev->radio->irqwork))
-                {
-                  work_queue(HPWORK, &dev->radio->irqwork,
-                             nrf53_radioi8_work_busy, (void *)dev, 0);
-                }
-
-              goto out;
-            }
-          else
-            {
-              /* Try again, shorts and interrupts were reset in ISR */
-
-              nrf53_radioi8_norm_setup_buf(dev, dev->radio->txbuf, true);
-              nrf53_radioi8_norm_trigger(dev);
+          nrf53_radioi8_norm_setup_buf(dev, dev->radio->txbuf, true);
+          nrf53_radioi8_norm_trigger(dev);
 
-              /* Do not restore RX */
+          /* Do not restore RX */
 
-              return;
-            }
+          return;
         }
     }
 
@@ -2154,20 +2321,30 @@ static void nrf53_radioi8_state_tx(struct 
nrf53_radioi8_dev_s *dev)
       if (dev->radio->state.slotted == true)
         {
 #ifdef CONFIG_NRF53_RADIO_IEEE802154_SUPERFRAME
-          dev->radio->state.CW -= 1;
+          /* The next step starts on the next boundary */
+
+          dev->radio->state.CW       -= 1;
+          dev->radio->state.boundary += 1;
 
           if (dev->radio->state.CW == 0)
             {
-              /* Enable TX - short TXREADY-START is enabled */
+              /* Transmit, the ACK wait starts with the TX */
 
-              NRF53_RADIO_PUTREG(lower, NRF53_RADIO_TASKS_TXEN_OFFSET, 1);
+              nrf53_radioi8_norm_setup_buf(dev, dev->radio->txbuf, false);
+              nrf53_radioi8_slotted_at(dev, NRF53_TIMER_CHAN_TXDELAY);
             }
           else
             {
-              /* Do not restore RX */
+              /* Next CCA */
 
-              return;
+              nrf53_radioi8_norm_setup_buf(dev, dev->radio->txbuf, true);
+              dev->radio->state.state = NRF53_RADIO_STATE_TX;
+              nrf53_radioi8_slotted_at(dev, NRF53_TIMER_CHAN_CSMADELAY);
             }
+
+          /* Do not restore RX */
+
+          return;
 #else
           ASSERT(0);
 #endif
diff --git a/arch/arm/src/nrf53/nrf53_ieee802154_radio.h 
b/arch/arm/src/nrf53/nrf53_ieee802154_radio.h
index c50bed096dd..f12061e0918 100644
--- a/arch/arm/src/nrf53/nrf53_ieee802154_radio.h
+++ b/arch/arm/src/nrf53/nrf53_ieee802154_radio.h
@@ -114,7 +114,8 @@ struct nrf53_radioi8_radio_data_s
 
   bool     waitack;             /* TX needs ACK */
   bool     framepending;        /* Frame pending from the last TX ACK */
-  bool     csma_busy;           /* Un-slotted CSMA busy */
+  bool     csma_busy;           /* CSMA-CA transaction in progress */
+  bool     csma_paused;         /* Slotted CSMA-CA waits for the next CAP */
   bool     slotted;             /* Slotted CSMA-CA */
 
   /* Radio configuration */
@@ -127,10 +128,12 @@ struct nrf53_radioi8_radio_data_s
 #ifdef CONFIG_NRF53_RADIO_IEEE802154_SUPERFRAME
   /* Superframe data */
 
-  bool    sftrack;              /* Device tracks the beacons */
-  bool    ble;                  /* Batter life extension */
-  bool    beacon_pending;       /* A beacon waits for the radio */
-  uint8_t bsn;                  /* macBSN, the beacon sequence number */
+  bool     sftrack;             /* Device tracks the beacons */
+  bool     ble;                 /* Battery life extension */
+  bool     beacon_pending;      /* A beacon waits for the radio */
+  uint8_t  bsn;                 /* macBSN, the beacon sequence number */
+  uint8_t  backoffs;            /* Backoff periods before the next CCA */
+  uint32_t boundary;            /* Backoff period boundary of the next step */
 #endif
 };
 
diff --git a/arch/arm/src/nrf53/nrf53_ieee802154_trace.c 
b/arch/arm/src/nrf53/nrf53_ieee802154_trace.c
index 7160cc2ee50..f728a25dd77 100644
--- a/arch/arm/src/nrf53/nrf53_ieee802154_trace.c
+++ b/arch/arm/src/nrf53/nrf53_ieee802154_trace.c
@@ -77,6 +77,7 @@ static const char *g_radio_trace_str[] =
   "DROPFRAME",
   "TXTRYAGAIN",
   "SFSYNC",
+  "CSMAPAUSE",
 };
 
 /* Trace data */
diff --git a/arch/arm/src/nrf53/nrf53_ieee802154_trace.h 
b/arch/arm/src/nrf53/nrf53_ieee802154_trace.h
index 439c7b0ed50..bbd48bf58cb 100644
--- a/arch/arm/src/nrf53/nrf53_ieee802154_trace.h
+++ b/arch/arm/src/nrf53/nrf53_ieee802154_trace.h
@@ -92,6 +92,7 @@ enum radio_trace_type_e
   RADIO_TRACE_DROPFRAME,
   RADIO_TRACE_TXRETRY,
   RADIO_TRACE_SFSYNC,
+  RADIO_TRACE_CSMAPAUSE,
 };
 
 /****************************************************************************

Reply via email to