Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ieee802154/submac: fix initialization code #16533

Merged
merged 5 commits into from
Aug 4, 2021
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
43 changes: 23 additions & 20 deletions drivers/netdev_ieee802154_submac/netdev_ieee802154_submac.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,30 @@ static int _init(netdev_t *netdev)
netdev_ieee802154_submac_t,
dev);
ieee802154_submac_t *submac = &netdev_submac->submac;
ieee802154_submac_init(submac, (network_uint16_t*) netdev_ieee802154->short_addr, (eui64_t*) netdev_ieee802154->long_addr);
netdev_ieee802154_setup(netdev_ieee802154);

int res = ieee802154_submac_init(submac,
(network_uint16_t*) netdev_ieee802154->short_addr,
(eui64_t*) netdev_ieee802154->long_addr);

if (res < 0) {
return res;
}

/* This function already sets the PAN ID to the default one */
netdev_ieee802154_reset(netdev_ieee802154);

uint16_t chan = submac->channel_num;
int16_t tx_power = submac->tx_pow;
netopt_enable_t enable = NETOPT_ENABLE;

/* Initialise netdev_ieee802154_t struct */
netdev_ieee802154_set(netdev_ieee802154, NETOPT_CHANNEL,
&chan, sizeof(chan));
netdev_ieee802154_set(netdev_ieee802154, NETOPT_ACK_REQ,
&enable, sizeof(enable));

netdev_submac->dev.txpower = tx_power;
return 0;
}

Expand All @@ -325,25 +347,6 @@ int netdev_ieee802154_submac_init(netdev_ieee802154_submac_t *netdev_submac,
netdev_submac->ack_timer.callback = _ack_timeout;
netdev_submac->ack_timer.arg = netdev_submac;

netdev_ieee802154_t *netdev_ieee802154 = &netdev_submac->dev;

/* This function already sets the PAN ID to the default one */
netdev_ieee802154_reset(netdev_ieee802154);

uint16_t chan = CONFIG_IEEE802154_DEFAULT_CHANNEL;
int16_t tx_power = CONFIG_IEEE802154_DEFAULT_TXPOWER;
netopt_enable_t enable = NETOPT_ENABLE;

netdev_ieee802154_setup(netdev_ieee802154);

/* Initialise netdev_ieee802154_t struct */
netdev_ieee802154_set(netdev_ieee802154, NETOPT_CHANNEL,
&chan, sizeof(chan));
netdev_ieee802154_set(netdev_ieee802154, NETOPT_ACK_REQ,
&enable, sizeof(enable));

netdev_submac->dev.txpower = tx_power;

return 0;
}

Expand Down
65 changes: 43 additions & 22 deletions sys/net/link_layer/ieee802154/submac.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,32 @@

static void _handle_tx_no_ack(ieee802154_submac_t *submac);

static inline void _req_set_trx_state_wait_busy(ieee802154_dev_t *dev,
ieee802154_trx_state_t state)
{
int res;

/* Some radios will run some house keeping tasks on event suchs as RX_DONE
* (e.g sending ACK frames) or TX_DONE. In such case we need to wait until
* the radio is not busy.
*/
do {
res = ieee802154_radio_request_set_trx_state(dev, state);
}
while (res == -EBUSY);
assert(res >= 0);
}

