Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions cpu/native/socket_zep/socket_zep.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,14 +511,22 @@
zepdev->state = ZEPDEV_STATE_TX;

/* 8 bit are mapped to 2 symbols */
unsigned time_tx = 2 * (zepdev->snd_len - sizeof(zep_v2_data_hdr_t)) * IEEE802154_SYMBOL_TIME_US;

Check warning on line 514 in cpu/native/socket_zep/socket_zep.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
DEBUG("socket_zep::request_transmit(%u bytes, %u µs)\n", zepdev->snd_len, time_tx);

dev->cb(dev, IEEE802154_RADIO_INDICATION_TX_START);

/* delay transmission to simulate airtime */
zepdev->ack_timer.callback = _send_frame;
ztimer_set(ZTIMER_USEC, &zepdev->ack_timer, time_tx);
/* native overhead prevents short timers from triggering in time,
send directly if delay is less than 200 µs */
if (time_tx <= 200) {
_send_frame(zepdev->ack_timer.arg);
}
else {
time_tx -= 200;
/* delay transmission to simulate airtime */
zepdev->ack_timer.callback = _send_frame;
ztimer_set(ZTIMER_USEC, &zepdev->ack_timer, time_tx);
}

return 0;
}
Expand Down
42 changes: 21 additions & 21 deletions cpu/nrf52/radio/nrf802154/nrf802154_radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
RADIO_SHORTS_CCABUSY_DISABLE_Msk | \
RADIO_SHORTS_TXREADY_START_Msk)

#define MAC_TIMER_CHAN_ACK (0U) /**< MAC timer channel for transmitting an ACK frame */
#define MAC_TIMER_CHAN_IFS (1U) /**< MAC timer channel for handling IFS logic */

static uint8_t rxbuf[IEEE802154_FRAME_LEN_MAX + 3]; /* len PHR + PSDU + LQI */
Expand All @@ -69,7 +68,6 @@ static uint8_t txbuf[IEEE802154_FRAME_LEN_MAX + 3]; /* len PHR + PSDU + LQI */
typedef enum {
STATE_IDLE,
STATE_TX,
STATE_ACK,
STATE_RX,
STATE_CCA_CLEAR,
STATE_CCA_BUSY,
Expand Down Expand Up @@ -415,6 +413,15 @@ static void _set_ifs_timer(bool lifs)
timer_start(NRF802154_TIMER);
}

static void _timer_cb(void *arg, int chan)
{
(void)arg;
if (chan == MAC_TIMER_CHAN_IFS) {
cfg.ifs = false;
}
timer_stop(NRF802154_TIMER);
}

/**
* @brief Set radio into DISABLED state
*/
Expand All @@ -424,6 +431,12 @@ int nrf802154_init(void)
/* reset buffer */
rxbuf[0] = 0;
txbuf[0] = 0;

int result = timer_init(NRF802154_TIMER, TIMER_FREQ, _timer_cb, NULL);
assert(result >= 0);
(void)result;
timer_stop(NRF802154_TIMER);

/* power off peripheral (but do not release the HFXO as we never requested
* it so far) */
NRF_RADIO->POWER = 0;
Expand Down Expand Up @@ -478,7 +491,6 @@ void isr_radio(void)
break;
case STATE_RX:
if (NRF_RADIO->CRCSTATUS) {
bool l2filter_passed = _l2filter(rxbuf+1);
bool is_ack = rxbuf[1] & IEEE802154_FCF_TYPE_ACK;

/* If radio is in promiscuous mode, indicate packet and
Expand All @@ -488,21 +500,19 @@ void isr_radio(void)
_state = STATE_IDLE;
dev->cb(dev, IEEE802154_RADIO_INDICATION_RX_DONE);
}
/* If the L2 filter passes, device if the frame is indicated
* directly or if the driver should send an ACK frame before
* the indication */
else if (l2filter_passed) {
DEBUG("[nrf802154] RX frame doesn't require ACK frame.\n");
_state = STATE_IDLE;
dev->cb(dev, IEEE802154_RADIO_INDICATION_RX_DONE);
}
/* In case the packet is an ACK and the ACK filter is disabled,
* indicate the frame reception */
else if (is_ack && !cfg.ack_filter) {
DEBUG("[nrf802154] Received ACK.\n");
_state = STATE_IDLE;
dev->cb(dev, IEEE802154_RADIO_INDICATION_RX_DONE);
}
/* If the L2 filter passes the frame is indicated directly */
else if (_l2filter(rxbuf+1)) {
DEBUG("[nrf802154] RX data frame.\n");
_state = STATE_IDLE;
dev->cb(dev, IEEE802154_RADIO_INDICATION_RX_DONE);
}
/* If all failed, simply drop the frame and continue listening
* to incoming frames */
else {
Expand All @@ -515,16 +525,6 @@ void isr_radio(void)
dev->cb(dev, IEEE802154_RADIO_INDICATION_CRC_ERROR);
}
break;
case STATE_ACK:
_state = STATE_IDLE;

/* We disable the radio to avoid unwanted emissions (see ERRATA
* ID 204, "Switching between TX and RX causes unwanted emissions")
*/
_disable();
DEBUG("[nrf52840] TX ACK done.");
_set_ifs_timer(false);
break;
default:
assert(false);
}
Expand Down
28 changes: 23 additions & 5 deletions sys/net/link_layer/ieee802154/submac.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@

#define CSMA_SENDER_BACKOFF_PERIOD_UNIT_US (320U)
#define ACK_TIMEOUT_US (864U)
/* 2.4 GHz, 250 kb/s, O-QPSK 62.5 ksymbols/s, 1 / 62 500 s = 16 µs */
/* 12 symbols -> 12 * 16us = 192us */
#define SIFS_PERIOD_US (192U)

/* internal type for IEEE 802.15.4 frame control field */
enum ieee802154_fcf {
_FCF_BEACON = IEEE802154_FCF_TYPE_BEACON,
_FCF_DATA = IEEE802154_FCF_TYPE_DATA,
_FCF_ACK = IEEE802154_FCF_TYPE_ACK,
_FCF_MACCMD = IEEE802154_FCF_TYPE_MACCMD
};

static char *str_states[IEEE802154_FSM_STATE_NUMOF] = {
"INVALID",
Expand Down Expand Up @@ -131,7 +142,8 @@
}

static ieee802154_fsm_state_t _fsm_state_prepare(ieee802154_submac_t *submac,
ieee802154_fsm_ev_t ev);
ieee802154_fsm_ev_t ev,
enum ieee802154_fcf ftype);

static ieee802154_fsm_state_t _fsm_state_tx(ieee802154_submac_t *submac,
ieee802154_fsm_ev_t ev);
Expand All @@ -149,7 +161,7 @@
return res;
}
/* skip async Tx request */
_fsm_state_prepare(submac, IEEE802154_FSM_EV_BH);
_fsm_state_prepare(submac, IEEE802154_FSM_EV_BH, IEEE802154_FCF_TYPE_ACK);
/* wait for Tx done */
while (_fsm_state_tx(submac, IEEE802154_FSM_EV_TX_DONE) == IEEE802154_FSM_STATE_INVALID) {
DEBUG("IEEE802154 submac: wait until ACK sent\n");
Expand Down Expand Up @@ -254,13 +266,15 @@
}

