Bluetooth: Controller: nRF54Lx: Review rework GRTC support

Review rework GRTC support for nRF54Lx SoCs.

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 f39c27bc95
10 changed files with 125 additions and 110 deletions

View file

@ -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);

View file

@ -0,0 +1,7 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/nrf5/cntr.h"

View file

@ -51,8 +51,9 @@ void cntr_init(void)
GRTC_CLKCFG_CLKFASTDIV_Msk);
#endif /* CONFIG_BT_CTLR_NRF_GRTC_START */
NRF_GRTC->EVENTS_COMPARE[10] = 0U;
NRF_GRTC->INTENSET1 = GRTC_INTENSET1_COMPARE10_Msk;
NRF_GRTC->EVENTS_COMPARE[HAL_CNTR_GRTC_CC_IDX_TICKER] = 0U;
NRF_GRTC->INTENSET1 = HAL_CNTR_GRTC_INTENSET_COMPARE_TICKER_Msk;
#if defined(CONFIG_BT_CTLR_NRF_GRTC_START)
NRF_GRTC->MODE = ((GRTC_MODE_SYSCOUNTEREN_Enabled <<
@ -115,7 +116,7 @@ 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.
@ -123,13 +124,13 @@ uint32_t cntr_cnt_get(void)
* 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 */
@ -138,7 +139,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
@ -147,17 +148,17 @@ 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 */
@ -165,22 +166,22 @@ void cntr_cmp_set(uint8_t cmp, uint32_t value)
/* 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;

View file

@ -0,0 +1,12 @@
/*
* 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_INTENSET_COMPARE_TICKER_Msk \
_CONCAT(_CONCAT(GRTC_INTENSET1_COMPARE, HAL_CNTR_GRTC_CC_IDX_TICKER), _Msk)
#define HAL_CNTR_GRTC_CC_IDX_RADIO 11
#endif /* CONFIG_BT_CTLR_NRF_GRTC */

View file

@ -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"
@ -1181,8 +1182,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 */
@ -1225,7 +1225,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 */
@ -1272,7 +1272,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 */
@ -1389,30 +1389,10 @@ 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;
uint32_t cntr_l, cntr_h, cntr_h_overflow, 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;
NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCEN = 0U;
/* NOTE: We are going to use TASKS_CAPTURE to read current
* SYSCOUNTER H and L, so that COMPARE registers can be set
@ -1421,43 +1401,43 @@ uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder)
/* 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));
/* Set a stale value in capture value */
stale = l - 1U;
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCL = stale;
stale = cntr_l - 1U;
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;
} while (l == stale);
cntr_l = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL;
} while (cntr_l == stale);
/* Read H value */
h = NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCH;
cntr_h = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].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 (ticks_start < l) {
h++;
if (ticks_start < cntr_l) {
cntr_h++;
}
/* 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 = cntr_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);
@ -1529,30 +1509,10 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start)
nrf_timer_cc_set(EVENT_TIMER, 0, remainder_us);
#if defined(CONFIG_BT_CTLR_NRF_GRTC)
uint32_t l, h, ho, stale;
uint32_t cntr_l, cntr_h, cntr_h_overflow, 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;
NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCEN = 0U;
/* NOTE: We are going to use TASKS_CAPTURE to read current
* SYSCOUNTER H and L, so that COMPARE registers can be set
@ -1561,43 +1521,43 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start)
/* 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));
/* Set a stale value in capture value */
stale = l - 1U;
NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCL = stale;
stale = cntr_l - 1U;
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;
} while (l == stale);
cntr_l = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL;
} while (cntr_l == stale);
/* Read H value */
h = NRF_GRTC->CC[GRTC_CC_IDX_RADIO].CCH;
cntr_h = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].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 (ticks_start < l) {
h++;
if (ticks_start < cntr_l) {
cntr_h++;
}
/* 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 = cntr_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);

View file

@ -101,6 +101,26 @@ 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)
/* Publish GRTC compare */
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) |
((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;
#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 */

View file

@ -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 */

View file

@ -18,6 +18,7 @@
#include "hal/swi.h"
#include "hal/ccm.h"
#include "hal/cntr.h"
#include "hal/radio.h"
#include "hal/ticker.h"
@ -119,8 +120,8 @@ 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]) {
nrf_grtc_event_clear(NRF_GRTC, NRF_GRTC_EVENT_COMPARE_10);
if (NRF_GRTC->EVENTS_COMPARE[HAL_CNTR_GRTC_CC_IDX_TICKER]) {
NRF_GRTC->EVENTS_COMPARE[HAL_CNTR_GRTC_CC_IDX_TICKER] = 0U;
#else /* !CONFIG_BT_CTLR_NRF_GRTC */
if (NRF_RTC->EVENTS_COMPARE[0]) {
nrf_rtc_event_clear(NRF_RTC, NRF_RTC_EVENT_COMPARE_0);

View file

@ -0,0 +1,5 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

View file

@ -0,0 +1,7 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/RV32M1/cntr.h"