diff --git a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h index 31e2f70fcd6..676c574155e 100644 --- a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h +++ b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h @@ -45,7 +45,8 @@ struct lll_conn_iso_stream { struct lll_conn_iso_stream_rxtx tx; /* TX parameters */ /* Event and payload counters */ - uint64_t event_count:39; /* cisEventCount */ + uint64_t event_count_prepare:39; /* cisEventCount in overlapping CIG prepare */ + uint64_t event_count:39; /* cisEventCount in current CIG event */ /* Acknowledgment and flow control */ uint8_t sn:1; /* Sequence number */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index 065b058f8fd..526403e92d9 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -150,6 +150,9 @@ static int prepare_cb(struct lll_prepare_param *p) /* Get reference to ACL context */ conn_lll = ull_conn_lll_get(cis_lll->acl_handle); + /* Pick the event_count calculated in the ULL prepare */ + cis_lll->event_count = cis_lll->event_count_prepare; + /* Event counter value, 0-15 bit of cisEventCounter */ event_counter = cis_lll->event_count; @@ -357,6 +360,9 @@ static int prepare_cb(struct lll_prepare_param *p) do { cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); if (cis_lll && cis_lll->active) { + /* Pick the event_count calculated in the ULL prepare */ + cis_lll->event_count = cis_lll->event_count_prepare; + /* Adjust sn and nesn for skipped CIG events */ payload_count_lazy_update(cis_lll, cig_lll->latency_event); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index 3ff20706dc6..00e641fd151 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -164,6 +164,9 @@ static int prepare_cb(struct lll_prepare_param *p) /* Get reference to ACL context */ conn_lll = ull_conn_lll_get(cis_lll->acl_handle); + /* Pick the event_count calculated in the ULL prepare */ + cis_lll->event_count = cis_lll->event_count_prepare; + /* Event counter value, 0-15 bit of cisEventCounter */ event_counter = cis_lll->event_count; @@ -374,6 +377,9 @@ static int prepare_cb(struct lll_prepare_param *p) break; } + /* Pick the event_count calculated in the ULL prepare */ + cis_lll->event_count = cis_lll->event_count_prepare; + /* Adjust sn and nesn for skipped CIG events */ payload_count_lazy(cis_lll, cig_lll->latency_event); diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index fa3e3715664..d49256e3b09 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -929,6 +929,11 @@ uint8_t ull_central_iso_setup(uint16_t cis_handle, #if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE) cis->pkt_seq_num = 0U; #endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ + /* It is intentional to initialize to the 39 bit maximum value and rollover to 0 in the + * prepare function, the event counter is pre-incremented in prepare function for the + * current ISO event. + */ + cis->lll.event_count_prepare = LLL_CONN_ISO_EVENT_COUNT_MAX; cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX; cis->lll.next_subevent = 0U; cis->lll.tifs_us = conn->lll.tifs_cis_us; diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c index a55d023668f..b25267a34bd 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c @@ -711,17 +711,17 @@ void ull_conn_iso_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift, * has been reached, and offset calculated. */ if (cis->lll.handle != 0xFFFF && cis->lll.active) { - cis->lll.event_count += (lazy + 1U); + cis->lll.event_count_prepare += (lazy + 1U); #if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING) - cis->lll.event_count -= cis->lll.lazy_active; + cis->lll.event_count_prepare -= cis->lll.lazy_active; cis->lll.lazy_active = 0U; #endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */ leading_event_count = MAX(leading_event_count, - cis->lll.event_count); + cis->lll.event_count_prepare); - ull_iso_lll_event_prepare(cis->lll.handle, cis->lll.event_count); + ull_iso_lll_event_prepare(cis->lll.handle, cis->lll.event_count_prepare); } /* Latch datapath validity entering event */ @@ -975,7 +975,7 @@ void ull_conn_iso_start(struct ll_conn *conn, uint16_t cis_handle, cis_offset = cis->offset + iso_interval_us - acl_latency_us; } - cis->lll.event_count += lost_cig_events; + cis->lll.event_count_prepare += lost_cig_events; lost_payloads = (lost_cig_events - (cis->lll.rx.ft - 1)) * cis->lll.rx.bn; cis->lll.rx.payload_count += lost_payloads; @@ -1520,7 +1520,7 @@ void ull_conn_iso_transmit_test_cig_interval(uint16_t handle, uint32_t ticks_at_ * on 64-bit sdu_counter: * (39 bits x 22 bits (4x10^6 us) = 61 bits / 8 bits (255 us) = 53 bits) */ - sdu_counter = DIV_ROUND_UP((cis->lll.event_count + 1U) * iso_interval, + sdu_counter = DIV_ROUND_UP((cis->lll.event_count_prepare + 1U) * iso_interval, sdu_interval); if (cis->hdr.test_mode.tx.sdu_counter == 0U) { diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c index 345fddb8746..77b3f240f1b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c @@ -333,6 +333,11 @@ uint8_t ull_peripheral_iso_setup(struct pdu_data_llctrl_cis_ind *ind, #if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE) cis->pkt_seq_num = 0U; #endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ + /* It is intentional to initialize to the 39 bit maximum value and rollover to 0 in the + * prepare function, the event counter is pre-incremented in prepare function for the + * current ISO event. + */ + cis->lll.event_count_prepare = LLL_CONN_ISO_EVENT_COUNT_MAX; cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX; cis->lll.next_subevent = 0U; cis->lll.tifs_us = conn->lll.tifs_cis_us;