Skip to content
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: Separate SDU interval for C_to_P and P_to_C #76453

Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 42 additions & 19 deletions subsys/bluetooth/controller/ll_sw/ull_central_iso.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ static void mfy_cis_offset_get(void *param);
static void ticker_op_cb(uint32_t status, void *param);
#endif /* CONFIG_BT_CTLR_CENTRAL_SPACING == 0 */

static void set_bn_max_pdu(bool framed, uint32_t iso_interval,
uint32_t sdu_interval, uint16_t max_sdu, uint8_t *bn,
uint8_t *max_pdu);
static uint32_t set_bn_max_pdu(bool framed, uint32_t iso_interval,
uint32_t iso_interval_cig, uint32_t sdu_interval,
uint16_t max_sdu, uint8_t *bn, uint8_t *max_pdu);
static uint8_t ll_cig_parameters_validate(void);
static uint8_t ll_cis_parameters_validate(uint8_t cis_idx, uint8_t cis_id,
uint16_t c_sdu, uint16_t p_sdu,
Expand Down Expand Up @@ -154,6 +154,7 @@ uint8_t ll_cig_parameters_commit(uint8_t cig_id, uint16_t *handles)
uint16_t cis_created_handles[STREAMS_PER_GROUP];
struct ll_conn_iso_stream *cis;
struct ll_conn_iso_group *cig;
uint32_t iso_interval_cig_us;
uint32_t iso_interval_us;
uint32_t cig_sync_delay;
uint32_t max_se_length;
Expand Down Expand Up @@ -228,19 +229,19 @@ uint8_t ll_cig_parameters_commit(uint8_t cig_id, uint16_t *handles)
* handle the throughput. For unframed these must be divisible, if they're not,
* framed mode must be forced.
*/
cig->iso_interval = cig->c_sdu_interval / ISO_INT_UNIT_US;
iso_interval_us = cig->c_sdu_interval;

if (cig->iso_interval < BT_HCI_ISO_INTERVAL_MIN) {
if (iso_interval_us < 5000U) {
/* ISO_Interval is below minimum (5 ms) */
cig->iso_interval = BT_HCI_ISO_INTERVAL_MIN;
iso_interval_us = 5000U;
Thalley marked this conversation as resolved.
Show resolved Hide resolved
}

#if defined(CONFIG_BT_CTLR_CONN_ISO_AVOID_SEGMENTATION)
/* Check if this is a HAP usecase which requires higher link bandwidth to ensure
* segmentation is not invoked in ISO-AL.
Comment on lines 242 to 243
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this PR, but how can the controller determine which LE Audio profile is being used? :s

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, @wopu-ot ?

*/
if (cig->central.framing && cig->c_sdu_interval == 10000U) {
cig->iso_interval = 6; /* 7500 us */
iso_interval_us = 7500U; /* us */
}
#endif

Expand All @@ -250,10 +251,11 @@ uint8_t ll_cig_parameters_commit(uint8_t cig_id, uint16_t *handles)
*/
force_framed = true;
}
} else {
iso_interval_us = cig->iso_interval * ISO_INT_UNIT_US;
Thalley marked this conversation as resolved.
Show resolved Hide resolved
}

iso_interval_us = cig->iso_interval * ISO_INT_UNIT_US;
cig->lll.iso_interval_us = iso_interval_us;
iso_interval_cig_us = iso_interval_us;

lll_hdr_init(&cig->lll, cig);
max_se_length = 0U;
Expand Down Expand Up @@ -360,29 +362,43 @@ uint8_t ll_cig_parameters_commit(uint8_t cig_id, uint16_t *handles)
* directions
*/
if (tx) {
uint32_t iso_interval_adjust_us;
uint8_t max_pdu;
uint8_t bn;

bn = cis->lll.tx.bn;
max_pdu = cis->lll.tx.max_pdu;
set_bn_max_pdu(cis->framed, iso_interval_us,
cig->c_sdu_interval,
cis->c_max_sdu, &bn, &max_pdu);
iso_interval_adjust_us =
set_bn_max_pdu(cis->framed, iso_interval_us,
iso_interval_cig_us, cig->c_sdu_interval,
cis->c_max_sdu, &bn, &max_pdu);
if (iso_interval_adjust_us != iso_interval_us) {
iso_interval_us = iso_interval_adjust_us;

goto ll_cig_parameters_commit_retry;
}
cis->lll.tx.bn = bn;
cis->lll.tx.max_pdu = max_pdu;
} else {
cis->lll.tx.bn = 0U;
}

if (rx) {
uint32_t iso_interval_adjust_us;
Thalley marked this conversation as resolved.
Show resolved Hide resolved
uint8_t max_pdu;
uint8_t bn;

bn = cis->lll.rx.bn;
max_pdu = cis->lll.rx.max_pdu;
set_bn_max_pdu(cis->framed, iso_interval_us,
cig->p_sdu_interval,
cis->p_max_sdu, &bn, &max_pdu);
iso_interval_adjust_us =
set_bn_max_pdu(cis->framed, iso_interval_us,
iso_interval_cig_us, cig->p_sdu_interval,
cis->p_max_sdu, &bn, &max_pdu);
if (iso_interval_adjust_us != iso_interval_us) {
iso_interval_us = iso_interval_adjust_us;

goto ll_cig_parameters_commit_retry;
}
cis->lll.rx.bn = bn;
cis->lll.rx.max_pdu = max_pdu;
} else {
Expand All @@ -402,6 +418,9 @@ uint8_t ll_cig_parameters_commit(uint8_t cig_id, uint16_t *handles)
(cis->central.p_rtn + 1) * cis->lll.rx.bn);
}

cig->lll.iso_interval_us = iso_interval_us;
cig->iso_interval = iso_interval_us / ISO_INT_UNIT_US;

handle_iter = UINT16_MAX;
total_time = 0U;

Expand Down Expand Up @@ -1170,9 +1189,9 @@ static void ticker_op_cb(uint32_t status, void *param)
}
#endif /* CONFIG_BT_CTLR_CENTRAL_SPACING == 0 */

static void set_bn_max_pdu(bool framed, uint32_t iso_interval,
uint32_t sdu_interval, uint16_t max_sdu, uint8_t *bn,
uint8_t *max_pdu)
static uint32_t set_bn_max_pdu(bool framed, uint32_t iso_interval,
uint32_t iso_interval_cig, uint32_t sdu_interval,
uint16_t max_sdu, uint8_t *bn, uint8_t *max_pdu)
Thalley marked this conversation as resolved.
Show resolved Hide resolved
{
if (framed) {
uint32_t max_drift_us;
Expand Down Expand Up @@ -1222,13 +1241,17 @@ static void set_bn_max_pdu(bool framed, uint32_t iso_interval,
}
} else {
/* For unframed, ISO_Interval must be N x SDU_Interval */
LL_ASSERT(iso_interval % sdu_interval == 0);
if ((iso_interval % sdu_interval) != 0) {
iso_interval += iso_interval_cig;
}
Thalley marked this conversation as resolved.
Show resolved Hide resolved

/* Core 5.3 Vol 6, Part G section 2.1:
* BN >= ceil(Max_SDU/Max_PDU * ISO_Interval/SDU_Interval)
*/
*bn = DIV_ROUND_UP(max_sdu * iso_interval, (*max_pdu) * sdu_interval);
}

return iso_interval;
}

static uint8_t ll_cig_parameters_validate(void)
Expand Down
Loading