static ieee802154_fsm_state_t _fsm_state_prepare(ieee802154_submac_t *submac,
ieee802154_fsm_ev_t ev)
ieee802154_fsm_ev_t ev,
enum ieee802154_fcf ftype)
{
ieee802154_dev_t *dev = &submac->dev;

switch (ev) {
case IEEE802154_FSM_EV_BH:
if (!_does_handle_csma(dev)) {
if (ftype == IEEE802154_FCF_TYPE_DATA
&& !_does_handle_csma(dev)) {
/* delay for an adequate random backoff period */
uint32_t bp = (random_uint32() & submac->backoff_mask) *
submac->csma_backoff_us;
Expand All @@ -272,6 +286,10 @@
submac->backoff_mask = (submac->backoff_mask << 1) | 1;
}
}
else if (ftype == IEEE802154_FCF_TYPE_ACK) {
/* no backoff for ACK frames but wait for SIFSPeriod */
ztimer_sleep(ZTIMER_USEC, SIFS_PERIOD_US);
}

while (ieee802154_radio_request_transmit(dev) == -EBUSY) {}
return IEEE802154_FSM_STATE_TX;
Expand Down Expand Up @@ -414,23 +432,23 @@

switch (submac->fsm_state) {
case IEEE802154_FSM_STATE_RX:
DEBUG("IEEE802154 submac: ieee802154_submac_process_ev(): IEEE802154_FSM_STATE_RX + %s\n", str_ev[ev]);

Check warning on line 435 in sys/net/link_layer/ieee802154/submac.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
new_state = _fsm_state_rx(submac, ev);
break;
case IEEE802154_FSM_STATE_IDLE:
DEBUG("IEEE802154 submac: ieee802154_submac_process_ev(): IEEE802154_FSM_STATE_IDLE + %s\n", str_ev[ev]);

Check warning on line 439 in sys/net/link_layer/ieee802154/submac.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
new_state = _fsm_state_idle(submac, ev);
break;
case IEEE802154_FSM_STATE_PREPARE:
DEBUG("IEEE802154 submac: ieee802154_submac_process_ev(): IEEE802154_FSM_STATE_PREPARE + %s\n", str_ev[ev]);

Check warning on line 443 in sys/net/link_layer/ieee802154/submac.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
new_state = _fsm_state_prepare(submac, ev);
new_state = _fsm_state_prepare(submac, ev, IEEE802154_FCF_TYPE_DATA);
break;
case IEEE802154_FSM_STATE_TX:
DEBUG("IEEE802154 submac: ieee802154_submac_process_ev(): IEEE802154_FSM_STATE_TX + %s\n", str_ev[ev]);

Check warning on line 447 in sys/net/link_layer/ieee802154/submac.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
new_state = _fsm_state_tx(submac, ev);
break;
case IEEE802154_FSM_STATE_WAIT_FOR_ACK:
DEBUG("IEEE802154 submac: ieee802154_submac_process_ev(): IEEE802154_FSM_STATE_WAIT_FOR_ACK + %s\n", str_ev[ev]);

Check warning on line 451 in sys/net/link_layer/ieee802154/submac.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
new_state = _fsm_state_wait_for_ack(submac, ev);
break;
default:
Expand All @@ -451,7 +469,7 @@
ieee802154_fsm_state_t current_state = submac->fsm_state;

if (current_state != IEEE802154_FSM_STATE_RX && current_state != IEEE802154_FSM_STATE_IDLE) {
DEBUG("IEEE802154 submac: ieee802154_send(): Sending aborted, current state is %s\n", str_states[current_state]);

Check warning on line 472 in sys/net/link_layer/ieee802154/submac.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
return -EBUSY;
}

Expand All @@ -472,12 +490,12 @@

if (!is_ack && ieee802154_submac_process_ev(submac, IEEE802154_FSM_EV_REQUEST_TX)
!= IEEE802154_FSM_STATE_PREPARE) {
DEBUG("IEEE802154 submac: ieee802154_send(): Tx frame failed %s\n", str_states[current_state]);

Check warning on line 493 in sys/net/link_layer/ieee802154/submac.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
return -EBUSY;
}
if (is_ack && ieee802154_submac_process_ev(submac, IEEE802154_FSM_EV_REQUEST_TX)
!= IEEE802154_FSM_STATE_IDLE) {
DEBUG("IEEE802154 submac: ieee802154_send(): Tx ACK failed %s\n", str_states[current_state]);

Check warning on line 498 in sys/net/link_layer/ieee802154/submac.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
return -EBUSY;
}
return 0;
Expand Down
Loading