Bluetooth: Controller: nRF54Lx: Use NRF_GRTC for radio scheduling

Use NRF_GRTC, Global real-time counter, instead of NRF_RTC.

NRF_GRTC is present in a different power domain in the SoC.
Also, NRF_GRTC provide microsecond resolution timing units,
in the future use of NRF_TIMER for packet timer can also be
replaced.

Use of NRF_RTC would keep Radio power domain ON in addition
to already ON NRF_GRTC's power domain, hence switch to using
NRF_GRTC on nRF54Lx SoC to have lower power consumptions.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2024-06-10 22:12:56 +02:00 committed by Anas Nashif
commit 55813ad95b
13 changed files with 392 additions and 18 deletions

View file

@ -831,6 +831,38 @@ config BT_CTLR_RX_PDU_META
prompt "RX pdu meta data"
bool
config BT_CTLR_NRF_GRTC
bool "Use nRF GRTC peripheral"
depends on SOC_SERIES_NRF54LX
select BT_TICKER_CNTR_FREE_RUNNING
default y
help
Enable use of nRF54Lx NRF_GRTC peripheral.
config BT_CTLR_NRF_GRTC_START
bool "Start nRF GRTC peripheral"
depends on BT_CTLR_NRF_GRTC
help
Enable explicit start of nRF54Lx NRF_GRTC peripheral.
config BT_CTLR_NRF_GRTC_KEEPRUNNING
bool "Keep running nRF GRTC peripheral"
depends on BT_CTLR_NRF_GRTC_START
help
Keep running nRF GRTC peripheral.
config BT_CTLR_NRF_GRTC_AUTOEN_CPUACTIVE
bool "Auto enable nRF GRTC on CPU active"
depends on BT_CTLR_NRF_GRTC_START
help
Auto enable nRF GRTC on CPU active.
config BT_CTLR_NRF_GRTC_AUTOEN_DEFAULT
bool "Auto enable nRF GRTC by default"
depends on BT_CTLR_NRF_GRTC_START
help
Auto enable nRF GRTC by default.
config BT_CTLR_RADIO_ENABLE_FAST
bool "Use tTXEN/RXEN,FAST ramp-up"
depends on SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X

View file

