diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 3bccb06d344..2da45e72a0d 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -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 */ 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 index 4a5ba5f753f..29ed17dcc7e 100644 --- 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 @@ -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. 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 b5557e483ad..8185036fbc3 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 @@ -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[] 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[] 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);