Bluetooth: Controller: Refactor sw_switch hal interface use

Refactor sw_switch hal interface use and document why some
PPI/DPPI channel group related subscriptions are not
disabled explicitly.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2024-07-06 01:28:18 +02:00 committed by Anas Nashif
commit 55b7dba8ec
3 changed files with 88 additions and 34 deletions

View file

@ -823,17 +823,12 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla
#if defined(CONFIG_BT_CTLR_PHY_CODED)
#if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
uint8_t ppi_en =
HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(sw_tifs_toggle);
uint8_t ppi_dis =
HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(sw_tifs_toggle);
uint8_t ppi_en = HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(sw_tifs_toggle);
uint8_t ppi_dis = HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(sw_tifs_toggle);
uint8_t cc_s2 = SW_SWITCH_TIMER_S2_EVTS_COMP(sw_tifs_toggle);
if (dir_curr == SW_SWITCH_RX && (phy_curr & PHY_CODED)) {
/* Switching to TX after RX on LE Coded PHY. */
uint8_t cc_s2 =
SW_SWITCH_TIMER_S2_EVTS_COMP(sw_tifs_toggle);
uint32_t delay_s2;
uint32_t new_cc_s2_value;
@ -874,7 +869,7 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla
* because the code is very fragile and hard to debug.
*/
if (end_evt_delay_en != END_EVT_DELAY_ENABLED) {
hal_radio_sw_switch_coded_config_clear(ppi_en, ppi_dis, cc,
hal_radio_sw_switch_coded_config_clear(ppi_en, ppi_dis, cc_s2,
sw_tifs_toggle);
}
@ -915,13 +910,12 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla
#if defined(CONFIG_BT_CTLR_PHY_CODED)
#if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
if (1) {
uint8_t ppi_en = HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(
sw_tifs_toggle);
uint8_t ppi_dis = HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(
sw_tifs_toggle);
uint8_t ppi_en = HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(sw_tifs_toggle);
uint8_t ppi_dis = HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(sw_tifs_toggle);
uint8_t cc_s2 = SW_SWITCH_TIMER_S2_EVTS_COMP(sw_tifs_toggle);
hal_radio_sw_switch_coded_config_clear(ppi_en,
ppi_dis, cc, sw_tifs_toggle);
hal_radio_sw_switch_coded_config_clear(ppi_en, ppi_dis, cc_s2,
sw_tifs_toggle);
hal_radio_sw_switch_disable_group_clear(ppi_dis, cc, sw_tifs_toggle);
}
#endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */

View file

@ -150,6 +150,10 @@ static inline void hal_trigger_aar_ppi_config(void)
nrf_aar_subscribe_set(NRF_AAR, NRF_AAR_TASK_START, HAL_TRIGGER_AAR_PPI);
}
/* When hardware does not support Coded PHY we still allow the Controller
* implementation to accept Coded PHY flags, but the Controller will use 1M
* PHY on air. This is implementation specific feature.
*/
#if defined(CONFIG_BT_CTLR_PHY_CODED) && defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
/*******************************************************************************
* Trigger Radio Rate override upon Rateboost event.
@ -457,6 +461,11 @@ static inline void hal_radio_sw_switch_disable(void)
HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(0)));
nrf_dppi_subscribe_clear(NRF_DPPIC,
HAL_SW_DPPI_TASK_EN_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(1)));
/* Invalidation of subscription of S2 timer Compare used when
* RXing on LE Coded PHY is not needed, as other DPPI subscription
* is disable on each sw_switch call already.
*/
}
static inline void hal_radio_sw_switch_b2b_tx_disable(uint8_t compare_reg_index)
@ -514,16 +523,20 @@ static inline void hal_radio_sw_switch_coded_tx_config_set(uint8_t ppi_en,
HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_REGISTER_EVT =
HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_EVT;
nrf_timer_subscribe_set(SW_SWITCH_TIMER,
nrf_timer_capture_task_get(SW_SWITCH_TIMER_EVTS_COMP(group_index)),
nrf_timer_capture_task_get(cc_s2),
HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI);
nrf_dppi_channels_enable(NRF_DPPIC,
BIT(HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI));
}
/* When hardware does not support Coded PHY we still allow the Controller
* implementation to accept Coded PHY flags, but the Controller will use 1M
* PHY on air. This is implementation specific feature.
*/
#if defined(CONFIG_BT_CTLR_PHY_CODED) && defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
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)
uint8_t ppi_dis, uint8_t cc_s2, uint8_t group_index)
{
/* Invalidate subscription of S2 timer Compare used when
* RXing on LE Coded PHY.
@ -531,8 +544,7 @@ static inline void hal_radio_sw_switch_coded_config_clear(uint8_t ppi_en,
* 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;
HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(cc_s2) = 0U;
}
#endif /* CONFIG_BT_CTLR_PHY_CODED && CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
@ -575,6 +587,32 @@ static inline void hal_radio_sw_switch_ppi_group_setup(void)
HAL_SW_DPPI_TASK_DIS_FROM_IDX(SW_SWITCH_TIMER_TASK_GROUP(1)));
/* Include the appropriate PPI channels in the two PPI Groups. */
#if defined(CONFIG_BT_CTLR_PHY_CODED)
nrf_dppi_group_clear(NRF_DPPIC,
SW_SWITCH_TIMER_TASK_GROUP(0));
nrf_dppi_channels_include_in_group(NRF_DPPIC,
BIT(HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(0)) |
BIT(HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(0)) |
BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(0)),
SW_SWITCH_TIMER_TASK_GROUP(0));
nrf_dppi_group_clear(NRF_DPPIC,
SW_SWITCH_TIMER_TASK_GROUP(1));
nrf_dppi_channels_include_in_group(NRF_DPPIC,
BIT(HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)) |
BIT(HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(1)) |
BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(1)),
SW_SWITCH_TIMER_TASK_GROUP(1));
/* NOTE: HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI_BASE is equal to
* HAL_SW_SWITCH_RADIO_ENABLE_PPI_BASE.
*/
BUILD_ASSERT(
!IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED) ||
(HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI_BASE ==
HAL_SW_SWITCH_RADIO_ENABLE_PPI_BASE),
"Radio enable and Group disable not on the same PPI channels.");
#else /* !CONFIG_BT_CTLR_PHY_CODED */
nrf_dppi_group_clear(NRF_DPPIC,
SW_SWITCH_TIMER_TASK_GROUP(0));
nrf_dppi_channels_include_in_group(NRF_DPPIC,
@ -587,6 +625,7 @@ static inline void hal_radio_sw_switch_ppi_group_setup(void)
BIT(HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(1)) |
BIT(HAL_SW_SWITCH_RADIO_ENABLE_PPI(1)),
SW_SWITCH_TIMER_TASK_GROUP(1));
#endif /* !CONFIG_BT_CTLR_PHY_CODED */
/* Sanity build-time check that RADIO Enable and Group Disable
* tasks are going to be subscribed on the same PPIs.

View file

@ -5,6 +5,24 @@
* SPDX-License-Identifier: Apache-2.0
*/
#if defined(CONFIG_BT_CTLR_PHY_CODED)
/* The 2 adjacent TIMER EVENTS_COMPARE event offsets used for implementing
* SW_SWITCH_TIMER-based auto-switch for TIFS, when receiving in 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 the SW SWITCH TIMER EVENTS_COMPARE[<cc_offset>] event
* to RADIO TASKS_TXEN/RXEN task.
*/
#define HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(index) \
(HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI_BASE + (index))
static inline void hal_radio_sw_switch_coded_config_clear(uint8_t ppi_en,
uint8_t ppi_dis, uint8_t cc_s2, uint8_t group_index);
#endif
static inline void hal_radio_nrf_ppi_channels_enable(uint32_t mask)
{
nrf_ppi_channels_enable(NRF_PPI, mask);
@ -441,6 +459,11 @@ static inline void hal_radio_sw_switch_disable(void)
NRF_PPI,
BIT(HAL_SW_SWITCH_TIMER_CLEAR_PPI) |
BIT(HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI));
/* Invalidation of subscription of S2 timer Compare used when
* RXing on LE Coded PHY is not needed, as other DPPI subscription
* is disable on each sw_switch call already.
*/
}
static inline void hal_radio_sw_switch_b2b_tx_disable(uint8_t compare_reg_index)
@ -462,19 +485,6 @@ static inline void hal_radio_sw_switch_cleanup(void)
#if defined(CONFIG_BT_CTLR_PHY_CODED) && \
defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
/* The 2 adjacent TIMER EVENTS_COMPARE event offsets used for implementing
* SW_SWITCH_TIMER-based auto-switch for TIFS, when receiving in 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 the SW SWITCH TIMER EVENTS_COMPARE[<cc_offset>] event
* to RADIO TASKS_TXEN/RXEN task.
*/
#define HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(index) \
(HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI_BASE + (index))
/* Cancel the SW switch timer running considering S8 timing:
* wire the RADIO EVENTS_RATEBOOST event to SW_SWITCH_TIMER TASKS_CAPTURE task.
*/
@ -507,15 +517,26 @@ static inline void hal_radio_sw_switch_coded_tx_config_set(uint8_t ppi_en,
nrf_ppi_event_endpoint_setup(NRF_PPI, HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI,
HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_EVT);
nrf_ppi_task_endpoint_setup(NRF_PPI, HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI,
HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_TASK(group_index));
HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_TASK(cc_s2));
nrf_ppi_channels_enable(
NRF_PPI,
BIT(HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI));
/* Note: below code is not absolutely needed, as other DPPI subscription
* is disable on each sw_switch call already.
*/
if (IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED) && false) {
/* We need to clear the other group S2 PPI */
group_index = (group_index + 1) & 0x01;
hal_radio_sw_switch_coded_config_clear(
HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(group_index),
0U, 0U, 0U);
}
}
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)
uint8_t ppi_dis, uint8_t cc_s2, uint8_t group_index)
{
/* Invalidate PPI used when RXing on LE Coded PHY. */
nrf_ppi_event_endpoint_setup(NRF_PPI, ppi_en, 0);