@ -11,6 +11,7 @@
#include "hal/debug.h"
#if !defined(CONFIG_BT_CTLR_NRF_GRTC)
#ifndef NRF_RTC
#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
#define NRF_RTC NRF_RTC10
@ -18,14 +19,65 @@
#define NRF_RTC NRF_RTC0
#endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
#endif /* !NRF_RTC */
#endif /* CONFIG_BT_CTLR_NRF_GRTC */
static uint8_t _refcount;
void cntr_init(void)
{
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
#if defined(CONFIG_BT_CTLR_NRF_GRTC_START)
NRF_GRTC->MODE = (GRTC_MODE_SYSCOUNTEREN_Disabled <<
GRTC_MODE_SYSCOUNTEREN_Pos) &
GRTC_MODE_SYSCOUNTEREN_Msk;
NRF_GRTC->TASKS_CLEAR = 1U;
#if defined(CONFIG_BT_CTLR_NRF_GRTC_KEEPRUNNING)
NRF_GRTC->KEEPRUNNING =
(GRTC_KEEPRUNNING_REQUEST1_Active <<
GRTC_KEEPRUNNING_REQUEST1_Pos) &
GRTC_KEEPRUNNING_REQUEST1_Msk;
NRF_GRTC->TIMEOUT = 0U;
NRF_GRTC->INTERVAL = 0U;
NRF_GRTC->WAKETIME = 4U;
#endif /* CONFIG_BT_CTLR_NRF_GRTC_KEEPRUNNING */
NRF_GRTC->CLKCFG = ((GRTC_CLKCFG_CLKSEL_LFXO <<
GRTC_CLKCFG_CLKSEL_Pos) &
GRTC_CLKCFG_CLKSEL_Msk) |
((GRTC_CLKCFG_CLKFASTDIV_Min <<
GRTC_CLKCFG_CLKFASTDIV_Pos) &
GRTC_CLKCFG_CLKFASTDIV_Msk);
#endif /* CONFIG_BT_CTLR_NRF_GRTC_START */
NRF_GRTC->EVENTS_COMPARE[10] = 0U;
NRF_GRTC->INTENSET1 = GRTC_INTENSET1_COMPARE10_Msk;
#if defined(CONFIG_BT_CTLR_NRF_GRTC_START)
NRF_GRTC->MODE = ((GRTC_MODE_SYSCOUNTEREN_Enabled <<
GRTC_MODE_SYSCOUNTEREN_Pos) &
GRTC_MODE_SYSCOUNTEREN_Msk) |
#if defined(CONFIG_BT_CTLR_NRF_GRTC_AUTOEN_CPUACTIVE)
((GRTC_MODE_AUTOEN_CpuActive <<
GRTC_MODE_AUTOEN_Pos) &
GRTC_MODE_AUTOEN_Msk) |
#endif /* CONFIG_BT_CTLR_NRF_GRTC_AUTOEN_CPUACTIVE */
#if defined(CONFIG_BT_CTLR_NRF_GRTC_AUTOEN_DEFAULT)
((GRTC_MODE_AUTOEN_Default <<
GRTC_MODE_AUTOEN_Pos) &
GRTC_MODE_AUTOEN_Msk) |
#endif /* CONFIG_BT_CTLR_NRF_GRTC_AUTOEN_DEFAULT */
0U;
NRF_GRTC->TASKS_START = 1U;
#endif /* CONFIG_BT_CTLR_NRF_GRTC_START */
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
NRF_RTC->PRESCALER = 0;
nrf_rtc_event_enable(NRF_RTC, RTC_EVTENSET_COMPARE0_Msk);
nrf_rtc_int_enable(NRF_RTC, RTC_INTENSET_COMPARE0_Msk);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
}
uint32_t cntr_start(void)
@ -34,7 +86,11 @@ uint32_t cntr_start(void)
return 1;
}
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
/* TODO: if we own and start GRTC, implement start here */
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
nrf_rtc_task_trigger(NRF_RTC, NRF_RTC_TASK_START);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
return 0;
}
@ -47,17 +103,89 @@ uint32_t cntr_stop(void)
return 1;
}
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
/* TODO: if we own and stop GRTC, implement stop here */
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
nrf_rtc_task_trigger(NRF_RTC, NRF_RTC_TASK_STOP);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
return 0;
}
uint32_t cntr_cnt_get(void)
{
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
uint32_t l, h, ho;
/* NOTE: For a 32-bit implementation, L value is read after H
* to avoid another L value after SYSCOUNTER gets ready.
* If both H and L values are desired, then swap the order and
* ensure that L value does not change when H value is read.
*/
do {
h = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERH;
l = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERL;
ho = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERH;
} while ((h & GRTC_SYSCOUNTER_SYSCOUNTERH_BUSY_Msk) ||
(ho & GRTC_SYSCOUNTER_SYSCOUNTERH_OVERFLOW_Msk));
return l;
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
return nrf_rtc_counter_get(NRF_RTC);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
}
void cntr_cmp_set(uint8_t cmp, uint32_t value)
{
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
uint32_t l, h, ho, stale;
/* NOTE: We are going to use TASKS_CAPTURE to read current
* SYSCOUNTER H and L, so that COMPARE registers can be set
* considering that we need to set H compare value too.
*/
/* Read current syscounter value */
do {
h = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERH;
l = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERL;
ho = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERH;
} while ((h & GRTC_SYSCOUNTER_SYSCOUNTERH_BUSY_Msk) ||
(ho & GRTC_SYSCOUNTER_SYSCOUNTERH_OVERFLOW_Msk));
/* Disable capture/compare */
NRF_GRTC->CC[cmp].CCEN = 0U;
/* Set a stale value in capture value */
stale = l - 1U;
NRF_GRTC->CC[cmp].CCL = stale;
/* Trigger a capture */
NRF_GRTC->TASKS_CAPTURE[cmp] = 1U;
/* Wait to get a new L value */
do {
l = NRF_GRTC->CC[cmp].CCL;
} while (l == stale);
/* Read H value */
h = NRF_GRTC->CC[cmp].CCH;
/* NOTE: HERE, we have h and l in sync. */
/* Handle rollover between current and expected value */
if (value < l) {
h++;
}
/* Set compare register values */
NRF_GRTC->CC[cmp].CCL = value;
NRF_GRTC->CC[cmp].CCH = h & GRTC_CC_CCH_CCH_Msk;
/* Enable compare */
NRF_GRTC->CC[cmp].CCEN = 1U;
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
nrf_rtc_cc_set(NRF_RTC, cmp, value);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
}

