@@ -67,7 +67,8 @@ static struct nrf5_802154_data nrf5_data;
67
67
static const struct device * nrf5_dev ;
68
68
#endif
69
69
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 */
71
72
72
73
#define NSEC_PER_TEN_SYMBOLS (10 * IEEE802154_PHY_OQPSK_780_TO_2450MHZ_SYMBOL_PERIOD_NS)
73
74
@@ -855,6 +856,38 @@ static void nrf5_config_mac_keys(struct ieee802154_key *mac_keys)
855
856
}
856
857
#endif /* CONFIG_NRF_802154_ENCRYPTION */
857
858
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
+
858
891
static int nrf5_configure (const struct device * dev ,
859
892
enum ieee802154_config_type type ,
860
893
const struct ieee802154_config * config )
@@ -1011,16 +1044,7 @@ static int nrf5_configure(const struct device *dev,
1011
1044
} break ;
1012
1045
1013
1046
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 );
1024
1048
} break ;
1025
1049
1026
1050
case IEEE802154_CONFIG_CSL_PERIOD : {
@@ -1136,7 +1160,8 @@ void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id)
1136
1160
const struct device * dev = nrf5_get_device ();
1137
1161
1138
1162
#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 ) {
1140
1165
if (!nrf5_data .rx_on_when_idle ) {
1141
1166
/* Transition to RxOff done automatically by the driver */
1142
1167
return ;
0 commit comments