Commit 210c27e3 authored by Vinayak Kariappa Chettimada's avatar Vinayak Kariappa Chettimada Committed by Anas Nashif
Browse files

Bluetooth: controller: Fix conn update assert in slave role

Explicitly track the connection update related ticker stop
and start to avoid asserting due to ticker update being done
at the same time for compensating the clock drift.

The compensation related ticker update failure in this case
can be safely ignored as new anchor point is used anyway
at the instant of the connection update.

Fixes #8796

Signed-off-by: default avatarVinayak Kariappa Chettimada <vich@nordicsemi.no>
parent 3637202c
Loading
Loading
Loading
Loading
+34 −17
Changes for subsys/bluetooth/controller/ll_sw/ctrl.c: 34 added lines, 17 removed lines.
Original line number Diff line number Diff line
@@ -167,6 +167,7 @@ static struct {
	u8_t  volatile ticker_id_prepare;
	u8_t  volatile ticker_id_event;
	u8_t  volatile ticker_id_stop;
	u8_t  volatile ticker_id_upd;

	enum  role volatile role;
	enum  state state;
@@ -250,10 +251,12 @@ static u16_t const gc_lookup_ppm[] = { 500, 250, 150, 100, 75, 50, 30, 20 };

static void common_init(void);
static void ticker_success_assert(u32_t status, void *params);
static void ticker_update_adv_assert(u32_t status, void *params);
static void ticker_stop_adv_assert(u32_t status, void *params);
static void ticker_stop_scan_assert(u32_t status, void *params);
static void ticker_update_adv_assert(u32_t status, void *params);
static void ticker_update_slave_assert(u32_t status, void *params);
static void ticker_stop_slave_assert(u32_t status, void *params);
static void ticker_start_slave_assert(u32_t status, void *params);
static void event_inactive(u32_t ticks_at_expire, u32_t remainder,
			   u16_t lazy, void *context);

@@ -4459,6 +4462,14 @@ static void ticker_success_assert(u32_t status, void *params)
	LL_ASSERT(status == TICKER_STATUS_SUCCESS);
}

static void ticker_update_adv_assert(u32_t status, void *params)
{
	ARG_UNUSED(params);

	LL_ASSERT((status == TICKER_STATUS_SUCCESS) ||
		  (_radio.ticker_id_stop == RADIO_TICKER_ID_ADV));
}

static void ticker_stop_adv_assert(u32_t status, void *params)
{
	ARG_UNUSED(params);
@@ -4509,20 +4520,27 @@ static void ticker_stop_scan_assert(u32_t status, void *params)
	}
}

static void ticker_update_adv_assert(u32_t status, void *params)
static void ticker_update_slave_assert(u32_t status, void *params)
{
	ARG_UNUSED(params);
	u8_t ticker_id = (u32_t)params & 0xFF;

	LL_ASSERT((status == TICKER_STATUS_SUCCESS) ||
		  (_radio.ticker_id_stop == RADIO_TICKER_ID_ADV));
		  (_radio.ticker_id_stop == ticker_id) ||
		  (_radio.ticker_id_upd == ticker_id));
}

static void ticker_update_slave_assert(u32_t status, void *params)
static void ticker_stop_slave_assert(u32_t status, void *params)
{
	u8_t ticker_id = (u32_t)params & 0xFF;
	LL_ASSERT(status == TICKER_STATUS_SUCCESS);

	LL_ASSERT((status == TICKER_STATUS_SUCCESS) ||
		  (_radio.ticker_id_stop == ticker_id));
	_radio.ticker_id_upd = (u8_t)((u32_t)params & 0xFF);
}

static void ticker_start_slave_assert(u32_t status, void *params)
{
	LL_ASSERT(status == TICKER_STATUS_SUCCESS);

	_radio.ticker_id_upd = 0;
}

static void mayfly_radio_active(void *params)
@@ -6729,6 +6747,7 @@ static inline u32_t event_conn_upd_prep(struct connection *conn,
		u32_t conn_interval_us;
		u32_t ticker_status;
		u32_t periodic_us;
		u8_t ticker_id;
		u16_t latency;

		/* procedure request acked */
@@ -6893,19 +6912,17 @@ static inline u32_t event_conn_upd_prep(struct connection *conn,
			      RADIO_TICKER_USER_ID_JOB, 0);

		/* start slave/master with new timings */
		ticker_id = RADIO_TICKER_ID_FIRST_CONNECTION + conn->handle;
		ticker_status =
			ticker_stop(RADIO_TICKER_INSTANCE_ID_RADIO,
				    RADIO_TICKER_USER_ID_WORKER,
				    RADIO_TICKER_ID_FIRST_CONNECTION +
				    conn->handle, ticker_success_assert,
				    (void *)__LINE__);
				    RADIO_TICKER_USER_ID_WORKER, ticker_id,
				    ticker_stop_slave_assert,
				    (void *)(u32_t)ticker_id);
		LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
			  (ticker_status == TICKER_STATUS_BUSY));
		ticker_status =
			ticker_start(RADIO_TICKER_INSTANCE_ID_RADIO,
				     RADIO_TICKER_USER_ID_WORKER,
				     RADIO_TICKER_ID_FIRST_CONNECTION +
				     conn->handle,
				     RADIO_TICKER_USER_ID_WORKER, ticker_id,
				     ticks_at_expire, ticks_win_offset,
				     HAL_TICKER_US_TO_TICKS(periodic_us),
				     HAL_TICKER_REMAINDER(periodic_us),
@@ -6913,8 +6930,8 @@ static inline u32_t event_conn_upd_prep(struct connection *conn,
				     (ticks_slot_offset + conn->hdr.ticks_slot),
				     conn->role ?
				     event_slave_prepare : event_master_prepare,
				     conn, ticker_success_assert,
				     (void *)__LINE__);
				     conn, ticker_start_slave_assert,
				     (void *)(u32_t)ticker_id);
		LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
			  (ticker_status == TICKER_STATUS_BUSY));