Skip to content

Commit

Permalink
Bluetooth: Controller: nRF54Lx: Review rework GRTC support
Browse files Browse the repository at this point in the history
Review rework GRTC support for nRF54Lx SoCs.

Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
  • Loading branch information
cvinayak committed Jun 14, 2024
1 parent 87f7a59 commit aa2503b
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 50 deletions.
2 changes: 2 additions & 0 deletions subsys/bluetooth/controller/hal/cntr.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

#include "hal/cntr_vendor_hal.h"

void cntr_init(void);
uint32_t cntr_start(void);
uint32_t cntr_stop(void);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "hal/nrf5/cntr.h"
42 changes: 21 additions & 21 deletions subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/cntr.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,21 +115,21 @@ uint32_t cntr_stop(void)
uint32_t cntr_cnt_get(void)
{
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
uint32_t l, h, ho;
uint32_t cntr_l, cntr_h, cntr_h_overflow;

/* 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));
cntr_h = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERH;
cntr_l = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERL;
cntr_h_overflow = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERH;
} while ((cntr_h & GRTC_SYSCOUNTER_SYSCOUNTERH_BUSY_Msk) ||
(cntr_h_overflow & GRTC_SYSCOUNTER_SYSCOUNTERH_OVERFLOW_Msk));

return l;
return cntr_l;
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
return nrf_rtc_counter_get(NRF_RTC);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
Expand All @@ -138,7 +138,7 @@ uint32_t cntr_cnt_get(void)
void cntr_cmp_set(uint8_t cmp, uint32_t value)
{
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
uint32_t l, h, ho, stale;
uint32_t cntr_l, cntr_h, cntr_h_overflow, stale;

/* NOTE: We are going to use TASKS_CAPTURE to read current
* SYSCOUNTER H and L, so that COMPARE registers can be set
Expand All @@ -147,40 +147,40 @@ void cntr_cmp_set(uint8_t cmp, uint32_t value)

/* 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));
cntr_h = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERH;
cntr_l = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERL;
cntr_h_overflow = NRF_GRTC->SYSCOUNTER[1].SYSCOUNTERH;
} while ((cntr_h & GRTC_SYSCOUNTER_SYSCOUNTERH_BUSY_Msk) ||
(cntr_h_overflow & GRTC_SYSCOUNTER_SYSCOUNTERH_OVERFLOW_Msk));

/* Disable capture/compare */
NRF_GRTC->CC[cmp].CCEN = 0U;

/* Set a stale value in capture value */
stale = l - 1U;
stale = cntr_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);
cntr_l = NRF_GRTC->CC[cmp].CCL;
} while (cntr_l == stale);

/* Read H value */
h = NRF_GRTC->CC[cmp].CCH;
cntr_h = NRF_GRTC->CC[cmp].CCH;

/* NOTE: HERE, we have h and l in sync. */
/* NOTE: HERE, we have cntr_h and cntr_l in sync. */

/* Handle rollover between current and expected value */
if (value < l) {
h++;
if (value < cntr_l) {
cntr_h++;
}

/* Set compare register values */
NRF_GRTC->CC[cmp].CCL = value;
NRF_GRTC->CC[cmp].CCH = h & GRTC_CC_CCH_CCH_Msk;
NRF_GRTC->CC[cmp].CCH = cntr_h & GRTC_CC_CCH_CCH_Msk;

/* Enable compare */
NRF_GRTC->CC[cmp].CCEN = 1U;
Expand Down
10 changes: 10 additions & 0 deletions subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/cntr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#if defined(CONFIG_BT_CTLR_NRF_GRTC)
#define HAL_CNTR_GRTC_CC_IDX_TICKER 10
#define HAL_CNTR_GRTC_CC_IDX_RADIO 11
#endif /* CONFIG_BT_CTLR_NRF_GRTC */
56 changes: 29 additions & 27 deletions subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "hal/cpu.h"
#include "hal/ccm.h"
#include "hal/cntr.h"
#include "hal/radio.h"
#include "hal/radio_df.h"
#include "hal/ticker.h"
Expand Down Expand Up @@ -1152,8 +1153,7 @@ 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;
NRF_GRTC->CC[HAL_CNTR_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 */
Expand Down Expand Up @@ -1196,7 +1196,7 @@ 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;
NRF_GRTC->CC[HAL_CNTR_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 */
Expand Down Expand Up @@ -1243,7 +1243,7 @@ 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;
NRF_GRTC->CC[HAL_CNTR_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 */
Expand Down Expand Up @@ -1348,10 +1348,10 @@ uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder)
uint32_t l, h, ho, stale;

/* Disable capture/compare */
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCEN = 0U;
NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCEN = 0U;

/* Publish GRTC compare */
NRF_GRTC->PUBLISH_COMPARE[GRTC_CC_IDX_RADIO] =
NRF_GRTC->PUBLISH_COMPARE[HAL_CNTR_GRTC_CC_IDX_RADIO] =
((HAL_EVENT_TIMER_START_PPI <<
GRTC_PUBLISH_COMPARE_CHIDX_Pos) &
GRTC_PUBLISH_COMPARE_CHIDX_Msk) |
Expand Down Expand Up @@ -1385,18 +1385,18 @@ uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder)

/* Set a stale value in capture value */
stale = l - 1U;
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCL = stale;
NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL = stale;

/* Trigger a capture */
NRF_GRTC->TASKS_CAPTURE[GRTC_CC_IDX_RADIO] = 1U;
NRF_GRTC->TASKS_CAPTURE[HAL_CNTR_GRTC_CC_IDX_RADIO] = 1U;

/* Wait to get a new L value */
do {
l = NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCL;
l = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL;
} while (l == stale);

/* Read H value */
h = NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCH;
h = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCH;

/* NOTE: HERE, we have h and l in sync. */

Expand All @@ -1406,14 +1406,14 @@ uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder)
}

