Periodic Advertising with long periodic intervals


Carl Stehle
 

I am having some difficulty establishing and maintaining scan
synchronization to a Periodic Advertising train when the Periodic
Advertising interval is relatively long (e.g. 10+ seconds).

I am using 2 nRF52840 DK boards (v1.1.10 2019.9) and a post-Zephyr
v2.6.0 version (commit #1836f10bb701f2b20f18bc59ec943cc39f57a9fc).

The Advertiser is samples/bluetooth/periodic_adv (with modified
Periodic Advertising interval values of 8000 i.e. 10sec).

The Scanner is samples/bluetooth/periodic_sync

Synchronization works well with shorter intervals (and sometimes
with longer intervals).

I have two questions:

1. In subsys/bluetooth/controller/ll_sw/ull_scan_aux.c
   ull_scan_aux_setup(), should the block:

    if (aux_ptr->ca) {
        window_widening_us = aux_offset_us / 2000U;
    } else {
        window_widening_us = aux_offset_us / 20000U;
    }

be instead:

    if (aux_ptr->ca) {
        window_widening_us = aux_offset_us / 20000U;
    } else {
        window_widening_us = aux_offset_us / 2000U;
    }

The reason being that in the Core Specification 5.2 Vol 6, Part B
2.3.4.5 AuxPtr field, CA value of 0 is 51-500ppm so window widening
should be greater than for CA value of 1, which is 0-50ppm.


2. In subsys/bluetooth/controller/ll_sw/ull_sync.c: ull_sync_setup()
[and perhaps subsys/bluetooth/controller/ll_sw/ull_slave.c:
ull_slave_setup()], should the "remainder_periodic" argument to
ticker_start() equal the interval after window widening?

Currently, the "ticks_periodic" argument to ticker_start() is
computed from:
    interval_us -= lll->window_widening_periodic_us;
(presumably to advance the scan by the window widening amount?)
but "remainder_periodic" is also computed from the same value.

Perhaps:
  "ticks_periodic" = interval_us - lll->window_widening_periodic_us;
  "remainder_periodic" = interval_us + lll->window_widening_periodic_us;


Regards,
Carl


Chettimada, Vinayak Kariappa
 

Hi Carl,

 

Question 1, it is a bug, please feel free to send a pull request.

 

Question 2, the window widening requires that the packet is listened for earlier that the periodic interval, hence the reduced interval_us. And the window used is twice the window widening value in the lower link layer. Thereafter, the drift is compensated for based on successful anchor point reception. No action required in the implementation.

 

Regards,

Vinayak

 

From: devel@... <devel@...> On Behalf Of Carl Stehle via lists.zephyrproject.org
Sent: 26 June 2021 00:19
To: devel@...
Subject: [Zephyr-devel] Periodic Advertising with long periodic intervals

 

I am having some difficulty establishing and maintaining scan
synchronization to a Periodic Advertising train when the Periodic
Advertising interval is relatively long (e.g. 10+ seconds).

I am using 2 nRF52840 DK boards (v1.1.10 2019.9) and a post-Zephyr
v2.6.0 version (commit #1836f10bb701f2b20f18bc59ec943cc39f57a9fc).

The Advertiser is samples/bluetooth/periodic_adv (with modified
Periodic Advertising interval values of 8000 i.e. 10sec).

The Scanner is samples/bluetooth/periodic_sync

Synchronization works well with shorter intervals (and sometimes
with longer intervals).

I have two questions:

1. In subsys/bluetooth/controller/ll_sw/ull_scan_aux.c
   ull_scan_aux_setup(), should the block:

    if (aux_ptr->ca) {
        window_widening_us = aux_offset_us / 2000U;
    } else {
        window_widening_us = aux_offset_us / 20000U;
    }

be instead:

    if (aux_ptr->ca) {
        window_widening_us = aux_offset_us / 20000U;
    } else {
        window_widening_us = aux_offset_us / 2000U;
    }

The reason being that in the Core Specification 5.2 Vol 6, Part B
2.3.4.5 AuxPtr field, CA value of 0 is 51-500ppm so window widening
should be greater than for CA value of 1, which is 0-50ppm.


2. In subsys/bluetooth/controller/ll_sw/ull_sync.c: ull_sync_setup()
[and perhaps subsys/bluetooth/controller/ll_sw/ull_slave.c:
ull_slave_setup()], should the "remainder_periodic" argument to
ticker_start() equal the interval after window widening?

Currently, the "ticks_periodic" argument to ticker_start() is
computed from:
    interval_us -= lll->window_widening_periodic_us;
(presumably to advance the scan by the window widening amount?)
but "remainder_periodic" is also computed from the same value.

Perhaps:
  "ticks_periodic" = interval_us - lll->window_widening_periodic_us;
  "remainder_periodic" = interval_us + lll->window_widening_periodic_us;


Regards,
Carl