View file

@ -1175,7 +1175,12 @@ uint32_t radio_bc_has_match(void)
void radio_tmr_status_reset(void)
{
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
#define GRTC_CC_IDX_RADIO 11U
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCEN = 0U;
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
nrf_rtc_event_disable(NRF_RTC, RTC_EVTENCLR_COMPARE2_Msk);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
#if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
hal_trigger_crypt_ppi_disable();
@ -1214,7 +1219,11 @@ void radio_tmr_status_reset(void)
void radio_tmr_tx_status_reset(void)
{
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCEN = 0U;
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
nrf_rtc_event_disable(NRF_RTC, RTC_EVTENCLR_COMPARE2_Msk);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
#if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
hal_trigger_crypt_ppi_disable();
@ -1257,7 +1266,11 @@ void radio_tmr_tx_status_reset(void)
void radio_tmr_rx_status_reset(void)
{
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCEN = 0U;
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
nrf_rtc_event_disable(NRF_RTC, RTC_EVTENCLR_COMPARE2_Msk);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
#if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
hal_trigger_crypt_ppi_disable();
@ -1370,8 +1383,81 @@ uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder)
nrf_timer_cc_set(EVENT_TIMER, 0, remainder);
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
uint32_t l, h, ho, stale;
/* Disable capture/compare */
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCEN = 0U;
/* Publish GRTC compare */
NRF_GRTC->PUBLISH_COMPARE[GRTC_CC_IDX_RADIO] =
((HAL_EVENT_TIMER_START_PPI <<
GRTC_PUBLISH_COMPARE_CHIDX_Pos) &
GRTC_PUBLISH_COMPARE_CHIDX_Msk) |
((GRTC_PUBLISH_COMPARE_EN_Enabled <<
GRTC_PUBLISH_COMPARE_EN_Pos) &
GRTC_PUBLISH_COMPARE_EN_Msk);
/* Enable same DPPI in Global domain */
NRF_DPPIC20->CHENSET = BIT(HAL_EVENT_TIMER_START_PPI);
/* Setup PPIB send subscribe */
NRF_PPIB21->SUBSCRIBE_SEND[HAL_EVENT_TIMER_START_PPI] =
BIT(HAL_EVENT_TIMER_START_PPI) | PPIB_SUBSCRIBE_SEND_EN_Msk;
/* Setup PPIB receive publish */
NRF_PPIB11->PUBLISH_RECEIVE[HAL_EVENT_TIMER_START_PPI] =
BIT(HAL_EVENT_TIMER_START_PPI) | PPIB_PUBLISH_RECEIVE_EN_Msk;
/* NOTE: We are going to use TASKS_CAPTURE to read current
* SYSCOUNTER H and L, so that COMPARE registers can be set
* considering that we need to set H compare value too.
*/
/* Read current syscounter value */
do {
h = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERH;
l = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERL;
ho = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERH;
} while ((h & GRTC_SYSCOUNTER_SYSCOUNTERH_BUSY_Msk) ||
(ho & GRTC_SYSCOUNTER_SYSCOUNTERH_OVERFLOW_Msk));
/* Set a stale value in capture value */
stale = l - 1U;
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCL = stale;
/* Trigger a capture */
NRF_GRTC->TASKS_CAPTURE[GRTC_CC_IDX_RADIO] = 1U;
/* Wait to get a new L value */
do {
l = NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCL;
} while (l == stale);
/* Read H value */
h = NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCH;
/* NOTE: HERE, we have h and l in sync. */
/* Handle rollover between current and expected value */
if (ticks_start < l) {
h++;
}
/* Clear compare event, if any */
NRF_GRTC->EVENTS_COMPARE[GRTC_CC_IDX_RADIO] = 0U;
/* Set compare register values */
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCL = ticks_start;
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCH = h & GRTC_CC_CCH_CCH_Msk;
/* Enable compare */
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCEN = 1U;
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
nrf_rtc_cc_set(NRF_RTC, 2, ticks_start);
nrf_rtc_event_enable(NRF_RTC, RTC_EVTENSET_COMPARE2_Msk);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
hal_event_timer_start_ppi_config();
hal_radio_nrf_ppi_channels_enable(BIT(HAL_EVENT_TIMER_START_PPI));
@ -1410,7 +1496,7 @@ uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder)
return remainder;
}
uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t tick)
uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start)
{
uint32_t remainder_us;
@ -1437,8 +1523,81 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t tick)
nrf_timer_cc_set(EVENT_TIMER, 0, remainder_us);
nrf_rtc_cc_set(NRF_RTC, 2, tick);
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
uint32_t l, h, ho, stale;
/* Disable capture/compare */
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCEN = 0U;
/* Publish GRTC compare */
NRF_GRTC->PUBLISH_COMPARE[GRTC_CC_IDX_RADIO] =
((HAL_EVENT_TIMER_START_PPI <<
GRTC_PUBLISH_COMPARE_CHIDX_Pos) &
GRTC_PUBLISH_COMPARE_CHIDX_Msk) |
((GRTC_PUBLISH_COMPARE_EN_Enabled <<
GRTC_PUBLISH_COMPARE_EN_Pos) &
GRTC_PUBLISH_COMPARE_EN_Msk);
/* Enable same DPPI in Global domain */
NRF_DPPIC20->CHENSET = BIT(HAL_EVENT_TIMER_START_PPI);
/* Setup PPIB send subscribe */
NRF_PPIB21->SUBSCRIBE_SEND[HAL_EVENT_TIMER_START_PPI] =
BIT(HAL_EVENT_TIMER_START_PPI) | PPIB_SUBSCRIBE_SEND_EN_Msk;
/* Setup PPIB receive publish */
NRF_PPIB11->PUBLISH_RECEIVE[HAL_EVENT_TIMER_START_PPI] =
BIT(HAL_EVENT_TIMER_START_PPI) | PPIB_PUBLISH_RECEIVE_EN_Msk;
/* NOTE: We are going to use TASKS_CAPTURE to read current
* SYSCOUNTER H and L, so that COMPARE registers can be set
* considering that we need to set H compare value too.
*/
/* Read current syscounter value */
do {
h = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERH;
l = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERL;
ho = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERH;
} while ((h & GRTC_SYSCOUNTER_SYSCOUNTERH_BUSY_Msk) ||
(ho & GRTC_SYSCOUNTER_SYSCOUNTERH_OVERFLOW_Msk));
/* Set a stale value in capture value */
stale = l - 1U;
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCL = stale;
/* Trigger a capture */
NRF_GRTC->TASKS_CAPTURE[GRTC_CC_IDX_RADIO] = 1U;
/* Wait to get a new L value */
do {
l = NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCL;
} while (l == stale);
/* Read H value */
h = NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCH;
/* NOTE: HERE, we have h and l in sync. */
/* Handle rollover between current and expected value */
if (ticks_start < l) {
h++;
}
/* Clear compare event, if any */
NRF_GRTC->EVENTS_COMPARE[GRTC_CC_IDX_RADIO] = 0U;
/* Set compare register values */
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCL = ticks_start;
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCH = h & GRTC_CC_CCH_CCH_Msk;
/* Enable compare */
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCEN = 1U;
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
nrf_rtc_cc_set(NRF_RTC, 2, ticks_start);
nrf_rtc_event_enable(NRF_RTC, RTC_EVTENSET_COMPARE2_Msk);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
hal_event_timer_start_ppi_config();
hal_radio_nrf_ppi_channels_enable(BIT(HAL_EVENT_TIMER_START_PPI));
@ -1549,7 +1708,20 @@ uint32_t radio_tmr_start_now(uint8_t trx)
uint32_t radio_tmr_start_get(void)
{
return nrf_rtc_cc_get(NRF_RTC, 2);
uint32_t start_ticks;
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
uint64_t cc;
cc = nrf_grtc_sys_counter_cc_get(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
start_ticks = cc & 0xffffffffUL;
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
start_ticks = nrf_rtc_cc_get(NRF_RTC, 2);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
return start_ticks;
}
void radio_tmr_stop(void)

View file

@ -139,7 +139,7 @@ void radio_tmr_tx_disable(void);
void radio_tmr_rx_disable(void);
void radio_tmr_tifs_set(uint32_t tifs);
uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder);
uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t tick);
uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start);
uint32_t radio_tmr_start_us(uint8_t trx, uint32_t us);
uint32_t radio_tmr_start_now(uint8_t trx);
uint32_t radio_tmr_start_get(void);

