Merge pull request #15397 from fjmolinas/pr_ieee802154_crc_error

sys/net/iee802154/radio: add IEEE802154_RADIO_INDICATION_CRC_ERROR
This commit is contained in:
José Alamos 2021-01-14 10:29:17 +01:00 committed by GitHub
commit 2bf10413d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 82 additions and 9 deletions

View File

@ -353,8 +353,10 @@ void cc2538_irq_handler(void)
cc2538_rf_dev.cb(&cc2538_rf_dev, IEEE802154_RADIO_INDICATION_RX_DONE); cc2538_rf_dev.cb(&cc2538_rf_dev, IEEE802154_RADIO_INDICATION_RX_DONE);
} }
else { else {
/* Disable RX while the frame has not been processed */
RFCORE_XREG_RXMASKCLR = 0xFF;
/* CRC failed; discard packet */ /* CRC failed; discard packet */
RFCORE_SFR_RFST = ISFLUSHRX; cc2538_rf_dev.cb(&cc2538_rf_dev, IEEE802154_RADIO_INDICATION_CRC_ERROR);
} }
} }
@ -396,11 +398,12 @@ static bool _get_cap(ieee802154_dev_t *dev, ieee802154_rf_caps_t cap)
(void) dev; (void) dev;
switch (cap) { switch (cap) {
case IEEE802154_CAP_24_GHZ: case IEEE802154_CAP_24_GHZ:
case IEEE802154_CAP_AUTO_CSMA:
case IEEE802154_CAP_IRQ_CRC_ERROR:
case IEEE802154_CAP_IRQ_TX_DONE: case IEEE802154_CAP_IRQ_TX_DONE:
case IEEE802154_CAP_IRQ_CCA_DONE: case IEEE802154_CAP_IRQ_CCA_DONE:
case IEEE802154_CAP_IRQ_RX_START: case IEEE802154_CAP_IRQ_RX_START:
case IEEE802154_CAP_IRQ_TX_START: case IEEE802154_CAP_IRQ_TX_START:
case IEEE802154_CAP_AUTO_CSMA:
return true; return true;
default: default:
return false; return false;

View File

@ -543,7 +543,7 @@ void isr_radio(void)
} }
else { else {
DEBUG("[nrf802154] CRC fail.\n"); DEBUG("[nrf802154] CRC fail.\n");
NRF_RADIO->TASKS_START = 1; dev->cb(dev, IEEE802154_RADIO_INDICATION_CRC_ERROR);
} }
break; break;
case STATE_ACK: case STATE_ACK:
@ -644,6 +644,7 @@ static bool _get_cap(ieee802154_dev_t *dev, ieee802154_rf_caps_t cap)
(void) dev; (void) dev;
switch (cap) { switch (cap) {
case IEEE802154_CAP_24_GHZ: case IEEE802154_CAP_24_GHZ:
case IEEE802154_CAP_IRQ_CRC_ERROR:
case IEEE802154_CAP_IRQ_RX_START: case IEEE802154_CAP_IRQ_RX_START:
case IEEE802154_CAP_IRQ_TX_START: case IEEE802154_CAP_IRQ_TX_START:
case IEEE802154_CAP_IRQ_TX_DONE: case IEEE802154_CAP_IRQ_TX_DONE:

View File

@ -38,8 +38,9 @@ extern "C" {
#include "xtimer.h" #include "xtimer.h"
#define NETDEV_SUBMAC_FLAGS_ACK_TIMEOUT (1 << 0) /**< Flag for ACK Timeout event */ #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_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_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 * @brief IEEE 802.15.4 SubMAC netdev descriptor

View File

@ -178,6 +178,10 @@ static void _isr(netdev_t *netdev)
if (flags & NETDEV_SUBMAC_FLAGS_RX_DONE) { if (flags & NETDEV_SUBMAC_FLAGS_RX_DONE) {
ieee802154_submac_rx_done_cb(submac); 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); } 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; break;
case IEEE802154_RADIO_INDICATION_RX_DONE: case IEEE802154_RADIO_INDICATION_RX_DONE:
netdev_submac->isr_flags |= NETDEV_SUBMAC_FLAGS_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: default:
break; break;
} }

View File

@ -16,6 +16,7 @@
* @author Francisco Molina <francois-xavier.molina@inria.fr> * @author Francisco Molina <francois-xavier.molina@inria.fr>
* @} * @}
*/ */
#include <stdatomic.h>
#include <sys/uio.h> #include <sys/uio.h>
#include "leds.h" #include "leds.h"
@ -40,6 +41,8 @@ openwsn_radio_t openwsn_radio;
/* stores the event capture time */ /* stores the event capture time */
static PORT_TIMER_WIDTH _txrx_event_capture_time = 0; static PORT_TIMER_WIDTH _txrx_event_capture_time = 0;
/* set if frame with valid CRC is received, false otherwise */
static atomic_bool _valid_crc = true;
void _idmanager_addr_override(void) void _idmanager_addr_override(void)
{ {
@ -89,12 +92,21 @@ static void _hal_radio_cb(ieee802154_dev_t *dev, ieee802154_trx_ev_t status)
while (ieee802154_radio_confirm_set_trx_state(openwsn_radio.dev) == -EAGAIN) {} while (ieee802154_radio_confirm_set_trx_state(openwsn_radio.dev) == -EAGAIN) {}
openwsn_radio.endFrame_cb(_txrx_event_capture_time); openwsn_radio.endFrame_cb(_txrx_event_capture_time);
break; break;
case IEEE802154_RADIO_INDICATION_CRC_ERROR:
_valid_crc = false;
ieee802154_radio_request_set_trx_state(openwsn_radio.dev,
IEEE802154_TRX_STATE_TRX_OFF);
while (ieee802154_radio_confirm_set_trx_state(openwsn_radio.dev) == -EAGAIN) {}
openwsn_radio.endFrame_cb(_txrx_event_capture_time);
break;
case IEEE802154_RADIO_INDICATION_RX_DONE: case IEEE802154_RADIO_INDICATION_RX_DONE:
_valid_crc = true;
ieee802154_radio_request_set_trx_state(openwsn_radio.dev,
IEEE802154_TRX_STATE_TRX_OFF);
while (ieee802154_radio_confirm_set_trx_state(openwsn_radio.dev) == -EAGAIN) {}
openwsn_radio.endFrame_cb(_txrx_event_capture_time); openwsn_radio.endFrame_cb(_txrx_event_capture_time);
break; break;
case IEEE802154_RADIO_INDICATION_TX_START: case IEEE802154_RADIO_INDICATION_TX_START:
openwsn_radio.startFrame_cb(_txrx_event_capture_time);
break;
case IEEE802154_RADIO_INDICATION_RX_START: case IEEE802154_RADIO_INDICATION_RX_START:
openwsn_radio.startFrame_cb(_txrx_event_capture_time); openwsn_radio.startFrame_cb(_txrx_event_capture_time);
break; break;
@ -312,6 +324,5 @@ void radio_getReceivedFrame(uint8_t *bufRead,
/* get rssi, lqi & crc */ /* get rssi, lqi & crc */
*rssi = ieee802154_rssi_to_dbm(rx_info.rssi); *rssi = ieee802154_rssi_to_dbm(rx_info.rssi);
*lqi = rx_info.lqi; *lqi = rx_info.lqi;
/* only valid crc frames are currently accepted */ *crc = _valid_crc ? 1 : 0;
*crc = 1;
} }

View File

@ -92,6 +92,10 @@ typedef enum {
* @brief the device support the IEEE802.15.4 Sub GHz band * @brief the device support the IEEE802.15.4 Sub GHz band
*/ */
IEEE802154_CAP_SUB_GHZ, IEEE802154_CAP_SUB_GHZ,
/**
* @brief the device reports reception off frames with invalid CRC.
*/
IEEE802154_CAP_IRQ_CRC_ERROR,
/** /**
* @brief the device reports when the transmission is done * @brief the device reports when the transmission is done
*/ */
@ -190,6 +194,18 @@ typedef enum {
*/ */
IEEE802154_RADIO_INDICATION_RX_START, IEEE802154_RADIO_INDICATION_RX_START,
/**
* @brief the transceiver received a frame with an invalid crc.
*
* The transceiver might not stay in @ref IEEE802154_TRX_STATE_RX_ON
* after receiving an invalid CRC. Therefore the upper layer must
* set the transceiver state (@ref ieee802154_radio_ops::request_set_trx_state).
* e.g.: @ref IEEE802154_TRX_STATE_TRX_OFF or @ref IEEE802154_TRX_STATE_TX_ON
* to stop listening or @ref IEEE802154_TRX_STATE_RX_ON to keep
* listening.
*/
IEEE802154_RADIO_INDICATION_CRC_ERROR,
/** /**
* @brief the transceiver sent out a valid SFD * @brief the transceiver sent out a valid SFD
* *

View File

@ -379,6 +379,13 @@ void ieee802154_submac_ack_timeout_fired(ieee802154_submac_t *submac);
*/ */
void ieee802154_submac_rx_done_cb(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. * @brief Indicate the SubMAC that the device finished the transmission procedure.
* *

View File

@ -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 */ /* All callbacks run in the same context */
void ieee802154_submac_rx_done_cb(ieee802154_submac_t *submac) void ieee802154_submac_rx_done_cb(ieee802154_submac_t *submac)
{ {

View File

@ -102,6 +102,21 @@ static xtimer_t timer_ack = {
.callback = _timer_ack_handler, .callback = _timer_ack_handler,
}; };
void _crc_error_handler(event_t *event)
{
(void) event;
puts("Packet with invalid CRC received");
ieee802154_dev_t* dev = ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID);
/* 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) {}
}
static event_t _crc_error_event = {
.handler = _crc_error_handler,
};
void _rx_done_handler(event_t *event) void _rx_done_handler(event_t *event)
{ {
(void) event; (void) event;
@ -139,6 +154,9 @@ static void _hal_radio_cb(ieee802154_dev_t *dev, ieee802154_trx_ev_t status)
case IEEE802154_RADIO_INDICATION_RX_DONE: case IEEE802154_RADIO_INDICATION_RX_DONE:
event_post(EVENT_PRIO_HIGHEST, &_rx_done_event); event_post(EVENT_PRIO_HIGHEST, &_rx_done_event);
break; break;
case IEEE802154_RADIO_INDICATION_CRC_ERROR:
event_post(EVENT_PRIO_HIGHEST, &_crc_error_event);
break;
default: default:
break; break;
} }