Skip to content

Commit 4ea350f

Browse files
committed
drivers: ieee802154: nrf5: new RX window cancels previous RX
According to the documentation of IEEE802154_CONFIG_RX_SLOT, if the previous RX slot hasn't begun yet, but a new one is scheduled, then the previous RX slot must be cancelled. The new RX slot effectively replaces the old one. If the previous slot is currently ongoing, then it is not affected. The new RX slot can be scheduled while the previous slot is still ongoing. Signed-off-by: Rafał Kuźnia <[email protected]>
1 parent 843ff70 commit 4ea350f

File tree

1 file changed

+37
-12
lines changed

1 file changed

+37
-12
lines changed

drivers/ieee802154/ieee802154_nrf5.c

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ static struct nrf5_802154_data nrf5_data;
6767
static const struct device *nrf5_dev;
6868
#endif
6969

70-
#define DRX_SLOT_RX 0 /* Delayed reception window ID */
70+
#define DRX_SLOT_RX_PRIMARY 0 /* Primary delayed reception window ID */
71+
#define DRX_SLOT_RX_SECONDARY 1 /* Secondary delayed reception window ID */
7172

7273
#define NSEC_PER_TEN_SYMBOLS (10 * IEEE802154_PHY_OQPSK_780_TO_2450MHZ_SYMBOL_PERIOD_NS)
7374

@@ -855,6 +856,38 @@ static void nrf5_config_mac_keys(struct ieee802154_key *mac_keys)
855856
}
856857
#endif /* CONFIG_NRF_802154_ENCRYPTION */
857858

859+
#if defined(CONFIG_IEEE802154_CSL_ENDPOINT)
860+
861+
static void nrf5_receive_at(const struct ieee802154_config *config)
862+
{
863+
bool primary_cancel = nrf_802154_receive_at_scheduled_cancel(DRX_SLOT_RX_PRIMARY);
864+
bool secondary_cancel = nrf_802154_receive_at_scheduled_cancel(DRX_SLOT_RX_SECONDARY);
865+
866+
if (!primary_cancel && !secondary_cancel) {
867+
/* Edge case: In between the primary and secondary slot cancellation
868+
* the secondary RX slot might have started. Due to ordering
869+
* of the above two cancellations we can assume that the primary
870+
* slot is already free.
871+
*/
872+
primary_cancel = true;
873+
}
874+
875+
uint32_t slot_id = primary_cancel ? DRX_SLOT_RX_PRIMARY : DRX_SLOT_RX_SECONDARY;
876+
877+
/* Note that even if the nrf_802154_receive_at function is not called in time
878+
* (for example due to the call being blocked by higher priority threads) and
879+
* the delayed reception window is not scheduled, the CSL phase will still be
880+
* calculated as if the following reception windows were at times
881+
* anchor_time + n * csl_period. The previously set
882+
* anchor_time will be used for calculations.
883+
*/
884+
nrf_802154_receive_at(config->rx_slot.start / NSEC_PER_USEC,
885+
config->rx_slot.duration / NSEC_PER_USEC,
886+
config->rx_slot.channel, slot_id);
887+
}
888+
889+
#endif /* CONFIG_IEEE802154_CSL_ENDPOINT */
890+
858891
static int nrf5_configure(const struct device *dev,
859892
enum ieee802154_config_type type,
860893
const struct ieee802154_config *config)
@@ -1011,16 +1044,7 @@ static int nrf5_configure(const struct device *dev,
10111044
} break;
10121045

10131046
case IEEE802154_CONFIG_RX_SLOT: {
1014-
/* Note that even if the nrf_802154_receive_at function is not called in time
1015-
* (for example due to the call being blocked by higher priority threads) and
1016-
* the delayed reception window is not scheduled, the CSL phase will still be
1017-
* calculated as if the following reception windows were at times
1018-
* anchor_time + n * csl_period. The previously set
1019-
* anchor_time will be used for calculations.
1020-
*/
1021-
nrf_802154_receive_at(config->rx_slot.start / NSEC_PER_USEC,
1022-
config->rx_slot.duration / NSEC_PER_USEC,
1023-
config->rx_slot.channel, DRX_SLOT_RX);
1047+
nrf5_receive_at(config);
10241048
} break;
10251049

10261050
case IEEE802154_CONFIG_CSL_PERIOD: {
@@ -1136,7 +1160,8 @@ void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id)
11361160
const struct device *dev = nrf5_get_device();
11371161

11381162
#if defined(CONFIG_IEEE802154_CSL_ENDPOINT)
1139-
if (id == DRX_SLOT_RX && error == NRF_802154_RX_ERROR_DELAYED_TIMEOUT) {
1163+
if ((id == DRX_SLOT_RX_PRIMARY || id == DRX_SLOT_RX_SECONDARY)
1164+
&& error == NRF_802154_RX_ERROR_DELAYED_TIMEOUT) {
11401165
if (!nrf5_data.rx_on_when_idle) {
11411166
/* Transition to RxOff done automatically by the driver */
11421167
return;

0 commit comments

Comments
 (0)