View file

@ -49,7 +49,12 @@
#error "Unsupported SoC."
#endif
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
#include <hal/nrf_grtc.h>
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
#include <hal/nrf_rtc.h>
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
#include <hal/nrf_timer.h>
#if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)

View file

@ -5,7 +5,9 @@
*/
/* Use the NRF_RTC instance for coarse radio event scheduling */
#if !defined(CONFIG_BT_CTLR_NRF_GRTC)
#define NRF_RTC NRF_RTC10
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
#error "Single Timer feature not supported yet"

View file

@ -100,7 +100,11 @@ static inline void hal_radio_end_time_capture_ppi_config(void)
*/
static inline void hal_event_timer_start_ppi_config(void)
{
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
nrf_rtc_publish_set(NRF_RTC, NRF_RTC_EVENT_COMPARE_2, HAL_EVENT_TIMER_START_PPI);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
nrf_timer_subscribe_set(EVENT_TIMER, NRF_TIMER_TASK_START, HAL_EVENT_TIMER_START_PPI);
}

View file

@ -45,7 +45,14 @@
#elif defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
#define HAL_SWI_RADIO_IRQ SWI02_IRQn
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
#define HAL_SWI_WORKER_IRQ GRTC_1_IRQn
#define HAL_RTC_IRQn GRTC_1_IRQn
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
#define HAL_SWI_WORKER_IRQ RTC10_IRQn
#define HAL_RTC_IRQn RTC10_IRQn
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
#if !defined(CONFIG_BT_CTLR_LOW_LAT) && \
(CONFIG_BT_CTLR_ULL_HIGH_PRIO == CONFIG_BT_CTLR_ULL_LOW_PRIO)
@ -54,8 +61,6 @@
#define HAL_SWI_JOB_IRQ SWI03_IRQn
#endif
#define HAL_RTC_IRQn RTC10_IRQn
#endif
static inline void hal_swi_init(void)

