@@ -238,6 +238,26 @@ static enum ieee802154_hw_caps nrf5_get_capabilities(const struct device *dev)
238
238
return nrf5_data .capabilities ;
239
239
}
240
240
241
+ FUNC_NORETURN static void nrf5_callback_timeout (void )
242
+ {
243
+ /* Callback from the radio driver did not come in specified timeout */
244
+ __ASSERT (false, "802.15.4 callback timeout" );
245
+ k_oops ();
246
+ CODE_UNREACHABLE ;
247
+ }
248
+
249
+ static void nrf5_callback_sem_take (struct k_sem * sem , uint32_t additional_ms )
250
+ {
251
+ if (CONFIG_IEEE802154_NRF5_CALLOUT_TIMEOUT_MS == 0 ) {
252
+ k_sem_take (sem , K_FOREVER );
253
+ } else {
254
+ if (k_sem_take (sem ,
255
+ K_MSEC (additional_ms + CONFIG_IEEE802154_NRF5_CALLOUT_TIMEOUT_MS )) != 0 ) {
256
+ nrf5_callback_timeout ();
257
+ }
258
+ }
259
+ }
260
+
241
261
static int nrf5_cca (const struct device * dev )
242
262
{
243
263
struct nrf5_802154_data * nrf5_radio = NRF5_802154_DATA (dev );
@@ -250,7 +270,7 @@ static int nrf5_cca(const struct device *dev)
250
270
/* The nRF driver guarantees that a callback will be called once
251
271
* the CCA function is done, thus unlocking the semaphore.
252
272
*/
253
- k_sem_take (& nrf5_radio -> cca_wait , K_FOREVER );
273
+ nrf5_callback_sem_take (& nrf5_radio -> cca_wait , 0 );
254
274
255
275
LOG_DBG ("Channel free? %d" , nrf5_radio -> channel_free );
256
276
@@ -480,8 +500,10 @@ static bool nrf5_tx_csma_ca(struct net_pkt *pkt, uint8_t *payload)
480
500
#if defined(CONFIG_NET_PKT_TXTIME )
481
501
/**
482
502
* @brief Convert 32-bit target time to absolute 64-bit target time.
503
+ * @param[in] target_time 32-bit time to convert
504
+ * @param[in] now_us Result of @ref nrf_802154_time_get
483
505
*/
484
- static uint64_t target_time_convert_to_64_bits (uint32_t target_time )
506
+ static uint64_t target_time_convert_to_64_bits_from_given (uint32_t target_time , uint64_t now_us )
485
507
{
486
508
/**
487
509
* Target time is provided as two 32-bit integers defining a moment in time
@@ -495,7 +517,6 @@ static uint64_t target_time_convert_to_64_bits(uint32_t target_time)
495
517
* time. Let's assume that half of the 32-bit range can be used for specifying
496
518
* target times in the future, and the other half - in the past.
497
519
*/
498
- uint64_t now_us = nrf_802154_time_get ();
499
520
uint32_t now_us_wrapped = (uint32_t )now_us ;
500
521
uint32_t time_diff = target_time - now_us_wrapped ;
501
522
uint64_t result = UINT64_C (0 );
@@ -545,7 +566,18 @@ static uint64_t target_time_convert_to_64_bits(uint32_t target_time)
545
566
return result ;
546
567
}
547
568
548
- static bool nrf5_tx_at (struct net_pkt * pkt , uint8_t * payload , bool cca )
569
+
570
+ #if defined(CONFIG_IEEE802154_CSL_ENDPOINT )
571
+ /**
572
+ * @brief Convert 32-bit target time to absolute 64-bit target time.
573
+ */
574
+ static uint64_t target_time_convert_to_64_bits (uint32_t target_time )
575
+ {
576
+ return target_time_convert_to_64_bits_from_given (target_time , nrf_802154_time_get ());
577
+ }
578
+ #endif
579
+
580
+ static bool nrf5_tx_at (struct net_pkt * pkt , uint8_t * payload , bool cca , uint32_t * time_ahead )
549
581
{
550
582
nrf_802154_transmit_at_metadata_t metadata = {
551
583
.frame_props = {
@@ -561,7 +593,16 @@ static bool nrf5_tx_at(struct net_pkt *pkt, uint8_t *payload, bool cca)
561
593
#endif
562
594
},
563
595
};
564
- uint64_t tx_at = target_time_convert_to_64_bits (net_pkt_txtime (pkt ) / NSEC_PER_USEC );
596
+ uint64_t now_us = nrf_802154_time_get ();
597
+ uint64_t tx_at = target_time_convert_to_64_bits_from_given (
598
+ net_pkt_txtime (pkt ) / NSEC_PER_USEC , now_us );
599
+
600
+ if (time_ahead != NULL ) {
601
+ * time_ahead = 0 ;
602
+ if (tx_at > now_us ) {
603
+ * time_ahead = (uint32_t )(tx_at - now_us );
604
+ }
605
+ }
565
606
566
607
return nrf_802154_transmit_raw_at (payload , tx_at , & metadata );
567
608
}
@@ -576,6 +617,7 @@ static int nrf5_tx(const struct device *dev,
576
617
uint8_t payload_len = frag -> len ;
577
618
uint8_t * payload = frag -> data ;
578
619
bool ret = true;
620
+ uint32_t callback_sem_take_additional_time = 0 ;
579
621
580
622
LOG_DBG ("%p (%u)" , payload , payload_len );
581
623
@@ -601,7 +643,9 @@ static int nrf5_tx(const struct device *dev,
601
643
case IEEE802154_TX_MODE_TXTIME_CCA :
602
644
__ASSERT_NO_MSG (pkt );
603
645
ret = nrf5_tx_at (pkt , nrf5_radio -> tx_psdu ,
604
- mode == IEEE802154_TX_MODE_TXTIME_CCA );
646
+ mode == IEEE802154_TX_MODE_TXTIME_CCA ,
647
+ & callback_sem_take_additional_time );
648
+ callback_sem_take_additional_time /= 1000 ;
605
649
break ;
606
650
#endif /* CONFIG_NET_PKT_TXTIME */
607
651
default :
@@ -620,7 +664,7 @@ static int nrf5_tx(const struct device *dev,
620
664
nrf_802154_channel_get (), nrf_802154_tx_power_get ());
621
665
622
666
/* Wait for the callback from the radio driver. */
623
- k_sem_take (& nrf5_radio -> tx_wait , K_FOREVER );
667
+ nrf5_callback_sem_take (& nrf5_radio -> tx_wait , callback_sem_take_additional_time );
624
668
625
669
LOG_DBG ("Result: %d" , nrf5_data .tx_result );
626
670
0 commit comments