Bluetooth: Controller: Collection of small fixes for BIS

Use PDU_BIS_LLID_FRAMED in empty PDUs for framed BIS

Allocate room for header when calculating max_pdu for framed BIS

Set group_sync_delay, stream_sync_delay and framed properly for BIS
broadcaster

Add missing call to isoal_tx_event_prepare() for BIS

Signed-off-by: Troels Nilsson <trnn@demant.com>
Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Troels Nilsson 2024-06-13 14:56:31 +02:00 committed by Anas Nashif
commit eea1573b2b
7 changed files with 66 additions and 26 deletions

View file

@ -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 +

View file

@ -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;

View file

@ -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);

View file

@ -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)
{

View file

@ -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);

View file

@ -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;

View file

@ -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);