diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h index 10d780a559c..1a5c1a3f8a7 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ticker.h @@ -68,8 +68,9 @@ HAL_TICKER_TICKS_TO_US(HAL_TICKER_PSEC_PER_USEC) /* Macro defining the margin for positioning re-scheduled nodes */ +#define HAL_TICKER_RESCHEDULE_MARGIN_US 150U #define HAL_TICKER_RESCHEDULE_MARGIN \ - HAL_TICKER_US_TO_TICKS(150) + HAL_TICKER_US_TO_TICKS(HAL_TICKER_RESCHEDULE_MARGIN_US) /* Remove ticks and return positive remainder value in microseconds */ static inline void hal_ticker_remove_jitter(uint32_t *ticks, diff --git a/subsys/bluetooth/controller/ticker/ticker.c b/subsys/bluetooth/controller/ticker/ticker.c index 639cd0ed57d..efeeff1bae7 100644 --- a/subsys/bluetooth/controller/ticker/ticker.c +++ b/subsys/bluetooth/controller/ticker/ticker.c @@ -840,6 +840,7 @@ static uint8_t ticker_resolve_collision(struct ticker_node *nodes, while (id_head != TICKER_NULL) { struct ticker_node *ticker_next = &nodes[id_head]; + uint32_t ticker_next_ticks_slot; /* Accumulate ticks_to_expire for each node */ acc_ticks_to_expire += ticker_next->ticks_to_expire; @@ -847,8 +848,17 @@ static uint8_t ticker_resolve_collision(struct ticker_node *nodes, break; } + if (TICKER_HAS_SLOT_WINDOW(ticker_next) && + (ticker_next->ticks_slot == 0U)) { + ticker_next_ticks_slot = + HAL_TICKER_RESCHEDULE_MARGIN; + } else { + ticker_next_ticks_slot = + ticker_next->ticks_slot; + } + /* We only care about nodes with slot reservation */ - if (ticker_next->ticks_slot == 0U) { + if (ticker_next_ticks_slot == 0U) { id_head = ticker_next->next; continue; } @@ -977,7 +987,8 @@ static uint8_t ticker_resolve_collision(struct ticker_node *nodes, /* Check if next node is within this reservation slot * and wins conflict resolution */ - if (curr_has_ticks_slot_window || + if ((curr_has_ticks_slot_window && + next_not_ticks_slot_window) || (!lazy_next_periodic_skip && (next_is_critical || next_force || @@ -1295,11 +1306,19 @@ void ticker_worker(void *param) #if !defined(CONFIG_BT_TICKER_LOW_LAT) && \ !defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC) + uint32_t ticker_ticks_slot; + + if (TICKER_HAS_SLOT_WINDOW(ticker) && + (ticker->ticks_slot == 0U)) { + ticker_ticks_slot = HAL_TICKER_RESCHEDULE_MARGIN; + } else { + ticker_ticks_slot = ticker->ticks_slot; + } + /* Check if node has slot reservation and resolve any collision * with other ticker nodes */ - if (((ticker->ticks_slot != 0U) || - TICKER_HAS_SLOT_WINDOW(ticker)) && + if ((ticker_ticks_slot != 0U) && (slot_reserved || (instance->ticks_slot_previous > ticks_expired) || ticker_resolve_collision(node, ticker))) { @@ -1431,7 +1450,7 @@ void ticker_worker(void *param) #if !defined(CONFIG_BT_TICKER_LOW_LAT) && \ !defined(CONFIG_BT_TICKER_SLOT_AGNOSTIC) - if (ticker->ticks_slot != 0U) { + if (ticker_ticks_slot != 0U) { /* Any further nodes will be skipped */ slot_reserved = 1U; } @@ -2061,13 +2080,21 @@ static inline void ticker_job_worker_bh(struct ticker_instance *instance, instance->ticks_slot_previous = 0U; } + uint32_t ticker_ticks_slot; + + if (TICKER_HAS_SLOT_WINDOW(ticker) && !ticker->ticks_slot) { + ticker_ticks_slot = HAL_TICKER_RESCHEDULE_MARGIN; + } else { + ticker_ticks_slot = ticker->ticks_slot; + } + /* If a reschedule is set pending, we will need to keep * the slot_previous information */ - if (ticker->ticks_slot && (state == 2U) && !skip_collision && + if (ticker_ticks_slot && (state == 2U) && !skip_collision && !TICKER_RESCHEDULE_PENDING(ticker)) { instance->ticker_id_slot_previous = id_expired; - instance->ticks_slot_previous = ticker->ticks_slot; + instance->ticks_slot_previous = ticker_ticks_slot; } #endif /* CONFIG_BT_TICKER_SLOT_AGNOSTIC */