/* Clear compare event, if any */
NRF_GRTC->EVENTS_COMPARE[GRTC_CC_IDX_RADIO] = 0U;
NRF_GRTC->EVENTS_COMPARE[HAL_CNTR_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;
NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL = ticks_start;
NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCH = h & GRTC_CC_CCH_CCH_Msk;

/* Enable compare */
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCEN = 1U;
NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCEN = 1U;

#else /* !CONFIG_BT_CTLR_NRF_GRTC */
nrf_rtc_cc_set(NRF_RTC, 2, ticks_start);
Expand Down Expand Up @@ -1472,10 +1472,10 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start)
uint32_t l, h, ho, stale;

/* Disable capture/compare */
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCEN = 0U;
NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCEN = 0U;

/* Publish GRTC compare */
NRF_GRTC->PUBLISH_COMPARE[GRTC_CC_IDX_RADIO] =
NRF_GRTC->PUBLISH_COMPARE[HAL_CNTR_GRTC_CC_IDX_RADIO] =
((HAL_EVENT_TIMER_START_PPI <<
GRTC_PUBLISH_COMPARE_CHIDX_Pos) &
GRTC_PUBLISH_COMPARE_CHIDX_Msk) |
Expand Down Expand Up @@ -1509,18 +1509,18 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start)

/* Set a stale value in capture value */
stale = l - 1U;
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCL = stale;
NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL = stale;

/* Trigger a capture */
NRF_GRTC->TASKS_CAPTURE[GRTC_CC_IDX_RADIO] = 1U;
NRF_GRTC->TASKS_CAPTURE[HAL_CNTR_GRTC_CC_IDX_RADIO] = 1U;

/* Wait to get a new L value */
do {
l = NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCL;
l = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL;
} while (l == stale);

/* Read H value */
h = NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCH;
h = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCH;

/* NOTE: HERE, we have h and l in sync. */

Expand All @@ -1530,14 +1530,14 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start)
}

/* Clear compare event, if any */
NRF_GRTC->EVENTS_COMPARE[GRTC_CC_IDX_RADIO] = 0U;
NRF_GRTC->EVENTS_COMPARE[HAL_CNTR_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;
NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL = ticks_start;
NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCH = h & GRTC_CC_CCH_CCH_Msk;

/* Enable compare */
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCEN = 1U;
NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCEN = 1U;

#else /* !CONFIG_BT_CTLR_NRF_GRTC */
nrf_rtc_cc_set(NRF_RTC, 2, ticks_start);
Expand Down Expand Up @@ -1637,9 +1637,11 @@ uint32_t radio_tmr_start_now(uint8_t trx)
uint32_t radio_tmr_start_get(void)
{
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
return (uint32_t)(nrf_grtc_sys_counter_cc_get(NRF_GRTC,
GRTC_CC_IDX_RADIO) &
0xffffffff);
uint64_t cc;

cc = nrf_grtc_sys_counter_cc_get(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);

return (uint32_t)(cc & 0xffffffffUL);
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
return nrf_rtc_cc_get(NRF_RTC, 2);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
Expand Down
2 changes: 1 addition & 1 deletion subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ 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)
{
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
cntr_cmp_set(10U, value);
cntr_cmp_set(HAL_CNTR_GRTC_CC_IDX_TICKER, value);
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
cntr_cmp_set(0U, value);
#endif /* !CONFIG_BT_CTLR_NRF_GRTC */
Expand Down
3 changes: 2 additions & 1 deletion subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "hal/swi.h"
#include "hal/ccm.h"
#include "hal/cntr.h"
#include "hal/radio.h"
#include "hal/ticker.h"

Expand Down Expand Up @@ -119,7 +120,7 @@ static void rtc0_nrf5_isr(const void *arg)

/* On compare0 run ticker worker instance0 */
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
if (NRF_GRTC->EVENTS_COMPARE[10]) {
if (NRF_GRTC->EVENTS_COMPARE[HAL_CNTR_GRTC_CC_IDX_TICKER]) {
nrf_grtc_event_clear(NRF_GRTC, NRF_GRTC_EVENT_COMPARE_10);
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
if (NRF_RTC->EVENTS_COMPARE[0]) {
Expand Down

0 comments on commit aa2503b

Please sign in to comment.