View file

@ -194,5 +194,9 @@ void hal_ticker_instance0_sched(uint8_t caller_id, uint8_t callee_id, uint8_t ch
void hal_ticker_instance0_trigger_set(uint32_t value)
{
cntr_cmp_set(0, value);
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
cntr_cmp_set(10U, value);
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
cntr_cmp_set(0U, value);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
}

View file

@ -5,17 +5,23 @@
* SPDX-License-Identifier: Apache-2.0
*/
#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U
#define HAL_TICKER_CNTR_CLK_UNIT_FSEC 30517578125UL
#define HAL_TICKER_FSEC_PER_USEC 1000000000UL
#define HAL_TICKER_PSEC_PER_USEC 1000000UL
#define HAL_TICKER_FSEC_PER_PSEC 1000UL
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
#define HAL_TICKER_CNTR_CLK_UNIT_FSEC 1000000000UL
/* Macro defines the h/w supported most significant bit */
#define HAL_TICKER_CNTR_MSBIT 31
/* Macro defining the HW supported counter bits */
#define HAL_TICKER_CNTR_MASK 0xFFFFFFFF
/* Macro defining the minimum counter compare offset */
#define HAL_TICKER_CNTR_CMP_OFFSET_MIN 3
#define HAL_TICKER_CNTR_CMP_OFFSET_MIN 1
/* Macro defining the max. counter update latency in ticks */
#define HAL_TICKER_CNTR_SET_LATENCY 0
#define HAL_TICKER_CNTR_SET_LATENCY 4
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
#define HAL_TICKER_CNTR_CLK_UNIT_FSEC 30517578125UL
/* Macro defines the h/w supported most significant bit */
#define HAL_TICKER_CNTR_MSBIT 23
@ -23,6 +29,17 @@
/* Macro defining the HW supported counter bits */
#define HAL_TICKER_CNTR_MASK 0x00FFFFFF
/* Macro defining the minimum counter compare offset */
#define HAL_TICKER_CNTR_CMP_OFFSET_MIN 3
/* Macro defining the max. counter update latency in ticks */
#define HAL_TICKER_CNTR_SET_LATENCY 0
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
#define HAL_TICKER_FSEC_PER_USEC 1000000000UL
#define HAL_TICKER_PSEC_PER_USEC 1000000UL
#define HAL_TICKER_FSEC_PER_PSEC 1000UL
/* Macro to translate microseconds to tick units.
* NOTE: This returns the floor value.
*/

View file

@ -8,8 +8,6 @@
#include <stdbool.h>
#include <errno.h>
#include <hal/nrf_rtc.h>
#include <zephyr/toolchain.h>
#include <soc.h>
@ -120,8 +118,13 @@ static void rtc0_nrf5_isr(const void *arg)
lll_prof_enter_ull_high();
/* On compare0 run ticker worker instance0 */
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
if (NRF_GRTC->EVENTS_COMPARE[10]) {
nrf_grtc_event_clear(NRF_GRTC, NRF_GRTC_EVENT_COMPARE_10);
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
if (NRF_RTC->EVENTS_COMPARE[0]) {
nrf_rtc_event_clear(NRF_RTC, NRF_RTC_EVENT_COMPARE_0);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
ticker_trigger(0);
}

View file

@ -940,7 +940,8 @@ static void isr_window(void *param)
ticks_at_start = ticker_ticks_now_get() +
HAL_TICKER_US_TO_TICKS(HAL_RADIO_ISR_LATENCY_MAX_US) +
HAL_TICKER_CNTR_CMP_OFFSET_MIN;
HAL_TICKER_CNTR_CMP_OFFSET_MIN +
HAL_TICKER_CNTR_SET_LATENCY;
remainder_us = radio_tmr_start_tick(0, ticks_at_start);
#else /* !CONFIG_BT_CENTRAL && !CONFIG_BT_CTLR_ADV_EXT */

View file

@ -55,7 +55,8 @@
* and ticker_update. Set to 32 us, which is ~1 tick with 32768 Hz
* clock.
*/
#define EVENT_TICKER_RES_MARGIN_US 32
#define EVENT_TICKER_RES_MARGIN_US DIV_ROUND_UP(HAL_TICKER_CNTR_CLK_UNIT_FSEC, \
HAL_TICKER_FSEC_PER_USEC)
#define EVENT_RX_JITTER_US(phy) 16 /* Radio Rx timing uncertainty */
#define EVENT_RX_TO_US(phy) ((((((phy)&0x03) + 4)<<3)/BIT((((phy)&0x3)>>1))) + \