diff --git a/cpu/cc2538/radio/cc2538_rf.c b/cpu/cc2538/radio/cc2538_rf.c index e72dd782af..cd3ab3785f 100644 --- a/cpu/cc2538/radio/cc2538_rf.c +++ b/cpu/cc2538/radio/cc2538_rf.c @@ -65,9 +65,11 @@ static const init_pair_t init_table[] = { {&RFCORE_XREG_FRMCTRL1, 0x00 }, {&RFCORE_XREG_SRCMATCH, 0x00 }, {&RFCORE_XREG_FIFOPCTRL, CC2538_RF_MAX_DATA_LEN }, - {&RFCORE_XREG_RFIRQM0, FIFOP | RXPKTDONE }, #if IS_USED(MODULE_IEEE802154_RADIO_HAL) - {&RFCORE_XREG_RFIRQM1, TXDONE | CSP_STOP }, + {&RFCORE_XREG_RFIRQM0, FIFOP | RXPKTDONE | SFD }, + {&RFCORE_XREG_RFIRQM1, TXDONE | CSP_STOP | TXACKDONE }, +#else + {&RFCORE_XREG_RFIRQM0, FIFOP | RXPKTDONE }, #endif {&RFCORE_XREG_RFERRM, STROBE_ERR | TXUNDERF | TXOVERF | RXUNDERF | RXOVERF | NLOCK}, {NULL, 0}, diff --git a/cpu/cc2538/radio/cc2538_rf_radio_ops.c b/cpu/cc2538/radio/cc2538_rf_radio_ops.c index 36863ea493..c232b5421e 100644 --- a/cpu/cc2538/radio/cc2538_rf_radio_ops.c +++ b/cpu/cc2538/radio/cc2538_rf_radio_ops.c @@ -43,6 +43,8 @@ static bool cc2538_cca_status; /**< status of the last CCA request */ static bool cc2538_cca; /**< used to check whether the last CCA result corresponds to a CCA request or send with CSMA-CA */ +static bool cc2538_sfd_listen; /**< used to check whether we should ignore + the SFD flag */ static int _write(ieee802154_dev_t *dev, const iolist_t *iolist) { @@ -314,22 +316,45 @@ void cc2538_irq_handler(void) RFCORE_SFR_RFIRQF0 = 0; RFCORE_SFR_RFIRQF1 = 0; + if ((flags_f0 & SFD) && cc2538_sfd_listen) { + if (RFCORE->XREG_FSMSTAT1bits.TX_ACTIVE) { + cc2538_rf_dev.cb(&cc2538_rf_dev, IEEE802154_RADIO_INDICATION_TX_START); + } + } + if (flags_f1 & TXDONE) { cc2538_rf_dev.cb(&cc2538_rf_dev, IEEE802154_RADIO_CONFIRM_TX_DONE); } + if ((flags_f0 & SFD) && cc2538_sfd_listen) { + if (RFCORE->XREG_FSMSTAT1bits.RX_ACTIVE) { + cc2538_rf_dev.cb(&cc2538_rf_dev, IEEE802154_RADIO_INDICATION_RX_START); + } + } + if (flags_f0 & RXPKTDONE) { /* CRC check */ uint8_t pkt_len = rfcore_peek_rx_fifo(0); if (rfcore_peek_rx_fifo(pkt_len) & CC2538_CRC_BIT_MASK) { - RFCORE_XREG_RFIRQM0 &= RXPKTDONE; + /* Disable RX while the frame has not been processed */ + RFCORE_XREG_RXMASKCLR = 0xFF; + /* If AUTOACK is enabled and the ACK request bit is set */ + if (RFCORE->XREG_FRMCTRL0bits.AUTOACK && + (rfcore_peek_rx_fifo(1) & IEEE802154_FCF_ACK_REQ)) { + /* The next SFD will be the ACK's, ignore it */ + cc2538_sfd_listen = false; + } cc2538_rf_dev.cb(&cc2538_rf_dev, IEEE802154_RADIO_INDICATION_RX_DONE); } else { /* CRC failed; discard packet */ RFCORE_SFR_RFST = ISFLUSHRX; } + } + /* Re-Enable SFD ISR after ACK is received */ + if (flags_f1 & TXACKDONE) { + cc2538_sfd_listen = true; } /* Check if the interrupt was triggered because the CSP finished its routine @@ -367,6 +392,8 @@ static bool _get_cap(ieee802154_dev_t *dev, ieee802154_rf_caps_t cap) case IEEE802154_CAP_24_GHZ: case IEEE802154_CAP_IRQ_TX_DONE: case IEEE802154_CAP_IRQ_CCA_DONE: + case IEEE802154_CAP_IRQ_RX_START: + case IEEE802154_CAP_IRQ_TX_START: case IEEE802154_CAP_AUTO_CSMA: return true; default: @@ -413,6 +440,8 @@ static int _request_on(ieee802154_dev_t *dev) { (void) dev; /* TODO */ + /* when turned on listen for SFD interrupts */ + cc2538_sfd_listen = true; return 0; }