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:
parent
b1bcd799fb
commit
eea1573b2b
7 changed files with 66 additions and 26 deletions
|
@ -68,6 +68,7 @@
|
||||||
#include "ll_sw/ull_sync_internal.h"
|
#include "ll_sw/ull_sync_internal.h"
|
||||||
#include "ll_sw/ull_conn_internal.h"
|
#include "ll_sw/ull_conn_internal.h"
|
||||||
#include "ll_sw/ull_sync_iso_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_sw/ull_df_internal.h"
|
||||||
|
|
||||||
#include "ll.h"
|
#include "ll.h"
|
||||||
|
@ -7892,7 +7893,9 @@ static void le_big_sync_established(struct pdu_data *pdu,
|
||||||
* SDU_Interval
|
* SDU_Interval
|
||||||
*/
|
*/
|
||||||
iso_interval_us = lll->iso_interval * ISO_INT_UNIT_US;
|
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) {
|
if (lll->framing) {
|
||||||
/* Framed */
|
/* Framed */
|
||||||
transport_latency_big = big_sync_delay +
|
transport_latency_big = big_sync_delay +
|
||||||
|
|
|
@ -294,7 +294,7 @@ static int prepare_cb_common(struct lll_prepare_param *p)
|
||||||
|
|
||||||
if (!link) {
|
if (!link) {
|
||||||
pdu = radio_pkt_empty_get();
|
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;
|
pdu->len = 0U;
|
||||||
} else {
|
} else {
|
||||||
pdu = (void *)tx->pdu;
|
pdu = (void *)tx->pdu;
|
||||||
|
@ -650,7 +650,8 @@ static void isr_tx_common(void *param,
|
||||||
}
|
}
|
||||||
if (!link || (tx->payload_count != payload_count)) {
|
if (!link || (tx->payload_count != payload_count)) {
|
||||||
pdu = radio_pkt_empty_get();
|
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;
|
pdu->len = 0U;
|
||||||
} else {
|
} else {
|
||||||
pdu = (void *)tx->pdu;
|
pdu = (void *)tx->pdu;
|
||||||
|
|
|
@ -348,8 +348,15 @@ static uint8_t big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bi
|
||||||
lll_adv_iso->max_pdu = max_pdu;
|
lll_adv_iso->max_pdu = max_pdu;
|
||||||
iso_interval_us = iso_interval * PERIODIC_INT_UNIT_US;
|
iso_interval_us = iso_interval * PERIODIC_INT_UNIT_US;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
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 {
|
} else {
|
||||||
lll_adv_iso->max_pdu = MIN(LL_BIS_OCTETS_TX_MAX, max_sdu);
|
lll_adv_iso->max_pdu = MIN(LL_BIS_OCTETS_TX_MAX, max_sdu);
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: SDU per max latency */
|
/* FIXME: SDU per max latency */
|
||||||
sdu_per_event = MAX((max_latency * USEC_PER_MSEC / sdu_interval), 2U) -
|
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;
|
static struct lll_prepare_param p;
|
||||||
struct ll_adv_iso_set *adv_iso = param;
|
struct ll_adv_iso_set *adv_iso = param;
|
||||||
uint32_t remainder_us;
|
uint32_t remainder_us;
|
||||||
|
uint64_t event_count;
|
||||||
uint32_t ret;
|
uint32_t ret;
|
||||||
uint8_t ref;
|
uint8_t ref;
|
||||||
|
|
||||||
DEBUG_RADIO_PREPARE_A(1);
|
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 */
|
/* Increment prepare reference count */
|
||||||
ref = ull_ref_inc(&adv_iso->ull);
|
ref = ull_ref_inc(&adv_iso->ull);
|
||||||
LL_ASSERT(ref);
|
LL_ASSERT(ref);
|
||||||
|
|
|
@ -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;
|
sdu_interval = lll_iso->sdu_interval;
|
||||||
burst_number = lll_iso->bn;
|
burst_number = lll_iso->bn;
|
||||||
flush_timeout = 0U; /* Not used for Broadcast ISO */
|
flush_timeout = 0U; /* Not used for Broadcast ISO */
|
||||||
group_sync_delay = 0U; /* FIXME: */
|
group_sync_delay = ull_iso_big_sync_delay(lll_iso->num_bis, lll_iso->bis_spacing,
|
||||||
stream_sync_delay = 0U; /* FIXME: */
|
lll_iso->nse, lll_iso->sub_interval,
|
||||||
framed = 0U; /* FIXME: pick the framing value from context */
|
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;
|
max_octets = lll_iso->max_pdu;
|
||||||
#endif /* CONFIG_BT_CTLR_ADV_ISO */
|
#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;
|
sdu_interval = lll_iso->sdu_interval;
|
||||||
burst_number = lll_iso->bn;
|
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;
|
stream_sync_delay = group_sync_delay - stream_handle * lll_iso->bis_spacing;
|
||||||
framed = lll_iso->framing;
|
framed = lll_iso->framing;
|
||||||
max_octets = lll_iso->max_pdu;
|
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
|
* BIG_Sync_Delay = (Num_BIS – 1) × BIS_Spacing
|
||||||
* + (NSE – 1) × Sub_Interval + MPT.
|
* + (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;
|
stream_sync_delay = group_sync_delay - stream_handle * lll_iso->bis_spacing;
|
||||||
|
|
||||||
role = ISOAL_ROLE_BROADCAST_SINK;
|
role = ISOAL_ROLE_BROADCAST_SINK;
|
||||||
framed = 0; /* FIXME: Get value from biginfo */
|
framed = lll_iso->framing;
|
||||||
bn = lll_iso->bn;
|
bn = lll_iso->bn;
|
||||||
ft = 0;
|
ft = 0;
|
||||||
sdu_interval = lll_iso->sdu_interval;
|
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);
|
isoal_tx_event_prepare(dp->source_hdl, event_count);
|
||||||
}
|
}
|
||||||
} else if (IS_ADV_ISO_HANDLE(handle)) {
|
} else if (IS_ADV_ISO_HANDLE(handle)) {
|
||||||
/* Send event deadline trigger to ISO-AL.
|
struct ll_iso_datapath *dp = NULL;
|
||||||
* TODO: Can be unified with CIS implementation.
|
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 {
|
} else {
|
||||||
LL_ASSERT(0);
|
LL_ASSERT(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_CONN_ISO */
|
#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)
|
#if defined(CONFIG_BT_CTLR_SYNC_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO)
|
||||||
void *ull_iso_pdu_rx_alloc_peek(uint8_t count)
|
void *ull_iso_pdu_rx_alloc_peek(uint8_t count)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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_get(void);
|
||||||
void ll_iso_rx_dequeue(void);
|
void ll_iso_rx_dequeue(void);
|
||||||
void ll_iso_transmit_test_send_sdu(uint16_t handle, uint32_t ticks_at_expire);
|
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 */
|
/* 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);
|
bool ll_data_path_configured(uint8_t data_path_dir, uint8_t data_path_id);
|
||||||
|
|
|
@ -815,18 +815,6 @@ void ull_sync_iso_done_terminate(struct node_rx_event_done *done)
|
||||||
(ret == TICKER_STATUS_BUSY));
|
(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)
|
static void disable(uint8_t sync_idx)
|
||||||
{
|
{
|
||||||
struct ll_sync_iso_set *sync_iso;
|
struct ll_sync_iso_set *sync_iso;
|
||||||
|
|
|
@ -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_estab_done(struct node_rx_event_done *done);
|
||||||
void ull_sync_iso_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);
|
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);
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue