From 4600fadf2bc3a7740eb2dffa135e6affa6f0af6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aurora=20Sletnes=20Bj=C3=B8rlo?= Date: Wed, 13 Jan 2021 11:22:40 +0100 Subject: [PATCH] bluetooth: controller: radio: Split radio_nrf5_ppi.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Splits the file into radio_nrf5_ppi.h and radio_nrf5_dppi.h and moves the nRF53 DPPI to radio_nrf5_dppi.h. Signed-off-by: Aurora Sletnes Bjørlo --- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h | 7 + .../nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 577 ++++++++++++++++++ .../nordic/hal/nrf5/radio/radio_nrf5_ppi.h | 497 +-------------- 3 files changed, 585 insertions(+), 496 deletions(-) create mode 100644 subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h index 2540f13cc07..17792f796a6 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h @@ -48,5 +48,12 @@ #define HAL_RADIO_PDU_LEN_MAX (BIT(8) - 1) #endif +#include + +#if defined(PPI_PRESENT) #include "radio_nrf5_ppi.h" +#endif +#if defined(DPPI_PRESENT) +#include "radio_nrf5_dppi.h" +#endif #include "radio_nrf5_txp.h" diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h new file mode 100644 index 00000000000..28581a3f910 --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -0,0 +1,577 @@ +/* + * Copyright (c) 2018 - 2020 Nordic Semiconductor ASA + * Copyright (c) 2018 Ioannis Glaropoulos + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#if defined(CONFIG_SOC_NRF5340_CPUNET) || defined(DPPI_PRESENT) + +#include +#include +#include +#include +#include +#include + +static inline void hal_radio_nrf_ppi_channels_enable(uint32_t mask) +{ + nrf_dppi_channels_enable(NRF_DPPIC, mask); +} + +static inline void hal_radio_nrf_ppi_channels_disable(uint32_t mask) +{ + nrf_dppi_channels_disable(NRF_DPPIC, mask); +} + +/******************************************************************************* + * Enable Radio on Event Timer tick: + * wire the EVENT_TIMER EVENTS_COMPARE[0] event to RADIO TASKS_TXEN/RXEN task. + */ +#define HAL_RADIO_ENABLE_ON_TICK_PPI 0 +#define HAL_RADIO_ENABLE_TX_ON_TICK_PPI HAL_RADIO_ENABLE_ON_TICK_PPI +#define HAL_RADIO_ENABLE_RX_ON_TICK_PPI HAL_RADIO_ENABLE_ON_TICK_PPI + +static inline void hal_radio_enable_on_tick_ppi_config_and_enable(uint8_t trx) +{ + nrf_timer_publish_set(EVENT_TIMER, NRF_TIMER_EVENT_COMPARE0, HAL_RADIO_ENABLE_ON_TICK_PPI); + + if (trx) { + nrf_radio_subscribe_set(NRF_RADIO, + NRF_RADIO_TASK_TXEN, HAL_RADIO_ENABLE_TX_ON_TICK_PPI); + + /* Address nRF5340 Engineering A Errata 16 */ + if (IS_ENABLED(CONFIG_BT_CTLR_TIFS_HW)) { + nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_RXEN); + } + } else { + nrf_radio_subscribe_set(NRF_RADIO, + NRF_RADIO_TASK_RXEN, HAL_RADIO_ENABLE_RX_ON_TICK_PPI); + + /* Address nRF5340 Engineering A Errata 16 */ + if (IS_ENABLED(CONFIG_BT_CTLR_TIFS_HW)) { + nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN); + } + } + + nrf_dppi_channels_enable( + NRF_DPPIC, BIT(HAL_RADIO_ENABLE_ON_TICK_PPI)); +} + +/******************************************************************************* + * Capture event timer on Address reception: + * wire the RADIO EVENTS_ADDRESS event to the + * EVENT_TIMER TASKS_CAPTURE[
] task. + */ +#define HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI 3 + +static inline void hal_radio_recv_timeout_cancel_ppi_config(void) +{ + nrf_radio_publish_set(NRF_RADIO, + NRF_RADIO_EVENT_ADDRESS, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); + nrf_timer_subscribe_set(EVENT_TIMER, + NRF_TIMER_TASK_CAPTURE1, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); +} + +/******************************************************************************* + * Disable Radio on HCTO: + * wire the EVENT_TIMER EVENTS_COMPARE[] event + * to the RADIO TASKS_DISABLE task. + */ +#define HAL_RADIO_DISABLE_ON_HCTO_PPI 4 + +static inline void hal_radio_disable_on_hcto_ppi_config(void) +{ + nrf_timer_publish_set(EVENT_TIMER, + NRF_TIMER_EVENT_COMPARE1, HAL_RADIO_DISABLE_ON_HCTO_PPI); + nrf_radio_subscribe_set(NRF_RADIO, + NRF_RADIO_TASK_DISABLE, HAL_RADIO_DISABLE_ON_HCTO_PPI); +} + +/******************************************************************************* + * Capture event timer on Radio end: + * wire the RADIO EVENTS_END event to the + * EVENT_TIMER TASKS_CAPTURE[] task. + */ +#define HAL_RADIO_END_TIME_CAPTURE_PPI 5 + +static inline void hal_radio_end_time_capture_ppi_config(void) +{ + nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_END, HAL_RADIO_END_TIME_CAPTURE_PPI); + nrf_timer_subscribe_set(EVENT_TIMER, + NRF_TIMER_TASK_CAPTURE2, HAL_RADIO_END_TIME_CAPTURE_PPI); +} + +/******************************************************************************* + * Start event timer on RTC tick: + * wire the RTC0 EVENTS_COMPARE[2] event to EVENT_TIMER TASKS_START task. + */ +#define HAL_EVENT_TIMER_START_PPI 1 + +static inline void hal_event_timer_start_ppi_config(void) +{ + nrf_rtc_publish_set(NRF_RTC0, NRF_RTC_EVENT_COMPARE_2, HAL_EVENT_TIMER_START_PPI); + nrf_timer_subscribe_set(EVENT_TIMER, NRF_TIMER_TASK_START, HAL_EVENT_TIMER_START_PPI); +} + +/******************************************************************************* + * Capture event timer on Radio ready: + * wire the RADIO EVENTS_READY event to the + * EVENT_TIMER TASKS_CAPTURE[] task. + */ +#define HAL_RADIO_READY_TIME_CAPTURE_PPI 2 + +static inline void hal_radio_ready_time_capture_ppi_config(void) +{ + nrf_radio_publish_set(NRF_RADIO, + NRF_RADIO_EVENT_READY, HAL_RADIO_READY_TIME_CAPTURE_PPI); + nrf_timer_subscribe_set(EVENT_TIMER, + NRF_TIMER_TASK_CAPTURE0, HAL_RADIO_READY_TIME_CAPTURE_PPI); +} + +/******************************************************************************* + * Trigger encryption task upon address reception: + * wire the RADIO EVENTS_ADDRESS event to the CCM TASKS_CRYPT task. + * + * Note: we do not need an additional PPI, since we have already set up + * a PPI to publish RADIO ADDRESS event. + */ +#define HAL_TRIGGER_CRYPT_PPI HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI + +static inline void hal_trigger_crypt_ppi_config(void) +{ + nrf_radio_publish_set(NRF_RADIO, + NRF_RADIO_EVENT_ADDRESS, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); + nrf_ccm_subscribe_set(NRF_CCM, NRF_CCM_TASK_CRYPT, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); +} + +/******************************************************************************* + * Trigger automatic address resolution on Bit counter match: + * wire the RADIO EVENTS_BCMATCH event to the AAR TASKS_START task. + */ +#define HAL_TRIGGER_AAR_PPI 6 + +static inline void hal_trigger_aar_ppi_config(void) +{ + nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH, HAL_TRIGGER_AAR_PPI); + nrf_aar_subscribe_set(NRF_AAR, NRF_AAR_TASK_START, HAL_TRIGGER_AAR_PPI); +} + +/******************************************************************************* + * Trigger Radio Rate override upon Rateboost event. + */ +#define HAL_TRIGGER_RATEOVERRIDE_PPI 13 + +static inline void hal_trigger_rateoverride_ppi_config(void) +{ + nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_RATEBOOST, HAL_TRIGGER_RATEOVERRIDE_PPI); + nrf_ccm_subscribe_set(NRF_CCM, NRF_CCM_TASK_RATEOVERRIDE, HAL_TRIGGER_RATEOVERRIDE_PPI); +} + +/******************************************************************************/ +#if !defined(CONFIG_BT_CTLR_TIFS_HW) +/* DPPI setup used for SW-based auto-switching during TIFS. */ + +/* Clear SW-switch timer on packet end: + * wire the RADIO EVENTS_END event to SW_SWITCH_TIMER TASKS_CLEAR task. + * + * Note: we do not need an additional PPI, since we have already set up + * a PPI to publish RADIO END event. + */ +#define HAL_SW_SWITCH_TIMER_CLEAR_PPI HAL_RADIO_END_TIME_CAPTURE_PPI + +static inline void hal_sw_switch_timer_clear_ppi_config(void) +{ + nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_END, HAL_SW_SWITCH_TIMER_CLEAR_PPI); + nrf_timer_subscribe_set(SW_SWITCH_TIMER, + NRF_TIMER_TASK_CLEAR, HAL_SW_SWITCH_TIMER_CLEAR_PPI); +} + +/* The 2 adjacent PPI groups used for implementing SW_SWITCH_TIMER-based + * auto-switch for TIFS. 'index' must be 0 or 1. + */ +#define SW_SWITCH_TIMER_TASK_GROUP(index) \ + (SW_SWITCH_TIMER_TASK_GROUP_BASE + index) + +/* The 2 adjacent TIMER EVENTS_COMPARE event offsets used for implementing + * SW_SWITCH_TIMER-based auto-switch for TIFS. 'index' must be 0 or 1. + */ +#define SW_SWITCH_TIMER_EVTS_COMP(index) \ + (SW_SWITCH_TIMER_EVTS_COMP_BASE + index) + +/* The 2 adjacent TIMER EVENTS_COMPARE event offsets used for implementing + * SW_SWITCH_TIMER-based auto-switch for TIFS, when receiving on LE Coded + * PHY. 'index' must be 0 or 1. + */ +#define SW_SWITCH_TIMER_S2_EVTS_COMP(index) \ + (SW_SWITCH_TIMER_EVTS_COMP_S2_BASE + index) + +/* Wire a SW SWITCH TIMER EVENTS_COMPARE[] event + * to a PPI GROUP TASK DISABLE task (PPI group with index ). + * 2 adjacent PPIs (8 & 9) and 2 adjacent PPI groups are used for this wiring; + * must be 0 or 1. must be a valid TIMER CC register offset. + */ +#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_BASE 8 +#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(index) \ + (HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_BASE + index) + +#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_EVT(cc_offset) \ + SW_SWITCH_TIMER->PUBLISH_COMPARE[cc_offset] +#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT(chan) \ + (((chan << TIMER_PUBLISH_COMPARE_CHIDX_Pos) \ + & TIMER_PUBLISH_COMPARE_CHIDX_Msk) | \ + ((TIMER_PUBLISH_COMPARE_EN_Enabled << TIMER_PUBLISH_COMPARE_EN_Pos) \ + & TIMER_PUBLISH_COMPARE_EN_Msk)) +#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(index) \ + NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(index)].DIS +#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK(chan) \ + (((chan << DPPIC_SUBSCRIBE_CHG_DIS_CHIDX_Pos) \ + & DPPIC_SUBSCRIBE_CHG_DIS_CHIDX_Msk) | \ + ((DPPIC_SUBSCRIBE_CHG_DIS_EN_Enabled << \ + DPPIC_SUBSCRIBE_CHG_DIS_EN_Pos) \ + & DPPIC_SUBSCRIBE_CHG_DIS_EN_Msk)) + +/* Enable the SW Switch PPI Group on RADIO END Event. + * + * Note: we do not need an additional PPI, since we have already set up + * a PPI to publish RADIO END event. + */ +#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI HAL_SW_SWITCH_TIMER_CLEAR_PPI +#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_EVT \ + (NRF_RADIO->PUBLISH_END) +#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_EVT \ + (((HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI << \ + RADIO_PUBLISH_END_CHIDX_Pos) \ + & RADIO_PUBLISH_END_CHIDX_Msk) | \ + ((RADIO_PUBLISH_END_EN_Enabled << RADIO_PUBLISH_END_EN_Pos) \ + & RADIO_PUBLISH_END_EN_Msk)) +#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(index) \ + (NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(index)].EN) +#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_TASK \ + (((HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI << \ + DPPIC_SUBSCRIBE_CHG_EN_CHIDX_Pos) \ + & DPPIC_SUBSCRIBE_CHG_EN_CHIDX_Msk) | \ + ((DPPIC_SUBSCRIBE_CHG_EN_EN_Enabled << \ + DPPIC_SUBSCRIBE_CHG_EN_EN_Pos) \ + & DPPIC_SUBSCRIBE_CHG_EN_EN_Msk)) + +/* Enable Radio on SW Switch timer event. + * Wire a SW SWITCH TIMER EVENTS_COMPARE[] event + * to a RADIO Enable task (TX or RX). + * + * Note: + * We use the same PPI as for disabling the SW Switch PPI groups, + * since we need to listen for the same event (SW Switch event). + * + * We use the same PPI for the alternative SW Switch Timer compare + * event. + */ +#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_BASE 8 +#define HAL_SW_SWITCH_RADIO_ENABLE_PPI(index) \ + (HAL_SW_SWITCH_RADIO_ENABLE_PPI_BASE + index) + +#define HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI_BASE \ + HAL_SW_SWITCH_RADIO_ENABLE_PPI_BASE +#define HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(index) \ + (HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI_BASE + index) + +#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(cc_offset) \ + SW_SWITCH_TIMER->PUBLISH_COMPARE[cc_offset] +#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(chan) \ + (((chan << TIMER_PUBLISH_COMPARE_CHIDX_Pos) \ + & TIMER_PUBLISH_COMPARE_CHIDX_Msk) | \ + ((TIMER_PUBLISH_COMPARE_EN_Enabled << TIMER_PUBLISH_COMPARE_EN_Pos) \ + & TIMER_PUBLISH_COMPARE_EN_Msk)) +#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_TASK_TX \ + NRF_RADIO->SUBSCRIBE_TXEN +#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_TASK_RX \ + NRF_RADIO->SUBSCRIBE_RXEN +#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_TX_SET(chan) \ + (((chan << RADIO_SUBSCRIBE_TXEN_CHIDX_Pos) \ + & RADIO_SUBSCRIBE_TXEN_CHIDX_Msk) | \ + ((RADIO_SUBSCRIBE_TXEN_EN_Enabled << \ + RADIO_SUBSCRIBE_TXEN_EN_Pos) \ + & RADIO_SUBSCRIBE_TXEN_EN_Msk)) +#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_RX_SET(chan) \ + (((chan << RADIO_SUBSCRIBE_RXEN_CHIDX_Pos) \ + & RADIO_SUBSCRIBE_RXEN_CHIDX_Msk) | \ + ((RADIO_SUBSCRIBE_RXEN_EN_Enabled << RADIO_SUBSCRIBE_RXEN_EN_Pos) \ + & RADIO_SUBSCRIBE_RXEN_EN_Msk)) + +/* Cancel the SW switch timer running considering S8 timing: + * wire the RADIO EVENTS_RATEBOOST event to SW_SWITCH_TIMER TASKS_CAPTURE task. + * + * Note: We already have a PPI where we publish the RATEBOOST event. + */ +#define HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI HAL_TRIGGER_RATEOVERRIDE_PPI +#define HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_REGISTER_EVT \ + NRF_RADIO->PUBLISH_RATEBOOST +#define HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_EVT \ + (((HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI << \ + RADIO_PUBLISH_RATEBOOST_CHIDX_Pos) \ + & RADIO_PUBLISH_RATEBOOST_CHIDX_Msk) | \ + ((RADIO_PUBLISH_RATEBOOST_EN_Enabled << \ + RADIO_PUBLISH_RATEBOOST_EN_Pos) \ + & RADIO_PUBLISH_RATEBOOST_EN_Msk)) +#define HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_REGISTER_TASK(cc_reg) \ + SW_SWITCH_TIMER->SUBSCRIBE_CAPTURE[cc_reg] +#define HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_TASK \ + (((HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI << \ + TIMER_SUBSCRIBE_CAPTURE_CHIDX_Pos) \ + & TIMER_SUBSCRIBE_CAPTURE_CHIDX_Msk) | \ + ((TIMER_SUBSCRIBE_CAPTURE_EN_Enabled << \ + TIMER_SUBSCRIBE_CAPTURE_EN_Pos) \ + & TIMER_SUBSCRIBE_CAPTURE_EN_Msk)) + + +static inline void hal_radio_sw_switch_setup( + uint8_t compare_reg, + uint8_t radio_enable_ppi, + uint8_t ppi_group_index) +{ + /* Set up software switch mechanism for next Radio switch. */ + + /* Wire RADIO END event to PPI Group[] enable task, + * over PPI[] + */ + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_EVT = + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_EVT; + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(ppi_group_index) = + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_TASK; + + /* We need to un-subscribe the other group from the PPI channel. */ + if (ppi_group_index == 0) { + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(1) = 0; + } else if (ppi_group_index == 1) { + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(0) = 0; + } + + /* Wire SW Switch timer event to the + * PPI[] for enabling Radio. Do + * not wire the task; it is done by the caller of + * the function depending on the desired direction + * (TX/RX). + */ + HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(compare_reg) = + HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(radio_enable_ppi); +} + +static inline void hal_radio_txen_on_sw_switch(uint8_t ppi) +{ + nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, ppi); +} + +static inline void hal_radio_rxen_on_sw_switch(uint8_t ppi) +{ + nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, ppi); +} + + +static inline void hal_radio_sw_switch_disable(void) +{ + /* We cannot deactivate the PPI channels, as other tasks + * are subscribed to RADIO_END event, i.e on the same channel. + * So we simply cancel the task subscription. + */ + nrf_timer_subscribe_clear(SW_SWITCH_TIMER, NRF_TIMER_TASK_CLEAR); + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(0) = 0; + HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(1) = 0; +} + +static inline void hal_radio_sw_switch_cleanup(void) +{ + hal_radio_sw_switch_disable(); + nrf_dppi_channels_disable(NRF_DPPIC, + (BIT(HAL_SW_SWITCH_TIMER_CLEAR_PPI) | + BIT(HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI))); + nrf_dppi_group_disable(NRF_DPPIC, SW_SWITCH_TIMER_TASK_GROUP(0)); + nrf_dppi_group_disable(NRF_DPPIC, SW_SWITCH_TIMER_TASK_GROUP(1)); +} + +static inline void hal_radio_sw_switch_coded_tx_config_set(uint8_t ppi_en, + uint8_t ppi_dis, uint8_t cc_s2, uint8_t group_index) +{ + /* Publish the SW Switch Timer Compare event for S2 timing + * to the PPI that will be used to trigger Radio enable. + */ + HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(cc_s2) = + HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(ppi_en); + + /* The Radio Enable Task is already subscribed to the channel. */ + + /* Wire the Group task disable to the S2 EVENTS_COMPARE. */ + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_EVT(cc_s2) = + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT(ppi_dis); + + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(group_index) = + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK(ppi_dis); + + /* Capture CC to cancel the timer that has assumed + * S8 reception, if packet will be received in S2. + */ + HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_REGISTER_EVT = + HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_EVT; + HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_REGISTER_TASK( + SW_SWITCH_TIMER_EVTS_COMP(group_index)) = + HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_TASK; + + nrf_dppi_channels_enable(NRF_DPPIC, + BIT(HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI)); +} + +static inline void hal_radio_sw_switch_coded_config_clear(uint8_t ppi_en, + uint8_t ppi_dis, uint8_t cc_reg, uint8_t group_index) +{ + /* Invalidate subscription of S2 timer Compare used when + * RXing on LE Coded PHY. + * + * Note: we do not un-subscribe the Radio enable task because + * we use the same PPI for both SW Switch Timer compare events. + */ + HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT( + SW_SWITCH_TIMER_S2_EVTS_COMP(group_index)) = 0; + + /* Wire the Group[group_index] task disable to the default + * SW Switch Timer EVENTS_COMPARE. + */ + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_EVT( + cc_reg) = + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT( + ppi_dis); + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK( + group_index) = + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK( + ppi_dis); +} + +static inline void hal_radio_sw_switch_ppi_group_setup(void) +{ + /* Include the appropriate PPI channels in the two PPI Groups, used for + * SW-based TIFS. + * + * Note that this needs to be done before any SUBSCRIBE task + * registers are written, therefore, we clear the task registers + * here. + */ + NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(0)].EN = 0; + NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(0)].DIS = 0; + NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(1)].EN = 0; + NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(1)].DIS = 0; + + NRF_DPPIC->TASKS_CHG[SW_SWITCH_TIMER_TASK_GROUP(0)].DIS = 1; + NRF_DPPIC->TASKS_CHG[SW_SWITCH_TIMER_TASK_GROUP(1)].DIS = 1; + + /* Include the appropriate PPI channels in the two PPI Groups. */ + NRF_DPPIC->CHG[SW_SWITCH_TIMER_TASK_GROUP(0)] = + BIT(HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(0)) | + BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(0)); + NRF_DPPIC->CHG[SW_SWITCH_TIMER_TASK_GROUP(1)] = + BIT(HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)) | + BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(1)); + + /* Sanity build-time check that RADIO Enable and Group Disable + * tasks are going to be subscribed on the same PPIs. + */ + BUILD_ASSERT( + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_BASE == + HAL_SW_SWITCH_RADIO_ENABLE_PPI_BASE, + "Radio enable and Group disable not on the same PPI channels."); + + /* Address nRF5340 Engineering A Errata 16 */ + nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN); + nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_RXEN); +} + +static inline void hal_radio_group_task_disable_ppi_setup(void) +{ + + /* Wire SW SWITCH TIMER EVENTS COMPARE event to + * PPI Group TASK [] DISABLE task, over PPI. + */ + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_EVT( + SW_SWITCH_TIMER_EVTS_COMP(0)) = + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT( + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(0)); + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(0) = + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK( + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(0)); + + /* Wire SW SWITCH TIMER event to + * PPI Group[] Disable Task, over PPI. + */ + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_EVT( + SW_SWITCH_TIMER_EVTS_COMP(1)) = + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT( + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)); + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(1) = + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK( + HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)); +} + +#endif /* !CONFIG_BT_CTLR_TIFS_HW */ + +#endif /* CONFIG_SOC_NRF5340_CPUNET || DPPI_PRESENT */ + +/******************************************************************************/ + +#define HAL_USED_PPI_CHANNELS \ + (BIT(HAL_RADIO_ENABLE_TX_ON_TICK_PPI) | \ + BIT(HAL_RADIO_ENABLE_RX_ON_TICK_PPI) | \ + BIT(HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI) | \ + BIT(HAL_RADIO_DISABLE_ON_HCTO_PPI) | \ + BIT(HAL_RADIO_END_TIME_CAPTURE_PPI) | \ + BIT(HAL_EVENT_TIMER_START_PPI) | \ + BIT(HAL_RADIO_READY_TIME_CAPTURE_PPI) | \ + BIT(HAL_TRIGGER_CRYPT_PPI) | \ + BIT(HAL_TRIGGER_AAR_PPI) | \ + HAL_USED_PPI_CHANNELS_2 | HAL_USED_PPI_CHANNELS_3 | \ + HAL_USED_PPI_CHANNELS_4 | HAL_USED_PPI_CHANNELS_5) + +#if defined(HAL_TRIGGER_RATEOVERRIDE_PPI) +#define HAL_USED_PPI_CHANNELS_2 \ + BIT(HAL_TRIGGER_RATEOVERRIDE_PPI) +#else +#define HAL_USED_PPI_CHANNELS_2 0 +#endif + +#if defined(HAL_ENABLE_PALNA_PPI) +#define HAL_USED_PPI_CHANNELS_3 \ + (BIT(HAL_ENABLE_PALNA_PPI) | \ + BIT(HAL_DISABLE_PALNA_PPI)) +#else +#define HAL_USED_PPI_CHANNELS_3 0 +#endif + +#if defined(HAL_SW_SWITCH_TIMER_CLEAR_PPI) +#define HAL_USED_PPI_CHANNELS_4 \ + (BIT(HAL_SW_SWITCH_TIMER_CLEAR_PPI) | \ + BIT(HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_BASE) | \ + BIT(HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_BASE + 1) | \ + BIT(HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI) | \ + BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI_BASE) | \ + BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI_BASE + 1)) +#else +#define HAL_USED_PPI_CHANNELS_4 0 +#endif + +#if defined(HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI_BASE) +#define HAL_USED_PPI_CHANNELS_5 \ + (BIT(HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI_BASE) | \ + BIT(HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI_BASE + 1) | \ + BIT(HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI)) +#else +#define HAL_USED_PPI_CHANNELS_5 0 +#endif + +BUILD_ASSERT( + (HAL_USED_PPI_CHANNELS & NRFX_PPI_CHANNELS_USED_BY_PWM_SW) == 0, + "PPI channels used by the Bluetooth controller overlap with those " + "assigned to the pwm_nrf5_sw driver."); + +#if defined(SW_SWITCH_TIMER_TASK_GROUP_BASE) +#define HAL_USED_PPI_GROUPS \ + (BIT(SW_SWITCH_TIMER_TASK_GROUP_BASE) | \ + BIT(SW_SWITCH_TIMER_TASK_GROUP_BASE + 1)) +#else +#define HAL_USED_PPI_GROUPS 0 +#endif diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h index f466f587881..40f58e915ff 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 - 2019 Nordic Semiconductor ASA + * Copyright (c) 2018 - 2020 Nordic Semiconductor ASA * Copyright (c) 2018 Ioannis Glaropoulos * * SPDX-License-Identifier: Apache-2.0 @@ -602,501 +602,6 @@ static inline void hal_radio_sw_switch_ppi_group_setup(void) } #endif /* !CONFIG_BT_CTLR_TIFS_HW */ - -#elif defined(CONFIG_SOC_NRF5340_CPUNET) - -#include -#include -#include -#include -#include -#include - -static inline void hal_radio_nrf_ppi_channels_enable(uint32_t mask) -{ - nrf_dppi_channels_enable(NRF_DPPIC, mask); -} - -static inline void hal_radio_nrf_ppi_channels_disable(uint32_t mask) -{ - nrf_dppi_channels_disable(NRF_DPPIC, mask); -} - -/******************************************************************************* - * Enable Radio on Event Timer tick: - * wire the EVENT_TIMER EVENTS_COMPARE[0] event to RADIO TASKS_TXEN/RXEN task. - */ -#define HAL_RADIO_ENABLE_ON_TICK_PPI 0 -#define HAL_RADIO_ENABLE_TX_ON_TICK_PPI HAL_RADIO_ENABLE_ON_TICK_PPI -#define HAL_RADIO_ENABLE_RX_ON_TICK_PPI HAL_RADIO_ENABLE_ON_TICK_PPI - -static inline void hal_radio_enable_on_tick_ppi_config_and_enable(uint8_t trx) -{ - nrf_timer_publish_set(EVENT_TIMER, NRF_TIMER_EVENT_COMPARE0, HAL_RADIO_ENABLE_ON_TICK_PPI); - - if (trx) { - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, HAL_RADIO_ENABLE_TX_ON_TICK_PPI); - - /* Address nRF5340 Engineering A Errata 16 */ - if (IS_ENABLED(CONFIG_BT_CTLR_TIFS_HW)) { - nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_RXEN); - } - } else { - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, HAL_RADIO_ENABLE_RX_ON_TICK_PPI); - - /* Address nRF5340 Engineering A Errata 16 */ - if (IS_ENABLED(CONFIG_BT_CTLR_TIFS_HW)) { - nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN); - } - } - - nrf_dppi_channels_enable( - NRF_DPPIC, BIT(HAL_RADIO_ENABLE_ON_TICK_PPI)); -} - -/******************************************************************************* - * Capture event timer on Address reception: - * wire the RADIO EVENTS_ADDRESS event to the - * EVENT_TIMER TASKS_CAPTURE[
] task. - */ -#define HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI 3 - -static inline void hal_radio_recv_timeout_cancel_ppi_config(void) -{ - nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); - nrf_timer_subscribe_set(EVENT_TIMER, NRF_TIMER_TASK_CAPTURE1, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); -} - -/******************************************************************************* - * Disable Radio on HCTO: - * wire the EVENT_TIMER EVENTS_COMPARE[] event - * to the RADIO TASKS_DISABLE task. - */ -#define HAL_RADIO_DISABLE_ON_HCTO_PPI 4 - -static inline void hal_radio_disable_on_hcto_ppi_config(void) -{ - nrf_timer_publish_set(EVENT_TIMER, NRF_TIMER_EVENT_COMPARE1, HAL_RADIO_DISABLE_ON_HCTO_PPI); - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_DISABLE, HAL_RADIO_DISABLE_ON_HCTO_PPI); -} - -/******************************************************************************* - * Capture event timer on Radio end: - * wire the RADIO EVENTS_END event to the - * EVENT_TIMER TASKS_CAPTURE[] task. - */ -#define HAL_RADIO_END_TIME_CAPTURE_PPI 5 - -static inline void hal_radio_end_time_capture_ppi_config(void) -{ - nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_END, HAL_RADIO_END_TIME_CAPTURE_PPI); - nrf_timer_subscribe_set(EVENT_TIMER, NRF_TIMER_TASK_CAPTURE2, HAL_RADIO_END_TIME_CAPTURE_PPI); -} - -/******************************************************************************* - * Start event timer on RTC tick: - * wire the RTC0 EVENTS_COMPARE[2] event to EVENT_TIMER TASKS_START task. - */ -#define HAL_EVENT_TIMER_START_PPI 1 - -static inline void hal_event_timer_start_ppi_config(void) -{ - nrf_rtc_publish_set(NRF_RTC0, NRF_RTC_EVENT_COMPARE_2, HAL_EVENT_TIMER_START_PPI); - nrf_timer_subscribe_set(EVENT_TIMER, NRF_TIMER_TASK_START, HAL_EVENT_TIMER_START_PPI); -} - -/******************************************************************************* - * Capture event timer on Radio ready: - * wire the RADIO EVENTS_READY event to the - * EVENT_TIMER TASKS_CAPTURE[] task. - */ -#define HAL_RADIO_READY_TIME_CAPTURE_PPI 2 - -static inline void hal_radio_ready_time_capture_ppi_config(void) -{ - nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_READY, HAL_RADIO_READY_TIME_CAPTURE_PPI); - nrf_timer_subscribe_set(EVENT_TIMER, NRF_TIMER_TASK_CAPTURE0, HAL_RADIO_READY_TIME_CAPTURE_PPI); -} - -/******************************************************************************* - * Trigger encryption task upon address reception: - * wire the RADIO EVENTS_ADDRESS event to the CCM TASKS_CRYPT task. - * - * Note: we do not need an additional PPI, since we have already set up - * a PPI to publish RADIO ADDRESS event. - */ -#define HAL_TRIGGER_CRYPT_PPI HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI - -static inline void hal_trigger_crypt_ppi_config(void) -{ - nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); - nrf_ccm_subscribe_set(NRF_CCM, NRF_CCM_TASK_CRYPT, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); -} - -/******************************************************************************* - * Trigger automatic address resolution on Bit counter match: - * wire the RADIO EVENTS_BCMATCH event to the AAR TASKS_START task. - */ -#define HAL_TRIGGER_AAR_PPI 6 - -static inline void hal_trigger_aar_ppi_config(void) -{ - nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH, HAL_TRIGGER_AAR_PPI); - nrf_aar_subscribe_set(NRF_AAR, NRF_AAR_TASK_START, HAL_TRIGGER_AAR_PPI); -} - -/******************************************************************************* - * Trigger Radio Rate override upon Rateboost event. - */ -#define HAL_TRIGGER_RATEOVERRIDE_PPI 13 - -static inline void hal_trigger_rateoverride_ppi_config(void) -{ - nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_RATEBOOST, HAL_TRIGGER_RATEOVERRIDE_PPI); - nrf_ccm_subscribe_set(NRF_CCM, NRF_CCM_TASK_RATEOVERRIDE, HAL_TRIGGER_RATEOVERRIDE_PPI); -} - -/******************************************************************************/ -#if !defined(CONFIG_BT_CTLR_TIFS_HW) -/* DPPI setup used for SW-based auto-switching during TIFS. */ - -/* Clear SW-switch timer on packet end: - * wire the RADIO EVENTS_END event to SW_SWITCH_TIMER TASKS_CLEAR task. - * - * Note: we do not need an additional PPI, since we have already set up - * a PPI to publish RADIO END event. - */ -#define HAL_SW_SWITCH_TIMER_CLEAR_PPI HAL_RADIO_END_TIME_CAPTURE_PPI - -static inline void hal_sw_switch_timer_clear_ppi_config(void) -{ - nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_END, HAL_SW_SWITCH_TIMER_CLEAR_PPI); - nrf_timer_subscribe_set(SW_SWITCH_TIMER, NRF_TIMER_TASK_CLEAR, HAL_SW_SWITCH_TIMER_CLEAR_PPI); -} - -/* The 2 adjacent PPI groups used for implementing SW_SWITCH_TIMER-based - * auto-switch for TIFS. 'index' must be 0 or 1. - */ -#define SW_SWITCH_TIMER_TASK_GROUP(index) \ - (SW_SWITCH_TIMER_TASK_GROUP_BASE + index) - -/* The 2 adjacent TIMER EVENTS_COMPARE event offsets used for implementing - * SW_SWITCH_TIMER-based auto-switch for TIFS. 'index' must be 0 or 1. - */ -#define SW_SWITCH_TIMER_EVTS_COMP(index) \ - (SW_SWITCH_TIMER_EVTS_COMP_BASE + index) - -/* The 2 adjacent TIMER EVENTS_COMPARE event offsets used for implementing - * SW_SWITCH_TIMER-based auto-switch for TIFS, when receiving on LE Coded - * PHY. 'index' must be 0 or 1. - */ -#define SW_SWITCH_TIMER_S2_EVTS_COMP(index) \ - (SW_SWITCH_TIMER_EVTS_COMP_S2_BASE + index) - -/* Wire a SW SWITCH TIMER EVENTS_COMPARE[] event - * to a PPI GROUP TASK DISABLE task (PPI group with index ). - * 2 adjacent PPIs (8 & 9) and 2 adjacent PPI groups are used for this wiring; - * must be 0 or 1. must be a valid TIMER CC register offset. - */ -#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_BASE 8 -#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(index) \ - (HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_BASE + index) - -#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_EVT(cc_offset) \ - SW_SWITCH_TIMER->PUBLISH_COMPARE[cc_offset] -#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT(chan) \ - (((chan << TIMER_PUBLISH_COMPARE_CHIDX_Pos) \ - & TIMER_PUBLISH_COMPARE_CHIDX_Msk) | \ - ((TIMER_PUBLISH_COMPARE_EN_Enabled << TIMER_PUBLISH_COMPARE_EN_Pos) \ - & TIMER_PUBLISH_COMPARE_EN_Msk)) -#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(index) \ - NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(index)].DIS -#define HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK(chan) \ - (((chan << DPPIC_SUBSCRIBE_CHG_DIS_CHIDX_Pos) \ - & DPPIC_SUBSCRIBE_CHG_DIS_CHIDX_Msk) | \ - ((DPPIC_SUBSCRIBE_CHG_DIS_EN_Enabled << \ - DPPIC_SUBSCRIBE_CHG_DIS_EN_Pos) \ - & DPPIC_SUBSCRIBE_CHG_DIS_EN_Msk)) - -/* Enable the SW Switch PPI Group on RADIO END Event. - * - * Note: we do not need an additional PPI, since we have already set up - * a PPI to publish RADIO END event. - */ -#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI HAL_SW_SWITCH_TIMER_CLEAR_PPI -#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_EVT \ - (NRF_RADIO->PUBLISH_END) -#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_EVT \ - (((HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI << \ - RADIO_PUBLISH_END_CHIDX_Pos) \ - & RADIO_PUBLISH_END_CHIDX_Msk) | \ - ((RADIO_PUBLISH_END_EN_Enabled << RADIO_PUBLISH_END_EN_Pos) \ - & RADIO_PUBLISH_END_EN_Msk)) -#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(index) \ - (NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(index)].EN) -#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_TASK \ - (((HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI << \ - DPPIC_SUBSCRIBE_CHG_EN_CHIDX_Pos) \ - & DPPIC_SUBSCRIBE_CHG_EN_CHIDX_Msk) | \ - ((DPPIC_SUBSCRIBE_CHG_EN_EN_Enabled << \ - DPPIC_SUBSCRIBE_CHG_EN_EN_Pos) \ - & DPPIC_SUBSCRIBE_CHG_EN_EN_Msk)) - -/* Enable Radio on SW Switch timer event. - * Wire a SW SWITCH TIMER EVENTS_COMPARE[] event - * to a RADIO Enable task (TX or RX). - * - * Note: - * We use the same PPI as for disabling the SW Switch PPI groups, - * since we need to listen for the same event (SW Switch event). - * - * We use the same PPI for the alternative SW Switch Timer compare - * event. - */ -#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_BASE 8 -#define HAL_SW_SWITCH_RADIO_ENABLE_PPI(index) \ - (HAL_SW_SWITCH_RADIO_ENABLE_PPI_BASE + index) - -#define HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI_BASE \ - HAL_SW_SWITCH_RADIO_ENABLE_PPI_BASE -#define HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(index) \ - (HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI_BASE + index) - -#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(cc_offset) \ - SW_SWITCH_TIMER->PUBLISH_COMPARE[cc_offset] -#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(chan) \ - (((chan << TIMER_PUBLISH_COMPARE_CHIDX_Pos) \ - & TIMER_PUBLISH_COMPARE_CHIDX_Msk) | \ - ((TIMER_PUBLISH_COMPARE_EN_Enabled << TIMER_PUBLISH_COMPARE_EN_Pos) \ - & TIMER_PUBLISH_COMPARE_EN_Msk)) -#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_TASK_TX \ - NRF_RADIO->SUBSCRIBE_TXEN -#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_TASK_RX \ - NRF_RADIO->SUBSCRIBE_RXEN -#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_TX_SET(chan) \ - (((chan << RADIO_SUBSCRIBE_TXEN_CHIDX_Pos) \ - & RADIO_SUBSCRIBE_TXEN_CHIDX_Msk) | \ - ((RADIO_SUBSCRIBE_TXEN_EN_Enabled << \ - RADIO_SUBSCRIBE_TXEN_EN_Pos) \ - & RADIO_SUBSCRIBE_TXEN_EN_Msk)) -#define HAL_SW_SWITCH_RADIO_ENABLE_PPI_TASK_RX_SET(chan) \ - (((chan << RADIO_SUBSCRIBE_RXEN_CHIDX_Pos) \ - & RADIO_SUBSCRIBE_RXEN_CHIDX_Msk) | \ - ((RADIO_SUBSCRIBE_RXEN_EN_Enabled << RADIO_SUBSCRIBE_RXEN_EN_Pos) \ - & RADIO_SUBSCRIBE_RXEN_EN_Msk)) - -/* Cancel the SW switch timer running considering S8 timing: - * wire the RADIO EVENTS_RATEBOOST event to SW_SWITCH_TIMER TASKS_CAPTURE task. - * - * Note: We already have a PPI where we publish the RATEBOOST event. - */ -#define HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI HAL_TRIGGER_RATEOVERRIDE_PPI -#define HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_REGISTER_EVT \ - NRF_RADIO->PUBLISH_RATEBOOST -#define HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_EVT \ - (((HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI << \ - RADIO_PUBLISH_RATEBOOST_CHIDX_Pos) \ - & RADIO_PUBLISH_RATEBOOST_CHIDX_Msk) | \ - ((RADIO_PUBLISH_RATEBOOST_EN_Enabled << \ - RADIO_PUBLISH_RATEBOOST_EN_Pos) \ - & RADIO_PUBLISH_RATEBOOST_EN_Msk)) -#define HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_REGISTER_TASK(cc_reg) \ - SW_SWITCH_TIMER->SUBSCRIBE_CAPTURE[cc_reg] -#define HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_TASK \ - (((HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI << \ - TIMER_SUBSCRIBE_CAPTURE_CHIDX_Pos) \ - & TIMER_SUBSCRIBE_CAPTURE_CHIDX_Msk) | \ - ((TIMER_SUBSCRIBE_CAPTURE_EN_Enabled << \ - TIMER_SUBSCRIBE_CAPTURE_EN_Pos) \ - & TIMER_SUBSCRIBE_CAPTURE_EN_Msk)) - - -static inline void hal_radio_sw_switch_setup( - uint8_t compare_reg, - uint8_t radio_enable_ppi, - uint8_t ppi_group_index) -{ - /* Set up software switch mechanism for next Radio switch. */ - - /* Wire RADIO END event to PPI Group[] enable task, - * over PPI[] - */ - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_EVT = - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_EVT; - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(ppi_group_index) = - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_TASK; - - /* We need to un-subscribe the other group from the PPI channel. */ - if (ppi_group_index == 0) { - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(1) = 0; - } else if (ppi_group_index == 1) { - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(0) = 0; - } - - /* Wire SW Switch timer event to the - * PPI[] for enabling Radio. Do - * not wire the task; it is done by the caller of - * the function depending on the desired direction - * (TX/RX). - */ - HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(compare_reg) = - HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(radio_enable_ppi); -} - -static inline void hal_radio_txen_on_sw_switch(uint8_t ppi) -{ - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, ppi); -} - -static inline void hal_radio_rxen_on_sw_switch(uint8_t ppi) -{ - nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, ppi); -} - - -static inline void hal_radio_sw_switch_disable(void) -{ - /* We cannot deactivate the PPI channels, as other tasks - * are subscribed to RADIO_END event, i.e on the same channel. - * So we simply cancel the task subscription. - */ - nrf_timer_subscribe_clear(SW_SWITCH_TIMER, NRF_TIMER_TASK_CLEAR); - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(0) = 0; - HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_TASK(1) = 0; -} - -static inline void hal_radio_sw_switch_cleanup(void) -{ - hal_radio_sw_switch_disable(); - nrf_dppi_channels_disable(NRF_DPPIC, - (BIT(HAL_SW_SWITCH_TIMER_CLEAR_PPI) | - BIT(HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI))); - nrf_dppi_group_disable(NRF_DPPIC, SW_SWITCH_TIMER_TASK_GROUP(0)); - nrf_dppi_group_disable(NRF_DPPIC, SW_SWITCH_TIMER_TASK_GROUP(1)); -} - -static inline void hal_radio_sw_switch_coded_tx_config_set(uint8_t ppi_en, - uint8_t ppi_dis, uint8_t cc_s2, uint8_t group_index) -{ - /* Publish the SW Switch Timer Compare event for S2 timing - * to the PPI that will be used to trigger Radio enable. - */ - HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(cc_s2) = - HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(ppi_en); - - /* The Radio Enable Task is already subscribed to the channel. */ - - /* Wire the Group task disable to the S2 EVENTS_COMPARE. */ - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_EVT(cc_s2) = - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT(ppi_dis); - - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(group_index) = - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK(ppi_dis); - - /* Capture CC to cancel the timer that has assumed - * S8 reception, if packet will be received in S2. - */ - HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_REGISTER_EVT = - HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_EVT; - HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_REGISTER_TASK( - SW_SWITCH_TIMER_EVTS_COMP(group_index)) = - HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_TASK; - - nrf_dppi_channels_enable(NRF_DPPIC, - BIT(HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI)); -} - -static inline void hal_radio_sw_switch_coded_config_clear(uint8_t ppi_en, - uint8_t ppi_dis, uint8_t cc_reg, uint8_t group_index) -{ - /* Invalidate subscription of S2 timer Compare used when - * RXing on LE Coded PHY. - * - * Note: we do not un-subscribe the Radio enable task because - * we use the same PPI for both SW Switch Timer compare events. - */ - HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT( - SW_SWITCH_TIMER_S2_EVTS_COMP(group_index)) = 0; - - /* Wire the Group[group_index] task disable to the default - * SW Switch Timer EVENTS_COMPARE. - */ - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_EVT( - cc_reg) = - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT( - ppi_dis); - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK( - group_index) = - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK( - ppi_dis); -} - -static inline void hal_radio_sw_switch_ppi_group_setup(void) -{ - /* Include the appropriate PPI channels in the two PPI Groups, used for - * SW-based TIFS. - * - * Note that this needs to be done before any SUBSCRIBE task - * registers are written, therefore, we clear the task registers - * here. - */ - NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(0)].EN = 0; - NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(0)].DIS = 0; - NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(1)].EN = 0; - NRF_DPPIC->SUBSCRIBE_CHG[SW_SWITCH_TIMER_TASK_GROUP(1)].DIS = 0; - - NRF_DPPIC->TASKS_CHG[SW_SWITCH_TIMER_TASK_GROUP(0)].DIS = 1; - NRF_DPPIC->TASKS_CHG[SW_SWITCH_TIMER_TASK_GROUP(1)].DIS = 1; - - /* Include the appropriate PPI channels in the two PPI Groups. */ - NRF_DPPIC->CHG[SW_SWITCH_TIMER_TASK_GROUP(0)] = - BIT(HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(0)) | - BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(0)); - NRF_DPPIC->CHG[SW_SWITCH_TIMER_TASK_GROUP(1)] = - BIT(HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)) | - BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(1)); - - /* Sanity build-time check that RADIO Enable and Group Disable - * tasks are going to be subscribed on the same PPIs. - */ - BUILD_ASSERT( - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_BASE == - HAL_SW_SWITCH_RADIO_ENABLE_PPI_BASE, - "Radio enable and Group disable not on the same PPI channels."); - - /* Address nRF5340 Engineering A Errata 16 */ - nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN); - nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_RXEN); -} - -static inline void hal_radio_group_task_disable_ppi_setup(void) -{ - - /* Wire SW SWITCH TIMER EVENTS COMPARE event to - * PPI Group TASK [] DISABLE task, over PPI. - */ - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_EVT( - SW_SWITCH_TIMER_EVTS_COMP(0)) = - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT( - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(0)); - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(0) = - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK( - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(0)); - - /* Wire SW SWITCH TIMER event to - * PPI Group[] Disable Task, over PPI. - */ - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_EVT( - SW_SWITCH_TIMER_EVTS_COMP(1)) = - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_EVT( - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)); - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_REGISTER_TASK(1) = - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI_TASK( - HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)); -} - -#endif - #endif /* CONFIG_SOC_SERIES_NRF51X || CONFIG_SOC_COMPATIBLE_NRF52X */ /******************************************************************************/