@@ -611,8 +611,15 @@ uint32_t radio_is_address(void)
611
611
}
612
612
613
613
#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER )
614
+ static uint32_t last_pdu_end_latency_us ;
614
615
static uint32_t last_pdu_end_us ;
615
616
617
+ static void last_pdu_end_us_init (uint32_t latency_us )
618
+ {
619
+ last_pdu_end_latency_us = latency_us ;
620
+ last_pdu_end_us = 0U ;
621
+ }
622
+
616
623
uint32_t radio_is_done (void )
617
624
{
618
625
if (NRF_RADIO -> NRF_RADIO_TRX_END_EVENT != 0 ) {
@@ -1388,7 +1395,11 @@ void radio_tmr_tifs_set(uint32_t tifs)
1388
1395
1389
1396
uint32_t radio_tmr_start (uint8_t trx , uint32_t ticks_start , uint32_t remainder )
1390
1397
{
1398
+ uint32_t remainder_us ;
1399
+
1400
+ /* Convert jitter to positive offset remainder in microseconds */
1391
1401
hal_ticker_remove_jitter (& ticks_start , & remainder );
1402
+ remainder_us = remainder ;
1392
1403
1393
1404
#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER )
1394
1405
/* When using single timer for software tIFS switching, ensure that
@@ -1401,18 +1412,18 @@ uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder)
1401
1412
uint32_t latency_ticks ;
1402
1413
uint32_t latency_us ;
1403
1414
1404
- latency_us = MAX (remainder , HAL_RADIO_ISR_LATENCY_MAX_US ) - remainder ;
1415
+ latency_us = MAX (remainder_us , HAL_RADIO_ISR_LATENCY_MAX_US ) - remainder_us ;
1405
1416
latency_ticks = HAL_TICKER_US_TO_TICKS (latency_us );
1406
1417
ticks_start -= latency_ticks ;
1407
- remainder += latency_us ;
1408
- #endif /* ! CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1418
+ remainder_us += latency_us ;
1419
+ #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1409
1420
1410
1421
nrf_timer_task_trigger (EVENT_TIMER , NRF_TIMER_TASK_CLEAR );
1411
1422
EVENT_TIMER -> MODE = 0 ;
1412
1423
EVENT_TIMER -> PRESCALER = HAL_EVENT_TIMER_PRESCALER_VALUE ;
1413
1424
EVENT_TIMER -> BITMODE = 2 ; /* 24 - bit */
1414
1425
1415
- nrf_timer_cc_set (EVENT_TIMER , HAL_EVENT_TIMER_TRX_CC_OFFSET , remainder );
1426
+ nrf_timer_cc_set (EVENT_TIMER , HAL_EVENT_TIMER_TRX_CC_OFFSET , remainder_us );
1416
1427
1417
1428
#if defined(CONFIG_BT_CTLR_NRF_GRTC )
1418
1429
uint32_t cntr_l , cntr_h , cntr_h_overflow , stale ;
@@ -1479,7 +1490,7 @@ uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder)
1479
1490
1480
1491
#if !defined(CONFIG_BT_CTLR_TIFS_HW )
1481
1492
#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER )
1482
- last_pdu_end_us = 0U ;
1493
+ last_pdu_end_us_init ( latency_us ) ;
1483
1494
1484
1495
#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1485
1496
nrf_timer_task_trigger (SW_SWITCH_TIMER , NRF_TIMER_TASK_CLEAR );
@@ -1506,15 +1517,15 @@ uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder)
1506
1517
#endif /* CONFIG_BT_CTLR_PHY_CODED && CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1507
1518
#endif /* !CONFIG_BT_CTLR_TIFS_HW */
1508
1519
1509
- return remainder ;
1520
+ return remainder_us ;
1510
1521
}
1511
1522
1512
1523
uint32_t radio_tmr_start_tick (uint8_t trx , uint32_t ticks_start )
1513
1524
{
1514
1525
uint32_t remainder_us ;
1515
1526
1516
1527
/* Setup compare event with min. 1 us offset */
1517
- remainder_us = 1 ;
1528
+ remainder_us = 1U ;
1518
1529
1519
1530
#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER )
1520
1531
/* When using single timer for software tIFS switching, ensure that
@@ -1531,7 +1542,7 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start)
1531
1542
latency_ticks = HAL_TICKER_US_TO_TICKS (latency_us );
1532
1543
ticks_start -= latency_ticks ;
1533
1544
remainder_us += latency_us ;
1534
- #endif /* ! CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1545
+ #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1535
1546
1536
1547
nrf_timer_task_trigger (EVENT_TIMER , NRF_TIMER_TASK_STOP );
1537
1548
nrf_timer_task_trigger (EVENT_TIMER , NRF_TIMER_TASK_CLEAR );
@@ -1603,7 +1614,7 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start)
1603
1614
1604
1615
#if !defined(CONFIG_BT_CTLR_TIFS_HW )
1605
1616
#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER )
1606
- last_pdu_end_us = 0U ;
1617
+ last_pdu_end_us_init ( latency_us ) ;
1607
1618
#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1608
1619
#if defined(CONFIG_SOC_COMPATIBLE_NRF53X ) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX )
1609
1620
/* NOTE: Timer clear DPPI configuration is needed only for nRF53
@@ -1630,7 +1641,10 @@ uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us)
1630
1641
1631
1642
#if !defined(CONFIG_BT_CTLR_TIFS_HW )
1632
1643
#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER )
1633
- last_pdu_end_us = 0U ;
1644
+ /* As timer is reset on every radio end, remove the accumulated
1645
+ * last_pdu_end_us in the given start_us.
1646
+ */
1647
+ start_us -= last_pdu_end_us ;
1634
1648
#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1635
1649
#if defined(CONFIG_SOC_COMPATIBLE_NRF53X ) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX )
1636
1650
/* NOTE: Timer clear DPPI configuration is needed only for nRF53
@@ -1672,7 +1686,7 @@ uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us)
1672
1686
1673
1687
latency_us = MAX (actual_us , HAL_RADIO_ISR_LATENCY_MAX_US ) - actual_us ;
1674
1688
actual_us += latency_us ;
1675
- #endif /* ! CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1689
+ #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1676
1690
1677
1691
nrf_timer_event_clear (EVENT_TIMER , HAL_EVENT_TIMER_TRX_EVENT );
1678
1692
nrf_timer_cc_set (EVENT_TIMER , HAL_EVENT_TIMER_TRX_CC_OFFSET , actual_us );
@@ -1684,6 +1698,10 @@ uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us)
1684
1698
} while ((now_us > start_us ) &&
1685
1699
(EVENT_TIMER -> EVENTS_COMPARE [HAL_EVENT_TIMER_TRX_CC_OFFSET ] == 0U ));
1686
1700
1701
+ #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER )
1702
+ actual_us += last_pdu_end_us ;
1703
+ #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1704
+
1687
1705
return actual_us ;
1688
1706
}
1689
1707
@@ -1697,9 +1715,26 @@ uint32_t radio_tmr_start_now(uint8_t trx)
1697
1715
nrf_timer_task_trigger (EVENT_TIMER , HAL_EVENT_TIMER_SAMPLE_TASK );
1698
1716
start_us = EVENT_TIMER -> CC [HAL_EVENT_TIMER_SAMPLE_CC_OFFSET ];
1699
1717
1718
+ #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER )
1719
+ /* As timer is reset on every radio end, add the accumulated
1720
+ * last_pdu_end_us to the captured current time.
1721
+ */
1722
+ start_us += last_pdu_end_us ;
1723
+ #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1724
+
1700
1725
/* Setup radio start at current time */
1701
1726
start_us = radio_tmr_start_us (trx , start_us );
1702
1727
1728
+ #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER )
1729
+ /* Remove the single timer start latency used to mitigate use of too
1730
+ * small compare register value. Thus, start_us returned be always
1731
+ * the value corresponding to the captured radio ready timestamp.
1732
+ * This is used in the calculation of aux_offset in subsequent
1733
+ * ADV_EXT_IND PDUs.
1734
+ */
1735
+ start_us -= last_pdu_end_latency_us ;
1736
+ #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1737
+
1703
1738
return start_us ;
1704
1739
}
1705
1740
@@ -1721,28 +1756,39 @@ uint32_t radio_tmr_start_get(void)
1721
1756
return start_ticks ;
1722
1757
}
1723
1758
1759
+ uint32_t radio_tmr_start_latency_get (void )
1760
+ {
1761
+ #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER )
1762
+ return last_pdu_end_latency_us ;
1763
+ #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1764
+ return 0U ;
1765
+ #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1766
+ }
1767
+
1724
1768
void radio_tmr_stop (void )
1725
1769
{
1726
1770
nrf_timer_task_trigger (EVENT_TIMER , NRF_TIMER_TASK_STOP );
1727
1771
#if defined(TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk )
1728
1772
nrf_timer_task_trigger (EVENT_TIMER , NRF_TIMER_TASK_SHUTDOWN );
1729
- #endif
1773
+ #endif /* TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk */
1730
1774
1731
1775
#if !defined(CONFIG_BT_CTLR_TIFS_HW )
1776
+ #if !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER )
1732
1777
nrf_timer_task_trigger (SW_SWITCH_TIMER , NRF_TIMER_TASK_STOP );
1733
1778
#if defined(TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk )
1734
1779
nrf_timer_task_trigger (SW_SWITCH_TIMER , NRF_TIMER_TASK_SHUTDOWN );
1735
- #endif
1780
+ #endif /* TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk */
1781
+ #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1736
1782
#endif /* !CONFIG_BT_CTLR_TIFS_HW */
1737
1783
1738
1784
#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX )
1739
1785
NRF_POWER -> TASKS_LOWPWR = 1U ;
1740
1786
#endif /* CONFIG_SOC_COMPATIBLE_NRF54LX */
1741
1787
}
1742
1788
1743
- void radio_tmr_hcto_configure (uint32_t hcto )
1789
+ void radio_tmr_hcto_configure (uint32_t hcto_us )
1744
1790
{
1745
- nrf_timer_cc_set (EVENT_TIMER , HAL_EVENT_TIMER_HCTO_CC_OFFSET , hcto );
1791
+ nrf_timer_cc_set (EVENT_TIMER , HAL_EVENT_TIMER_HCTO_CC_OFFSET , hcto_us );
1746
1792
1747
1793
hal_radio_recv_timeout_cancel_ppi_config ();
1748
1794
hal_radio_disable_on_hcto_ppi_config ();
@@ -1751,6 +1797,18 @@ void radio_tmr_hcto_configure(uint32_t hcto)
1751
1797
BIT (HAL_RADIO_DISABLE_ON_HCTO_PPI ));
1752
1798
}
1753
1799
1800
+ void radio_tmr_hcto_configure_abs (uint32_t hcto_from_start_us )
1801
+ {
1802
+ #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER )
1803
+ /* As timer is reset on every radio end, remove the accumulated
1804
+ * last_pdu_end_us in the given hcto_us.
1805
+ */
1806
+ hcto_from_start_us -= last_pdu_end_us ;
1807
+ #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1808
+
1809
+ radio_tmr_hcto_configure (hcto_from_start_us );
1810
+ }
1811
+
1754
1812
void radio_tmr_aa_capture (void )
1755
1813
{
1756
1814
hal_radio_ready_time_capture_ppi_config ();
@@ -1825,7 +1883,11 @@ uint32_t radio_tmr_end_get(void)
1825
1883
1826
1884
uint32_t radio_tmr_tifs_base_get (void )
1827
1885
{
1886
+ #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER )
1887
+ return 0U ;
1888
+ #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1828
1889
return radio_tmr_end_get ();
1890
+ #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1829
1891
}
1830
1892
1831
1893
#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER )
0 commit comments