diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index a2a2b2ad156..d06cf7cc042 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -68,6 +68,7 @@ #include "ll_sw/ull_sync_internal.h" #include "ll_sw/ull_conn_internal.h" #include "ll_sw/ull_sync_iso_internal.h" +#include "ll_sw/ull_iso_internal.h" #include "ll_sw/ull_df_internal.h" #include "ll.h" @@ -7892,7 +7893,9 @@ static void le_big_sync_established(struct pdu_data *pdu, * SDU_Interval */ iso_interval_us = lll->iso_interval * ISO_INT_UNIT_US; - big_sync_delay = ull_big_sync_delay(lll); + big_sync_delay = ull_iso_big_sync_delay(lll->num_bis, lll->bis_spacing, lll->nse, + lll->sub_interval, lll->phy, lll->max_pdu, + lll->enc); if (lll->framing) { /* Framed */ transport_latency_big = big_sync_delay + diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c index f11cd49c733..b0251ce06cc 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c @@ -294,7 +294,7 @@ static int prepare_cb_common(struct lll_prepare_param *p) if (!link) { pdu = radio_pkt_empty_get(); - pdu->ll_id = PDU_BIS_LLID_START_CONTINUE; + pdu->ll_id = lll->framing ? PDU_BIS_LLID_FRAMED : PDU_BIS_LLID_START_CONTINUE; pdu->len = 0U; } else { pdu = (void *)tx->pdu; @@ -650,7 +650,8 @@ static void isr_tx_common(void *param, } if (!link || (tx->payload_count != payload_count)) { pdu = radio_pkt_empty_get(); - pdu->ll_id = PDU_BIS_LLID_START_CONTINUE; + pdu->ll_id = lll->framing ? PDU_BIS_LLID_FRAMED : + PDU_BIS_LLID_START_CONTINUE; pdu->len = 0U; } else { pdu = (void *)tx->pdu; diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c index 69b22cc4818..2f7a9d5d23e 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c @@ -349,7 +349,14 @@ static uint8_t big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bi iso_interval_us = iso_interval * PERIODIC_INT_UNIT_US; } else { - lll_adv_iso->max_pdu = MIN(LL_BIS_OCTETS_TX_MAX, max_sdu); + if (framing) { + /* Try to allocate room for one SDU + header */ + lll_adv_iso->max_pdu = MIN(LL_BIS_OCTETS_TX_MAX, + max_sdu + PDU_ISO_SEG_HDR_SIZE + + PDU_ISO_SEG_TIMEOFFSET_SIZE); + } else { + lll_adv_iso->max_pdu = MIN(LL_BIS_OCTETS_TX_MAX, max_sdu); + } /* FIXME: SDU per max latency */ sdu_per_event = MAX((max_latency * USEC_PER_MSEC / sdu_interval), 2U) - @@ -1504,11 +1511,19 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift, static struct lll_prepare_param p; struct ll_adv_iso_set *adv_iso = param; uint32_t remainder_us; + uint64_t event_count; uint32_t ret; uint8_t ref; DEBUG_RADIO_PREPARE_A(1); + event_count = adv_iso->lll.payload_count / adv_iso->lll.bn; + for (int i = 0; i < adv_iso->lll.num_bis; i++) { + uint16_t stream_handle = adv_iso->lll.stream_handle[i]; + + ull_iso_lll_event_prepare(LL_BIS_ADV_HANDLE_FROM_IDX(stream_handle), event_count); + } + /* Increment prepare reference count */ ref = ull_ref_inc(&adv_iso->ull); LL_ASSERT(ref); diff --git a/subsys/bluetooth/controller/ll_sw/ull_iso.c b/subsys/bluetooth/controller/ll_sw/ull_iso.c index 30100b915ed..00c791c1655 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_iso.c @@ -321,9 +321,12 @@ uint8_t ll_setup_iso_path(uint16_t handle, uint8_t path_dir, uint8_t path_id, sdu_interval = lll_iso->sdu_interval; burst_number = lll_iso->bn; flush_timeout = 0U; /* Not used for Broadcast ISO */ - group_sync_delay = 0U; /* FIXME: */ - stream_sync_delay = 0U; /* FIXME: */ - framed = 0U; /* FIXME: pick the framing value from context */ + group_sync_delay = ull_iso_big_sync_delay(lll_iso->num_bis, lll_iso->bis_spacing, + lll_iso->nse, lll_iso->sub_interval, + lll_iso->phy, lll_iso->max_pdu, + lll_iso->enc); + stream_sync_delay = group_sync_delay - stream_handle * lll_iso->bis_spacing; + framed = lll_iso->framing; max_octets = lll_iso->max_pdu; #endif /* CONFIG_BT_CTLR_ADV_ISO */ @@ -347,7 +350,10 @@ uint8_t ll_setup_iso_path(uint16_t handle, uint8_t path_dir, uint8_t path_id, sdu_interval = lll_iso->sdu_interval; burst_number = lll_iso->bn; - group_sync_delay = ull_big_sync_delay(lll_iso); + group_sync_delay = ull_iso_big_sync_delay(lll_iso->num_bis, lll_iso->bis_spacing, + lll_iso->nse, lll_iso->sub_interval, + lll_iso->phy, lll_iso->max_pdu, + lll_iso->enc); stream_sync_delay = group_sync_delay - stream_handle * lll_iso->bis_spacing; framed = lll_iso->framing; max_octets = lll_iso->max_pdu; @@ -881,11 +887,14 @@ uint8_t ll_iso_receive_test(uint16_t handle, uint8_t payload_type) * BIG_Sync_Delay = (Num_BIS – 1) × BIS_Spacing * + (NSE – 1) × Sub_Interval + MPT. */ - group_sync_delay = ull_big_sync_delay(lll_iso); + group_sync_delay = ull_iso_big_sync_delay(lll_iso->num_bis, lll_iso->bis_spacing, + lll_iso->nse, lll_iso->sub_interval, + lll_iso->phy, lll_iso->max_pdu, + lll_iso->enc); stream_sync_delay = group_sync_delay - stream_handle * lll_iso->bis_spacing; role = ISOAL_ROLE_BROADCAST_SINK; - framed = 0; /* FIXME: Get value from biginfo */ + framed = lll_iso->framing; bn = lll_iso->bn; ft = 0; sdu_interval = lll_iso->sdu_interval; @@ -1497,15 +1506,38 @@ void ull_iso_lll_event_prepare(uint16_t handle, uint64_t event_count) isoal_tx_event_prepare(dp->source_hdl, event_count); } } else if (IS_ADV_ISO_HANDLE(handle)) { - /* Send event deadline trigger to ISO-AL. - * TODO: Can be unified with CIS implementation. - */ + struct ll_iso_datapath *dp = NULL; + struct lll_adv_iso_stream *stream; + uint16_t stream_handle; + + stream_handle = LL_BIS_ADV_IDX_FROM_HANDLE(handle); + stream = ull_adv_iso_stream_get(stream_handle); + + if (stream) { + dp = stream->dp; + } + + if (dp) { + isoal_tx_event_prepare(dp->source_hdl, event_count); + } } else { LL_ASSERT(0); } } #endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */ +#if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_SYNC_ISO) +uint32_t ull_iso_big_sync_delay(uint8_t num_bis, uint32_t bis_spacing, uint8_t nse, + uint32_t sub_interval, uint8_t phy, uint8_t max_pdu, bool enc) +{ + /* BT Core v5.4 - Vol 6, Part B, Section 4.4.6.4: + * BIG_Sync_Delay = (Num_BIS – 1) × BIS_Spacing + (NSE – 1) × Sub_Interval + MPT. + */ + return (num_bis - 1) * bis_spacing + (nse - 1) * sub_interval + + BYTES2US(PDU_OVERHEAD_SIZE(phy) + max_pdu + (enc ? 4 : 0), phy); +} +#endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_SYNC_ISO */ + #if defined(CONFIG_BT_CTLR_SYNC_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO) void *ull_iso_pdu_rx_alloc_peek(uint8_t count) { diff --git a/subsys/bluetooth/controller/ll_sw/ull_iso_internal.h b/subsys/bluetooth/controller/ll_sw/ull_iso_internal.h index cb7b1bb7cda..46b3983a25e 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_iso_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ull_iso_internal.h @@ -29,6 +29,8 @@ void ll_iso_rx_put(memq_link_t *link, void *rx); void *ll_iso_rx_get(void); void ll_iso_rx_dequeue(void); void ll_iso_transmit_test_send_sdu(uint16_t handle, uint32_t ticks_at_expire); +uint32_t ull_iso_big_sync_delay(uint8_t num_bis, uint32_t bis_spacing, uint8_t nse, + uint32_t sub_interval, uint8_t phy, uint8_t max_pdu, bool enc); /* Must be implemented by vendor if vendor-specific data path is supported */ bool ll_data_path_configured(uint8_t data_path_dir, uint8_t data_path_id); diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c b/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c index 841c9e01b5c..1f665ead76a 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c @@ -815,18 +815,6 @@ void ull_sync_iso_done_terminate(struct node_rx_event_done *done) (ret == TICKER_STATUS_BUSY)); } -uint32_t ull_big_sync_delay(const struct lll_sync_iso *lll_iso) -{ - /* BT Core v5.4 - Vol 6, Part B, Section 4.4.6.4: - * BIG_Sync_Delay = (Num_BIS – 1) × BIS_Spacing + (NSE – 1) × Sub_Interval + MPT. - */ - return (lll_iso->num_bis - 1) * lll_iso->bis_spacing + - (lll_iso->nse - 1) * lll_iso->sub_interval + - BYTES2US(PDU_OVERHEAD_SIZE(lll_iso->phy) + - lll_iso->max_pdu + (lll_iso->enc ? 4 : 0), - lll_iso->phy); -} - static void disable(uint8_t sync_idx) { struct ll_sync_iso_set *sync_iso; diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync_iso_internal.h b/subsys/bluetooth/controller/ll_sw/ull_sync_iso_internal.h index 19c5315bfee..ba2de603d22 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync_iso_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ull_sync_iso_internal.h @@ -15,4 +15,3 @@ void ull_sync_iso_setup(struct ll_sync_iso_set *sync_iso, void ull_sync_iso_estab_done(struct node_rx_event_done *done); void ull_sync_iso_done(struct node_rx_event_done *done); void ull_sync_iso_done_terminate(struct node_rx_event_done *done); -uint32_t ull_big_sync_delay(const struct lll_sync_iso *lll_iso);