static void _tx_end(ieee802154_submac_t *submac, int status,
ieee802154_tx_info_t *info)
{
ieee802154_dev_t *dev = submac->dev;

ieee802154_radio_request_set_trx_state(dev, submac->state == IEEE802154_STATE_LISTEN ? IEEE802154_TRX_STATE_RX_ON : IEEE802154_TRX_STATE_TRX_OFF);
ieee802154_trx_state_t next_state = submac->state == IEEE802154_STATE_LISTEN
? IEEE802154_TRX_STATE_RX_ON
: IEEE802154_TRX_STATE_TRX_OFF;

_req_set_trx_state_wait_busy(dev, next_state);
submac->wait_for_ack = false;
submac->tx = false;
while (ieee802154_radio_confirm_set_trx_state(dev) == -EAGAIN) {}
Expand All @@ -53,7 +72,8 @@ static int _perform_csma_ca(ieee802154_submac_t *submac)
ieee802154_dev_t *dev = submac->dev;

if (submac->csma_retries_nb <= submac->csma_retries) {
ieee802154_radio_request_set_trx_state(dev, IEEE802154_TRX_STATE_TX_ON);
_req_set_trx_state_wait_busy(dev, IEEE802154_TRX_STATE_TX_ON);

/* delay for an adequate random backoff period */
uint32_t bp = (random_uint32() & submac->backoff_mask) *
CSMA_SENDER_BACKOFF_PERIOD_UNIT_MS;
Expand Down Expand Up @@ -104,7 +124,7 @@ int ieee802154_csma_ca_transmit(ieee802154_submac_t *submac)
ieee802154_radio_has_frame_retrans(dev)) {

/* Make sure we are in TX_ON */
ieee802154_radio_request_set_trx_state(dev, IEEE802154_TRX_STATE_TX_ON);
_req_set_trx_state_wait_busy(dev, IEEE802154_TRX_STATE_TX_ON);
while (ieee802154_radio_confirm_set_trx_state(dev) == -EAGAIN) {}

int res;
Expand All @@ -131,7 +151,9 @@ static void _perform_retrans(ieee802154_submac_t *submac)

if (_has_retrans_left(submac)) {
submac->retrans++;
ieee802154_csma_ca_transmit(submac);
int res = ieee802154_csma_ca_transmit(submac);
(void) res;
assert(res >= 0);
}
else {
ieee802154_radio_set_frame_filter_mode(dev, IEEE802154_FILTER_ACCEPT);
Expand All @@ -150,8 +172,9 @@ 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);
_req_set_trx_state_wait_busy(dev, IEEE802154_TRX_STATE_RX_ON);
while (ieee802154_radio_confirm_set_trx_state(dev) == -EAGAIN) {}
}

Expand Down Expand Up @@ -190,11 +213,7 @@ void ieee802154_submac_rx_done_cb(ieee802154_submac_t *submac)
* transition here in order to release it */
ieee802154_trx_state_t next_state = submac->state == IEEE802154_STATE_LISTEN ? IEEE802154_TRX_STATE_RX_ON : IEEE802154_TRX_STATE_TRX_OFF;

/* Some radios will run some house keeping tasks on RX_DONE (e.g
* sending ACK frames). In such case we need to wait until the radio is
* not busy
*/
while (ieee802154_radio_request_set_trx_state(submac->dev, next_state) == -EBUSY);
_req_set_trx_state_wait_busy(submac->dev, next_state);
while (ieee802154_radio_confirm_set_trx_state(submac->dev) == -EAGAIN) {}
}
}
Expand Down Expand Up @@ -228,7 +247,6 @@ static void _handle_tx_medium_busy(ieee802154_submac_t *submac)

if (ieee802154_radio_has_frame_retrans(dev) ||
ieee802154_radio_has_auto_csma(dev)) {
ieee802154_radio_request_set_trx_state(dev, IEEE802154_TRX_STATE_RX_ON);
_tx_end(submac, TX_STATUS_MEDIUM_BUSY, NULL);
}
else {
Expand All @@ -242,7 +260,6 @@ static void _handle_tx_no_ack(ieee802154_submac_t *submac)
ieee802154_dev_t *dev = submac->dev;

if (ieee802154_radio_has_frame_retrans(dev)) {
ieee802154_radio_request_set_trx_state(dev, IEEE802154_TRX_STATE_RX_ON);
_tx_end(submac, TX_STATUS_NO_ACK, NULL);
}
else {
Expand Down Expand Up @@ -300,8 +317,7 @@ int ieee802154_send(ieee802154_submac_t *submac, const iolist_t *iolist)
submac->wait_for_ack = cnf;
submac->retrans = 0;

ieee802154_csma_ca_transmit(submac);
return 0;
return ieee802154_csma_ca_transmit(submac);
}

int ieee802154_submac_init(ieee802154_submac_t *submac, const network_uint16_t *short_addr,
Expand All @@ -312,7 +328,10 @@ int ieee802154_submac_init(ieee802154_submac_t *submac, const network_uint16_t *
submac->tx = false;
submac->state = IEEE802154_STATE_LISTEN;

ieee802154_radio_request_on(dev);
int res;
if ((res = ieee802154_radio_request_on(dev)) < 0) {
return res;
}

/* generate EUI-64 and short address */
memcpy(&submac->ext_addr, ext_addr, sizeof(eui64_t));
Expand Down Expand Up @@ -370,17 +389,19 @@ int ieee802154_submac_init(ieee802154_submac_t *submac, const network_uint16_t *
/* Configure PHY settings (mode, channel, TX power) */
ieee802154_phy_conf_t conf =
{ .phy_mode = submac->phy_mode,
.channel = CONFIG_IEEE802154_DEFAULT_CHANNEL,
.page = CONFIG_IEEE802154_DEFAULT_CHANNEL,
.pow = CONFIG_IEEE802154_DEFAULT_TXPOWER };
.channel = submac->channel_num,
.page = submac->channel_page,
.pow = submac->tx_pow };

ieee802154_radio_config_phy(dev, &conf);
assert(ieee802154_radio_set_cca_threshold(dev,
CONFIG_IEEE802154_CCA_THRESH_DEFAULT) >= 0);
ieee802154_radio_set_cca_threshold(dev,
CONFIG_IEEE802154_CCA_THRESH_DEFAULT);
assert(res >= 0);

ieee802154_radio_request_set_trx_state(dev, IEEE802154_TRX_STATE_RX_ON);
_req_set_trx_state_wait_busy(dev, IEEE802154_TRX_STATE_RX_ON);
while (ieee802154_radio_confirm_set_trx_state(dev) == -EAGAIN) {};

return 0;
return res;
}

int ieee802154_set_phy_conf(ieee802154_submac_t *submac, uint16_t channel_num,
Expand Down