Skip to content

Commit 5194dd9

Browse files
committed
nimble/phy: Add support for using GRTC of nRF54L15
In latest nrfx versions the support for RTCx for nRF54L15 has been removed and the GRTC should be used instead. The GRTC SYSCOUNTER has a resolution of 1us, so then optimal cputime freq would be equal to 31250Hz to ensure smooth calculations, but since the LL timing is tuned for 32768Hz, let's simulate the 32768Hz for now.
1 parent 824dd11 commit 5194dd9

4 files changed

Lines changed: 93 additions & 0 deletions

File tree

nimble/drivers/nrf5x/src/ble_phy.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,10 @@ struct nrf_ccm_data g_nrf_ccm_data;
424424
#endif
425425
#endif
426426

427+
#ifdef GRTC_AS_RADIO_TIMER
428+
uint64_t hal_grtc_counter_get(void);
429+
#endif
430+
427431
static void
428432
timer0_reset(void)
429433
{
@@ -725,6 +729,10 @@ ble_phy_tifs_set(uint16_t tifs)
725729
static int
726730
ble_phy_set_start_time(uint32_t cputime, uint8_t rem_us, bool tx)
727731
{
732+
#ifdef GRTC_AS_RADIO_TIMER
733+
uint64_t now_grtc;
734+
uint64_t start_us;
735+
#endif
728736
uint32_t next_cc;
729737
uint32_t cur_cc;
730738
uint32_t cntr;
@@ -795,8 +803,14 @@ ble_phy_set_start_time(uint32_t cputime, uint8_t rem_us, bool tx)
795803
* need to account for it.
796804
*/
797805
next_cc = cputime & 0xffffff;
806+
#ifdef GRTC_AS_RADIO_TIMER
807+
cur_cc = ble_phy_grtc_ticks_to_rtc(NRF_GRTC->CC[3].CCL) & 0xffffff;
808+
now_grtc = hal_grtc_counter_get();
809+
cntr = ble_phy_grtc_ticks_to_rtc(now_grtc) & 0xffffff;
810+
#else
798811
cur_cc = NRF_RTC0->CC[0];
799812
cntr = NRF_RTC0->COUNTER;
813+
#endif
800814

801815
delta = (cur_cc - cntr) & 0xffffff;
802816
if ((delta <= 3) && (delta != 0)) {
@@ -820,10 +834,17 @@ ble_phy_set_start_time(uint32_t cputime, uint8_t rem_us, bool tx)
820834
}
821835
#endif
822836

837+
#ifdef GRTC_AS_RADIO_TIMER
838+
start_us = now_grtc + ble_phy_rtc_ticks_to_grtc(delta);
839+
nrf_grtc_sys_counter_cc_set(NRF_GRTC, 3, start_us);
840+
NRF_GRTC->EVENTS_COMPARE[3] = 0;
841+
nrf_grtc_sys_counter_compare_event_enable(NRF_GRTC, 3);
842+
#else
823843
/* Set RTC compare to start TIMER0 */
824844
NRF_RTC0->EVENTS_COMPARE[0] = 0;
825845
nrf_rtc_cc_set(NRF_RTC0, 0, next_cc);
826846
nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk);
847+
#endif
827848

828849
/* Enable PPI */
829850
#if PHY_USE_FEM
@@ -851,6 +872,9 @@ static int
851872
ble_phy_set_start_now(void)
852873
{
853874
os_sr_t sr;
875+
#ifdef GRTC_AS_RADIO_TIMER
876+
uint64_t now_grtc;
877+
#endif
854878
uint32_t now;
855879
uint32_t radio_rem_us;
856880
#if PHY_USE_FEM_LNA
@@ -888,6 +912,13 @@ ble_phy_set_start_now(void)
888912
NRF_TIMER0->EVENTS_COMPARE[2] = 0;
889913
#endif
890914

915+
#ifdef GRTC_AS_RADIO_TIMER
916+
now_grtc = hal_grtc_counter_get();
917+
nrf_grtc_sys_counter_cc_set(NRF_GRTC, 3, now_grtc + 91);
918+
NRF_GRTC->EVENTS_COMPARE[3] = 0;
919+
nrf_grtc_sys_counter_compare_event_enable(NRF_GRTC, 3);
920+
now = ble_phy_grtc_ticks_to_rtc(now_grtc);
921+
#else
891922
/*
892923
* Set RTC compare to start TIMER0. We need to set it to at least N+2 ticks
893924
* from current value to guarantee triggering compare event, but let's set
@@ -898,6 +929,7 @@ ble_phy_set_start_now(void)
898929
NRF_RTC0->EVENTS_COMPARE[0] = 0;
899930
nrf_rtc_cc_set(NRF_RTC0, 0, (now + 3) & 0xffffff);
900931
nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk);
932+
#endif
901933

902934
#if PHY_USE_FEM_LNA
903935
phy_fem_enable_lna();
@@ -2467,7 +2499,9 @@ ble_phy_stop_usec_timer(void)
24672499
#ifndef NRF54L_SERIES
24682500
NRF_TIMER0->TASKS_SHUTDOWN = 1;
24692501
#endif
2502+
#ifndef GRTC_AS_RADIO_TIMER
24702503
nrf_rtc_event_disable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk);
2504+
#endif
24712505
}
24722506

24732507
/**

nimble/drivers/nrf5x/src/nrf54l/phy.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,12 @@ phy_ppi_init(void)
8787
NRF_RADIO->PUBLISH_END = DPPI_CH_PUB(RADIO_EVENTS_END);
8888
NRF_RADIO->PUBLISH_PAYLOAD = DPPI_CH_PUB(RADIO_EVENTS_PAYLOAD_RADIO);
8989
NRF_RADIO->PUBLISH_BCMATCH = DPPI_CH_PUB(RADIO_EVENTS_BCMATCH);
90+
#ifdef GRTC_AS_RADIO_TIMER
91+
NRF_GRTC->PUBLISH_COMPARE[3] = DPPI_CH_PUB(DPPI20_GRTC_EVENTS_COMPARE_3);
92+
PPIB_PERI_RADIO_0(DPPI20_GRTC_EVENTS_COMPARE_3, RTC0_EVENTS_COMPARE_0);
93+
#else
9094
NRF_RTC0->PUBLISH_COMPARE[0] = DPPI_CH_PUB(RTC0_EVENTS_COMPARE_0);
95+
#endif
9196

9297
NRF_TIMER0->PUBLISH_COMPARE[0] = DPPI_CH_PUB(TIMER0_EVENTS_COMPARE_0);
9398
NRF_TIMER0->PUBLISH_COMPARE[3] = DPPI_CH_PUB(TIMER0_EVENTS_COMPARE_3);

nimble/drivers/nrf5x/src/nrf54l/phy_ppi.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#define DPPI_CH_GPIOTE20_TASKS_CLR_1 3
4949
#define DPPI_CH_GPIOTE20_TASKS_SET_2 4
5050
#define DPPI_CH_GPIOTE20_TASKS_CLR_2 5
51+
#define DPPI_CH_DPPI20_GRTC_EVENTS_COMPARE_3 6
5152

5253
#define DPPI_CH_ENABLE_ALL (DPPIC_CHEN_CH0_Msk | DPPIC_CHEN_CH1_Msk | \
5354
DPPIC_CHEN_CH2_Msk | DPPIC_CHEN_CH3_Msk | \
@@ -71,6 +72,15 @@
7172
#define PPIB_RADIO_PERI_4(_src, _dst) PPIB_RADIO_PERI(4, _src, _dst)
7273
#define PPIB_RADIO_PERI_5(_src, _dst) PPIB_RADIO_PERI(5, _src, _dst)
7374

75+
/* Create PPIB links between PERI and RADIO power domain. */
76+
#define PPIB_PERI_RADIO(_ch, _src, _dst) \
77+
NRF_PPIB21->SUBSCRIBE_SEND[_ch] = DPPI_CH_SUB(_src); \
78+
NRF_PPIB11->PUBLISH_RECEIVE[_ch] = DPPI_CH_PUB(_dst); \
79+
NRF_DPPIC20->CHENSET |= 1 << DPPI_CH_ ## _src; \
80+
NRF_DPPIC10->CHENSET |= 1 << DPPI_CH_ ## _dst;
81+
82+
#define PPIB_PERI_RADIO_0(_src, _dst) PPIB_PERI_RADIO(0, _src, _dst)
83+
7484
/* Create PPIB link from RADIO to MCU power domain. */
7585
#define PPIB_RADIO_MCU(_ch, _src, _dst) \
7686
NRF_PPIB10->SUBSCRIBE_SEND[_ch] = DPPI_CH_SUB(_src); \

nimble/drivers/nrf5x/src/phy_priv.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,50 @@ int8_t phy_txpower_round(int8_t dbm);
114114
#define RADIO_INTENSET_ADDRESS_Msk RADIO_INTENSET00_ADDRESS_Msk
115115
#define RADIO_INTENSET_READY_Msk RADIO_INTENSET00_READY_Msk
116116
#include "nrf54l/phy_ppi.h"
117+
118+
#define GRTC_AS_RADIO_TIMER
119+
120+
#ifdef GRTC_AS_RADIO_TIMER
121+
#include <nrf_grtc.h>
122+
123+
static inline uint64_t
124+
grtc_counter_get(void)
125+
{
126+
uint32_t counterl_val, counterh_val, counterh;
127+
uint64_t counter;
128+
129+
nrf_grtc_sys_counter_active_set(NRF_GRTC, true);
130+
do {
131+
counterl_val = nrf_grtc_sys_counter_low_get(NRF_GRTC);
132+
counterh = nrf_grtc_sys_counter_high_get(NRF_GRTC);
133+
} while (counterh & NRF_GRTC_SYSCOUNTERH_BUSY_MASK);
134+
135+
do {
136+
counterl_val = nrf_grtc_sys_counter_low_get(NRF_GRTC);
137+
counterh = nrf_grtc_sys_counter_high_get(NRF_GRTC);
138+
counterh_val = counterh & NRF_GRTC_SYSCOUNTERH_VALUE_MASK;
139+
} while (counterh & NRF_GRTC_SYSCOUNTERH_BUSY_MASK);
140+
141+
if (counterh & NRF_GRTC_SYSCOUNTERH_OVERFLOW_MASK) {
142+
--counterh_val;
143+
}
144+
145+
counter = ((uint64_t)counterh_val << 32) | counterl_val;
146+
return counter;
147+
}
148+
149+
static inline uint64_t
150+
ble_phy_rtc_ticks_to_grtc(uint32_t ticks)
151+
{
152+
return (uint64_t)ticks << 5;
153+
}
154+
155+
static inline uint32_t
156+
ble_phy_grtc_ticks_to_rtc(uint64_t us)
157+
{
158+
return (uint32_t)(us >> 5);
159+
}
160+
#endif
117161
#endif
118162

119163
#endif /* H_PHY_PRIV_ */

0 commit comments

Comments
 (0)