-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Bluetooth: Controller: Fix single switch timer use in ISO Sync #96653
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
Bluetooth: Controller: Fix single switch timer use in ISO Sync #96653
Conversation
0ca5b96 to
826c113
Compare
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.
Pull Request Overview
This PR fixes the implementation of Broadcast ISO Synchronized Receiver when using a single switch timer to properly handle minimum compare value requirements. The changes update the overhead calculation logic to account for maximum ISR latency and improve timing precision for radio receptions.
- Refactors overhead calculation to include HAL_RADIO_ISR_LATENCY_MAX_US consideration
- Removes timer start delay subtraction from jitter calculation
- Adds detailed comments explaining each overhead component
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| /* If single timer used, then consider required max. latency */ | ||
| overhead_us = MAX(overhead_us, HAL_RADIO_ISR_LATENCY_MAX_US); | ||
| /* Add chain delay overhead */ | ||
| overhead_us += radio_rx_chain_delay_get(lll->phy, PHY_FLAGS_S8); |
Copilot
AI
Sep 28, 2025
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.
The overhead calculation logic has changed significantly but the addr_us_get(lll->phy) component that was previously included in the overhead is now missing. This could affect the total overhead calculation unless this component is intentionally excluded in the new implementation.
| overhead_us += radio_rx_chain_delay_get(lll->phy, PHY_FLAGS_S8); | |
| overhead_us += radio_rx_chain_delay_get(lll->phy, PHY_FLAGS_S8); | |
| /* Add address timing overhead */ | |
| overhead_us += addr_us_get(lll->phy); |
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.
Intentionally excluded, use of duration until address is incorrect; only overhead duration between last bit on-air to first bit on-air be calculated.
826c113 to
36f1766
Compare
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.
Pull Request Overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| overhead_us += HAL_RADIO_ISR_LATENCY_MAX_US; | ||
| /* Add chain delay overhead */ | ||
| overhead_us += radio_rx_chain_delay_get(lll->phy, PHY_FLAGS_S8); | ||
| /* Add active clock jitter overhead per subevent */ |
Copilot
AI
Oct 4, 2025
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.
The comment says 'per subevent', but the code adds a single 2×EVENT_CLOCK_JITTER_US term independent of the number of subevents. Either reword the comment (e.g., 'Add base active clock jitter overhead') or, if the intent was to account per subevent, incorporate the subevent factor explicitly.
| /* Add active clock jitter overhead per subevent */ | |
| /* Add base active clock jitter overhead */ |
| LL_ASSERT(EVENT_IFS_US > overhead_us); | ||
|
|
||
| /* Max. available jitter */ | ||
| jitter_max_us = (EVENT_IFS_US - overhead_us) >> 1; |
Copilot
AI
Oct 4, 2025
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.
[nitpick] Using a bit shift to divide by 2 reduces readability with no performance benefit on modern compilers. Prefer an explicit division: jitter_max_us = (EVENT_IFS_US - overhead_us) / 2;
| jitter_max_us = (EVENT_IFS_US - overhead_us) >> 1; | |
| jitter_max_us = (EVENT_IFS_US - overhead_us) / 2; |
| /* Required radio ready duration, settling time */ | ||
| overhead_us = radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8); | ||
| /* If single timer used, then consider required max. latency */ | ||
| overhead_us += HAL_RADIO_ISR_LATENCY_MAX_US; |
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.
Previous use of MAX here was incorrect, the required HAL_RADIO_ISR_LATENCY_MAX_US is addition to required radio_rx_ready_delay_get in order to have radio ready when using single timer for packet and tIFS swtich timer in nRF54Lx.
Test that covers the change in this PR is in #75760, which checks for drifting bap_broadcast_assistant ACL over BIG sync events, exposes the use of higher jitter duration needed when later subevents are required to be received.
Fix implementation of Broadcast ISO Synchronized Receiver using single switch timer to consider minimum compare value requirement. This fix reduces latencies to setup radio receptions and fixes an assertion in lll_sync_iso when radio_tmr_start_us() is checked for latencies. Relates to commit 5dfc58c ("Bluetooth: Controller: Fix single switch timer minimum compare value"). Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
36f1766 to
cca9d4e
Compare
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.
Pull Request Overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| /* Max. available clock jitter */ | ||
| jitter_max_us = (EVENT_IFS_US - overhead_us) >> 1; | ||
| /* Max. clock jitter per subevent */ | ||
| jitter_max_us = (jitter_max_us * nse) / (lll->num_bis * lll->nse); | ||
| overhead_us = HAL_RADIO_TMR_START_DELAY_US; | ||
| if (jitter_max_us > overhead_us) { | ||
| jitter_max_us -= overhead_us; | ||
| } else { | ||
| jitter_max_us = 0U; | ||
| } | ||
| /* Min. clock jitter we shall use */ | ||
| jitter_max_us = MAX(jitter_max_us, (EVENT_CLOCK_JITTER_US << 1)); | ||
|
|
||
| /* Jitter for current subevent */ | ||
| jitter_us = (EVENT_CLOCK_JITTER_US << 1) * nse; | ||
| if (jitter_us > jitter_max_us) { |
Copilot
AI
Oct 4, 2025
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.
"Raising a variable named jitter_max_us with MAX(...) can exceed the true available jitter budget derived from EVENT_IFS_US - overhead_us, potentially allowing jitter_us to surpass the timing slack and causing missed radio timings. Instead, keep jitter_max_us as the budget ceiling and enforce the minimum on jitter_us (if needed) or remove the minimum entirely. For example: compute jitter_max_us on lines 1367–1369 as-is, then clamp jitter_us with both lower and upper bounds:
| /* Overhead within EVENT_IFS_US to exclude from max. jitter */ | ||
| /* Required radio ready duration, settling time */ | ||
| overhead_us = radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8); | ||
| /* If single timer used, then consider required max. latency */ |
Copilot
AI
Oct 4, 2025
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.
The comment states this addition applies 'If single timer used,' but the code unconditionally adds HAL_RADIO_ISR_LATENCY_MAX_US. Either guard this with the appropriate build-time/runtime condition for single-switch timer, or update the comment to reflect that this latency is always considered here.
| /* If single timer used, then consider required max. latency */ | |
| /* Always consider required max. latency (HAL_RADIO_ISR_LATENCY_MAX_US) */ |
| jitter_max_us = (jitter_max_us * nse) / (lll->num_bis * lll->nse); | ||
| overhead_us = HAL_RADIO_TMR_START_DELAY_US; | ||
| if (jitter_max_us > overhead_us) { | ||
| jitter_max_us -= overhead_us; | ||
| } else { | ||
| jitter_max_us = 0U; | ||
| } | ||
| /* Min. clock jitter we shall use */ | ||
| jitter_max_us = MAX(jitter_max_us, (EVENT_CLOCK_JITTER_US << 1)); | ||
|
|
||
| /* Jitter for current subevent */ | ||
| jitter_us = (EVENT_CLOCK_JITTER_US << 1) * nse; |
Copilot
AI
Oct 4, 2025
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.
[nitpick] Using both nse (local) and lll->nse (struct field) in the same expression is confusing. Consider renaming the local nse to something like subevent_idx or adding an inline comment clarifying that nse here is the current subevent index while lll->nse is the total number of subevents.
|



Fix implementation of Broadcast ISO Synchronized Receiver using single switch timer to consider minimum compare value requirement.
This fix reduces latencies to setup radio receptions and fixes an assertion in lll_sync_iso when radio_tmr_start_us() is checked for latencies.
Relates to commit 5dfc58c ("Bluetooth: Controller: Fix single switch timer minimum compare value").