diff --git a/drivers/include/net/netdev/ieee802154_submac.h b/drivers/include/net/netdev/ieee802154_submac.h index f91f0298e9..a148f788f8 100644 --- a/drivers/include/net/netdev/ieee802154_submac.h +++ b/drivers/include/net/netdev/ieee802154_submac.h @@ -38,8 +38,9 @@ extern "C" { #include "xtimer.h" #define NETDEV_SUBMAC_FLAGS_ACK_TIMEOUT (1 << 0) /**< Flag for ACK Timeout event */ -#define NETDEV_SUBMAC_FLAGS_TX_DONE (1 << 1) /**< Flag for TX Done event */ -#define NETDEV_SUBMAC_FLAGS_RX_DONE (1 << 2) /**< Flag for RX Done event */ +#define NETDEV_SUBMAC_FLAGS_TX_DONE (1 << 1) /**< Flag for TX Done event */ +#define NETDEV_SUBMAC_FLAGS_RX_DONE (1 << 2) /**< Flag for RX Done event */ +#define NETDEV_SUBMAC_FLAGS_CRC_ERROR (1 << 3) /**< Flag for CRC ERROR event */ /** * @brief IEEE 802.15.4 SubMAC netdev descriptor diff --git a/drivers/netdev_ieee802154_submac/netdev_ieee802154_submac.c b/drivers/netdev_ieee802154_submac/netdev_ieee802154_submac.c index adc6f053ba..b54b5f8371 100644 --- a/drivers/netdev_ieee802154_submac/netdev_ieee802154_submac.c +++ b/drivers/netdev_ieee802154_submac/netdev_ieee802154_submac.c @@ -178,6 +178,10 @@ static void _isr(netdev_t *netdev) if (flags & NETDEV_SUBMAC_FLAGS_RX_DONE) { ieee802154_submac_rx_done_cb(submac); } + + if (flags & NETDEV_SUBMAC_FLAGS_CRC_ERROR) { + ieee802154_submac_crc_error_cb(submac); + } } while (netdev_submac->isr_flags != 0); } @@ -268,6 +272,10 @@ static void _hal_radio_cb(ieee802154_dev_t *dev, ieee802154_trx_ev_t status) break; case IEEE802154_RADIO_INDICATION_RX_DONE: netdev_submac->isr_flags |= NETDEV_SUBMAC_FLAGS_RX_DONE; + break; + case IEEE802154_RADIO_INDICATION_CRC_ERROR: + netdev_submac->isr_flags |= NETDEV_SUBMAC_FLAGS_CRC_ERROR; + break; default: break; } diff --git a/sys/include/net/ieee802154/submac.h b/sys/include/net/ieee802154/submac.h index 1f777d2b50..5548ce9f8c 100644 --- a/sys/include/net/ieee802154/submac.h +++ b/sys/include/net/ieee802154/submac.h @@ -379,6 +379,13 @@ void ieee802154_submac_ack_timeout_fired(ieee802154_submac_t *submac); */ void ieee802154_submac_rx_done_cb(ieee802154_submac_t *submac); +/** + * @brief Indicate the SubMAC that a frame with invalid CRC was received. + * + * @param[in] submac pointer to the SubMAC descriptor + */ +void ieee802154_submac_crc_error_cb(ieee802154_submac_t *submac); + /** * @brief Indicate the SubMAC that the device finished the transmission procedure. * diff --git a/sys/net/link_layer/ieee802154/submac.c b/sys/net/link_layer/ieee802154/submac.c index 0193a83c45..352e3da991 100644 --- a/sys/net/link_layer/ieee802154/submac.c +++ b/sys/net/link_layer/ieee802154/submac.c @@ -147,6 +147,14 @@ void ieee802154_submac_ack_timeout_fired(ieee802154_submac_t *submac) } } +void ieee802154_submac_crc_error_cb(ieee802154_submac_t *submac) +{ + ieee802154_dev_t *dev = submac->dev; + /* switch back to RX_ON state */ + ieee802154_radio_request_set_trx_state(dev, IEEE802154_TRX_STATE_RX_ON); + while (ieee802154_radio_confirm_set_trx_state(dev) == -EAGAIN) {} +} + /* All callbacks run in the same context */ void ieee802154_submac_rx_done_cb(ieee802154_submac_t *submac) {