-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Bluetooth: controller: nRF5: Back-to-Back Radio Tx interface #33118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0471175
81b912a
d5c621e
f597fa4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -489,28 +489,55 @@ void *radio_pkt_decrypt_get(void) | |
| #endif | ||
|
|
||
| #if !defined(CONFIG_BT_CTLR_TIFS_HW) | ||
|
|
||
| #define SW_SWITCH_PREV_RX 0 | ||
| #define SW_SWITCH_NEXT_RX 0 | ||
| #define SW_SWITCH_PREV_TX 1 | ||
| #define SW_SWITCH_NEXT_TX 1 | ||
| #define SW_SWITCH_PREV_PHY_1M 0 | ||
|
||
| #define SW_SWITCH_PREV_FLAGS_DONTCARE 0 | ||
| #define SW_SWITCH_NEXT_FLAGS_DONTCARE 0 | ||
|
||
|
|
||
| static uint8_t sw_tifs_toggle; | ||
|
|
||
| static void sw_switch(uint8_t dir, uint8_t phy_curr, uint8_t flags_curr, uint8_t phy_next, | ||
| uint8_t flags_next) | ||
| static inline void sw_switch(uint8_t dir_curr, uint8_t dir_next, | ||
| uint8_t phy_curr, uint8_t flags_curr, | ||
| uint8_t phy_next, uint8_t flags_next) | ||
| { | ||
| uint8_t ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(sw_tifs_toggle); | ||
| uint8_t cc = SW_SWITCH_TIMER_EVTS_COMP(sw_tifs_toggle); | ||
| uint32_t delay; | ||
|
|
||
| hal_radio_sw_switch_setup(cc, ppi, sw_tifs_toggle); | ||
|
|
||
| if (dir) { | ||
| /* NOTE: As constants are passed to dir_curr and dir_next, the | ||
| * compiler should optimize out the redundant code path as | ||
| * this is an inline function. | ||
| */ | ||
| if (dir_next) { | ||
| /* TX */ | ||
|
|
||
| /* Calculate delay with respect to current (RX) and next | ||
| * (TX) PHY. If RX PHY is LE Coded, assume S8 coding scheme. | ||
| /* Calculate delay with respect to current and next PHY. | ||
| */ | ||
| delay = HAL_RADIO_NS2US_ROUND( | ||
| hal_radio_tx_ready_delay_ns_get(phy_next, flags_next) + | ||
| hal_radio_rx_chain_delay_ns_get(phy_curr, 1)); | ||
|
|
||
| hal_radio_txen_on_sw_switch(ppi); | ||
| if (dir_curr) { | ||
| delay = HAL_RADIO_NS2US_ROUND( | ||
| hal_radio_tx_ready_delay_ns_get(phy_next, | ||
| flags_next) + | ||
| hal_radio_tx_chain_delay_ns_get(phy_curr, | ||
| flags_curr)); | ||
|
|
||
| hal_radio_b2b_txen_on_sw_switch(ppi); | ||
| } else { | ||
| /* If RX PHY is LE Coded, calculate for S8 coding. | ||
| * Assumption being, S8 has higher delay. | ||
| */ | ||
| delay = HAL_RADIO_NS2US_ROUND( | ||
| hal_radio_tx_ready_delay_ns_get(phy_next, | ||
| flags_next) + | ||
| hal_radio_rx_chain_delay_ns_get(phy_curr, 1)); | ||
|
|
||
| hal_radio_txen_on_sw_switch(ppi); | ||
| } | ||
|
|
||
| #if defined(CONFIG_BT_CTLR_PHY_CODED) | ||
| #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED) | ||
|
|
@@ -520,7 +547,7 @@ static void sw_switch(uint8_t dir, uint8_t phy_curr, uint8_t flags_curr, uint8_t | |
| HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI( | ||
| sw_tifs_toggle); | ||
|
|
||
| if (phy_curr & PHY_CODED) { | ||
| if (!dir_curr && (phy_curr & PHY_CODED)) { | ||
| /* Switching to TX after RX on LE Coded PHY. */ | ||
|
|
||
| uint8_t cc_s2 = | ||
|
|
@@ -530,12 +557,11 @@ static void sw_switch(uint8_t dir, uint8_t phy_curr, uint8_t flags_curr, uint8_t | |
|
|
||
| /* Calculate assuming reception on S2 coding scheme. */ | ||
| delay_s2 = HAL_RADIO_NS2US_ROUND( | ||
| hal_radio_tx_ready_delay_ns_get( | ||
| phy_next, flags_next) + | ||
| hal_radio_tx_ready_delay_ns_get(phy_next, | ||
| flags_next) + | ||
| hal_radio_rx_chain_delay_ns_get(phy_curr, 0)); | ||
|
|
||
| SW_SWITCH_TIMER->CC[cc_s2] = | ||
| SW_SWITCH_TIMER->CC[cc]; | ||
| SW_SWITCH_TIMER->CC[cc_s2] = SW_SWITCH_TIMER->CC[cc]; | ||
|
|
||
| if (delay_s2 < SW_SWITCH_TIMER->CC[cc_s2]) { | ||
| SW_SWITCH_TIMER->CC[cc_s2] -= delay_s2; | ||
|
|
@@ -545,7 +571,8 @@ static void sw_switch(uint8_t dir, uint8_t phy_curr, uint8_t flags_curr, uint8_t | |
|
|
||
| hal_radio_sw_switch_coded_tx_config_set(ppi_en, ppi_dis, | ||
| cc_s2, sw_tifs_toggle); | ||
| } else { | ||
|
|
||
| } else if (!dir_curr) { | ||
| /* Switching to TX after RX on LE 1M/2M PHY */ | ||
|
|
||
| hal_radio_sw_switch_coded_config_clear(ppi_en, | ||
|
|
@@ -564,12 +591,10 @@ static void sw_switch(uint8_t dir, uint8_t phy_curr, uint8_t flags_curr, uint8_t | |
| #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); | ||
|
|
||
| hal_radio_sw_switch_coded_config_clear(ppi_en, | ||
| ppi_dis, cc, sw_tifs_toggle); | ||
|
|
@@ -578,26 +603,32 @@ static void sw_switch(uint8_t dir, uint8_t phy_curr, uint8_t flags_curr, uint8_t | |
| #endif /* CONFIG_BT_CTLR_PHY_CODED */ | ||
| } | ||
|
|
||
| if (delay < | ||
| SW_SWITCH_TIMER->CC[cc]) { | ||
| if (delay < SW_SWITCH_TIMER->CC[cc]) { | ||
| nrf_timer_cc_set(SW_SWITCH_TIMER, cc, | ||
| SW_SWITCH_TIMER->CC[cc] - delay); | ||
| (SW_SWITCH_TIMER->CC[cc] - delay)); | ||
| } else { | ||
| nrf_timer_cc_set(SW_SWITCH_TIMER, cc, 1); | ||
| } | ||
|
|
||
| hal_radio_nrf_ppi_channels_enable(BIT(HAL_SW_SWITCH_TIMER_CLEAR_PPI) | | ||
| BIT(HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI)); | ||
|
|
||
| #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) | ||
| /* Since the event timer is cleared on END, we | ||
| * always need to capture the PDU END time-stamp. | ||
| #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) || \ | ||
| defined(CONFIG_SOC_SERIES_NRF53X) | ||
| /* NOTE: nRF5340 shares the DPPI channel being triggered by Radio End | ||
| * for End time capture and sw_switch DPPI channel toggling hence | ||
| * always need to capture End time. Or when using single event | ||
| * timer since the timer is cleared on Radio End, we always need | ||
| * to capture the Radio End time-stamp. | ||
| */ | ||
| radio_tmr_end_capture(); | ||
| #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ | ||
| hal_radio_end_time_capture_ppi_config(); | ||
| #if !defined(CONFIG_SOC_SERIES_NRF53X) | ||
| hal_radio_nrf_ppi_channels_enable(BIT(HAL_RADIO_END_TIME_CAPTURE_PPI)); | ||
| #endif /* !CONFIG_SOC_SERIES_NRF53X */ | ||
| #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER || CONFIG_SOC_SERIES_NRF53X */ | ||
|
|
||
| sw_tifs_toggle += 1U; | ||
| sw_tifs_toggle &= 1; | ||
| sw_tifs_toggle &= 1U; | ||
| } | ||
| #endif /* CONFIG_BT_CTLR_TIFS_HW */ | ||
|
|
||
|
|
@@ -610,12 +641,19 @@ void radio_switch_complete_and_rx(uint8_t phy_rx) | |
| #else /* !CONFIG_BT_CTLR_TIFS_HW */ | ||
| NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | | ||
| RADIO_SHORTS_END_DISABLE_Msk; | ||
| sw_switch(0, 0, 0, phy_rx, 0); | ||
|
|
||
| /* NOTE: As Tx chain delays are negligible constant values (~1 us) | ||
| * across nRF5x radios, sw_switch assumes the 1M chain delay for | ||
| * calculations. | ||
| */ | ||
| sw_switch(SW_SWITCH_PREV_TX, SW_SWITCH_NEXT_RX, | ||
| SW_SWITCH_PREV_PHY_1M, SW_SWITCH_PREV_FLAGS_DONTCARE, | ||
| phy_rx, SW_SWITCH_NEXT_FLAGS_DONTCARE); | ||
| #endif /* !CONFIG_BT_CTLR_TIFS_HW */ | ||
| } | ||
|
|
||
| void radio_switch_complete_and_tx(uint8_t phy_rx, uint8_t flags_rx, uint8_t phy_tx, | ||
| uint8_t flags_tx) | ||
| void radio_switch_complete_and_tx(uint8_t phy_rx, uint8_t flags_rx, | ||
| uint8_t phy_tx, uint8_t flags_tx) | ||
| { | ||
| #if defined(CONFIG_BT_CTLR_TIFS_HW) | ||
| NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | | ||
|
|
@@ -624,7 +662,25 @@ void radio_switch_complete_and_tx(uint8_t phy_rx, uint8_t flags_rx, uint8_t phy_ | |
| #else /* !CONFIG_BT_CTLR_TIFS_HW */ | ||
| NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | | ||
| RADIO_SHORTS_END_DISABLE_Msk; | ||
| sw_switch(1, phy_rx, flags_rx, phy_tx, flags_tx); | ||
|
|
||
| sw_switch(SW_SWITCH_PREV_RX, SW_SWITCH_NEXT_TX, | ||
| phy_rx, flags_rx, phy_tx, flags_tx); | ||
| #endif /* !CONFIG_BT_CTLR_TIFS_HW */ | ||
| } | ||
|
|
||
| void radio_switch_complete_and_b2b_tx(uint8_t phy_curr, uint8_t flags_curr, | ||
| uint8_t phy_next, uint8_t flags_next) | ||
| { | ||
| #if defined(CONFIG_BT_CTLR_TIFS_HW) | ||
| NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | | ||
| RADIO_SHORTS_END_DISABLE_Msk | | ||
| RADIO_SHORTS_DISABLED_TXEN_Msk; | ||
| #else /* !CONFIG_BT_CTLR_TIFS_HW */ | ||
| NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | | ||
| RADIO_SHORTS_END_DISABLE_Msk; | ||
|
|
||
| sw_switch(SW_SWITCH_PREV_TX, SW_SWITCH_NEXT_TX, | ||
| phy_curr, flags_curr, phy_next, flags_next); | ||
| #endif /* !CONFIG_BT_CTLR_TIFS_HW */ | ||
| } | ||
|
|
||
|
|
@@ -954,8 +1010,16 @@ uint32_t radio_tmr_ready_get(void) | |
|
|
||
| void radio_tmr_end_capture(void) | ||
| { | ||
| /* NOTE: nRF5340 shares the DPPI channel being triggered by Radio End | ||
| * for End time capture and sw_switch DPPI channel toggling hence | ||
| * always need to capture End time. Hence, the below code is | ||
| * present in hal_sw_switch_timer_clear_ppi_config() and | ||
| * sw_switch(). | ||
| */ | ||
| #if defined(CONFIG_BT_CTLR_TIFS_HW) || !defined(CONFIG_SOC_SERIES_NRF53X) | ||
| hal_radio_end_time_capture_ppi_config(); | ||
| hal_radio_nrf_ppi_channels_enable(BIT(HAL_RADIO_END_TIME_CAPTURE_PPI)); | ||
| #endif /* CONFIG_BT_CTLR_TIFS_HW || !CONFIG_SOC_SERIES_NRF53X */ | ||
| } | ||
|
|
||
| uint32_t radio_tmr_end_get(void) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SW_SWITCH_DIR_*used for both TX and RX would be less confusingThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are aliases to hardcoded 0 or 1, used to convey the parameter name supplied to inlined
sw_switchfile static function. They are not intended to be used as parameter values to other functions.Do you mean to rename to