Skip to content

Commit 9112242

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 9112242

File tree

1 file changed

+36
-12
lines changed

1 file changed

+36
-12
lines changed

drivers/ieee802154/ieee802154_nrf5.c

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

10131045
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);
1046+
nrf5_receive_at(config);
10241047
} break;
10251048

10261049
case IEEE802154_CONFIG_CSL_PERIOD: {
@@ -1136,7 +1159,8 @@ void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id)
11361159
const struct device *dev = nrf5_get_device();
11371160

11381161
#if defined(CONFIG_IEEE802154_CSL_ENDPOINT)
1139-
if (id == DRX_SLOT_RX && error == NRF_802154_RX_ERROR_DELAYED_TIMEOUT) {
1162+
if ((id == DRX_SLOT_RX_PRIMARY || id == DRX_SLOT_RX_SECONDARY)
1163+
&& error == NRF_802154_RX_ERROR_DELAYED_TIMEOUT) {
11401164
if (!nrf5_data.rx_on_when_idle) {
11411165
/* Transition to RxOff done automatically by the driver */
11421166
return;

0 commit comments

Comments
 (0)