1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #15237 from jia200x/pr/fix_hal_nrf802154

radio/nrf802154: fix state transition and `off` function
This commit is contained in:
benpicco 2020-10-20 23:30:25 +02:00 committed by GitHub
commit 8c9bc2ada0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 11 deletions

View File

@ -172,6 +172,7 @@ static int _confirm_transmit(ieee802154_dev_t *dev, ieee802154_tx_info_t *info)
_state = STATE_IDLE;
NRF_RADIO->SHORTS = DEFAULT_SHORTS;
DEBUG("[nrf802154] TX Finished\n");
return 0;
}
@ -185,10 +186,12 @@ static int _request_transmit(ieee802154_dev_t *dev)
_state = STATE_TX;
if (cfg.cca_send) {
DEBUG("[nrf802154] Transmit a frame using CCA\n");
NRF_RADIO->SHORTS = CCA_SHORTS;
NRF_RADIO->TASKS_RXEN = 1;
}
else {
DEBUG("[nrf802154] Transmit a frame using Direct Transmission\n");
NRF_RADIO->TASKS_TXEN = 1;
}
@ -244,9 +247,11 @@ static int _confirm_cca(ieee802154_dev_t *dev)
switch (_state) {
case STATE_CCA_CLEAR:
DEBUG("[nrf802154] Channel is clear\n");
res = true;
break;
case STATE_CCA_BUSY:
DEBUG("[nrf802154] Channel is busy\n");
res = false;
break;
default:
@ -262,9 +267,11 @@ static int _request_cca(ieee802154_dev_t *dev)
(void) dev;
if (_state != STATE_RX) {
DEBUG("[nrf802154] CCA request fail: EBUSY\n");
return -EBUSY;
}
DEBUG("[nrf802154] CCA Requested\n");
/* Go back to RxIdle state and start CCA */
NRF_RADIO->TASKS_STOP = 1;
NRF_RADIO->TASKS_CCASTART = 1;
@ -298,6 +305,7 @@ static int set_cca_threshold(ieee802154_dev_t *dev, int8_t threshold)
static void _set_txpower(int16_t txpower)
{
DEBUG("[nrf802154]: Setting TX power to %i\n", txpower);
if (txpower > 8) {
NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Pos8dBm;
}
@ -360,6 +368,7 @@ static int _confirm_set_trx_state(ieee802154_dev_t *dev)
radio_state == RADIO_STATE_STATE_TxDisable || radio_state == RADIO_STATE_STATE_RxDisable) {
return -EAGAIN;
}
DEBUG("[nrf802154]: State transition finished\n");
return 0;
}
@ -368,6 +377,7 @@ static int _request_set_trx_state(ieee802154_dev_t *dev, ieee802154_trx_state_t
(void) dev;
if (_state != STATE_IDLE && _state != STATE_RX) {
DEBUG("[nrf802154]: set_trx_state failed: -EBUSY\n");
return -EBUSY;
}
@ -379,15 +389,18 @@ static int _request_set_trx_state(ieee802154_dev_t *dev, ieee802154_trx_state_t
switch (state) {
case IEEE802154_TRX_STATE_TRX_OFF:
_state = STATE_IDLE;
DEBUG("[nrf802154]: Request state to TRX_OFF\n");
break;
case IEEE802154_TRX_STATE_RX_ON:
NRF_RADIO->PACKETPTR = (uint32_t)rxbuf;
NRF_RADIO->TASKS_RXEN = 1;
_state = STATE_RX;
DEBUG("[nrf802154]: Request state to RX_ON\n");
break;
case IEEE802154_TRX_STATE_TX_ON:
NRF_RADIO->PACKETPTR = (uint32_t)txbuf;
_state = STATE_IDLE;
DEBUG("[nrf802154]: Request state to TX_ON\n");
break;
}
@ -418,6 +431,7 @@ static void _timer_cb(void *arg, int chan)
*/
int nrf802154_init(void)
{
DEBUG("[nrf802154]: Init\n");
/* reset buffer */
rxbuf[0] = 0;
txbuf[0] = 0;
@ -482,6 +496,7 @@ void isr_radio(void)
/* If radio is in promiscuos mode, indicate packet and
* don't event think of sending an ACK frame :) */
if (cfg.promisc) {
DEBUG("[nrf802154] Promiscuous mode is enabled.\n");
dev->cb(dev, IEEE802154_RADIO_INDICATION_RX_DONE);
}
/* If the L2 filter passes, device if the frame is indicated
@ -495,31 +510,31 @@ void isr_radio(void)
_state = STATE_ACK;
}
else {
DEBUG("[nrf802154] RX frame doesn't require ACK frame.\n");
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");
dev->cb(dev, IEEE802154_RADIO_INDICATION_RX_DONE);
}
/* If all failed, simply drop the frame and continue listening
* to incoming frames */
else {
DEBUG("[nrf802154] Addr filter failed or ACK filter on.\n");
NRF_RADIO->TASKS_START = 1;
}
}
else {
DEBUG("[nrf802154] CRC fail.\n");
NRF_RADIO->TASKS_START = 1;
}
break;
case STATE_ACK:
_state = STATE_RX;
NRF_RADIO->PACKETPTR = (uint32_t) rxbuf;
_disable();
/* This will take around 0.5 us */
while (NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) {};
NRF_RADIO->TASKS_RXEN = 1;
_state = STATE_IDLE;
DEBUG("[nrf52840] TX ACK done.")
_set_ifs_timer(false);
break;
default:
@ -540,6 +555,7 @@ static int _request_on(ieee802154_dev_t *dev)
{
(void) dev;
_state = STATE_IDLE;
DEBUG("[nrf802154]: Request to turn on\n");
NRF_RADIO->POWER = 1;
/* make sure the radio is disabled/stopped */
_disable();
@ -578,13 +594,17 @@ static int _request_on(ieee802154_dev_t *dev)
static int _config_phy(ieee802154_dev_t *dev, const ieee802154_phy_conf_t *conf)
{
(void) dev;
_disable();
int8_t pow = conf->pow;
if (pow < TX_POWER_MIN || pow > TX_POWER_MAX) {
return -EINVAL;
}
_disable();
/* This will take in worst case 21 us */
while (NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) {};
/* The value of this register represents the frequency offset (in MHz) from
* 2400 MHz. Channel 11 (first 2.4 GHz band channel) starts at 2405 MHz
* and all channels have a bandwidth of 5 MHz. Thus, we subtract 10 to the
@ -592,14 +612,25 @@ static int _config_phy(ieee802154_dev_t *dev, const ieee802154_phy_conf_t *conf)
*/
NRF_RADIO->FREQUENCY = (((uint8_t) conf->channel) - 10) * 5;
DEBUG("[nrf802154] setting channel to %i\n", conf->channel);
DEBUG("[nrf802154] setting TX power to %i\n", conf->pow);
_set_txpower(pow);
if (_state == STATE_RX) {
NRF_RADIO->TASKS_RXEN = 1;
/* This takes in worst case 40 us */
while (NRF_RADIO->STATE == RADIO_STATE_STATE_RxRu) {}
}
return 0;
}
static int _off(ieee802154_dev_t *dev)
{
(void) dev;
NRF_RADIO->POWER = 1;
DEBUG("[nrf802154] Turning off the radio\n");
NRF_RADIO->POWER = 0;
return 0;
}
@ -619,6 +650,7 @@ static bool _get_cap(ieee802154_dev_t *dev, ieee802154_rf_caps_t cap)
int _len(ieee802154_dev_t *dev)
{
(void) dev;
DEBUG("[nrf802154] Length of frame is %i\n", (size_t)rxbuf[0] - IEEE802154_FCS_LEN);
return (size_t)rxbuf[0] - IEEE802154_FCS_LEN;
}
@ -631,15 +663,19 @@ int _set_cca_mode(ieee802154_dev_t *dev, ieee802154_cca_mode_t mode)
switch (mode) {
case IEEE802154_CCA_MODE_ED_THRESHOLD:
DEBUG("[nrf802154]: set CCA Mode to ED Threshold\n");
tmp = RADIO_CCACTRL_CCAMODE_EdMode;
break;
case IEEE802154_CCA_MODE_CARRIER_SENSING:
tmp = RADIO_CCACTRL_CCAMODE_CarrierOrEdMode;
DEBUG("[nrf802154]: set CCA Mode to Carrier Sensing\n");
break;
case IEEE802154_CCA_MODE_ED_THRESH_AND_CS:
DEBUG("[nrf802154]: set CCA Mode to ED Threshold AND Carrier Sensing\n");
tmp = RADIO_CCACTRL_CCAMODE_CarrierAndEdMode;
break;
case IEEE802154_CCA_MODE_ED_THRESH_OR_CS:
DEBUG("[nrf802154]: set CCA Mode to ED Threshold OR Carrier Sensing\n");
tmp = RADIO_CCACTRL_CCAMODE_CarrierOrEdMode;
break;
}
@ -720,6 +756,7 @@ void nrf802154_setup(nrf802154_t *dev)
#if IS_USED(MODULE_NETDEV_IEEE802154_SUBMAC)
netdev_t *netdev = (netdev_t*) dev;
netdev_register(netdev, NETDEV_NRF802154, 0);
DEBUG("[nrf802154] init submac.\n")
netdev_ieee802154_submac_init(&dev->netdev, &nrf802154_hal_dev);
#endif
nrf802154_init();

View File

@ -116,6 +116,10 @@ void _rx_done_handler(event_t *event)
/* Print packet while we wait for the state transition */
_print_packet(size, info.lqi, info.rssi);
}
/* Go out of the HAL's FB Lock state after frame reception and trigger a
* state change */
_set_trx_state(IEEE802154_TRX_STATE_RX_ON, false);
}
static event_t _rx_done_event = {
@ -228,6 +232,7 @@ static int _init(void)
ieee802154_phy_conf_t conf = {.channel=CONFIG_IEEE802154_DEFAULT_CHANNEL, .page=CONFIG_IEEE802154_DEFAULT_SUBGHZ_PAGE, .pow=CONFIG_IEEE802154_DEFAULT_TXPOWER};
ieee802154_radio_config_phy(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), &conf);
ieee802154_radio_set_cca_threshold(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), CONFIG_IEEE802154_CCA_THRESH_DEFAULT);
/* Set the transceiver state to RX_ON in order to receive packets */
_set_trx_state(IEEE802154_TRX_STATE_RX_ON, false);
@ -482,9 +487,6 @@ int config_phy(int argc, char **argv)
puts("Success!");
}
/* Set the transceiver state to RX_ON in order to receive packets */
_set_trx_state(IEEE802154_TRX_STATE_RX_ON, false);
return 0;
}