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:
parent
e998593c2e
commit
55813ad95b
13 changed files with 392 additions and 18 deletions
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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))) + \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue