You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by an...@apache.org on 2024/10/01 09:03:35 UTC
(mynewt-nimble) branch master updated (5baa3f4ba -> b6d7261d7)
This is an automated email from the ASF dual-hosted git repository.
andk pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
from 5baa3f4ba docs: Fix the layout in multiple .rst files for the PDF output
new 64d5000f7 nimble/ll: Fix periodic advertising event timing
new b6d7261d7 nimble/ll: Fix BIG event scheduling relative to padv
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
nimble/controller/include/controller/ble_ll_adv.h | 6 +-
nimble/controller/src/ble_ll_adv.c | 97 +++++++++++++----------
nimble/controller/src/ble_ll_iso_big.c | 35 ++++----
3 files changed, 73 insertions(+), 65 deletions(-)
(mynewt-nimble) 02/02: nimble/ll: Fix BIG event scheduling relative to padv
Posted by an...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
commit b6d7261d75028226ea01decab0fa5281c0eecbe8
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Mon Sep 23 17:34:41 2024 +0200
nimble/ll: Fix BIG event scheduling relative to padv
This fixes scheduling of BIG events relative to padv.
The start time of a BIG event should be relative to padv event start,
not padv sched start time which in theory may be different if that's not
for the 1st AUX_SYNC_IND.
Also if padv event start time is in the past, we still need to schedule
BIG event in the future instead of just failing.
---
nimble/controller/include/controller/ble_ll_adv.h | 6 ++--
nimble/controller/src/ble_ll_adv.c | 17 ++++++-----
nimble/controller/src/ble_ll_iso_big.c | 35 +++++++++++------------
3 files changed, 28 insertions(+), 30 deletions(-)
diff --git a/nimble/controller/include/controller/ble_ll_adv.h b/nimble/controller/include/controller/ble_ll_adv.h
index db35209dc..6c332faf3 100644
--- a/nimble/controller/include/controller/ble_ll_adv.h
+++ b/nimble/controller/include/controller/ble_ll_adv.h
@@ -201,9 +201,9 @@ int ble_ll_adv_periodic_set_info_transfer(const uint8_t *cmdbuf, uint8_t len,
/* Get advertising instance with periodic advertising configured */
struct ble_ll_adv_sm *ble_ll_adv_sync_get(uint8_t handle);
-/* Get periodic advertising event scheduled time */
-int ble_ll_adv_sync_sched_get(struct ble_ll_adv_sm *advsm,
- uint32_t *start_time, uint32_t *end_time);
+int ble_ll_adv_padv_event_start_get(struct ble_ll_adv_sm *advsm,
+ uint32_t *event_start,
+ uint8_t *event_start_rem_us);
#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
struct ble_ll_iso_big;
diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c
index d8eaaaf3a..809a88776 100644
--- a/nimble/controller/src/ble_ll_adv.c
+++ b/nimble/controller/src/ble_ll_adv.c
@@ -5337,19 +5337,18 @@ ble_ll_adv_sync_get(uint8_t handle)
}
int
-ble_ll_adv_sync_sched_get(struct ble_ll_adv_sm *advsm, uint32_t *start_time,
- uint32_t *end_time)
+ble_ll_adv_padv_event_start_get(struct ble_ll_adv_sm *advsm,
+ uint32_t *event_start,
+ uint8_t *event_start_rem_us)
{
- struct ble_ll_adv_sync *sync;
-
if (!advsm || !advsm->periodic_adv_active) {
- return -EIO;
+ return -EINVAL;
}
- sync = SYNC_CURRENT(advsm);
-
- *start_time = sync->sch.start_time + g_ble_ll_sched_offset_ticks;
- *end_time = sync->sch.end_time;
+ *event_start = advsm->padv_event_start;
+ if (event_start_rem_us) {
+ *event_start_rem_us = advsm->padv_event_start_rem_us;
+ }
return 0;
}
diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c
index b07e5c1d8..19af3e61f 100644
--- a/nimble/controller/src/ble_ll_iso_big.c
+++ b/nimble/controller/src/ble_ll_iso_big.c
@@ -1111,41 +1111,40 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
* not enough for some phys to run scheduler item.
*/
- uint32_t start_time, end_time, big_time;
+ uint32_t padv_start_time, big_start_time;
uint32_t sync_delay_ticks = ble_ll_tmr_u2t_up(big->sync_delay);
- uint32_t iso_interval_ticks = ble_ll_tmr_u2t_up(big->iso_interval * 1250);
int big_event_fixed;
- rc = ble_ll_adv_sync_sched_get(big->advsm, &start_time, &end_time);
+ rc = ble_ll_adv_padv_event_start_get(big->advsm, &padv_start_time, NULL);
if (rc) {
- /* Set 1st BIG one interval after "now", this ensures it's always
- * scheduled in the future.
- */
- big_time = ble_ll_tmr_get() + iso_interval_ticks;
+ /* 1st event will be moved by 1 interval before scheduling so this will
+ * be always in the future */
+ big_start_time = ble_ll_tmr_get();
big_event_fixed = 0;
} else {
/* Set 1st BIG event directly before periodic advertising event, this
* way it will not overlap it even if periodic advertising data changes.
* Make sure it's in the future.
*/
- big_time = start_time - g_ble_ll_sched_offset_ticks - sync_delay_ticks - 1;
- while (big_time - g_ble_ll_sched_offset_ticks < ble_ll_tmr_get()) {
- big_time += iso_interval_ticks;
- }
+ big_start_time = padv_start_time - g_ble_ll_sched_offset_ticks -
+ sync_delay_ticks - 1;
big_event_fixed = 1;
}
- big->anchor_base_ticks = big_time;
+ big->anchor_base_ticks = big_start_time;
big->anchor_base_rem_us = 0;
big->anchor_offset = 0;
- big_sched_set(big);
+ do {
+ big->anchor_offset++;
+ big_sched_set(big);
- rc = ble_ll_sched_iso_big(&big->sch, 1, big_event_fixed);
- if (rc < 0) {
- ble_ll_iso_big_free(big);
- return -EFAULT;
- }
+ if (LL_TMR_LEQ(big->sch.start_time, ble_ll_tmr_get())) {
+ rc = -1;
+ } else {
+ rc = ble_ll_sched_iso_big(&big->sch, 1, big_event_fixed);
+ }
+ } while (rc < 0);
ble_ll_iso_big_update_event_start(big);
(mynewt-nimble) 01/02: nimble/ll: Fix periodic advertising event timing
Posted by an...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
commit 64d5000f7257c774e17235c1f96d85eda28c0971
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Mon Sep 23 15:03:21 2024 +0200
nimble/ll: Fix periodic advertising event timing
This modifies padv event start time calculations to use single event
start time as anchor and calculate subsequent event start times as an
offset from that event.
This virtually removes drift due to rounding errors and avoids relative
drift of padv vs. BIG events.
---
nimble/controller/src/ble_ll_adv.c | 80 +++++++++++++++++++++-----------------
1 file changed, 45 insertions(+), 35 deletions(-)
diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c
index f194ec21c..d8eaaaf3a 100644
--- a/nimble/controller/src/ble_ll_adv.c
+++ b/nimble/controller/src/ble_ll_adv.c
@@ -170,10 +170,16 @@ struct ble_ll_adv_sm
uint8_t periodic_num_used_chans;
uint8_t periodic_chanmap[BLE_LL_CHAN_MAP_LEN];
uint16_t periodic_adv_itvl;
- uint32_t periodic_adv_itvl_ticks;
- uint8_t periodic_adv_itvl_rem_us;
- uint8_t periodic_adv_event_start_time_remainder;
- uint32_t periodic_adv_event_start_time;
+
+ uint32_t padv_itvl_us;
+
+ uint16_t padv_anchor_offset;
+ uint32_t padv_anchor;
+ uint8_t padv_anchor_rem_us;
+
+ uint32_t padv_event_start;
+ uint8_t padv_event_start_rem_us;
+
struct ble_ll_adv_sync periodic_sync[2];
struct ble_npl_event adv_periodic_txdone_ev;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
@@ -639,20 +645,20 @@ ble_ll_adv_put_syncinfo(struct ble_ll_adv_sm *advsm,
conn_cnt = connsm->event_cntr;
/* get anchor for conn event that is before periodic_adv_event_start_time */
- while (LL_TMR_GT(anchor_ticks, advsm->periodic_adv_event_start_time)) {
+ while (LL_TMR_GT(anchor_ticks, advsm->padv_event_start)) {
ble_ll_conn_get_anchor(connsm, --conn_cnt, &anchor_ticks, &anchor_rem_us);
}
- offset = ble_ll_tmr_t2u(advsm->periodic_adv_event_start_time - anchor_ticks);
+ offset = ble_ll_tmr_t2u(advsm->padv_event_start - anchor_ticks);
offset -= anchor_rem_us;
- offset += advsm->periodic_adv_event_start_time_remainder;
+ offset += advsm->padv_event_start_rem_us;
/* connEventCount */
put_le16(conn_event_cnt, conn_cnt);
#endif
} else {
- anchor_ticks = advsm->periodic_adv_event_start_time;
- anchor_rem_us = advsm->periodic_adv_event_start_time_remainder;
+ anchor_ticks = advsm->padv_event_start;
+ anchor_rem_us = advsm->padv_event_start_rem_us;
itvl_us = advsm->periodic_adv_itvl * BLE_LL_ADV_PERIODIC_ITVL;
/* Get periodic event that is past AUX start time (so that we always
@@ -2420,7 +2426,7 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm,
* Preincrement event counter as we later send this in PDU so make sure
* same values are used
*/
- chan = ble_ll_utils_dci_csa2(++advsm->periodic_event_cntr,
+ chan = ble_ll_utils_dci_csa2(advsm->periodic_event_cntr,
advsm->periodic_channel_id,
advsm->periodic_num_used_chans,
advsm->periodic_chanmap);
@@ -2432,14 +2438,20 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm,
sch = &sync->sch;
- ble_ll_tmr_add_u(&advsm->periodic_adv_event_start_time,
- &advsm->periodic_adv_event_start_time_remainder,
- advsm->periodic_adv_itvl_rem_us);
+ advsm->padv_event_start = advsm->padv_anchor;
+ advsm->padv_event_start_rem_us = advsm->padv_anchor_rem_us;
+ ble_ll_tmr_add(&advsm->padv_event_start, &advsm->padv_event_start_rem_us,
+ advsm->padv_itvl_us * advsm->padv_anchor_offset);
+
+ if (advsm->padv_anchor_offset == UINT16_MAX) {
+ advsm->padv_anchor_offset = 0;
+ advsm->padv_anchor = advsm->padv_event_start;
+ advsm->padv_anchor_rem_us = advsm->padv_event_start_rem_us;
+ }
- sch->start_time = advsm->periodic_adv_event_start_time;
- sch->remainder = advsm->periodic_adv_event_start_time_remainder;
- sch->end_time = sch->start_time + ble_ll_tmr_u2t_up(max_usecs);
- sch->start_time -= g_ble_ll_sched_offset_ticks;
+ sch->start_time = advsm->padv_event_start - g_ble_ll_sched_offset_ticks;
+ sch->remainder = advsm->padv_event_start_rem_us;
+ sch->end_time = advsm->padv_event_start + ble_ll_tmr_u2t_up(max_usecs);
rc = ble_ll_sched_periodic_adv(sch, first_pdu);
if (rc) {
@@ -2451,10 +2463,14 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm,
sync->start_time = sch->start_time + g_ble_ll_sched_offset_ticks;
assert(first_pdu ||
- (sync->start_time == advsm->periodic_adv_event_start_time));
+ (sync->start_time == advsm->padv_event_start));
- /* The event start time is when we start transmission of the SYNC PDU */
- advsm->periodic_adv_event_start_time = sync->start_time;
+ if (first_pdu) {
+ /* Need to update anchor on 1st PDU since it's start time can be changed
+ * while scheduling */
+ advsm->padv_anchor = sync->start_time;
+ advsm->padv_event_start = sync->start_time;
+ }
}
static void
@@ -2535,8 +2551,8 @@ ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm)
* is scheduled past advertising interval.
*/
if (sync->auxptr_zero ||
- (LL_TMR_GT(sch->end_time, advsm->periodic_adv_event_start_time +
- advsm->periodic_adv_itvl_ticks))) {
+ (LL_TMR_GT(sch->end_time, advsm->padv_event_start +
+ advsm->periodic_adv_itvl))) {
STATS_INC(ble_ll_stats, periodic_chain_drop_event);
ble_ll_sched_rmv_elem(&sync->sch);
}
@@ -2560,7 +2576,9 @@ ble_ll_adv_sync_schedule(struct ble_ll_adv_sm *advsm, bool first_pdu)
static void
ble_ll_adv_reschedule_periodic_event(struct ble_ll_adv_sm *advsm)
{
- advsm->periodic_adv_event_start_time += advsm->periodic_adv_itvl_ticks;
+ advsm->periodic_event_cntr++;
+ advsm->padv_anchor_offset++;
+
ble_ll_adv_sync_schedule(advsm, false);
}
@@ -2634,8 +2652,6 @@ ble_ll_adv_periodic_event_done(struct ble_npl_event *ev)
static void
ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm)
{
- uint32_t usecs;
-
/*
* The Advertising DID is not required to change when a SyncInfo field is
* added to or removed from an advertising set. However, if it does not
@@ -2660,16 +2676,9 @@ ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm)
(advsm->periodic_access_addr & 0x0000ffff);
advsm->periodic_crcinit = ble_ll_rand() & 0xffffff;
- usecs = (uint32_t)advsm->periodic_adv_itvl * BLE_LL_ADV_PERIODIC_ITVL;
- advsm->periodic_adv_itvl_ticks = ble_ll_tmr_u2t_r(usecs,
- &advsm->periodic_adv_itvl_rem_us);
-
- /* There is no point in starting periodic advertising until next advertising
- * event since SyncInfo is needed for synchronization
- */
- advsm->periodic_adv_event_start_time_remainder = 0;
- advsm->periodic_adv_event_start_time = advsm->adv_pdu_start_time +
- ble_ll_tmr_u2t(advsm->adv_itvl_usecs + 5000);
+ advsm->padv_anchor_offset = 1;
+ advsm->padv_anchor = ble_ll_tmr_get();
+ advsm->padv_anchor_rem_us = 0;
ble_ll_adv_sync_schedule(advsm, true);
}
@@ -3977,6 +3986,7 @@ ble_ll_adv_periodic_set_param(const uint8_t *cmdbuf, uint8_t len)
}
advsm->periodic_adv_itvl = adv_itvl_max;
+ advsm->padv_itvl_us = adv_itvl_max * BLE_LL_ADV_PERIODIC_ITVL;
advsm->periodic_adv_props = props;
ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_CONFIGURED);